blob: 0dbaa4cc4b4660c600ec034fc5df0cad04355c1e [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001/*****************************************************************************
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__
126static DCL_UINT8 bm_buf_excp_tx[QBM_QUEUE_GET_MEM_SIZE(QBM_TYPE_CCCI_COMM, TX_BUF_NUM)];
127static DCL_UINT8 bm_buf_excp_rx[QBM_QUEUE_GET_MEM_SIZE(QBM_TYPE_CCCI_COMM, RX_BUF_NUM)];
128#else
129static DCL_UINT8 bm_buf_excp_tx[QBM_QUEUE_GET_MEM_SIZE(QBM_SIZE_TTY_INT, TX_BUF_NUM)];
130static DCL_UINT8 bm_buf_excp_rx[QBM_QUEUE_GET_MEM_SIZE(QBM_SIZE_TTY_INT, RX_BUF_NUM)];
131#endif
132
133static void *excp_tgpd_head = NULL;
134static void *excp_tgpd_tail = NULL;
135static void *excp_rgpd_head = NULL;
136static void *excp_rgpd_tail = NULL;
137
138static void *excp_tgpd_free_head = NULL;
139static void *excp_tgpd_free_tail = NULL;
140static void *excp_rgpd_free_head = NULL;
141static void *excp_rgpd_free_tail = NULL;
142
143typedef 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
151extern void dbg_print(char *fmt,...);
152
153#define TTYUT_DBG_PRINT(...)
154
155
156/*for debug only (CCCI)*/
157static 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
166void _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 */
203static 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
241static 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
270static 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
295static 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
315static 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
334static 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
497static 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
622DCL_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
715static kal_bool excp_ttyut_task_init(void)
716{
717 return KAL_TRUE;
718}
719
720static 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
753kal_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