1 /******************************************************************************
2 *
3 * Copyright(c) 2019 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 *****************************************************************************/
15 #define _PHL_TEST_VERIFY_C_
16 #include "../../phl_headers.h"
17 #include "phl_test_verify_def.h"
18 #include "phl_test_verify_api.h"
19 #include "./dbcc/phl_test_dbcc_api.h"
20
21 #ifdef CONFIG_PHL_TEST_VERIFY
22
23 static struct s_handler test_handlers[VERIFY_FEATURES_MAX] = {
24 { func_null }, /* VERIFY_FEATURES_NULL = 0 */
25 { rtw_test_dbcc_cmd_process }, /* VERIFY_FEATURES_DBCC */
26 };
27
verify_cmd_done_notification_complete(void * ctx,struct phl_msg * msg)28 void verify_cmd_done_notification_complete(void *ctx, struct phl_msg *msg)
29 {
30 struct verify_context *ver_ctx = (struct verify_context *)ctx;
31
32 if (msg->inbuf) {
33 PHL_INFO("%s: Free info buf\n", __FUNCTION__);
34 _os_mem_free(ver_ctx->phl_com->drv_priv, msg->inbuf, msg->inlen);
35 }
36 }
37
verify_cmd_done_notification(struct verify_context * ver_ctx,u8 feature,u8 cmd_id)38 void verify_cmd_done_notification(struct verify_context *ver_ctx, u8 feature,
39 u8 cmd_id)
40 {
41 struct phl_msg msg = { 0 };
42 struct phl_msg_attribute attr = { 0 };
43 u8 *info = NULL;
44
45 info = _os_mem_alloc(ver_ctx->phl_com->drv_priv, 2);
46 if (info == NULL) {
47 PHL_ERR("%s: Allocate msg hub buffer fail!\n", __FUNCTION__);
48 return;
49 }
50
51 info[0] = feature;
52 info[1] = cmd_id;
53
54 SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_FUNC_MDL_TEST_MODULE);
55 SET_MSG_EVT_ID_FIELD(msg.msg_id, MSG_EVT_MP_CMD_DONE);
56
57 attr.completion.completion = verify_cmd_done_notification_complete;
58 attr.completion.priv = ver_ctx;
59
60 msg.inbuf = info;
61 msg.inlen = 2;
62
63 if (phl_msg_hub_send(ver_ctx->phl, &attr, &msg) != RTW_PHL_STATUS_SUCCESS) {
64 PHL_ERR("%s: send msg_hub failed\n", __func__);
65 _os_mem_free(ver_ctx->phl_com->drv_priv, info, 2);
66 }
67 }
68
verify_get_rpt_check(struct verify_context * ver_ctx,void * rpt_buf)69 bool verify_get_rpt_check(struct verify_context *ver_ctx, void *rpt_buf)
70 {
71 bool ret = true;
72 struct verify_cmd_hdr *rpt_hdr = (struct verify_cmd_hdr *)ver_ctx->rpt;
73 struct verify_cmd_hdr *rpt_buf_hdr = (struct verify_cmd_hdr *)rpt_buf;
74
75 if ((rpt_hdr->feature != rpt_buf_hdr->feature) ||
76 (rpt_hdr->cmd != rpt_buf_hdr->cmd)) {
77 PHL_WARN("%s: Report buffer not match!\n", __FUNCTION__);
78 rpt_buf_hdr->cmd_ok = true;
79 rpt_buf_hdr->status = RTW_PHL_STATUS_FAILURE;
80 ret = false;
81 }
82
83 return ret;
84 }
85
verify_get_feature_from_buf(struct verify_context * ver_ctx)86 u8 verify_get_feature_from_buf(struct verify_context *ver_ctx)
87 {
88 u8 *buf_tmp = NULL;
89 u8 feature = VERIFY_FEATURES_MAX;
90
91 if (ver_ctx && ver_ctx->buf) {
92 buf_tmp = (u8 *)ver_ctx->buf;
93 feature = buf_tmp[0];
94 }
95 return feature;
96 }
97
verify_bp_handler(void * ctx,struct test_bp_info * bp_info)98 u8 verify_bp_handler(void *ctx, struct test_bp_info *bp_info)
99 {
100 struct verify_context *ver_ctx = (struct verify_context *)ctx;
101 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
102
103 PHL_INFO("%s: bp_info->type = %x\n", __FUNCTION__, bp_info->type);
104
105 switch (bp_info->type) {
106 case BP_INFO_TYPE_MP_CMD_EVENT:
107 if (ver_ctx->status == VERIFY_STATUS_WAIT_CMD) {
108 ver_ctx->status = VERIFY_STATUS_CMD_EVENT;
109 _os_sema_up(ver_ctx->phl_com->drv_priv, &(ver_ctx->cmd_sema));
110 phl_status = RTW_PHL_STATUS_SUCCESS;
111 }
112 default:
113 break;
114 }
115 return phl_status;
116 }
117
verify_get_fail_rsn(void * ctx,char * rsn,u32 max_len)118 u8 verify_get_fail_rsn(void *ctx, char *rsn, u32 max_len)
119 {
120 //struct verify_context *ver_ctx = (struct verify_context *)ctx;
121 return true;
122 }
123
verify_is_test_end(void * ctx)124 u8 verify_is_test_end(void *ctx)
125 {
126 struct verify_context *ver_ctx = (struct verify_context *)ctx;
127
128 return ver_ctx->is_test_end;
129 }
130
verifyg_is_test_pass(void * ctx)131 u8 verifyg_is_test_pass(void *ctx)
132 {
133 //struct verify_context *ver_ctx = (struct verify_context *)ctx;
134 return true;
135 }
136
verify_start(void * ctx)137 u8 verify_start(void *ctx)
138 {
139 struct verify_context *ver_ctx = (struct verify_context *)ctx;
140 struct rtw_phl_com_t *phl_com = ver_ctx->phl_com;
141 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
142 u8 feature = VERIFY_FEATURES_MAX;
143
144 FUNCIN();
145
146 /* drv_mode maybe control by MP */
147 //phl_com->drv_mode = RTW_DRV_MODE_MP;
148 while (!verify_is_test_end(ver_ctx)) {
149 _os_sema_down(phl_com->drv_priv, &(ver_ctx->cmd_sema));
150 if (ver_ctx->status == VERIFY_STATUS_CMD_EVENT) {
151 ver_ctx->status = VERIFY_STATUS_RUN_CMD;
152 feature = verify_get_feature_from_buf(ver_ctx);
153
154 /* Clear report buffer before executing next command */
155 if (ver_ctx->rpt != NULL) {
156 PHL_INFO("%s: Report not empty, cleanup!\n", __FUNCTION__);
157 _os_mem_free(phl_com->drv_priv, ver_ctx->rpt, ver_ctx->rpt_len);
158 ver_ctx->rpt = NULL;
159 ver_ctx->rpt_len = 0;
160 }
161
162 if (feature < VERIFY_FEATURES_MAX) {
163 PHL_INFO("%s: feature id = %u\n", __FUNCTION__, feature);
164 phl_status = ver_ctx->handler[feature].callback(ver_ctx);
165 } else {
166 PHL_WARN("%s: Unknown VERIFY_FEATURE! (%d)\n", __FUNCTION__, feature);
167 }
168
169 if (ver_ctx->rpt != NULL) {
170 struct verify_cmd_hdr *hdr = (struct verify_cmd_hdr *)ver_ctx->rpt;
171 verify_cmd_done_notification(ver_ctx, hdr->feature, hdr->cmd);
172 PHL_INFO("%s: Indication class(%d) cmd(%d)\n",
173 __FUNCTION__, hdr->feature, hdr->cmd);
174 }
175
176 /* Clear command buffer after executing the command */
177 if (ver_ctx->buf != NULL) {
178 PHL_INFO("%s: Command buf not empty, cleanup!\n", __FUNCTION__);
179 _os_mem_free(phl_com->drv_priv, ver_ctx->buf, ver_ctx->buf_len);
180 ver_ctx->buf = NULL;
181 ver_ctx->buf_len = 0;
182 }
183 ver_ctx->status = VERIFY_STATUS_WAIT_CMD;
184 }
185 }
186
187 FUNCOUT();
188 return (u8)phl_status;
189 }
190
verify_change_mode(struct verify_context * ver_ctx,enum rtw_drv_mode driver_mode)191 void verify_change_mode(struct verify_context *ver_ctx, enum rtw_drv_mode driver_mode)
192 {
193 struct phl_info_t *phl_info = ver_ctx->phl;
194
195 PHL_INFO("%s Change to %x\n", __FUNCTION__, driver_mode);
196
197 /* Need PHL stop function later */
198
199 phl_info->phl_com->drv_mode = driver_mode;
200
201 #ifdef RTW_WKARD_MP_MODE_CHANGE
202 #else
203 /* Ouden : does need reset ? it already do in the mp start */
204 //rtw_phl_reset(phl_info);
205 #endif
206
207 }
208
phl_test_verify_alloc(struct phl_info_t * phl_info,void * hal,void ** ctx)209 enum rtw_phl_status phl_test_verify_alloc(struct phl_info_t *phl_info, void *hal, void **ctx)
210 {
211 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
212 struct rtw_phl_com_t *phl_com = phl_info->phl_com;
213 struct verify_context *ver_ctx = NULL;
214
215 ver_ctx = _os_mem_alloc(phl_com->drv_priv, sizeof(struct verify_context));
216
217 if (ver_ctx == NULL) {
218 PHL_ERR("alloc verify context failed\n");
219 phl_status = RTW_PHL_STATUS_RESOURCE;
220 goto exit;
221 }
222 _os_sema_init(phl_com->drv_priv, &(ver_ctx->cmd_sema), 0);
223 ver_ctx->cur_phy = HW_PHY_0;
224 ver_ctx->phl = phl_info;
225 ver_ctx->phl_com = phl_com;
226 ver_ctx->hal = hal;
227 ver_ctx->status = VERIFY_STATUS_INIT;
228 ver_ctx->handler = test_handlers;
229 *ctx = ver_ctx;
230 phl_status = RTW_PHL_STATUS_SUCCESS;
231
232 exit:
233 return phl_status;
234 }
235
phl_test_verify_free(void ** ctx)236 void phl_test_verify_free(void **ctx)
237 {
238 struct verify_context *ver_ctx = NULL;
239
240 if (*ctx == NULL)
241 return;
242
243 ver_ctx = (struct verify_context *)(*ctx);
244 _os_sema_free(ver_ctx->phl_com->drv_priv, &(ver_ctx->cmd_sema));
245 _os_mem_free(ver_ctx->phl_com->drv_priv, ver_ctx, sizeof(struct verify_context));
246 ver_ctx = NULL;
247 *ctx = NULL;
248 }
249
phl_test_verify_init(void * ctx)250 void phl_test_verify_init(void *ctx)
251 {
252 struct verify_context *ver_ctx = NULL;
253 struct test_obj_ctrl_interface *pCtrl = NULL;
254
255 if (ctx == NULL)
256 return;
257
258 ver_ctx = (struct verify_context *)ctx;
259 pCtrl = &(ver_ctx->test_ctrl);
260
261 ver_ctx->status = VERIFY_STATUS_WAIT_CMD;
262 ver_ctx->is_test_end = false;
263 pCtrl->bp_handler = verify_bp_handler;
264 pCtrl->get_fail_rsn = verify_get_fail_rsn;
265 pCtrl->is_test_end = verify_is_test_end;
266 pCtrl->is_test_pass = verifyg_is_test_pass;
267 pCtrl->start_test = verify_start;
268 rtw_phl_test_add_new_test_obj(ver_ctx->phl_com,
269 "verify_test",
270 ver_ctx,
271 TEST_LVL_LOW,
272 pCtrl,
273 -1,
274 TEST_SUB_MODULE_VERIFY,
275 INTGR_TEST_MODE);
276 }
277
phl_test_verify_deinit(void * ctx)278 void phl_test_verify_deinit(void *ctx)
279 {
280 struct verify_context *ver_ctx = NULL;
281 if (ctx == NULL)
282 return;
283
284 ver_ctx = (struct verify_context *)ctx;
285
286 if (ver_ctx->status < VERIFY_STATUS_WAIT_CMD)
287 return;
288
289 ver_ctx->is_test_end = true;
290 _os_sema_up(ver_ctx->phl_com->drv_priv, &(ver_ctx->cmd_sema));
291 ver_ctx->status = VERIFY_STATUS_INIT;
292 }
293
phl_test_verify_start(void * ctx)294 void phl_test_verify_start(void *ctx)
295 {
296 struct verify_context *ver_ctx = NULL;
297
298 if (ctx == NULL)
299 return;
300
301 ver_ctx = (struct verify_context *)ctx;
302
303 #if 0 /* verify keep in current mode */
304 verify_change_mode(ver_ctx, RTW_DRV_MODE_MP);
305 #endif
306 }
307
phl_test_verify_stop(void * ctx)308 void phl_test_verify_stop(void *ctx)
309 {
310 struct verify_context *ver_ctx = NULL;
311
312 if (ctx == NULL)
313 return;
314
315 ver_ctx = (struct verify_context *)ctx;
316
317 if (ver_ctx->status < VERIFY_STATUS_WAIT_CMD)
318 return;
319 #if 0 /* verify keep in current mode */
320 verify_change_mode(ver_ctx, RTW_DRV_MODE_NORMAL);
321 #endif
322 }
323
phl_test_verify_cmd_process(void * ctx,void * buf,u32 buf_len,u8 submdid)324 void phl_test_verify_cmd_process(void *ctx, void *buf, u32 buf_len, u8 submdid)
325 {
326 struct verify_context *ver_ctx = NULL;
327 struct rtw_phl_com_t *phl_com = NULL;
328 struct test_bp_info bp_info;
329
330 FUNCIN();
331
332 if (ctx == NULL)
333 return;
334
335 ver_ctx = (struct verify_context *)ctx;
336 phl_com = ver_ctx->phl_com;
337
338 if ((buf == NULL) || (buf_len <= 0)) {
339 PHL_ERR("%s: Invalid buffer content!\n", __func__);
340 return;
341 }
342
343 if (ver_ctx->status == VERIFY_STATUS_WAIT_CMD) {
344 ver_ctx->buf_len = buf_len;
345 ver_ctx->buf = _os_mem_alloc(phl_com->drv_priv, buf_len);
346 _os_mem_cpy(phl_com->drv_priv, ver_ctx->buf, buf, buf_len);
347 _os_mem_set(phl_com->drv_priv, &bp_info, 0, sizeof(struct test_bp_info));
348 bp_info.type = BP_INFO_TYPE_MP_CMD_EVENT;
349 rtw_phl_test_setup_bp(phl_com, &bp_info, submdid);
350 } else {
351 PHL_WARN("%s: Previous command is still running!\n", __FUNCTION__);
352 }
353
354 FUNCOUT();
355 }
356
phl_test_verify_get_rpt(void * ctx,void * buf,u32 buf_len)357 void phl_test_verify_get_rpt(void *ctx, void *buf, u32 buf_len)
358 {
359 struct verify_context *ver_ctx = NULL;
360 FUNCIN();
361
362 if (ctx == NULL) {
363 PHL_WARN("%s: mp is NULL!\n", __FUNCTION__);
364 goto exit;
365 }
366
367 ver_ctx = (struct verify_context *)ctx;
368
369 if (ver_ctx->status != VERIFY_STATUS_WAIT_CMD) {
370 PHL_WARN("%s: command is running!\n", __FUNCTION__);
371 goto exit;
372 }
373
374 if (ver_ctx->rpt == NULL) {
375 PHL_DBG("%s: ver_ctx->rpt is NULL!\n", __FUNCTION__);
376 goto exit;
377 }
378
379 if (buf_len < ver_ctx->rpt_len) {
380 PHL_WARN("%s: buffer not enough!\n", __FUNCTION__);
381 goto exit;
382 }
383
384 if (verify_get_rpt_check(ver_ctx, buf) == true) {
385 _os_mem_cpy(ver_ctx->phl_com->drv_priv, buf, ver_ctx->rpt, ver_ctx->rpt_len);
386 _os_mem_free(ver_ctx->phl_com->drv_priv, ver_ctx->rpt, ver_ctx->rpt_len);
387 ver_ctx->rpt = NULL;
388 ver_ctx->rpt_len = 0;
389 }
390
391 exit:
392 FUNCOUT();
393 }
394 #endif /* CONFIG_PHL_TEST_MP */
395