xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/phl/phl_cmd_btc.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_CMD_BTC_C_
16 #include "phl_headers.h"
17 
18 #ifdef CONFIG_BTCOEX
19 #ifdef CONFIG_PHL_CMD_BTC
_fail_hdlr(void * phl,struct phl_msg * msg)20 static void _fail_hdlr(void *phl, struct phl_msg *msg)
21 {
22 }
23 
_hdl_tmr(void * phl,struct phl_msg * msg)24 static void _hdl_tmr(void *phl, struct phl_msg *msg)
25 {
26 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
27 
28 	rtw_hal_btc_timer(phl_info->hal, (void *)msg->inbuf);
29 }
30 
_hdl_role_notify(void * phl,struct phl_msg * msg)31 static void _hdl_role_notify(void *phl, struct phl_msg *msg)
32 {
33 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
34 	struct rtw_role_cmd *rcmd = NULL;
35 	struct rtw_wifi_role_t *wrole = NULL;
36 	struct rtw_phl_stainfo_t *sta = NULL;
37 
38 	if (msg->inbuf && (msg->inlen == sizeof(struct rtw_role_cmd))) {
39 		rcmd  = (struct rtw_role_cmd *)msg->inbuf;
40 		wrole = rcmd->wrole;
41 		sta = rtw_phl_get_stainfo_self(phl_info, wrole);
42 
43 		rtw_hal_btc_update_role_info_ntfy(phl_info->hal,
44 			rcmd->wrole->id, wrole, sta, rcmd->rstate);
45 	} else {
46 		PHL_ERR("%s: invalid msg, buf = %p, len = %d\n",
47 			__func__, msg->inbuf, msg->inlen);
48 	}
49 }
50 
_hdl_pkt_evt_notify(void * phl,struct phl_msg * msg)51 static void _hdl_pkt_evt_notify(void *phl, struct phl_msg *msg)
52 {
53 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
54 	struct rtw_pkt_evt_ntfy *pkt_evt = NULL;
55 	struct rtw_wifi_role_t *wrole = NULL;
56 
57 	if (msg->inbuf && (msg->inlen == sizeof(struct rtw_pkt_evt_ntfy))) {
58 		pkt_evt = (struct rtw_pkt_evt_ntfy *)msg->inbuf;
59 		wrole = pkt_evt->wrole; /* not used currently */
60 
61 		rtw_hal_btc_packet_event_ntfy(phl_info->hal,
62 					(u8)pkt_evt->type);
63 	} else {
64 		PHL_ERR("%s: invalid msg, buf = %p, len = %d\n",
65 			__func__, msg->inbuf, msg->inlen);
66 	}
67 }
68 
_btc_cmd_init(void * phl,void * dispr,void ** priv)69 static enum phl_mdl_ret_code _btc_cmd_init(void *phl, void *dispr,
70 						  void **priv)
71 {
72 	PHL_INFO("[BTCCMD], %s(): \n", __func__);
73 
74 	*priv = phl;
75 	return MDL_RET_SUCCESS;
76 }
77 
_btc_cmd_deinit(void * dispr,void * priv)78 static void _btc_cmd_deinit(void *dispr, void *priv)
79 {
80 	PHL_INFO("[BTCCMD], %s(): \n", __func__);
81 }
82 
_btc_cmd_start(void * dispr,void * priv)83 static enum phl_mdl_ret_code _btc_cmd_start(void *dispr, void *priv)
84 {
85 	enum phl_mdl_ret_code ret = MDL_RET_SUCCESS;
86 
87 	PHL_INFO("[BTCCMD], %s(): \n", __func__);
88 
89 	return ret;
90 }
91 
_btc_cmd_stop(void * dispr,void * priv)92 static enum phl_mdl_ret_code _btc_cmd_stop(void *dispr, void *priv)
93 {
94 	enum phl_mdl_ret_code ret = MDL_RET_SUCCESS;
95 
96 	PHL_INFO("[BTCCMD], %s(): \n", __func__);
97 
98 	return ret;
99 }
100 
101 static enum phl_mdl_ret_code
_btc_internal_pre_msg_hdlr(struct phl_info_t * phl_info,void * dispr,struct phl_msg * msg)102 _btc_internal_pre_msg_hdlr(struct phl_info_t *phl_info,
103                            void *dispr,
104                            struct phl_msg *msg)
105 {
106 	enum phl_mdl_ret_code ret = MDL_RET_IGNORE;
107 	enum phl_msg_evt_id evt_id = MSG_EVT_ID_FIELD(msg->msg_id);
108 
109 	/*PHL_INFO("[BTCCMD], msg->band_idx = %d,  msg->msg_id = 0x%x\n",
110 		msg->band_idx, msg->msg_id);*/
111 
112 	switch(evt_id) {
113 	case MSG_EVT_BTC_REQ_BT_SLOT:
114 		PHL_INFO("[BTCCMD], MSG_EVT_BTC_REQ_BT_SLOT \n");
115 		ret = MDL_RET_SUCCESS;
116 		break;
117 
118 	case MSG_EVT_BTC_PKT_EVT_NTFY:
119 		PHL_INFO("[BTCCMD], MSG_EVT_BTC_PKT_EVT_NTFY \n");
120 		_hdl_pkt_evt_notify(phl_info, msg);
121 		ret = MDL_RET_SUCCESS;
122 		break;
123 
124 	default:
125 		break;
126 	}
127 
128 	return ret;
129 }
130 
131 static enum phl_mdl_ret_code
_btc_internal_post_msg_hdlr(struct phl_info_t * phl_info,void * dispr,struct phl_msg * msg)132 _btc_internal_post_msg_hdlr(struct phl_info_t *phl_info,
133                             void *dispr,
134                             struct phl_msg *msg)
135 {
136 	enum phl_mdl_ret_code ret = MDL_RET_IGNORE;
137 	enum phl_msg_evt_id evt_id = MSG_EVT_ID_FIELD(msg->msg_id);
138 
139 	switch(evt_id) {
140 	case MSG_EVT_BTC_TMR:
141 		PHL_DBG("[BTCCMD], MSG_EVT_BTC_TMR \n");
142 		_hdl_tmr(phl_info, msg);
143 		ret = MDL_RET_SUCCESS;
144 		break;
145 
146 	case MSG_EVT_BTC_FWEVNT:
147 		PHL_DBG("[BTCCMD], MSG_EVT_BTC_FWEVNT \n");
148 		rtw_hal_btc_fwinfo_ntfy(phl_info->hal);
149 		ret = MDL_RET_SUCCESS;
150 		break;
151 
152 	default:
153 		break;
154 	}
155 
156 	return ret;
157 }
158 
159 static enum phl_mdl_ret_code
_btc_internal_msg_hdlr(struct phl_info_t * phl_info,void * dispr,struct phl_msg * msg)160 _btc_internal_msg_hdlr(struct phl_info_t *phl_info,
161                        void *dispr,
162                        struct phl_msg *msg)
163 {
164 	enum phl_mdl_ret_code ret = MDL_RET_FAIL;
165 
166 	if (IS_MSG_IN_PRE_PHASE(msg->msg_id))
167 		ret = _btc_internal_pre_msg_hdlr(phl_info, dispr, msg);
168 	else
169 		ret = _btc_internal_post_msg_hdlr(phl_info, dispr, msg);
170 
171 	return ret;
172 }
173 
174 static enum phl_mdl_ret_code
_btc_external_pre_msg_hdlr(struct phl_info_t * phl_info,void * dispr,struct phl_msg * msg)175 _btc_external_pre_msg_hdlr(struct phl_info_t *phl_info,
176                            void *dispr,
177                            struct phl_msg *msg)
178 {
179 	enum phl_mdl_ret_code ret = MDL_RET_IGNORE;
180 	enum phl_msg_evt_id evt_id = MSG_EVT_ID_FIELD(msg->msg_id);
181 	enum band_type band = BAND_ON_5G;
182 	struct rtw_hal_com_t *hal_com = rtw_hal_get_halcom(phl_info->hal);
183 	enum phl_phy_idx phy_idx = HW_PHY_0;
184 
185 	/*PHL_INFO("[BTCCMD], msg->band_idx = %d,  msg->msg_id = 0x%x\n",
186 		msg->band_idx, msg->msg_id);*/
187 
188 	switch(evt_id) {
189 		case MSG_EVT_SCAN_START:
190 			if (MSG_MDL_ID_FIELD(msg->msg_id) != PHL_FG_MDL_SCAN)
191 				break;
192 
193 			if (msg->band_idx == HW_BAND_1)
194 				phy_idx = HW_PHY_1;
195 			PHL_INFO("[BTCCMD], MSG_EVT_SCAN_START \n");
196 			band = hal_com->band[msg->band_idx].cur_chandef.band;
197 			rtw_hal_btc_scan_start_ntfy(phl_info->hal, phy_idx, band);
198 
199 			ret = MDL_RET_SUCCESS;
200 			break;
201 
202 		case MSG_EVT_CONNECT_START:
203 			if (MSG_MDL_ID_FIELD(msg->msg_id) != PHL_FG_MDL_CONNECT)
204 				break;
205 
206 			PHL_INFO("[BTCCMD], MSG_EVT_CONNECT_START \n");
207 			ret = MDL_RET_SUCCESS;
208 			break;
209 
210 		default:
211 			break;
212 	}
213 
214 	return ret;
215 }
216 
217 static enum phl_mdl_ret_code
_btc_external_post_msg_hdlr(struct phl_info_t * phl_info,void * dispr,struct phl_msg * msg)218 _btc_external_post_msg_hdlr(struct phl_info_t *phl_info,
219                             void *dispr,
220                             struct phl_msg *msg)
221 {
222 	enum phl_mdl_ret_code ret = MDL_RET_IGNORE;
223 	enum phl_msg_evt_id evt_id = MSG_EVT_ID_FIELD(msg->msg_id);
224 	struct hal_info_t *hal_info = (struct hal_info_t *)phl_info->hal;
225 	enum phl_phy_idx phy_idx = HW_PHY_0;
226 
227 	switch(evt_id) {
228 		case MSG_EVT_SCAN_END:
229 			if (MSG_MDL_ID_FIELD(msg->msg_id) != PHL_FG_MDL_SCAN)
230 				break;
231 
232 			if (msg->band_idx == HW_BAND_1)
233 				phy_idx = HW_PHY_1;
234 			PHL_DBG("[BTCCMD], MSG_EVT_SCAN_END \n");
235 			rtw_hal_btc_scan_finish_ntfy(hal_info, phy_idx);
236 			ret = MDL_RET_SUCCESS;
237 			break;
238 
239 		case MSG_EVT_CONNECT_END:
240 			if (MSG_MDL_ID_FIELD(msg->msg_id) != PHL_FG_MDL_CONNECT)
241 				break;
242 
243 			PHL_DBG("[BTCCMD], MSG_EVT_CONNECT_END \n");
244 			ret = MDL_RET_SUCCESS;
245 			break;
246 
247 		case MSG_EVT_ROLE_NTFY:
248 			if (MSG_MDL_ID_FIELD(msg->msg_id) != PHL_MDL_MRC)
249 				break;
250 
251 			PHL_DBG("[BTCCMD], MSG_EVT_ROLE_NTFY \n");
252 			_hdl_role_notify(phl_info, msg);
253 			ret = MDL_RET_SUCCESS;
254 			break;
255 
256 		case MSG_EVT_BTC_TMR:
257 			PHL_DBG("[BTCCMD], MSG_EVT_BTC_TMR \n");
258 			_hdl_tmr(phl_info, msg);
259 			ret = MDL_RET_SUCCESS;
260 			break;
261 
262 		case MSG_EVT_BTC_FWEVNT:
263 			PHL_DBG("[BTCCMD], MSG_EVT_BTC_FWEVNT \n");
264 			rtw_hal_btc_fwinfo_ntfy(phl_info->hal);
265 			ret = MDL_RET_SUCCESS;
266 			break;
267 
268 		default:
269 			break;
270 	}
271 
272 	return ret;
273 }
274 
275 static enum phl_mdl_ret_code
_btc_external_msg_hdlr(struct phl_info_t * phl_info,void * dispr,struct phl_msg * msg)276 _btc_external_msg_hdlr(struct phl_info_t *phl_info,
277                        void *dispr,
278                        struct phl_msg *msg)
279 {
280 	enum phl_mdl_ret_code ret = MDL_RET_FAIL;
281 
282 	if (IS_MSG_IN_PRE_PHASE(msg->msg_id))
283 		ret = _btc_external_pre_msg_hdlr(phl_info, dispr, msg);
284 	else
285 		ret = _btc_external_post_msg_hdlr(phl_info, dispr, msg);
286 
287 	return ret;
288 }
289 
290 static enum phl_mdl_ret_code
_btc_msg_hdlr(void * dispr,void * priv,struct phl_msg * msg)291 _btc_msg_hdlr(void *dispr, void *priv, struct phl_msg *msg)
292 {
293 	enum phl_mdl_ret_code ret = MDL_RET_IGNORE;
294 	struct phl_info_t *phl_info = (struct phl_info_t *)priv;
295 
296 	FUNCIN();
297 
298 	if (IS_MSG_FAIL(msg->msg_id)) {
299 		PHL_TRACE(COMP_PHL_DBG, _PHL_WARNING_,
300 			  "%s: cmd dispatcher notify cmd failure: 0x%x.\n",
301 			   __FUNCTION__, msg->msg_id);
302 		_fail_hdlr(phl_info, msg);
303 		FUNCOUT();
304 		return MDL_RET_FAIL;
305 	}
306 
307 	if (IS_PRIVATE_MSG(msg->msg_id)) {
308 		FUNCOUT();
309 		return ret;
310 	}
311 
312 	switch(MSG_MDL_ID_FIELD(msg->msg_id)) {
313 		case PHL_MDL_BTC:
314 			ret = _btc_internal_msg_hdlr(phl_info, dispr, msg);
315 			break;
316 
317 		default:
318 			ret = _btc_external_msg_hdlr(phl_info, dispr, msg);
319 			break;
320 	}
321 
322 	FUNCOUT();
323 	return ret;
324 }
325 
326 static enum phl_mdl_ret_code
_btc_set_info(void * dispr,void * priv,struct phl_module_op_info * info)327 _btc_set_info(void *dispr, void *priv,
328 			 struct phl_module_op_info *info)
329 {
330 	PHL_INFO("[BTCCMD], %s(): \n", __func__);
331 
332 	return MDL_RET_SUCCESS;
333 }
334 
335 static enum phl_mdl_ret_code
_btc_query_info(void * dispr,void * priv,struct phl_module_op_info * info)336 _btc_query_info(void *dispr, void *priv,
337 			   struct phl_module_op_info *info)
338 {
339 	PHL_INFO("[BTCCMD], %s(): \n", __func__);
340 
341 	return MDL_RET_SUCCESS;
342 }
343 
_btc_set_stbc(struct phl_info_t * phl_info,u8 * buf)344 static void _btc_set_stbc(struct phl_info_t *phl_info, u8 *buf)
345 {
346 	struct rtw_hal_com_t *hal_com = rtw_hal_get_halcom(phl_info->hal);
347 
348 	hal_com->btc_ctrl.disable_rx_stbc = buf[0];
349 	PHL_INFO("[BTCCMD], %s(): disable_rx_stbc(%d) \n",
350 			__func__, hal_com->btc_ctrl.disable_rx_stbc);
351 }
352 
phl_register_btc_module(struct phl_info_t * phl_info)353 enum rtw_phl_status phl_register_btc_module(struct phl_info_t *phl_info)
354 {
355 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
356 	struct phl_bk_module_ops bk_ops = {0};
357 
358 	PHL_INFO("[BTCCMD], %s(): \n", __func__);
359 
360 	bk_ops.init = _btc_cmd_init;
361 	bk_ops.deinit = _btc_cmd_deinit;
362 	bk_ops.start = _btc_cmd_start;
363 	bk_ops.stop = _btc_cmd_stop;
364 	bk_ops.msg_hdlr = _btc_msg_hdlr;
365 	bk_ops.set_info = _btc_set_info;
366 	bk_ops.query_info = _btc_query_info;
367 
368 	phl_status = phl_disp_eng_register_module(phl_info, HW_BAND_0,
369 						PHL_MDL_BTC, &bk_ops);
370 	if (RTW_PHL_STATUS_SUCCESS != phl_status) {
371 		PHL_ERR("Failed to register BTC module in cmd dispr of hw band 0\n");
372 	}
373 
374 	return phl_status;
375 }
376 
rtw_phl_btc_send_cmd(struct rtw_phl_com_t * phl_com,u8 * buf,u32 len,u16 ev_id)377 bool rtw_phl_btc_send_cmd(struct rtw_phl_com_t *phl_com,
378 				u8 *buf, u32 len, u16 ev_id)
379 {
380 	struct phl_info_t *phl_info = phl_com->phl_priv;
381 	u8 band_idx = HW_BAND_0;
382 	struct phl_msg msg = {0};
383 	struct phl_msg_attribute attr = {0};
384 
385 	msg.inbuf = buf;
386 	msg.inlen = len;
387 	SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_MDL_BTC);
388 	msg.band_idx = band_idx;
389 	switch (ev_id) {
390 	case BTC_HMSG_TMR_EN:
391 		SET_MSG_EVT_ID_FIELD(msg.msg_id,
392 			MSG_EVT_BTC_TMR);
393 		break;
394 	case BTC_HMSG_SET_BT_REQ_SLOT:
395 		SET_MSG_EVT_ID_FIELD(msg.msg_id,
396 			MSG_EVT_BTC_REQ_BT_SLOT);
397 		break;
398 	case BTC_HMSG_FW_EV:
399 		SET_MSG_EVT_ID_FIELD(msg.msg_id,
400 			MSG_EVT_BTC_FWEVNT);
401 		break;
402 	case BTC_HMSG_SET_BT_REQ_STBC:
403 		_btc_set_stbc(phl_info, buf);
404 		return true;
405 	default:
406 		PHL_ERR("%s: Unknown msg !\n", __func__);
407 		return false;
408 	}
409 
410 	if (phl_disp_eng_send_msg(phl_info, &msg, &attr, NULL) !=
411 				RTW_PHL_STATUS_SUCCESS) {
412 		PHL_ERR("%s: [BTC] dispr_send_msg failed !\n", __func__);
413 		return false;
414 	}
415 
416 	return true;
417 }
418 
419 static void
_phl_pkt_evt_ntfy_done(void * priv,struct phl_msg * msg)420 _phl_pkt_evt_ntfy_done(void* priv, struct phl_msg* msg)
421 {
422 	struct phl_info_t *phl_info = (struct phl_info_t *)priv;
423 
424 	if(msg->inbuf && msg->inlen){
425 		_os_mem_free(phl_to_drvpriv(phl_info),
426 			msg->inbuf, msg->inlen);
427 	}
428 }
429 
rtw_phl_btc_packet_event_notify(void * phl,u8 role_id,u8 pkt_evt_type)430 void rtw_phl_btc_packet_event_notify(void *phl, u8 role_id, u8 pkt_evt_type)
431 {
432 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
433 	struct phl_msg msg = {0};
434 	struct phl_msg_attribute attr = {0};
435 	struct rtw_pkt_evt_ntfy *pkt_evt = NULL;
436 
437 	pkt_evt = (struct rtw_pkt_evt_ntfy *)_os_mem_alloc(
438 		phl_to_drvpriv(phl_info), sizeof(struct rtw_pkt_evt_ntfy));
439 	if (pkt_evt == NULL) {
440 		PHL_ERR("%s: alloc packet cmd fail.\n", __func__);
441 		return;
442 	}
443 
444 	pkt_evt->type = pkt_evt_type;
445 
446 	msg.inbuf = (u8 *)pkt_evt;
447 	msg.inlen = sizeof(struct rtw_pkt_evt_ntfy);
448 
449 	SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_MDL_BTC);
450 	SET_MSG_EVT_ID_FIELD(msg.msg_id, MSG_EVT_BTC_PKT_EVT_NTFY);
451 	msg.band_idx = HW_BAND_0;
452 	attr.completion.completion = _phl_pkt_evt_ntfy_done;
453 	attr.completion.priv = phl_info;
454 
455 	if (phl_disp_eng_send_msg(phl_info, &msg, &attr, NULL) !=
456 				RTW_PHL_STATUS_SUCCESS) {
457 		PHL_ERR("%s: dispr_send_msg failed !\n", __func__);
458 		goto cmd_fail;
459 	}
460 
461 	return;
462 
463 cmd_fail:
464 	_os_mem_free(phl_to_drvpriv(phl_info), pkt_evt,
465 			sizeof(struct rtw_pkt_evt_ntfy));
466 }
467 
rtw_phl_btc_pkt_2_evt_type(u8 packet_type)468 u8 rtw_phl_btc_pkt_2_evt_type(u8 packet_type)
469 {
470 	u8 pkt_evt_type = BTC_PKT_EVT_MAX;
471 
472 	switch (packet_type) {
473 	case PACKET_NORMAL:
474 		pkt_evt_type = BTC_PKT_EVT_NORMAL;
475 		break;
476 	case PACKET_DHCP:
477 		pkt_evt_type = BTC_PKT_EVT_DHCP;
478 		break;
479 	case PACKET_ARP:
480 		pkt_evt_type = BTC_PKT_EVT_ARP;
481 		break;
482 	case PACKET_EAPOL:
483 		pkt_evt_type = BTC_PKT_EVT_EAPOL;
484 		break;
485 	case PACKET_EAPOL_START:
486 		pkt_evt_type = BTC_PKT_EVT_EAPOL_START;
487 		break;
488 	default:
489 		PHL_ERR("%s packet type(%d) not support\n",
490 			__func__, packet_type);
491 		break;
492 	}
493 
494 	return pkt_evt_type;
495 }
496 #endif /*CONFIG_PHL_CMD_BTC*/
497 
498 #ifndef CONFIG_FSM
rtw_phl_btc_notify(void * phl,enum RTW_PHL_BTC_NOTIFY notify,struct rtw_phl_btc_ntfy * ntfy)499 int rtw_phl_btc_notify(void *phl, enum RTW_PHL_BTC_NOTIFY notify,
500 				struct rtw_phl_btc_ntfy *ntfy)
501 {
502 	PHL_ERR("CMD_BTC not support :%s\n", __func__);
503 	return 0;
504 }
rtw_phl_btc_role_notify(void * phl,u8 role_id,enum role_state rstate)505 void rtw_phl_btc_role_notify(void *phl, u8 role_id, enum role_state rstate)
506 {
507 	struct rtw_phl_btc_ntfy ntfy = {0};
508 	struct rtw_phl_btc_role_info_param *prinfo = &ntfy.u.rinfo;
509 
510 	prinfo->role_id = role_id;
511 	prinfo->rstate = rstate;
512 
513 	ntfy.notify = PHL_BTC_NTFY_ROLE_INFO;
514 	ntfy.ops = NULL;
515 	ntfy.priv = NULL;
516 	ntfy.ntfy_cb = NULL;
517 
518 	rtw_phl_btc_notify(phl, ntfy.notify, &ntfy);
519 }
520 
rtw_phl_btc_hub_msg_hdl(void * phl,struct phl_msg * msg)521 void rtw_phl_btc_hub_msg_hdl(void *phl, struct phl_msg *msg)
522 {
523 }
524 #endif
525 
526 #endif /*CONFIG_BTCOEX*/
527 
528