[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/driver/tty/src/excp_tty_ut.c b/mcu/driver/tty/src/excp_tty_ut.c
new file mode 100644
index 0000000..0dbaa4c
--- /dev/null
+++ b/mcu/driver/tty/src/excp_tty_ut.c
@@ -0,0 +1,767 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * excp_tty_ut.c
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * TTY Core unit test file in exception mode - it needs Host Test Program to run test.
+ * It works with enabling compile flag __EXCEPT_TTY_UT__.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ * 03 11 2015 i-wei.tsai
+ * [MOLY00097392] [UMOLY] [TTY] Timer tick macro modification
+ * .
+ *
+ * 09 13 2013 i-wei.tsai
+ * [MOLY00037205] [CCCI Exception] CCCI exception mode 1st check-in.
+ * CCCI Exception IT
+ *
+ * 06 26 2013 i-wei.tsai
+ * [MOLY00027496] [TTYCore] Features check-in
+ * 1. add new TTY_CMD_MTU_SIZE support
+ * 2. add plug-in/plug-out indication
+ * 3. fix issue of flushing rx internal gpd
+ *
+ * 05 29 2013 haoren.kao
+ * [MOLY00024108] Support New USB Core
+ * Replace with New USB Core.
+ * We sync with the following codes from HaoRen MOLY CBr w1322:
+ * 1. USB Core
+ * 2. USB Class - acm/rndis/mbim
+ * 3. ipcore
+ * 4. ttycore
+ * 5. ethercore
+ *
+ * 11 12 2012 haoren.kao
+ * [MOLY00005322] TATAKA merge to MOLY
+ * * Shorten the busy loop time from about 5 ms to 10 us in order to avoid host test program SetCommState timeout.
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "dcl.h"
+#include "hmu.h"
+#include "kal_debug.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+#include "syscomp_config.h"
+
+#include "devdrv_ls.h"
+#include "drv_msgid.h"
+#include "md_drv_sap.h"
+#include "kal_public_defs.h"
+
+
+//#define __EXPT_CCCI_TTY_IT__
+
+#ifdef __EXPT_CCCI_TTY_IT__
+#define EXCEPTION_TEST_PORT uart_port_dhl_sp_expt
+//#define EXCEPTION_TEST_PORT uart_port_dhl_ctrl_sp_expt
+#else
+#define EXCEPTION_TEST_PORT uart_port_usb2
+#endif
+#define TX_BUF_NUM 500
+#define RX_BUF_NUM 499+1/*for tailed gpd*/
+#define TEST_LB_PKT_NUM 200
+#define EXCPT_TTY_UT_CHUNK_SIZE_DEFAULT (QBM_TTY_XXX_DATA_LEN)
+
+#ifdef __EXPT_CCCI_TTY_IT__
+#define EXPT_TTY_TX_GPD_TYPE QBM_TYPE_CCCI_COMM
+#define EXPT_TTY_RX_GPD_TYPE QBM_TYPE_CCCI_COMM
+#else
+#define EXPT_TTY_TX_GPD_TYPE QBM_TYPE_TTY_INT
+#define EXPT_TTY_RX_GPD_TYPE QBM_TYPE_TTY_INT
+#endif
+
+#define EXCP_HALT() while(1)
+
+#ifdef __EXPT_CCCI_TTY_IT__
+static DCL_UINT8 bm_buf_excp_tx[QBM_QUEUE_GET_MEM_SIZE(QBM_TYPE_CCCI_COMM, TX_BUF_NUM)];
+static DCL_UINT8 bm_buf_excp_rx[QBM_QUEUE_GET_MEM_SIZE(QBM_TYPE_CCCI_COMM, RX_BUF_NUM)];
+#else
+static DCL_UINT8 bm_buf_excp_tx[QBM_QUEUE_GET_MEM_SIZE(QBM_SIZE_TTY_INT, TX_BUF_NUM)];
+static DCL_UINT8 bm_buf_excp_rx[QBM_QUEUE_GET_MEM_SIZE(QBM_SIZE_TTY_INT, RX_BUF_NUM)];
+#endif
+
+static void *excp_tgpd_head = NULL;
+static void *excp_tgpd_tail = NULL;
+static void *excp_rgpd_head = NULL;
+static void *excp_rgpd_tail = NULL;
+
+static void *excp_tgpd_free_head = NULL;
+static void *excp_tgpd_free_tail = NULL;
+static void *excp_rgpd_free_head = NULL;
+static void *excp_rgpd_free_tail = NULL;
+
+typedef enum {
+ GPD_TYPE_TX,
+ GPD_TYPE_RX,
+} GPD_TYPE;
+
+
+#define BUSY_LOOP(_n) do{volatile int i; volatile int j=0; for (i=0; i<_n; i++) {j+=i*2;}}while(0)
+
+extern void dbg_print(char *fmt,...);
+
+#define TTYUT_DBG_PRINT(...)
+
+
+/*for debug only (CCCI)*/
+static volatile kal_uint32 DBG_LOCK = 1;
+
+#define BUSY_STOP() \
+ do{ \
+ while(1){ \
+ if(DBG_LOCK == 0) break; \
+ } \
+ }while(0) \
+
+void _excp_qbm_init(void)
+{
+ bm_queue_config conf;
+ kal_uint32 size;
+ kal_uint8 *pool;
+
+ qbm_init();
+
+ /* Tx GPD queue init */
+ qbm_init_q_config(&conf);
+ size = QBM_QUEUE_GET_MEM_SIZE(EXPT_TTY_TX_GPD_TYPE, TX_BUF_NUM);
+ pool = &bm_buf_excp_tx[0];
+ conf.buff_num = TX_BUF_NUM;
+ conf.p_mem_pool_str = pool;
+ conf.p_mem_pool_end = pool + size;
+ qbm_init_queue_non_free(EXPT_TTY_TX_GPD_TYPE, &conf, &excp_tgpd_head, &excp_tgpd_tail);
+
+ excp_tgpd_free_head = excp_tgpd_head;
+ excp_tgpd_free_tail = excp_tgpd_tail;
+
+ /* Rx GPD queue init */
+ qbm_init_q_config(&conf);
+ size = QBM_QUEUE_GET_MEM_SIZE(EXPT_TTY_RX_GPD_TYPE, RX_BUF_NUM);
+ pool = &bm_buf_excp_rx[0];
+ conf.buff_num = RX_BUF_NUM;
+ conf.p_mem_pool_str = pool;
+ conf.p_mem_pool_end = pool + size;
+ qbm_init_queue_non_free(EXPT_TTY_RX_GPD_TYPE, &conf, &excp_rgpd_head, &excp_rgpd_tail);
+
+ excp_rgpd_free_head = excp_rgpd_head;
+ excp_rgpd_free_tail = excp_rgpd_tail;
+
+}
+
+/**
+ * @ return gpd number allocated successfully
+ */
+static DCL_UINT16 _excp_alloc_gpd(
+ GPD_TYPE type,
+ kal_uint32 buff_num,
+ void **pp_head,
+ void **pp_tail
+ )
+{
+ kal_uint16 alloc_num = 0;
+ void *free_head;
+ void *free_tail;
+ void *cur;
+ void *pre = NULL;
+
+ free_head = (type == GPD_TYPE_TX) ? excp_tgpd_free_head : excp_rgpd_free_head;
+ free_tail = (type == GPD_TYPE_TX) ? excp_tgpd_free_tail : excp_rgpd_free_tail;
+
+ cur = free_head;
+
+ while (cur != NULL && buff_num > 0)
+ {
+ alloc_num ++;
+ buff_num --;
+ pre = cur;
+ cur = QBM_DES_GET_NEXT(cur);
+ }
+
+ *pp_head = free_head;
+ *pp_tail = pre;
+
+ if (type == GPD_TYPE_TX) {
+ excp_tgpd_free_head = cur;
+ } else {
+ excp_rgpd_free_head = cur;
+ }
+
+ return alloc_num;
+}
+
+static void _excp_free_gpd(
+ GPD_TYPE type,
+ void *p_head,
+ void *p_tail
+ )
+{
+ void *free_head;
+ void *free_tail;
+
+ free_head = (type == GPD_TYPE_TX) ? excp_tgpd_free_head : excp_rgpd_free_head;
+ free_tail = (type == GPD_TYPE_TX) ? excp_tgpd_free_tail : excp_rgpd_free_tail;
+
+ if (free_head == NULL) {
+ free_head = p_head;
+ } else {
+ QBM_DES_SET_NEXT(free_tail, p_head);
+ }
+ free_tail = p_tail;
+
+ if (type == GPD_TYPE_TX) {
+ excp_tgpd_free_head = free_head;
+ excp_tgpd_free_tail = free_tail;
+ } else {
+ excp_rgpd_free_head = free_head;
+ excp_rgpd_free_tail = free_tail;
+ }
+}
+
+
+static kal_uint32 _excp_rst_gpd_list(kal_uint32 type,qbm_gpd* first_gpd, qbm_gpd* last_gpd)
+{
+ qbm_gpd* current_gpd = NULL;
+ qbm_gpd* next_gpd = NULL;
+ kal_uint32 num_gpd = 0;
+
+ ASSERT(first_gpd && last_gpd);
+ current_gpd = first_gpd;
+
+ do {
+ next_gpd = QBM_DES_GET_NEXT(current_gpd);
+ qbm_reset_pd(type, (void*)current_gpd);
+ qbm_cal_set_checksum((kal_uint8 *)current_gpd);
+ QBM_CACHE_FLUSH(current_gpd, sizeof(qbm_gpd));
+ num_gpd ++;
+ if ( current_gpd == last_gpd )
+ {
+ break;
+ }
+ current_gpd = next_gpd;
+ } while ( current_gpd != NULL );
+
+ return num_gpd;
+}
+
+static void* _excp_get_qbm_dataptr(void* gpd)
+{
+ void* bd = NULL;
+ void* data_ptr = NULL;
+
+ ASSERT(NULL!=gpd);
+ if(0 != QBM_DES_GET_BDP(gpd)){
+ //4 <case 1> GPD->BD->BUFF
+ bd = QBM_DES_GET_DATAPTR(gpd);
+ ASSERT(NULL!=bd);
+ data_ptr = QBM_DES_GET_DATAPTR(bd);
+ }else{
+ //4 <case 2> GPD->BUFF
+ data_ptr = QBM_DES_GET_DATAPTR(gpd);
+ }
+
+ ASSERT(NULL!=data_ptr);
+ return data_ptr;
+}
+
+static void _excp_set_qbm_datalen(void* gpd, kal_uint32 data_len)
+{
+ void* bd = NULL;
+
+ ASSERT(NULL != gpd);
+ /*QBM_TYPE_CCCI_COMM specific function*/
+ ASSERT(QBM_TYPE_CCCI_COMM == QBM_GET_TYPE(gpd));
+ /*Must have BD*/
+ ASSERT(0 != QBM_DES_GET_BDP(gpd));
+
+ bd = QBM_DES_GET_DATAPTR(gpd);
+ ASSERT(NULL!=bd);
+ QBM_DES_SET_DATALEN(bd, data_len);
+ qbm_cal_set_checksum((kal_uint8 *)bd);
+
+ QBM_DES_SET_DATALEN(gpd, data_len);
+ qbm_cal_set_checksum((kal_uint8 *)gpd);
+}
+
+static void excp_loopback_test(DCL_HANDLE handle, kal_bool is_before_reset, kal_uint32 num)
+{
+ unsigned char *tx_buf_ptr;
+ unsigned char *rx_buf_ptr;
+ kal_char trigger_string[50] = {0};
+ kal_uint32 i;
+ kal_uint32 total_rx_num;
+ TTY_CTRL_EXCP_ASSIGN_RX_GPD_T ttyCtlAsnRxGpd;
+ TTY_CTRL_EXCP_GET_RX_GPD_T ttyCtlGetRxGpd;
+ TTY_CTRL_EXCP_TX_GPD_T ttyCtlTxGpd;
+ TTY_CTRL_EXCP_TX_DONE_INFO_T ttyCtlTxDoneInfo;
+ TTY_CTRL_EXCP_HIF_STATE_T ttyCtlHifSt;
+ UART_CTRL_GET_CHUNK_SIZE_T ur_ctrl_get_chunk_size;
+
+ /*
+ Wait a period of time to let Host have enought time to open com port
+ */
+ for (i = 0; i < 500000; i ++)
+ {
+ if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); }
+ BUSY_LOOP(100);
+ }
+
+ /*
+ Send a packet to trigger Host start loopback test
+ #format: "exception num" (ex. "exception 50")
+ */
+ _excp_alloc_gpd(GPD_TYPE_TX, 1, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd);
+ tx_buf_ptr = QBM_DES_GET_DATAPTR(ttyCtlTxGpd.first_gpd);
+ kal_mem_set(trigger_string, 0, sizeof(trigger_string));
+ sprintf(trigger_string, "exception %d", num);
+ kal_mem_cpy(tx_buf_ptr, trigger_string, strlen(trigger_string)+1);
+
+ // Set Tx GPD
+ QBM_CACHE_FLUSH(tx_buf_ptr, strlen(trigger_string)+1);
+ QBM_DES_SET_DATALEN(ttyCtlTxGpd.first_gpd, strlen(trigger_string)+1);
+ QBM_DES_SET_HWO(ttyCtlTxGpd.first_gpd);
+ qbm_cal_set_checksum(ttyCtlTxGpd.first_gpd);
+ QBM_CACHE_FLUSH(ttyCtlTxGpd.first_gpd, sizeof(qbm_gpd));
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlTxGpd);
+ // Polling Tx Done Info until all Tx GPD are sent and retrieved
+ do {
+ if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); }
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_DONE_INFO, (DCL_CTRL_DATA_T*) &ttyCtlTxDoneInfo);
+
+ if (ttyCtlTxDoneInfo.num > 0) {
+ _excp_free_gpd(GPD_TYPE_TX, ttyCtlTxDoneInfo.first_gpd, ttyCtlTxDoneInfo.last_gpd);
+ break;
+ }
+ } while (1);
+
+
+ /* Assign Rx GPD to driver */
+ _excp_alloc_gpd(GPD_TYPE_RX, 2/*1 for tailed GPD*/, &ttyCtlAsnRxGpd.first_gpd, &ttyCtlAsnRxGpd.last_gpd);
+ DclSerialPort_Control(handle, TTY_CMD_GET_CHUNK_SIZE, (DCL_CTRL_DATA_T*)&ur_ctrl_get_chunk_size);
+ // first gpd
+ if(ur_ctrl_get_chunk_size.chunkSize == 1)
+ {
+ QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.first_gpd, EXCPT_TTY_UT_CHUNK_SIZE_DEFAULT);
+ }
+ else
+ {
+ QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.first_gpd, ur_ctrl_get_chunk_size.chunkSize);
+ }
+ QBM_DES_SET_HWO(ttyCtlAsnRxGpd.first_gpd);
+ qbm_cal_set_checksum(ttyCtlAsnRxGpd.first_gpd);
+ QBM_CACHE_FLUSH(ttyCtlAsnRxGpd.first_gpd, sizeof(qbm_gpd));
+ // last gpd
+ if(ur_ctrl_get_chunk_size.chunkSize == 1)
+ {
+ QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.first_gpd, EXCPT_TTY_UT_CHUNK_SIZE_DEFAULT);
+ }
+ else
+ {
+ QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.last_gpd, ur_ctrl_get_chunk_size.chunkSize);
+ }
+ QBM_DES_SET_HWO(ttyCtlAsnRxGpd.last_gpd);
+ qbm_cal_set_checksum(ttyCtlAsnRxGpd.last_gpd);
+ QBM_CACHE_FLUSH(ttyCtlAsnRxGpd.last_gpd, sizeof(qbm_gpd));
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_ASSIGN_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlAsnRxGpd);
+
+ total_rx_num = 0;
+ while (total_rx_num < num) // Polling Received Rx GPD and transmit the data to Host
+ {
+ void *cur_tx;
+ void *cur_rx;
+ kal_uint16 rx_len;
+ kal_uint16 gpd_num;
+
+ /* Get Rx GPD */
+ do {
+ if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);}
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_GET_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlGetRxGpd);
+ } while (ttyCtlGetRxGpd.num == 0);
+ total_rx_num += ttyCtlGetRxGpd.num;
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] receive %d gpds, has received total %d gpds\r\n", ttyCtlGetRxGpd.num, total_rx_num);
+
+ /* Allocate Tx GPD and re-transmit the rx data to Host */
+ gpd_num = ttyCtlGetRxGpd.num;
+ _excp_alloc_gpd(GPD_TYPE_TX, gpd_num, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd);
+
+ cur_rx = ttyCtlGetRxGpd.first_gpd;
+ cur_tx = ttyCtlTxGpd.first_gpd;
+
+ for (i = 0; i < ttyCtlGetRxGpd.num; i ++)
+ {
+ rx_buf_ptr = QBM_DES_GET_DATAPTR(cur_rx);
+ rx_len = QBM_DES_GET_DATALEN(cur_rx);
+ tx_buf_ptr = QBM_DES_GET_DATAPTR(cur_tx);
+
+ QBM_CACHE_INVALID(rx_buf_ptr, rx_len);
+ kal_mem_cpy(tx_buf_ptr, rx_buf_ptr, rx_len);
+ QBM_CACHE_FLUSH(tx_buf_ptr, rx_len);
+
+ /* Set Tx GPD */
+ QBM_DES_SET_DATALEN(cur_tx, rx_len);
+ QBM_DES_SET_HWO(cur_tx);
+ qbm_cal_set_checksum(cur_tx);
+ QBM_CACHE_FLUSH(cur_tx, sizeof(qbm_gpd));
+
+ /* Reset Rx GPD */
+ QBM_DES_SET_ALLOW_LEN(cur_rx, ur_ctrl_get_chunk_size.chunkSize);
+ QBM_DES_SET_HWO(cur_rx);
+ qbm_cal_set_checksum(cur_rx);
+ QBM_CACHE_FLUSH(cur_rx, sizeof(qbm_gpd));
+
+ cur_tx = QBM_DES_GET_NEXT(cur_tx);
+ cur_rx = QBM_DES_GET_NEXT(cur_rx);
+ }
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlTxGpd);
+
+ if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); }
+
+ /* Re-assign Rx GPD to driver */
+ ttyCtlAsnRxGpd.first_gpd = ttyCtlGetRxGpd.first_gpd;
+ ttyCtlAsnRxGpd.last_gpd = ttyCtlGetRxGpd.last_gpd;
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_ASSIGN_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlAsnRxGpd);
+
+ /* Polling Tx Done Info until all Tx GPD are sent and retrieved */
+ do {
+ if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);}
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_DONE_INFO, (DCL_CTRL_DATA_T*) &ttyCtlTxDoneInfo);
+
+ if (ttyCtlTxDoneInfo.num > 0) {
+ _excp_free_gpd(GPD_TYPE_TX, ttyCtlTxDoneInfo.first_gpd, ttyCtlTxDoneInfo.last_gpd);
+ gpd_num -= ttyCtlTxDoneInfo.num;
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] has sent %d gpds\r\n", ttyCtlTxDoneInfo.num);
+ }
+ } while (gpd_num > 0);
+
+ /* Check HIF state */
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_STATE, (DCL_CTRL_DATA_T*) &ttyCtlHifSt);
+ if (ttyCtlHifSt.hif_state != HIF_STATE_NORMAL) {
+ EXCP_HALT();
+ }
+
+ if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); }
+ }
+
+}
+
+static void excp_ccci_loopback_test(DCL_HANDLE handle, kal_uint32 num)
+{
+ unsigned char *tx_buf_ptr;
+ unsigned char *rx_buf_ptr;
+ kal_char trigger_string[50] = {0};
+ kal_uint32 i;
+ kal_uint32 total_rx_num;
+ TTY_CTRL_EXCP_ASSIGN_RX_GPD_T ttyCtlAsnRxGpd;
+ TTY_CTRL_EXCP_GET_RX_GPD_T ttyCtlGetRxGpd;
+ TTY_CTRL_EXCP_TX_GPD_T ttyCtlTxGpd;
+ TTY_CTRL_EXCP_TX_DONE_INFO_T ttyCtlTxDoneInfo;
+ TTY_CTRL_EXCP_HIF_STATE_T ttyCtlHifSt;
+ UART_CTRL_GET_MTU_SIZE_T ur_ctrl_get_mtu_size;
+ kal_uint32 tmp_num;
+
+ /*For debug test only*/
+ //BUSY_STOP();
+
+ /* Assign Rx GPD to driver */
+ // TODO:Need to revise APIs. Because in exception mode(espicailly in HISR), some QBM APIs shall not be used. (ex:enhance mutex)
+ //tmp_num = _excp_alloc_gpd(GPD_TYPE_RX, 2/*1 for tailed GPD*/, &ttyCtlAsnRxGpd.first_gpd, &ttyCtlAsnRxGpd.last_gpd);
+ tmp_num = qbmt_alloc_q_no_tail(EXPT_TTY_RX_GPD_TYPE, 2, &ttyCtlAsnRxGpd.first_gpd, &ttyCtlAsnRxGpd.last_gpd);
+ if(tmp_num!= 2) while(1);
+ DclSerialPort_Control(handle, TTY_CMD_GET_MTU_SIZE, (DCL_CTRL_DATA_T*)&ur_ctrl_get_mtu_size);
+ QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.first_gpd, ur_ctrl_get_mtu_size.ulmtu_sz);
+ QBM_DES_SET_HWO(ttyCtlAsnRxGpd.first_gpd);
+ qbm_cal_set_checksum(ttyCtlAsnRxGpd.first_gpd);
+ QBM_CACHE_FLUSH(ttyCtlAsnRxGpd.first_gpd, sizeof(qbm_gpd));
+ // last gpd
+ QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.last_gpd, ur_ctrl_get_mtu_size.ulmtu_sz);
+ QBM_DES_SET_HWO(ttyCtlAsnRxGpd.last_gpd);
+ qbm_cal_set_checksum(ttyCtlAsnRxGpd.last_gpd);
+ QBM_CACHE_FLUSH(ttyCtlAsnRxGpd.last_gpd, sizeof(qbm_gpd));
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_ASSIGN_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlAsnRxGpd);
+
+ total_rx_num = 0;
+ //while (total_rx_num < num) // Polling Received Rx GPD and transmit the data to Host
+ while(1)
+ {
+ void *cur_tx;
+ void *cur_rx;
+ kal_uint16 rx_len;
+ kal_uint16 gpd_num;
+
+ /* Get Rx GPD */
+ do {
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_GET_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlGetRxGpd);
+ } while (ttyCtlGetRxGpd.num == 0);
+ total_rx_num += ttyCtlGetRxGpd.num;
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] receive %d gpds, has received total %d gpds\r\n", ttyCtlGetRxGpd.num, total_rx_num);
+
+ /* Allocate Tx GPD and re-transmit the rx data to Host */
+ gpd_num = ttyCtlGetRxGpd.num;
+ //_excp_alloc_gpd(GPD_TYPE_TX, gpd_num, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd);
+ tmp_num = qbmt_alloc_q_no_tail(EXPT_TTY_TX_GPD_TYPE, gpd_num, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd);
+ if(tmp_num!= gpd_num) while(1);
+
+ cur_rx = ttyCtlGetRxGpd.first_gpd;
+ cur_tx = ttyCtlTxGpd.first_gpd;
+
+ for (i = 0; i < ttyCtlGetRxGpd.num; i ++)
+ {
+ rx_buf_ptr = _excp_get_qbm_dataptr(cur_rx);
+ rx_len = QBM_DES_GET_DATALEN(cur_rx);
+ tx_buf_ptr = _excp_get_qbm_dataptr(cur_tx);
+
+ QBM_CACHE_INVALID(rx_buf_ptr, rx_len);
+ kal_mem_cpy(tx_buf_ptr, rx_buf_ptr, rx_len);
+ QBM_CACHE_FLUSH(tx_buf_ptr, rx_len);
+
+ /* Set Tx GPD */
+ _excp_set_qbm_datalen(cur_tx, rx_len);
+ QBM_DES_SET_HWO(cur_tx);
+ qbm_cal_set_checksum(cur_tx);
+ QBM_CACHE_FLUSH(cur_tx, sizeof(qbm_gpd));
+
+ /* Reset Rx GPD */
+ _excp_rst_gpd_list(EXPT_TTY_RX_GPD_TYPE,cur_rx,cur_rx);
+ QBM_DES_SET_ALLOW_LEN(cur_rx, ur_ctrl_get_mtu_size.ulmtu_sz);
+ //QBM_DES_SET_HWO(cur_rx);
+ qbm_cal_set_checksum(cur_rx);
+ QBM_CACHE_FLUSH(cur_rx, sizeof(qbm_gpd));
+
+ cur_tx = QBM_DES_GET_NEXT(cur_tx);
+ cur_rx = QBM_DES_GET_NEXT(cur_rx);
+ }
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlTxGpd);
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);
+
+ /*Re-assign Rx GPD to driver */
+ ttyCtlAsnRxGpd.first_gpd = ttyCtlGetRxGpd.first_gpd;
+ ttyCtlAsnRxGpd.last_gpd = ttyCtlGetRxGpd.last_gpd;
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_ASSIGN_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlAsnRxGpd);
+
+ /* Polling Tx Done Info until all Tx GPD are sent and retrieved */
+ do {
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);
+
+ /*Debug only to check sdio interrupt status*/
+ //if((*SDIO_IRQ_DL_FTE0SR) & SDIO_INT_MASK) while(1);
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_DONE_INFO, (DCL_CTRL_DATA_T*) &ttyCtlTxDoneInfo);
+
+ if (ttyCtlTxDoneInfo.num > 0) {
+ //_excp_free_gpd(GPD_TYPE_TX, ttyCtlTxDoneInfo.first_gpd, ttyCtlTxDoneInfo.last_gpd);
+ qbmt_dest_q(ttyCtlTxDoneInfo.first_gpd, ttyCtlTxDoneInfo.last_gpd);
+ gpd_num -= ttyCtlTxDoneInfo.num;
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] has sent %d gpds\r\n", ttyCtlTxDoneInfo.num);
+ }
+ } while (gpd_num > 0);
+
+ /* Check HIF state */
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_STATE, (DCL_CTRL_DATA_T*) &ttyCtlHifSt);
+ if (ttyCtlHifSt.hif_state != HIF_STATE_NORMAL) {
+ EXCP_HALT();
+ }
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);
+ }
+
+}
+
+DCL_STATUS excp_ttyut(void)
+{
+ DCL_HANDLE handle;
+
+ //for debug only
+ //BUSY_STOP();
+
+ hmu_except_init();
+
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut start\r\n");
+
+ handle = DclSerialPort_Open(EXCEPTION_TEST_PORT, 0);
+
+ /* Init QBM for exception */
+ _excp_qbm_init();
+
+ /* Test Case 1: Loopback before RESET */
+ /* HIF init and Clear channel */
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_INIT, NULL);
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_CLEAR_CHANNEL, NULL);
+
+#ifdef __EXPT_CCCI_TTY_IT__
+ excp_ccci_loopback_test(handle, TEST_LB_PKT_NUM);
+#else
+ //BUSY_LOOP(60000000);
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut case 1\r\n");
+ {
+ excp_loopback_test(handle, KAL_TRUE, TEST_LB_PKT_NUM);
+ }
+
+ /* Test Case 2: RESET */
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut case 2\r\n");
+ {
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_RESET, NULL);
+ }
+
+ /* Test Case 3: Loopback after RESET */
+ /* HIF init */
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_INIT, NULL);
+ //BUSY_LOOP(60000000);
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut case 3\r\n");
+ {
+ excp_loopback_test(handle, KAL_FALSE, TEST_LB_PKT_NUM);
+ }
+
+ /* Test Case 4: HIF_STATE return TXERROR */
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut case 4\r\n");
+ {
+ TTY_CTRL_EXCP_TX_GPD_T ttyCtlTxGpd;
+ TTY_CTRL_EXCP_TX_DONE_INFO_T ttyCtlTxDoneInfo;
+ TTY_CTRL_EXCP_HIF_STATE_T ttyCtlHifSt;
+ kal_uint16 gpd_num;
+ kal_uint16 count;
+
+ BUSY_LOOP(50000);
+ while (1)
+ {
+ gpd_num = _excp_alloc_gpd(GPD_TYPE_TX, 1, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd);
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] allocate %d gpd\r\n", gpd_num);
+ if (gpd_num == 0) {
+ break;
+ }
+ QBM_DES_SET_DATALEN(ttyCtlTxGpd.first_gpd, 100);
+ QBM_DES_SET_HWO(ttyCtlTxGpd.first_gpd);
+ qbm_cal_set_checksum(ttyCtlTxGpd.first_gpd);
+ QBM_CACHE_FLUSH(ttyCtlTxGpd.first_gpd, sizeof(qbm_gpd));
+
+ BUSY_LOOP(300000);
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlTxGpd);
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);
+ }
+
+ count = 10000;
+ while (count-- > 0)
+ {
+ BUSY_LOOP(30000);
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_DONE_INFO, (DCL_CTRL_DATA_T*) &ttyCtlTxDoneInfo);
+ }
+
+ DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_STATE, (DCL_CTRL_DATA_T*) &ttyCtlHifSt);
+ if (ttyCtlHifSt.hif_state != HIF_STATE_TXERROR) {
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] ERROR!! HIF_STATE return NORMAL\r\n");
+ EXCP_HALT();
+ } else {
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] HIF_STATE return HIF_STATE_TXERROR\r\n");
+ }
+ }
+
+ TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut end\r\n");
+#endif
+ return STATUS_OK;
+}
+
+static kal_bool excp_ttyut_task_init(void)
+{
+ return KAL_TRUE;
+}
+
+static void excp_ttyut_task_main(task_entry_struct *task_entry_ptr)
+{
+ DCL_HANDLE handle;
+ UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes;
+ char *dummy_string = "DUMMYdummyDummY";
+ DCL_STATUS status;
+ UART_CTRL_GET_DRV_STATE_T getDrvState;
+
+ handle = DclSerialPort_Open(EXCEPTION_TEST_PORT, 0);
+
+ DclSerialPort_UpModuleInit(handle, MOD_EXCP_TTYUT, 0); // conventional init
+
+ /*If taking CCCI exception IT test, task will be blocked here. Because, driver is attached when exception init*/
+ getDrvState.u4OwnerId = MOD_EXCP_TTYUT;
+ do {
+ kal_sleep_task(KAL_TICKS_100_MSEC);
+ status = DclSerialPort_Control(handle, TTY_CMD_GET_DRV_STATE, (DCL_CTRL_DATA_T*) &getDrvState);
+ } while ((getDrvState.drv_state != DRV_ST_ATTACHED) || (status != STATUS_OK));
+
+ kal_sleep_task(KAL_TICKS_5_SEC);
+
+ /* Transmit a dummy packet */
+ ur_ctrl_putbytes.u4OwenrId = MOD_EXCP_TTYUT;
+ ur_ctrl_putbytes.puBuffaddr = (DCL_UINT8*)dummy_string;
+ ur_ctrl_putbytes.u2Length = strlen(dummy_string);
+ DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes);
+
+ kal_sleep_task(KAL_TICKS_5_SEC);
+
+ /* Trigger an assert to enter exception mode */
+ ASSERT(0);
+}
+
+kal_bool excp_ttyut_create(comptask_handler_struct **handle)
+{
+ static const comptask_handler_struct excp_ttyut_handler_info =
+ {
+ excp_ttyut_task_main, /* task entry function */
+ excp_ttyut_task_init, /* task initialization function */
+ NULL /* task reset handler */
+ };
+
+ TTYUT_DBG_PRINT("=========>excp_ttyut_create\r\n");
+
+ *handle = (comptask_handler_struct *)&excp_ttyut_handler_info;
+ return KAL_TRUE;
+}
+