rjw | 6c1fd8f | 2022-11-30 14:33:01 +0800 | [diff] [blame] | 1 | /***************************************************************************** |
| 2 | * Copyright Statement: |
| 3 | * -------------------- |
| 4 | * This software is protected by Copyright and the information contained |
| 5 | * herein is confidential. The software may not be copied and the information |
| 6 | * contained herein may not be used or disclosed except with the written |
| 7 | * permission of MediaTek Inc. (C) 2012 |
| 8 | * |
| 9 | * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
| 10 | * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
| 11 | * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON |
| 12 | * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
| 13 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
| 14 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
| 15 | * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
| 16 | * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
| 17 | * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH |
| 18 | * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO |
| 19 | * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S |
| 20 | * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. |
| 21 | * |
| 22 | * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE |
| 23 | * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
| 24 | * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
| 25 | * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO |
| 26 | * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
| 27 | * |
| 28 | * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE |
| 29 | * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF |
| 30 | * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND |
| 31 | * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER |
| 32 | * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC). |
| 33 | * |
| 34 | *****************************************************************************/ |
| 35 | |
| 36 | /******************************************************************************* |
| 37 | * Filename: |
| 38 | * --------- |
| 39 | * excp_tty_ut.c |
| 40 | * |
| 41 | * Project: |
| 42 | * -------- |
| 43 | * MOLY |
| 44 | * |
| 45 | * Description: |
| 46 | * ------------ |
| 47 | * TTY Core unit test file in exception mode - it needs Host Test Program to run test. |
| 48 | * It works with enabling compile flag __EXCEPT_TTY_UT__. |
| 49 | * |
| 50 | * Author: |
| 51 | * ------- |
| 52 | * ------- |
| 53 | * |
| 54 | * ========================================================================== |
| 55 | * $Log$ |
| 56 | * |
| 57 | * 03 11 2015 i-wei.tsai |
| 58 | * [MOLY00097392] [UMOLY] [TTY] Timer tick macro modification |
| 59 | * . |
| 60 | * |
| 61 | * 09 13 2013 i-wei.tsai |
| 62 | * [MOLY00037205] [CCCI Exception] CCCI exception mode 1st check-in. |
| 63 | * CCCI Exception IT |
| 64 | * |
| 65 | * 06 26 2013 i-wei.tsai |
| 66 | * [MOLY00027496] [TTYCore] Features check-in |
| 67 | * 1. add new TTY_CMD_MTU_SIZE support |
| 68 | * 2. add plug-in/plug-out indication |
| 69 | * 3. fix issue of flushing rx internal gpd |
| 70 | * |
| 71 | * 05 29 2013 haoren.kao |
| 72 | * [MOLY00024108] Support New USB Core |
| 73 | * Replace with New USB Core. |
| 74 | * We sync with the following codes from HaoRen MOLY CBr w1322: |
| 75 | * 1. USB Core |
| 76 | * 2. USB Class - acm/rndis/mbim |
| 77 | * 3. ipcore |
| 78 | * 4. ttycore |
| 79 | * 5. ethercore |
| 80 | * |
| 81 | * 11 12 2012 haoren.kao |
| 82 | * [MOLY00005322] TATAKA merge to MOLY |
| 83 | * * Shorten the busy loop time from about 5 ms to 10 us in order to avoid host test program SetCommState timeout. |
| 84 | ****************************************************************************/ |
| 85 | |
| 86 | #include <stdio.h> |
| 87 | #include <stdlib.h> |
| 88 | |
| 89 | #include "dcl.h" |
| 90 | #include "hmu.h" |
| 91 | #include "kal_debug.h" |
| 92 | #include "qmu_bm.h" |
| 93 | #include "qmu_bm_util.h" |
| 94 | #include "syscomp_config.h" |
| 95 | |
| 96 | #include "devdrv_ls.h" |
| 97 | #include "drv_msgid.h" |
| 98 | #include "md_drv_sap.h" |
| 99 | #include "kal_public_defs.h" |
| 100 | |
| 101 | |
| 102 | //#define __EXPT_CCCI_TTY_IT__ |
| 103 | |
| 104 | #ifdef __EXPT_CCCI_TTY_IT__ |
| 105 | #define EXCEPTION_TEST_PORT uart_port_dhl_sp_expt |
| 106 | //#define EXCEPTION_TEST_PORT uart_port_dhl_ctrl_sp_expt |
| 107 | #else |
| 108 | #define EXCEPTION_TEST_PORT uart_port_usb2 |
| 109 | #endif |
| 110 | #define TX_BUF_NUM 500 |
| 111 | #define RX_BUF_NUM 499+1/*for tailed gpd*/ |
| 112 | #define TEST_LB_PKT_NUM 200 |
| 113 | #define EXCPT_TTY_UT_CHUNK_SIZE_DEFAULT (QBM_TTY_XXX_DATA_LEN) |
| 114 | |
| 115 | #ifdef __EXPT_CCCI_TTY_IT__ |
| 116 | #define EXPT_TTY_TX_GPD_TYPE QBM_TYPE_CCCI_COMM |
| 117 | #define EXPT_TTY_RX_GPD_TYPE QBM_TYPE_CCCI_COMM |
| 118 | #else |
| 119 | #define EXPT_TTY_TX_GPD_TYPE QBM_TYPE_TTY_INT |
| 120 | #define EXPT_TTY_RX_GPD_TYPE QBM_TYPE_TTY_INT |
| 121 | #endif |
| 122 | |
| 123 | #define EXCP_HALT() while(1) |
| 124 | |
| 125 | #ifdef __EXPT_CCCI_TTY_IT__ |
| 126 | static DCL_UINT8 bm_buf_excp_tx[QBM_QUEUE_GET_MEM_SIZE(QBM_TYPE_CCCI_COMM, TX_BUF_NUM)]; |
| 127 | static DCL_UINT8 bm_buf_excp_rx[QBM_QUEUE_GET_MEM_SIZE(QBM_TYPE_CCCI_COMM, RX_BUF_NUM)]; |
| 128 | #else |
| 129 | static DCL_UINT8 bm_buf_excp_tx[QBM_QUEUE_GET_MEM_SIZE(QBM_SIZE_TTY_INT, TX_BUF_NUM)]; |
| 130 | static DCL_UINT8 bm_buf_excp_rx[QBM_QUEUE_GET_MEM_SIZE(QBM_SIZE_TTY_INT, RX_BUF_NUM)]; |
| 131 | #endif |
| 132 | |
| 133 | static void *excp_tgpd_head = NULL; |
| 134 | static void *excp_tgpd_tail = NULL; |
| 135 | static void *excp_rgpd_head = NULL; |
| 136 | static void *excp_rgpd_tail = NULL; |
| 137 | |
| 138 | static void *excp_tgpd_free_head = NULL; |
| 139 | static void *excp_tgpd_free_tail = NULL; |
| 140 | static void *excp_rgpd_free_head = NULL; |
| 141 | static void *excp_rgpd_free_tail = NULL; |
| 142 | |
| 143 | typedef enum { |
| 144 | GPD_TYPE_TX, |
| 145 | GPD_TYPE_RX, |
| 146 | } GPD_TYPE; |
| 147 | |
| 148 | |
| 149 | #define BUSY_LOOP(_n) do{volatile int i; volatile int j=0; for (i=0; i<_n; i++) {j+=i*2;}}while(0) |
| 150 | |
| 151 | extern void dbg_print(char *fmt,...); |
| 152 | |
| 153 | #define TTYUT_DBG_PRINT(...) |
| 154 | |
| 155 | |
| 156 | /*for debug only (CCCI)*/ |
| 157 | static volatile kal_uint32 DBG_LOCK = 1; |
| 158 | |
| 159 | #define BUSY_STOP() \ |
| 160 | do{ \ |
| 161 | while(1){ \ |
| 162 | if(DBG_LOCK == 0) break; \ |
| 163 | } \ |
| 164 | }while(0) \ |
| 165 | |
| 166 | void _excp_qbm_init(void) |
| 167 | { |
| 168 | bm_queue_config conf; |
| 169 | kal_uint32 size; |
| 170 | kal_uint8 *pool; |
| 171 | |
| 172 | qbm_init(); |
| 173 | |
| 174 | /* Tx GPD queue init */ |
| 175 | qbm_init_q_config(&conf); |
| 176 | size = QBM_QUEUE_GET_MEM_SIZE(EXPT_TTY_TX_GPD_TYPE, TX_BUF_NUM); |
| 177 | pool = &bm_buf_excp_tx[0]; |
| 178 | conf.buff_num = TX_BUF_NUM; |
| 179 | conf.p_mem_pool_str = pool; |
| 180 | conf.p_mem_pool_end = pool + size; |
| 181 | qbm_init_queue_non_free(EXPT_TTY_TX_GPD_TYPE, &conf, &excp_tgpd_head, &excp_tgpd_tail); |
| 182 | |
| 183 | excp_tgpd_free_head = excp_tgpd_head; |
| 184 | excp_tgpd_free_tail = excp_tgpd_tail; |
| 185 | |
| 186 | /* Rx GPD queue init */ |
| 187 | qbm_init_q_config(&conf); |
| 188 | size = QBM_QUEUE_GET_MEM_SIZE(EXPT_TTY_RX_GPD_TYPE, RX_BUF_NUM); |
| 189 | pool = &bm_buf_excp_rx[0]; |
| 190 | conf.buff_num = RX_BUF_NUM; |
| 191 | conf.p_mem_pool_str = pool; |
| 192 | conf.p_mem_pool_end = pool + size; |
| 193 | qbm_init_queue_non_free(EXPT_TTY_RX_GPD_TYPE, &conf, &excp_rgpd_head, &excp_rgpd_tail); |
| 194 | |
| 195 | excp_rgpd_free_head = excp_rgpd_head; |
| 196 | excp_rgpd_free_tail = excp_rgpd_tail; |
| 197 | |
| 198 | } |
| 199 | |
| 200 | /** |
| 201 | * @ return gpd number allocated successfully |
| 202 | */ |
| 203 | static DCL_UINT16 _excp_alloc_gpd( |
| 204 | GPD_TYPE type, |
| 205 | kal_uint32 buff_num, |
| 206 | void **pp_head, |
| 207 | void **pp_tail |
| 208 | ) |
| 209 | { |
| 210 | kal_uint16 alloc_num = 0; |
| 211 | void *free_head; |
| 212 | void *free_tail; |
| 213 | void *cur; |
| 214 | void *pre = NULL; |
| 215 | |
| 216 | free_head = (type == GPD_TYPE_TX) ? excp_tgpd_free_head : excp_rgpd_free_head; |
| 217 | free_tail = (type == GPD_TYPE_TX) ? excp_tgpd_free_tail : excp_rgpd_free_tail; |
| 218 | |
| 219 | cur = free_head; |
| 220 | |
| 221 | while (cur != NULL && buff_num > 0) |
| 222 | { |
| 223 | alloc_num ++; |
| 224 | buff_num --; |
| 225 | pre = cur; |
| 226 | cur = QBM_DES_GET_NEXT(cur); |
| 227 | } |
| 228 | |
| 229 | *pp_head = free_head; |
| 230 | *pp_tail = pre; |
| 231 | |
| 232 | if (type == GPD_TYPE_TX) { |
| 233 | excp_tgpd_free_head = cur; |
| 234 | } else { |
| 235 | excp_rgpd_free_head = cur; |
| 236 | } |
| 237 | |
| 238 | return alloc_num; |
| 239 | } |
| 240 | |
| 241 | static void _excp_free_gpd( |
| 242 | GPD_TYPE type, |
| 243 | void *p_head, |
| 244 | void *p_tail |
| 245 | ) |
| 246 | { |
| 247 | void *free_head; |
| 248 | void *free_tail; |
| 249 | |
| 250 | free_head = (type == GPD_TYPE_TX) ? excp_tgpd_free_head : excp_rgpd_free_head; |
| 251 | free_tail = (type == GPD_TYPE_TX) ? excp_tgpd_free_tail : excp_rgpd_free_tail; |
| 252 | |
| 253 | if (free_head == NULL) { |
| 254 | free_head = p_head; |
| 255 | } else { |
| 256 | QBM_DES_SET_NEXT(free_tail, p_head); |
| 257 | } |
| 258 | free_tail = p_tail; |
| 259 | |
| 260 | if (type == GPD_TYPE_TX) { |
| 261 | excp_tgpd_free_head = free_head; |
| 262 | excp_tgpd_free_tail = free_tail; |
| 263 | } else { |
| 264 | excp_rgpd_free_head = free_head; |
| 265 | excp_rgpd_free_tail = free_tail; |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | |
| 270 | static kal_uint32 _excp_rst_gpd_list(kal_uint32 type,qbm_gpd* first_gpd, qbm_gpd* last_gpd) |
| 271 | { |
| 272 | qbm_gpd* current_gpd = NULL; |
| 273 | qbm_gpd* next_gpd = NULL; |
| 274 | kal_uint32 num_gpd = 0; |
| 275 | |
| 276 | ASSERT(first_gpd && last_gpd); |
| 277 | current_gpd = first_gpd; |
| 278 | |
| 279 | do { |
| 280 | next_gpd = QBM_DES_GET_NEXT(current_gpd); |
| 281 | qbm_reset_pd(type, (void*)current_gpd); |
| 282 | qbm_cal_set_checksum((kal_uint8 *)current_gpd); |
| 283 | QBM_CACHE_FLUSH(current_gpd, sizeof(qbm_gpd)); |
| 284 | num_gpd ++; |
| 285 | if ( current_gpd == last_gpd ) |
| 286 | { |
| 287 | break; |
| 288 | } |
| 289 | current_gpd = next_gpd; |
| 290 | } while ( current_gpd != NULL ); |
| 291 | |
| 292 | return num_gpd; |
| 293 | } |
| 294 | |
| 295 | static void* _excp_get_qbm_dataptr(void* gpd) |
| 296 | { |
| 297 | void* bd = NULL; |
| 298 | void* data_ptr = NULL; |
| 299 | |
| 300 | ASSERT(NULL!=gpd); |
| 301 | if(0 != QBM_DES_GET_BDP(gpd)){ |
| 302 | //4 <case 1> GPD->BD->BUFF |
| 303 | bd = QBM_DES_GET_DATAPTR(gpd); |
| 304 | ASSERT(NULL!=bd); |
| 305 | data_ptr = QBM_DES_GET_DATAPTR(bd); |
| 306 | }else{ |
| 307 | //4 <case 2> GPD->BUFF |
| 308 | data_ptr = QBM_DES_GET_DATAPTR(gpd); |
| 309 | } |
| 310 | |
| 311 | ASSERT(NULL!=data_ptr); |
| 312 | return data_ptr; |
| 313 | } |
| 314 | |
| 315 | static void _excp_set_qbm_datalen(void* gpd, kal_uint32 data_len) |
| 316 | { |
| 317 | void* bd = NULL; |
| 318 | |
| 319 | ASSERT(NULL != gpd); |
| 320 | /*QBM_TYPE_CCCI_COMM specific function*/ |
| 321 | ASSERT(QBM_TYPE_CCCI_COMM == QBM_GET_TYPE(gpd)); |
| 322 | /*Must have BD*/ |
| 323 | ASSERT(0 != QBM_DES_GET_BDP(gpd)); |
| 324 | |
| 325 | bd = QBM_DES_GET_DATAPTR(gpd); |
| 326 | ASSERT(NULL!=bd); |
| 327 | QBM_DES_SET_DATALEN(bd, data_len); |
| 328 | qbm_cal_set_checksum((kal_uint8 *)bd); |
| 329 | |
| 330 | QBM_DES_SET_DATALEN(gpd, data_len); |
| 331 | qbm_cal_set_checksum((kal_uint8 *)gpd); |
| 332 | } |
| 333 | |
| 334 | static void excp_loopback_test(DCL_HANDLE handle, kal_bool is_before_reset, kal_uint32 num) |
| 335 | { |
| 336 | unsigned char *tx_buf_ptr; |
| 337 | unsigned char *rx_buf_ptr; |
| 338 | kal_char trigger_string[50] = {0}; |
| 339 | kal_uint32 i; |
| 340 | kal_uint32 total_rx_num; |
| 341 | TTY_CTRL_EXCP_ASSIGN_RX_GPD_T ttyCtlAsnRxGpd; |
| 342 | TTY_CTRL_EXCP_GET_RX_GPD_T ttyCtlGetRxGpd; |
| 343 | TTY_CTRL_EXCP_TX_GPD_T ttyCtlTxGpd; |
| 344 | TTY_CTRL_EXCP_TX_DONE_INFO_T ttyCtlTxDoneInfo; |
| 345 | TTY_CTRL_EXCP_HIF_STATE_T ttyCtlHifSt; |
| 346 | UART_CTRL_GET_CHUNK_SIZE_T ur_ctrl_get_chunk_size; |
| 347 | |
| 348 | /* |
| 349 | Wait a period of time to let Host have enought time to open com port |
| 350 | */ |
| 351 | for (i = 0; i < 500000; i ++) |
| 352 | { |
| 353 | if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); } |
| 354 | BUSY_LOOP(100); |
| 355 | } |
| 356 | |
| 357 | /* |
| 358 | Send a packet to trigger Host start loopback test |
| 359 | #format: "exception num" (ex. "exception 50") |
| 360 | */ |
| 361 | _excp_alloc_gpd(GPD_TYPE_TX, 1, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd); |
| 362 | tx_buf_ptr = QBM_DES_GET_DATAPTR(ttyCtlTxGpd.first_gpd); |
| 363 | kal_mem_set(trigger_string, 0, sizeof(trigger_string)); |
| 364 | sprintf(trigger_string, "exception %d", num); |
| 365 | kal_mem_cpy(tx_buf_ptr, trigger_string, strlen(trigger_string)+1); |
| 366 | |
| 367 | // Set Tx GPD |
| 368 | QBM_CACHE_FLUSH(tx_buf_ptr, strlen(trigger_string)+1); |
| 369 | QBM_DES_SET_DATALEN(ttyCtlTxGpd.first_gpd, strlen(trigger_string)+1); |
| 370 | QBM_DES_SET_HWO(ttyCtlTxGpd.first_gpd); |
| 371 | qbm_cal_set_checksum(ttyCtlTxGpd.first_gpd); |
| 372 | QBM_CACHE_FLUSH(ttyCtlTxGpd.first_gpd, sizeof(qbm_gpd)); |
| 373 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlTxGpd); |
| 374 | // Polling Tx Done Info until all Tx GPD are sent and retrieved |
| 375 | do { |
| 376 | if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); } |
| 377 | |
| 378 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_DONE_INFO, (DCL_CTRL_DATA_T*) &ttyCtlTxDoneInfo); |
| 379 | |
| 380 | if (ttyCtlTxDoneInfo.num > 0) { |
| 381 | _excp_free_gpd(GPD_TYPE_TX, ttyCtlTxDoneInfo.first_gpd, ttyCtlTxDoneInfo.last_gpd); |
| 382 | break; |
| 383 | } |
| 384 | } while (1); |
| 385 | |
| 386 | |
| 387 | /* Assign Rx GPD to driver */ |
| 388 | _excp_alloc_gpd(GPD_TYPE_RX, 2/*1 for tailed GPD*/, &ttyCtlAsnRxGpd.first_gpd, &ttyCtlAsnRxGpd.last_gpd); |
| 389 | DclSerialPort_Control(handle, TTY_CMD_GET_CHUNK_SIZE, (DCL_CTRL_DATA_T*)&ur_ctrl_get_chunk_size); |
| 390 | // first gpd |
| 391 | if(ur_ctrl_get_chunk_size.chunkSize == 1) |
| 392 | { |
| 393 | QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.first_gpd, EXCPT_TTY_UT_CHUNK_SIZE_DEFAULT); |
| 394 | } |
| 395 | else |
| 396 | { |
| 397 | QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.first_gpd, ur_ctrl_get_chunk_size.chunkSize); |
| 398 | } |
| 399 | QBM_DES_SET_HWO(ttyCtlAsnRxGpd.first_gpd); |
| 400 | qbm_cal_set_checksum(ttyCtlAsnRxGpd.first_gpd); |
| 401 | QBM_CACHE_FLUSH(ttyCtlAsnRxGpd.first_gpd, sizeof(qbm_gpd)); |
| 402 | // last gpd |
| 403 | if(ur_ctrl_get_chunk_size.chunkSize == 1) |
| 404 | { |
| 405 | QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.first_gpd, EXCPT_TTY_UT_CHUNK_SIZE_DEFAULT); |
| 406 | } |
| 407 | else |
| 408 | { |
| 409 | QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.last_gpd, ur_ctrl_get_chunk_size.chunkSize); |
| 410 | } |
| 411 | QBM_DES_SET_HWO(ttyCtlAsnRxGpd.last_gpd); |
| 412 | qbm_cal_set_checksum(ttyCtlAsnRxGpd.last_gpd); |
| 413 | QBM_CACHE_FLUSH(ttyCtlAsnRxGpd.last_gpd, sizeof(qbm_gpd)); |
| 414 | |
| 415 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_ASSIGN_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlAsnRxGpd); |
| 416 | |
| 417 | total_rx_num = 0; |
| 418 | while (total_rx_num < num) // Polling Received Rx GPD and transmit the data to Host |
| 419 | { |
| 420 | void *cur_tx; |
| 421 | void *cur_rx; |
| 422 | kal_uint16 rx_len; |
| 423 | kal_uint16 gpd_num; |
| 424 | |
| 425 | /* Get Rx GPD */ |
| 426 | do { |
| 427 | if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);} |
| 428 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_GET_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlGetRxGpd); |
| 429 | } while (ttyCtlGetRxGpd.num == 0); |
| 430 | total_rx_num += ttyCtlGetRxGpd.num; |
| 431 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] receive %d gpds, has received total %d gpds\r\n", ttyCtlGetRxGpd.num, total_rx_num); |
| 432 | |
| 433 | /* Allocate Tx GPD and re-transmit the rx data to Host */ |
| 434 | gpd_num = ttyCtlGetRxGpd.num; |
| 435 | _excp_alloc_gpd(GPD_TYPE_TX, gpd_num, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd); |
| 436 | |
| 437 | cur_rx = ttyCtlGetRxGpd.first_gpd; |
| 438 | cur_tx = ttyCtlTxGpd.first_gpd; |
| 439 | |
| 440 | for (i = 0; i < ttyCtlGetRxGpd.num; i ++) |
| 441 | { |
| 442 | rx_buf_ptr = QBM_DES_GET_DATAPTR(cur_rx); |
| 443 | rx_len = QBM_DES_GET_DATALEN(cur_rx); |
| 444 | tx_buf_ptr = QBM_DES_GET_DATAPTR(cur_tx); |
| 445 | |
| 446 | QBM_CACHE_INVALID(rx_buf_ptr, rx_len); |
| 447 | kal_mem_cpy(tx_buf_ptr, rx_buf_ptr, rx_len); |
| 448 | QBM_CACHE_FLUSH(tx_buf_ptr, rx_len); |
| 449 | |
| 450 | /* Set Tx GPD */ |
| 451 | QBM_DES_SET_DATALEN(cur_tx, rx_len); |
| 452 | QBM_DES_SET_HWO(cur_tx); |
| 453 | qbm_cal_set_checksum(cur_tx); |
| 454 | QBM_CACHE_FLUSH(cur_tx, sizeof(qbm_gpd)); |
| 455 | |
| 456 | /* Reset Rx GPD */ |
| 457 | QBM_DES_SET_ALLOW_LEN(cur_rx, ur_ctrl_get_chunk_size.chunkSize); |
| 458 | QBM_DES_SET_HWO(cur_rx); |
| 459 | qbm_cal_set_checksum(cur_rx); |
| 460 | QBM_CACHE_FLUSH(cur_rx, sizeof(qbm_gpd)); |
| 461 | |
| 462 | cur_tx = QBM_DES_GET_NEXT(cur_tx); |
| 463 | cur_rx = QBM_DES_GET_NEXT(cur_rx); |
| 464 | } |
| 465 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlTxGpd); |
| 466 | |
| 467 | if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); } |
| 468 | |
| 469 | /* Re-assign Rx GPD to driver */ |
| 470 | ttyCtlAsnRxGpd.first_gpd = ttyCtlGetRxGpd.first_gpd; |
| 471 | ttyCtlAsnRxGpd.last_gpd = ttyCtlGetRxGpd.last_gpd; |
| 472 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_ASSIGN_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlAsnRxGpd); |
| 473 | |
| 474 | /* Polling Tx Done Info until all Tx GPD are sent and retrieved */ |
| 475 | do { |
| 476 | if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL);} |
| 477 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_DONE_INFO, (DCL_CTRL_DATA_T*) &ttyCtlTxDoneInfo); |
| 478 | |
| 479 | if (ttyCtlTxDoneInfo.num > 0) { |
| 480 | _excp_free_gpd(GPD_TYPE_TX, ttyCtlTxDoneInfo.first_gpd, ttyCtlTxDoneInfo.last_gpd); |
| 481 | gpd_num -= ttyCtlTxDoneInfo.num; |
| 482 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] has sent %d gpds\r\n", ttyCtlTxDoneInfo.num); |
| 483 | } |
| 484 | } while (gpd_num > 0); |
| 485 | |
| 486 | /* Check HIF state */ |
| 487 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_STATE, (DCL_CTRL_DATA_T*) &ttyCtlHifSt); |
| 488 | if (ttyCtlHifSt.hif_state != HIF_STATE_NORMAL) { |
| 489 | EXCP_HALT(); |
| 490 | } |
| 491 | |
| 492 | if (!is_before_reset) {DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); } |
| 493 | } |
| 494 | |
| 495 | } |
| 496 | |
| 497 | static void excp_ccci_loopback_test(DCL_HANDLE handle, kal_uint32 num) |
| 498 | { |
| 499 | unsigned char *tx_buf_ptr; |
| 500 | unsigned char *rx_buf_ptr; |
| 501 | kal_char trigger_string[50] = {0}; |
| 502 | kal_uint32 i; |
| 503 | kal_uint32 total_rx_num; |
| 504 | TTY_CTRL_EXCP_ASSIGN_RX_GPD_T ttyCtlAsnRxGpd; |
| 505 | TTY_CTRL_EXCP_GET_RX_GPD_T ttyCtlGetRxGpd; |
| 506 | TTY_CTRL_EXCP_TX_GPD_T ttyCtlTxGpd; |
| 507 | TTY_CTRL_EXCP_TX_DONE_INFO_T ttyCtlTxDoneInfo; |
| 508 | TTY_CTRL_EXCP_HIF_STATE_T ttyCtlHifSt; |
| 509 | UART_CTRL_GET_MTU_SIZE_T ur_ctrl_get_mtu_size; |
| 510 | kal_uint32 tmp_num; |
| 511 | |
| 512 | /*For debug test only*/ |
| 513 | //BUSY_STOP(); |
| 514 | |
| 515 | /* Assign Rx GPD to driver */ |
| 516 | // TODO:Need to revise APIs. Because in exception mode(espicailly in HISR), some QBM APIs shall not be used. (ex:enhance mutex) |
| 517 | //tmp_num = _excp_alloc_gpd(GPD_TYPE_RX, 2/*1 for tailed GPD*/, &ttyCtlAsnRxGpd.first_gpd, &ttyCtlAsnRxGpd.last_gpd); |
| 518 | tmp_num = qbmt_alloc_q_no_tail(EXPT_TTY_RX_GPD_TYPE, 2, &ttyCtlAsnRxGpd.first_gpd, &ttyCtlAsnRxGpd.last_gpd); |
| 519 | if(tmp_num!= 2) while(1); |
| 520 | DclSerialPort_Control(handle, TTY_CMD_GET_MTU_SIZE, (DCL_CTRL_DATA_T*)&ur_ctrl_get_mtu_size); |
| 521 | QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.first_gpd, ur_ctrl_get_mtu_size.ulmtu_sz); |
| 522 | QBM_DES_SET_HWO(ttyCtlAsnRxGpd.first_gpd); |
| 523 | qbm_cal_set_checksum(ttyCtlAsnRxGpd.first_gpd); |
| 524 | QBM_CACHE_FLUSH(ttyCtlAsnRxGpd.first_gpd, sizeof(qbm_gpd)); |
| 525 | // last gpd |
| 526 | QBM_DES_SET_ALLOW_LEN(ttyCtlAsnRxGpd.last_gpd, ur_ctrl_get_mtu_size.ulmtu_sz); |
| 527 | QBM_DES_SET_HWO(ttyCtlAsnRxGpd.last_gpd); |
| 528 | qbm_cal_set_checksum(ttyCtlAsnRxGpd.last_gpd); |
| 529 | QBM_CACHE_FLUSH(ttyCtlAsnRxGpd.last_gpd, sizeof(qbm_gpd)); |
| 530 | |
| 531 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_ASSIGN_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlAsnRxGpd); |
| 532 | |
| 533 | total_rx_num = 0; |
| 534 | //while (total_rx_num < num) // Polling Received Rx GPD and transmit the data to Host |
| 535 | while(1) |
| 536 | { |
| 537 | void *cur_tx; |
| 538 | void *cur_rx; |
| 539 | kal_uint16 rx_len; |
| 540 | kal_uint16 gpd_num; |
| 541 | |
| 542 | /* Get Rx GPD */ |
| 543 | do { |
| 544 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); |
| 545 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_GET_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlGetRxGpd); |
| 546 | } while (ttyCtlGetRxGpd.num == 0); |
| 547 | total_rx_num += ttyCtlGetRxGpd.num; |
| 548 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] receive %d gpds, has received total %d gpds\r\n", ttyCtlGetRxGpd.num, total_rx_num); |
| 549 | |
| 550 | /* Allocate Tx GPD and re-transmit the rx data to Host */ |
| 551 | gpd_num = ttyCtlGetRxGpd.num; |
| 552 | //_excp_alloc_gpd(GPD_TYPE_TX, gpd_num, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd); |
| 553 | tmp_num = qbmt_alloc_q_no_tail(EXPT_TTY_TX_GPD_TYPE, gpd_num, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd); |
| 554 | if(tmp_num!= gpd_num) while(1); |
| 555 | |
| 556 | cur_rx = ttyCtlGetRxGpd.first_gpd; |
| 557 | cur_tx = ttyCtlTxGpd.first_gpd; |
| 558 | |
| 559 | for (i = 0; i < ttyCtlGetRxGpd.num; i ++) |
| 560 | { |
| 561 | rx_buf_ptr = _excp_get_qbm_dataptr(cur_rx); |
| 562 | rx_len = QBM_DES_GET_DATALEN(cur_rx); |
| 563 | tx_buf_ptr = _excp_get_qbm_dataptr(cur_tx); |
| 564 | |
| 565 | QBM_CACHE_INVALID(rx_buf_ptr, rx_len); |
| 566 | kal_mem_cpy(tx_buf_ptr, rx_buf_ptr, rx_len); |
| 567 | QBM_CACHE_FLUSH(tx_buf_ptr, rx_len); |
| 568 | |
| 569 | /* Set Tx GPD */ |
| 570 | _excp_set_qbm_datalen(cur_tx, rx_len); |
| 571 | QBM_DES_SET_HWO(cur_tx); |
| 572 | qbm_cal_set_checksum(cur_tx); |
| 573 | QBM_CACHE_FLUSH(cur_tx, sizeof(qbm_gpd)); |
| 574 | |
| 575 | /* Reset Rx GPD */ |
| 576 | _excp_rst_gpd_list(EXPT_TTY_RX_GPD_TYPE,cur_rx,cur_rx); |
| 577 | QBM_DES_SET_ALLOW_LEN(cur_rx, ur_ctrl_get_mtu_size.ulmtu_sz); |
| 578 | //QBM_DES_SET_HWO(cur_rx); |
| 579 | qbm_cal_set_checksum(cur_rx); |
| 580 | QBM_CACHE_FLUSH(cur_rx, sizeof(qbm_gpd)); |
| 581 | |
| 582 | cur_tx = QBM_DES_GET_NEXT(cur_tx); |
| 583 | cur_rx = QBM_DES_GET_NEXT(cur_rx); |
| 584 | } |
| 585 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlTxGpd); |
| 586 | |
| 587 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); |
| 588 | |
| 589 | /*Re-assign Rx GPD to driver */ |
| 590 | ttyCtlAsnRxGpd.first_gpd = ttyCtlGetRxGpd.first_gpd; |
| 591 | ttyCtlAsnRxGpd.last_gpd = ttyCtlGetRxGpd.last_gpd; |
| 592 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_ASSIGN_RX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlAsnRxGpd); |
| 593 | |
| 594 | /* Polling Tx Done Info until all Tx GPD are sent and retrieved */ |
| 595 | do { |
| 596 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); |
| 597 | |
| 598 | /*Debug only to check sdio interrupt status*/ |
| 599 | //if((*SDIO_IRQ_DL_FTE0SR) & SDIO_INT_MASK) while(1); |
| 600 | |
| 601 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_DONE_INFO, (DCL_CTRL_DATA_T*) &ttyCtlTxDoneInfo); |
| 602 | |
| 603 | if (ttyCtlTxDoneInfo.num > 0) { |
| 604 | //_excp_free_gpd(GPD_TYPE_TX, ttyCtlTxDoneInfo.first_gpd, ttyCtlTxDoneInfo.last_gpd); |
| 605 | qbmt_dest_q(ttyCtlTxDoneInfo.first_gpd, ttyCtlTxDoneInfo.last_gpd); |
| 606 | gpd_num -= ttyCtlTxDoneInfo.num; |
| 607 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] has sent %d gpds\r\n", ttyCtlTxDoneInfo.num); |
| 608 | } |
| 609 | } while (gpd_num > 0); |
| 610 | |
| 611 | /* Check HIF state */ |
| 612 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_STATE, (DCL_CTRL_DATA_T*) &ttyCtlHifSt); |
| 613 | if (ttyCtlHifSt.hif_state != HIF_STATE_NORMAL) { |
| 614 | EXCP_HALT(); |
| 615 | } |
| 616 | |
| 617 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); |
| 618 | } |
| 619 | |
| 620 | } |
| 621 | |
| 622 | DCL_STATUS excp_ttyut(void) |
| 623 | { |
| 624 | DCL_HANDLE handle; |
| 625 | |
| 626 | //for debug only |
| 627 | //BUSY_STOP(); |
| 628 | |
| 629 | hmu_except_init(); |
| 630 | |
| 631 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut start\r\n"); |
| 632 | |
| 633 | handle = DclSerialPort_Open(EXCEPTION_TEST_PORT, 0); |
| 634 | |
| 635 | /* Init QBM for exception */ |
| 636 | _excp_qbm_init(); |
| 637 | |
| 638 | /* Test Case 1: Loopback before RESET */ |
| 639 | /* HIF init and Clear channel */ |
| 640 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_INIT, NULL); |
| 641 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_CLEAR_CHANNEL, NULL); |
| 642 | |
| 643 | #ifdef __EXPT_CCCI_TTY_IT__ |
| 644 | excp_ccci_loopback_test(handle, TEST_LB_PKT_NUM); |
| 645 | #else |
| 646 | //BUSY_LOOP(60000000); |
| 647 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut case 1\r\n"); |
| 648 | { |
| 649 | excp_loopback_test(handle, KAL_TRUE, TEST_LB_PKT_NUM); |
| 650 | } |
| 651 | |
| 652 | /* Test Case 2: RESET */ |
| 653 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut case 2\r\n"); |
| 654 | { |
| 655 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_RESET, NULL); |
| 656 | } |
| 657 | |
| 658 | /* Test Case 3: Loopback after RESET */ |
| 659 | /* HIF init */ |
| 660 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_INIT, NULL); |
| 661 | //BUSY_LOOP(60000000); |
| 662 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut case 3\r\n"); |
| 663 | { |
| 664 | excp_loopback_test(handle, KAL_FALSE, TEST_LB_PKT_NUM); |
| 665 | } |
| 666 | |
| 667 | /* Test Case 4: HIF_STATE return TXERROR */ |
| 668 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut case 4\r\n"); |
| 669 | { |
| 670 | TTY_CTRL_EXCP_TX_GPD_T ttyCtlTxGpd; |
| 671 | TTY_CTRL_EXCP_TX_DONE_INFO_T ttyCtlTxDoneInfo; |
| 672 | TTY_CTRL_EXCP_HIF_STATE_T ttyCtlHifSt; |
| 673 | kal_uint16 gpd_num; |
| 674 | kal_uint16 count; |
| 675 | |
| 676 | BUSY_LOOP(50000); |
| 677 | while (1) |
| 678 | { |
| 679 | gpd_num = _excp_alloc_gpd(GPD_TYPE_TX, 1, &ttyCtlTxGpd.first_gpd, &ttyCtlTxGpd.last_gpd); |
| 680 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] allocate %d gpd\r\n", gpd_num); |
| 681 | if (gpd_num == 0) { |
| 682 | break; |
| 683 | } |
| 684 | QBM_DES_SET_DATALEN(ttyCtlTxGpd.first_gpd, 100); |
| 685 | QBM_DES_SET_HWO(ttyCtlTxGpd.first_gpd); |
| 686 | qbm_cal_set_checksum(ttyCtlTxGpd.first_gpd); |
| 687 | QBM_CACHE_FLUSH(ttyCtlTxGpd.first_gpd, sizeof(qbm_gpd)); |
| 688 | |
| 689 | BUSY_LOOP(300000); |
| 690 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_GPD, (DCL_CTRL_DATA_T*) &ttyCtlTxGpd); |
| 691 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_POLL, NULL); |
| 692 | } |
| 693 | |
| 694 | count = 10000; |
| 695 | while (count-- > 0) |
| 696 | { |
| 697 | BUSY_LOOP(30000); |
| 698 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_TX_DONE_INFO, (DCL_CTRL_DATA_T*) &ttyCtlTxDoneInfo); |
| 699 | } |
| 700 | |
| 701 | DclSerialPort_Control(handle, TTY_CMD_EXCEPTION_HIF_STATE, (DCL_CTRL_DATA_T*) &ttyCtlHifSt); |
| 702 | if (ttyCtlHifSt.hif_state != HIF_STATE_TXERROR) { |
| 703 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] ERROR!! HIF_STATE return NORMAL\r\n"); |
| 704 | EXCP_HALT(); |
| 705 | } else { |
| 706 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] HIF_STATE return HIF_STATE_TXERROR\r\n"); |
| 707 | } |
| 708 | } |
| 709 | |
| 710 | TTYUT_DBG_PRINT("[EXCEPT TTYUT] excp_ttyut end\r\n"); |
| 711 | #endif |
| 712 | return STATUS_OK; |
| 713 | } |
| 714 | |
| 715 | static kal_bool excp_ttyut_task_init(void) |
| 716 | { |
| 717 | return KAL_TRUE; |
| 718 | } |
| 719 | |
| 720 | static void excp_ttyut_task_main(task_entry_struct *task_entry_ptr) |
| 721 | { |
| 722 | DCL_HANDLE handle; |
| 723 | UART_CTRL_PUT_BYTES_T ur_ctrl_putbytes; |
| 724 | char *dummy_string = "DUMMYdummyDummY"; |
| 725 | DCL_STATUS status; |
| 726 | UART_CTRL_GET_DRV_STATE_T getDrvState; |
| 727 | |
| 728 | handle = DclSerialPort_Open(EXCEPTION_TEST_PORT, 0); |
| 729 | |
| 730 | DclSerialPort_UpModuleInit(handle, MOD_EXCP_TTYUT, 0); // conventional init |
| 731 | |
| 732 | /*If taking CCCI exception IT test, task will be blocked here. Because, driver is attached when exception init*/ |
| 733 | getDrvState.u4OwnerId = MOD_EXCP_TTYUT; |
| 734 | do { |
| 735 | kal_sleep_task(KAL_TICKS_100_MSEC); |
| 736 | status = DclSerialPort_Control(handle, TTY_CMD_GET_DRV_STATE, (DCL_CTRL_DATA_T*) &getDrvState); |
| 737 | } while ((getDrvState.drv_state != DRV_ST_ATTACHED) || (status != STATUS_OK)); |
| 738 | |
| 739 | kal_sleep_task(KAL_TICKS_5_SEC); |
| 740 | |
| 741 | /* Transmit a dummy packet */ |
| 742 | ur_ctrl_putbytes.u4OwenrId = MOD_EXCP_TTYUT; |
| 743 | ur_ctrl_putbytes.puBuffaddr = (DCL_UINT8*)dummy_string; |
| 744 | ur_ctrl_putbytes.u2Length = strlen(dummy_string); |
| 745 | DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*) &ur_ctrl_putbytes); |
| 746 | |
| 747 | kal_sleep_task(KAL_TICKS_5_SEC); |
| 748 | |
| 749 | /* Trigger an assert to enter exception mode */ |
| 750 | ASSERT(0); |
| 751 | } |
| 752 | |
| 753 | kal_bool excp_ttyut_create(comptask_handler_struct **handle) |
| 754 | { |
| 755 | static const comptask_handler_struct excp_ttyut_handler_info = |
| 756 | { |
| 757 | excp_ttyut_task_main, /* task entry function */ |
| 758 | excp_ttyut_task_init, /* task initialization function */ |
| 759 | NULL /* task reset handler */ |
| 760 | }; |
| 761 | |
| 762 | TTYUT_DBG_PRINT("=========>excp_ttyut_create\r\n"); |
| 763 | |
| 764 | *handle = (comptask_handler_struct *)&excp_ttyut_handler_info; |
| 765 | return KAL_TRUE; |
| 766 | } |
| 767 | |