/****************************************************************************** * * Copyright(c) 2019 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * *****************************************************************************/ #define _TEST_MODULE_C_ #ifdef CONFIG_PHL_TEST_SUITE #include "../phl_headers.h" #define MAX_TEST_OBJ_NUM 128 #define THREAD_SLEEP_UNIT 1000 /* ms */ #define MAX_TEST_CMD_BUF 2000 #define TEST_MGNT_ALREADY_INIT(_test_mgnt) \ ((_test_mgnt) && TEST_STATUS_FLAG((_test_mgnt)->status,TM_STATUS_INIT)) #define IS_TEST_MGNT_ALLOC(_phl_com) ((_phl_com) && ((_phl_com)->test_mgnt)) enum TEST_MGNT_STATUS_FALGS{ TM_STATUS_INIT = BIT0, TM_STATUS_FORCE_STOP = BIT1, TM_STATUS_THREAD_START = BIT2 }; enum TEST_OBJ_STATUS_FALGS{ /* regular status*/ TO_STATUS_PASS = BIT0, TO_STATUS_FAIL = BIT1, TO_STATUS_ENQ = BIT2, TO_STATUS_RUNNING = BIT3, /* process error status*/ TO_STATUS_RUN_THREAD_FAIL = BIT24, TO_STATUS_TIMEOUT = BIT25, }; struct test_object_ex { struct test_object test_obj; u32 start_time; u32 end_time; u32 status; struct rtw_phl_handler handler; void* test_mgnt; _os_thread objthread; u8 submd_obj_id; u8 submd_test_mode; }; struct test_obj_queue { _os_list q; _os_mutex lock; }; struct test_mgnt_info{ struct test_obj_queue idle_queue; struct test_obj_queue busy_queue; struct test_obj_queue rpt_queue; struct test_obj_queue err_queue; struct test_object_ex test_obj_pool[MAX_TEST_OBJ_NUM]; struct test_object_ex *cur_test_obj; s32 max_run_time[TEST_LVL_MAX]; _os_thread thread; u32 status; _os_sema busy_chk; struct rtw_phl_com_t *phl_com; struct phl_info_t *phl; void *hal; /* test module context root */ void *mp_ctx; void *ver_ctx; }; struct test_module_cmd { u8 type; u8 buf[MAX_TEST_CMD_BUF]; u16 len; }; struct test_module_info { u8 tm_type; u8 tm_mode; }; static void _init_test_obj_queue(void *d, struct test_obj_queue *queue) { INIT_LIST_HEAD(&queue->q); _os_mutex_init(d, &queue->lock); } static void _deinit_test_obj_queue(void *d, struct test_obj_queue *queue) { _os_mutex_deinit(d, &queue->lock); } static int _enqueue_obj(void *d, struct test_obj_queue *queue, struct test_object_ex *obj) { _os_mutex_lock(d, &queue->lock); list_add_tail(&(obj->test_obj.list), &queue->q); _os_mutex_unlock(d, &queue->lock); return 0; } static u8 _dequeue_head_obj(void *d, struct test_obj_queue *queue, struct test_object_ex **obj) { (*obj) = NULL; if(list_empty(&(queue->q))) return false; _os_mutex_lock(d, &queue->lock); (*obj) = list_first_entry(&(queue->q), struct test_object_ex, test_obj.list); list_del(&((*obj)->test_obj.list)); _os_mutex_unlock(d, &queue->lock); return ((*obj) == NULL|| ((struct list_head*)(*obj)) == &(queue->q)) ? \ (false) : (true); } int run_test(void *testobj) { struct test_object_ex *obj = (struct test_object_ex *)testobj; struct test_mgnt_info *test_mgnt = obj->test_mgnt; u8 ret = false; u32 start_time = 0; u32 end_time = 0; void *d = test_mgnt->phl_com->drv_priv; /* -1: no limit, 0: not set use default value */ s32 limit = obj->test_obj.total_time_ms; enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS; if (obj->test_obj.total_time_ms != -1) { limit = (obj->test_obj.total_time_ms) ? \ (obj->test_obj.total_time_ms) : \ (test_mgnt->max_run_time[obj->test_obj.run_lvl]); } SET_STATUS_FLAG(obj->status, TO_STATUS_RUNNING); pstatus = phl_schedule_handler(test_mgnt->phl_com, &(obj->handler)); if (RTW_PHL_STATUS_SUCCESS != pstatus) { SET_STATUS_FLAG(obj->status, TO_STATUS_RUN_THREAD_FAIL); CLEAR_STATUS_FLAG(obj->status, TO_STATUS_RUNNING); return 0; } start_time = _os_get_cur_time_us(); /*wait test end*/ while (!(obj->test_obj.ctrl.is_test_end(obj->test_obj.priv))) { end_time = _os_get_cur_time_us(); if ((limit >= 0) && ((s32)((end_time-start_time)/1000) >= limit)) { SET_STATUS_FLAG(obj->status, TO_STATUS_TIMEOUT); obj->end_time = end_time; break; } _os_sleep_us(test_mgnt->phl_com->drv_priv, THREAD_SLEEP_UNIT); } if (!TEST_STATUS_FLAG(obj->status, TO_STATUS_TIMEOUT)) obj->end_time = _os_get_cur_time_us(); ret = obj->test_obj.ctrl.is_test_pass(obj->test_obj.priv); SET_STATUS_FLAG(obj->status, (!ret) ? \ (TO_STATUS_FAIL) : (TO_STATUS_PASS)); _enqueue_obj(d, &(test_mgnt->rpt_queue), obj); if (obj->submd_test_mode == INTGR_TEST_MODE) { if (!_os_thread_check_stop(d, &(obj->objthread))) _os_thread_wait_stop(d, &obj->objthread); } CLEAR_STATUS_FLAG(obj->status, TO_STATUS_RUNNING); PHL_INFO("[TM]: obj thread (%s) stop.\n", obj->test_obj.name); return 0; } int test_thread(void *param) { struct test_mgnt_info *test_mgnt = (struct test_mgnt_info *)phl_container_of(param, struct test_mgnt_info, thread); void *d = NULL; struct test_object_ex *obj; if (!IS_TEST_MGNT_ALLOC(test_mgnt->phl_com)) return 0; d = test_mgnt->phl_com->drv_priv; if (!TEST_MGNT_ALREADY_INIT(test_mgnt)) { PHL_ERR("[TM]: return.\n"); return 0; } PHL_INFO("[TM]: thread started.\n"); SET_STATUS_FLAG(test_mgnt->status, TM_STATUS_THREAD_START); while (!TEST_STATUS_FLAG(test_mgnt->status, TM_STATUS_FORCE_STOP)) { _os_sema_down(d, &(test_mgnt->busy_chk)); if (TEST_STATUS_FLAG(test_mgnt->status, TM_STATUS_FORCE_STOP)) break; while (_dequeue_head_obj(d, &(test_mgnt->busy_queue), &(test_mgnt->cur_test_obj))) { _os_thread *thread = NULL; obj = test_mgnt->cur_test_obj; CLEAR_STATUS_FLAG(obj->status, TO_STATUS_ENQ); if (obj->submd_test_mode == UNIT_TEST_MODE) { PHL_INFO("[TM]: %s UNIT_TEST_MODE \n", __FUNCTION__); run_test(obj); } else if (obj->submd_test_mode == INTGR_TEST_MODE) { PHL_INFO("[TM]: %s INTGR_TEST_MODE \n", __FUNCTION__); thread = &obj->objthread; _os_thread_init(d, thread, run_test, obj, obj->test_obj.name); _os_thread_schedule(d, thread); } test_mgnt->cur_test_obj = NULL; } } _os_thread_wait_stop(d, &test_mgnt->thread); CLEAR_STATUS_FLAG(test_mgnt->status, TM_STATUS_THREAD_START); PHL_INFO("[TM]: test mgnt thread is down\n"); return 0; } static void _test_submodule_deinit(void *tm) { struct test_mgnt_info *test_mgnt = (struct test_mgnt_info *)tm; phl_test_mp_deinit(test_mgnt->mp_ctx); phl_test_verify_deinit(test_mgnt->ver_ctx); } u8 phl_test_module_init(struct phl_info_t *phl_info) { struct rtw_phl_com_t* phl_com = phl_info->phl_com; struct test_mgnt_info *test_mgnt = NULL; void *d = NULL; u8 i = 0; if(phl_com==NULL) goto _test_module_mem; d = phl_com->drv_priv; test_mgnt = (struct test_mgnt_info *)_os_mem_alloc(d, sizeof(struct test_mgnt_info)); if (test_mgnt == NULL) goto _test_module_mem; _os_mem_set(d, test_mgnt, 0, sizeof(struct test_mgnt_info)); phl_com->test_mgnt = test_mgnt; test_mgnt->phl_com = phl_com; test_mgnt->phl = phl_info; test_mgnt->hal = phl_info->hal; for(i = 0; i < MAX_TEST_OBJ_NUM; i++) test_mgnt->test_obj_pool[i].submd_obj_id = TEST_SUB_MODULE_UNKNOWN; if (phl_test_mp_alloc(test_mgnt->phl, test_mgnt->hal, &(test_mgnt->mp_ctx)) != RTW_PHL_STATUS_SUCCESS) { PHL_INFO("[TM]: %s phl_test_mp_alloc fail!\n",__FUNCTION__); goto _mp_module_mem; } if(phl_test_verify_alloc(test_mgnt->phl, test_mgnt->hal, &(test_mgnt->ver_ctx)) != RTW_PHL_STATUS_SUCCESS) { PHL_INFO("[TM]: %s phl_test_verify_alloc fail!\n",__FUNCTION__); goto _verify_module_mem; } PHL_INFO("[TM]: %s\n",__FUNCTION__); return true; _verify_module_mem: phl_test_mp_free(&test_mgnt->mp_ctx); _mp_module_mem: _os_mem_free(d, test_mgnt, sizeof(struct test_mgnt_info)); _test_module_mem: return false; } void phl_test_module_deinit(struct rtw_phl_com_t* phl_com) { void *d = NULL; struct test_mgnt_info *test_mgnt = NULL; if(!IS_TEST_MGNT_ALLOC(phl_com)) return; d = phl_com->drv_priv; test_mgnt = phlcom_to_test_mgnt(phl_com); if(TEST_MGNT_ALREADY_INIT(test_mgnt)) phl_test_module_stop(phl_com); phl_test_mp_free(&test_mgnt->mp_ctx); phl_test_verify_free(&test_mgnt->ver_ctx); _os_mem_free(d, test_mgnt, sizeof(struct test_mgnt_info)); phl_com->test_mgnt = NULL; PHL_INFO("[TM]: %s\n",__FUNCTION__); } u8 phl_test_module_start(struct rtw_phl_com_t* phl_com) { struct test_mgnt_info *test_mgnt = NULL; _os_thread *thread = NULL; void *d = NULL; u32 i = 0; if(!IS_TEST_MGNT_ALLOC(phl_com)) return false; d = phl_com->drv_priv; test_mgnt = phlcom_to_test_mgnt(phl_com); if(TEST_MGNT_ALREADY_INIT(test_mgnt)) { PHL_INFO("[TM]: %s, already initialized\n",__FUNCTION__); return true; } test_mgnt->status = 0; _init_test_obj_queue(d, &(test_mgnt->busy_queue)); _init_test_obj_queue(d, &(test_mgnt->idle_queue)); _init_test_obj_queue(d, &(test_mgnt->rpt_queue)); _init_test_obj_queue(d, &(test_mgnt->err_queue)); /*insert all elements in obj pool into idle Q*/ for(i = 0; i < MAX_TEST_OBJ_NUM;i++) { test_mgnt->test_obj_pool[i].submd_obj_id = TEST_SUB_MODULE_UNKNOWN; _enqueue_obj(d, &(test_mgnt->idle_queue), &(test_mgnt->test_obj_pool[i])); } test_mgnt->max_run_time[TEST_LVL_LOW] = TEST_LVL_LOW_TO; test_mgnt->max_run_time[TEST_LVL_NORMAL] = TEST_LVL_NORMAL_TO; test_mgnt->max_run_time[TEST_LVL_HIGH] = TEST_LVL_HIGH_TO; SET_STATUS_FLAG(test_mgnt->status, TM_STATUS_INIT); thread = &(test_mgnt->thread); _os_sema_init(d, &(test_mgnt->busy_chk), 0); _os_thread_init(d, thread, test_thread, thread, "test_thread"); _os_thread_schedule(d, thread); PHL_INFO("[TM]: %s\n",__FUNCTION__); return true; } void phl_test_module_stop(struct rtw_phl_com_t* phl_com) { struct test_mgnt_info *test_mgnt = NULL; void *d = NULL; u32 i = 0; if(!IS_TEST_MGNT_ALLOC(phl_com)) return; d = phl_com->drv_priv; test_mgnt = phlcom_to_test_mgnt(phl_com); if(!TEST_MGNT_ALREADY_INIT(test_mgnt)) return; /* Call all sub module deinit */ _test_submodule_deinit(test_mgnt); SET_STATUS_FLAG(test_mgnt->status, TM_STATUS_FORCE_STOP); _os_thread_stop(d, &(test_mgnt->thread)); _os_sema_up(d, &(test_mgnt->busy_chk)); /*wait thread stop*/ PHL_INFO("[TM]: %s stop test_thread\n",__FUNCTION__); _os_thread_deinit(d, &(test_mgnt->thread)); _os_sema_free(d, &(test_mgnt->busy_chk)); /*clean up test obj resource*/ for (i = 0; i < MAX_TEST_OBJ_NUM; i++) { struct test_object_ex *obj = &(test_mgnt->test_obj_pool[i]); if (obj->submd_obj_id != TEST_SUB_MODULE_UNKNOWN && obj->status != TO_STATUS_ENQ) { if (obj->submd_test_mode == INTGR_TEST_MODE) { if (!_os_thread_check_stop(d, &(obj->objthread))) { _os_thread_stop(d, &(obj->objthread)); _os_thread_deinit(d, &(obj->objthread)); } } phl_deregister_handler(phl_com, &(obj->handler)); } } /*no need to empty test obj Q before deinit*/ _deinit_test_obj_queue(d, &(test_mgnt->busy_queue)); _deinit_test_obj_queue(d, &(test_mgnt->idle_queue)); _deinit_test_obj_queue(d, &(test_mgnt->rpt_queue)); _deinit_test_obj_queue(d, &(test_mgnt->err_queue)); CLEAR_STATUS_FLAG(test_mgnt->status, TM_STATUS_INIT); PHL_INFO("[TM]: %s\n",__FUNCTION__); } u8 rtw_phl_test_set_max_run_time(struct rtw_phl_com_t* phl_com, enum TEST_RUN_LVL lvl, u32 timeout_ms) { struct test_mgnt_info *test_mgnt = NULL; if(!IS_TEST_MGNT_ALLOC(phl_com)) return false; test_mgnt = phlcom_to_test_mgnt(phl_com); if(!TEST_MGNT_ALREADY_INIT(test_mgnt)) return false; test_mgnt = phlcom_to_test_mgnt(phl_com); test_mgnt->max_run_time[lvl] = timeout_ms; return true; } void setup_test_rpt(void *d, struct test_rpt* rpt,struct test_object_ex *obj) { char str[] = "Exceed Time Limit"; char str2[] = "Test not run"; char str3[] = "None"; _os_mem_cpy(d, rpt->name, obj->test_obj.name, TEST_NAME_LEN); if(TEST_STATUS_FLAG(obj->status, TO_STATUS_TIMEOUT)) { _os_mem_cpy(d, rpt->rsn, str, sizeof(str)); rpt->status = 0; rpt->total_time = (u32)((obj->end_time - obj->start_time)/1000); } else if(TEST_STATUS_FLAG(obj->status, TO_STATUS_RUN_THREAD_FAIL)) { _os_mem_cpy(d, rpt->rsn, str2, sizeof(str2)); rpt->status = 0; rpt->total_time = 0; } else{ obj->test_obj.ctrl.get_fail_rsn(obj->test_obj.priv, (char*)&(rpt->rsn[0]), TEST_NAME_LEN-1); if(_os_strlen((u8*)rpt->rsn) <= 0) _os_mem_cpy(d, rpt->rsn, str3, sizeof(str3)); if (TEST_STATUS_FLAG(obj->status, TO_STATUS_PASS)) rpt->status = 1; else rpt->status = 0; rpt->total_time = (u32)((obj->end_time - obj->start_time)/1000); } } u8 rtw_phl_test_get_rpt(struct rtw_phl_com_t* phl_com, u8* buf, u32 len) { struct test_mgnt_info *test_mgnt = NULL; struct test_object_ex *obj = NULL; u32 rpt_size = sizeof(struct test_rpt); void *d = NULL; u8 is_rpt_empty = true; if(!IS_TEST_MGNT_ALLOC(phl_com)) return false; d = phl_com->drv_priv; test_mgnt = phlcom_to_test_mgnt(phl_com); if(!TEST_MGNT_ALREADY_INIT(test_mgnt)) return false; while (len >= rpt_size) { if(_dequeue_head_obj(d, &(test_mgnt->rpt_queue), &obj)) { is_rpt_empty = false; setup_test_rpt(d, (struct test_rpt*)buf, obj); if (TEST_STATUS_FLAG(obj->status, TO_STATUS_TIMEOUT)) _enqueue_obj(d, &(test_mgnt->err_queue), obj); else { if (obj->submd_test_mode == INTGR_TEST_MODE) { if (!_os_thread_check_stop(d, &(obj->objthread))) { PHL_INFO("[TM]: %s obj thread (%s) stop.\n", __FUNCTION__, obj->test_obj.name); _os_thread_stop(d, &(obj->objthread)); _os_thread_deinit(d, &(obj->objthread)); } } phl_deregister_handler(phl_com, &(obj->handler)); obj->status = 0; obj->submd_obj_id = TEST_SUB_MODULE_UNKNOWN; _enqueue_obj(d, &(test_mgnt->idle_queue), obj); } buf += rpt_size; len -= rpt_size; } else break; } return (is_rpt_empty)?(false):(true); } u8 rtw_phl_test_is_test_complete(struct rtw_phl_com_t* phl_com) { struct test_mgnt_info *test_mgnt = NULL; void *d = NULL; if(!IS_TEST_MGNT_ALLOC(phl_com)) return false; d = phl_com->drv_priv; test_mgnt = phlcom_to_test_mgnt(phl_com); if(!TEST_MGNT_ALREADY_INIT(test_mgnt)) return false; if (list_empty(&(test_mgnt->busy_queue.q)) && !(test_mgnt->cur_test_obj)) return true; return false; } static void _test_obj_thread_callback(void *context) { struct rtw_phl_handler *phl_handler = (struct rtw_phl_handler *)phl_container_of(context, struct rtw_phl_handler, os_handler); struct test_object_ex *obj = (struct test_object_ex *)phl_handler->context; obj->start_time = _os_get_cur_time_us(); obj->test_obj.ctrl.start_test(obj->test_obj.priv); } u8 init_obj_thread(struct test_mgnt_info *test_mgnt, struct test_object_ex *obj, enum TEST_RUN_LVL lvl) { enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE; switch(lvl){ case TEST_LVL_LOW: case TEST_LVL_NORMAL: obj->handler.type = RTW_PHL_HANDLER_PRIO_LOW; break; case TEST_LVL_HIGH: obj->handler.type = RTW_PHL_HANDLER_PRIO_HIGH; break; case TEST_LVL_NONE: case TEST_LVL_MAX: PHL_TRACE(COMP_PHL_DBG, _PHL_DEBUG_, "init_obj_thread(): Unsupported case:%d, please check it\n", lvl); break; default: PHL_TRACE(COMP_PHL_DBG, _PHL_DEBUG_, "init_obj_thread(): Unrecognize case:%d, please check it\n", lvl); break; } obj->handler.callback = _test_obj_thread_callback; obj->handler.context = obj; obj->handler.drv_priv = test_mgnt->phl_com->drv_priv; pstatus = phl_register_handler(test_mgnt->phl_com, &(obj->handler)); return (RTW_PHL_STATUS_SUCCESS != pstatus) ? (false) : (true); } u8 rtw_phl_test_add_new_test_obj(struct rtw_phl_com_t *phl_com, char *name, void *custom_priv, enum TEST_RUN_LVL lvl, struct test_obj_ctrl_interface *ctrl_intf, s32 total_time_ms, u8 submd_id, u8 test_mode) { struct test_mgnt_info *test_mgnt = NULL; struct test_object_ex *obj = NULL; void *d = NULL; u8 i; u8 is_idle_empty = true; u32 name_len = (_os_strlen((u8 *)name) > (u32)(TEST_NAME_LEN - 1)) ?\ ((u32)(TEST_NAME_LEN - 1)) :\ (_os_strlen((u8 *)name) + 1); if (!IS_TEST_MGNT_ALLOC(phl_com)) return false; d = phl_com->drv_priv; test_mgnt = phlcom_to_test_mgnt(phl_com); if (!TEST_MGNT_ALREADY_INIT(test_mgnt)) return false; for (i = 0; i < MAX_TEST_OBJ_NUM; i++) { obj = &(test_mgnt->test_obj_pool[i]); if (obj->submd_obj_id == submd_id && obj->status == TO_STATUS_RUNNING) { PHL_INFO("%s() Error same submd id %d\n", __func__, obj->submd_obj_id); return false; } } if (_dequeue_head_obj(d, &(test_mgnt->idle_queue), &obj)) { is_idle_empty = false; if (TEST_STATUS_FLAG(obj->status, TO_STATUS_ENQ)) phl_deregister_handler(phl_com, &(obj->handler)); /*cleanup entire test obj before reuse*/ _os_mem_set(d, obj, 0, sizeof(struct test_object_ex)); _os_mem_cpy(d, &(obj->test_obj.ctrl), ctrl_intf, sizeof(struct test_obj_ctrl_interface)); _os_mem_cpy(d, &(obj->test_obj.name[0]), name, name_len); obj->test_obj.priv = custom_priv; obj->test_obj.run_lvl = lvl; obj->test_mgnt = test_mgnt; obj->test_obj.total_time_ms = (lvl <= TEST_LVL_LOW) ?\ (total_time_ms) : (0); obj->submd_obj_id = submd_id; obj->submd_test_mode = test_mode; if (init_obj_thread(test_mgnt, obj, lvl)) { SET_STATUS_FLAG(obj->status, TO_STATUS_ENQ); _enqueue_obj(d, &(test_mgnt->busy_queue), obj); _os_sema_up(d, &(test_mgnt->busy_chk)); PHL_INFO("[TM]: %s, id %u EnQ\n", __FUNCTION__, submd_id); } else { _enqueue_obj(d, &(test_mgnt->idle_queue), obj); PHL_INFO("[TM]: %s, id %u EnQ fail\n", __FUNCTION__, submd_id); } } if (is_idle_empty || !TEST_STATUS_FLAG(obj->status, TO_STATUS_ENQ)) return false; return true; } u8 rtw_phl_test_setup_bp(struct rtw_phl_com_t* phl_com, struct test_bp_info* bp_info, u8 submdid) { u8 i; struct test_mgnt_info *test_mgnt = NULL; struct test_object_ex *obj = NULL; if(!IS_TEST_MGNT_ALLOC(phl_com)) return false; test_mgnt = phlcom_to_test_mgnt(phl_com); for (i = 0; i < MAX_TEST_OBJ_NUM; i++) { obj = &(test_mgnt->test_obj_pool[i]); if (obj->submd_obj_id == submdid && TEST_STATUS_FLAG(obj->status, TO_STATUS_RUNNING)) { PHL_DBG("%s() objid = %d setup bp\n", __func__, obj->submd_obj_id); break; } } if(!TEST_MGNT_ALREADY_INIT(test_mgnt)) return false; return (obj && TEST_STATUS_FLAG(obj->status, TO_STATUS_RUNNING))?\ (obj->test_obj.ctrl.bp_handler(obj->test_obj.priv, bp_info)):\ (BP_RET_RUN_ORIGIN_SEC); } void rtw_phl_test_submodule_init(struct rtw_phl_com_t* phl_com, void *buf) { struct test_mgnt_info *test_mgnt = (struct test_mgnt_info *)phl_com->test_mgnt; struct test_module_info *tm_info = NULL; if(buf == NULL) return; tm_info = (struct test_module_info *)buf; switch(tm_info->tm_type) { case TEST_SUB_MODULE_MP: phl_test_mp_init(test_mgnt->mp_ctx); phl_test_mp_start(test_mgnt->mp_ctx, tm_info->tm_mode); break; case TEST_SUB_MODULE_VERIFY: phl_test_verify_init(test_mgnt->ver_ctx); phl_test_verify_start(test_mgnt->ver_ctx); break; case TEST_SUB_MODULE_FPGA: case TEST_SUB_MODULE_TOOL: default: break; } } void rtw_phl_test_submodule_deinit(struct rtw_phl_com_t* phl_com, void *buf) { struct test_mgnt_info *test_mgnt = (struct test_mgnt_info *)phl_com->test_mgnt; struct test_module_info *tm_info = NULL; if(buf == NULL) return; tm_info = (struct test_module_info *)buf; switch(tm_info->tm_type) { case TEST_SUB_MODULE_MP: phl_test_mp_stop(test_mgnt->mp_ctx, tm_info->tm_mode); phl_test_mp_deinit(test_mgnt->mp_ctx); break; case TEST_SUB_MODULE_VERIFY: phl_test_verify_stop(test_mgnt->ver_ctx); phl_test_verify_deinit(test_mgnt->ver_ctx); break; case TEST_SUB_MODULE_FPGA: case TEST_SUB_MODULE_TOOL: default: break; } } void rtw_phl_test_submodule_cmd_process(struct rtw_phl_com_t* phl_com, void *buf, u32 buf_len) { struct test_mgnt_info *test_mgnt = (struct test_mgnt_info *)phl_com->test_mgnt; struct test_module_cmd *cmd = NULL; u8 type = TEST_SUB_MODULE_UNKNOWN; if(buf == NULL) return; cmd = (struct test_module_cmd *)buf; type = cmd->type; /* debug_dump_data(cmd->buf, MAX_TEST_CMD_BUF, "[TM] cmd buf ="); */ PHL_INFO("%s: len = %d\n", __FUNCTION__, cmd->len); switch(type) { case TEST_SUB_MODULE_MP: phl_test_mp_cmd_process(test_mgnt->mp_ctx, cmd->buf, cmd->len, TEST_SUB_MODULE_MP); break; case TEST_SUB_MODULE_VERIFY: phl_test_verify_cmd_process(test_mgnt->ver_ctx, cmd->buf, cmd->len, TEST_SUB_MODULE_VERIFY); break; case TEST_SUB_MODULE_FPGA: case TEST_SUB_MODULE_TOOL: default: break; } } void rtw_phl_test_submodule_get_rpt(struct rtw_phl_com_t* phl_com, void *buf, u32 buf_len) { struct test_mgnt_info *test_mgnt = (struct test_mgnt_info *)phl_com->test_mgnt; struct test_module_cmd *cmd = NULL; u8 type = TEST_SUB_MODULE_UNKNOWN; if(!buf) return; cmd = (struct test_module_cmd *)buf; type = cmd->type; switch(type) { case TEST_SUB_MODULE_MP: phl_test_mp_get_rpt(test_mgnt->mp_ctx, cmd->buf, cmd->len); break; case TEST_SUB_MODULE_VERIFY: phl_test_verify_get_rpt(test_mgnt->ver_ctx, cmd->buf, cmd->len); break; case TEST_SUB_MODULE_FPGA: case TEST_SUB_MODULE_TOOL: default: break; } } #endif /*ifdef CONFIG_PHL_TEST_SUITE*/