xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/phl/test/verify/phl_test_verify.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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