2025-05-10 21:58:58 +08:00

760 lines
21 KiB
C

/******************************************************************************
*
* 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*/