xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/phl/hal_g6/hal_api_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 _HAL_API_BTC_C_
16 #include "hal_headers.h"
17 #include "btc/hal_btc.h"
18 
19 #ifdef CONFIG_BTCOEX
20 /*******************************************
21  * C2H FW message
22  *******************************************/
23 #define BTC_FWBUF_NUM 4
24 struct fw_msg_entry {
25 	_os_list list;
26 	u8 c2h_class;
27 	u8 c2h_func;
28 	u16 len;
29 	u8 buf[RTW_PHL_BTC_FWINFO_BUF];
30 };
31 
_bt_msg_init(struct rtw_hal_com_t * hal_com,struct hal_bt_msg * msg)32 static void _bt_msg_init(struct rtw_hal_com_t *hal_com,
33 				struct hal_bt_msg *msg)
34 {
35 	void *d = halcom_to_drvpriv(hal_com);
36 
37 	_os_spinlock_init(d, &msg->lock);
38 	_os_mem_set(d, &msg->latest[0], 0, RTW_BTC_OVERWRITE_BUF_LEN);
39 	_os_mem_set(d, &msg->working[0], 0, RTW_BTC_OVERWRITE_BUF_LEN);
40 	msg->len = 0;
41 	msg->cnt = 0;
42 }
43 
_bt_msg_deinit(struct rtw_hal_com_t * hal_com,struct hal_bt_msg * msg)44 static void _bt_msg_deinit(struct rtw_hal_com_t *hal_com,
45 				struct hal_bt_msg *msg)
46 {
47 	void *d = halcom_to_drvpriv(hal_com);
48 
49 	_os_spinlock_free(d, &msg->lock);
50 }
51 
_msg_enq(struct rtw_hal_com_t * hal_com,struct phl_queue * q,struct fw_msg_entry * entry)52 static void _msg_enq(struct rtw_hal_com_t *hal_com,
53 			struct phl_queue *q, struct fw_msg_entry *entry)
54 {
55 	pq_push(halcom_to_drvpriv(hal_com), q, &entry->list, _tail, _bh);
56 }
57 
_msg_deq(struct rtw_hal_com_t * hal_com,struct phl_queue * q)58 static struct fw_msg_entry *_msg_deq(struct rtw_hal_com_t *hal_com,
59 					struct phl_queue *q)
60 {
61 	struct fw_msg_entry *entry = NULL;
62 	_os_list *list = NULL;
63 
64 	if (pq_pop(halcom_to_drvpriv(hal_com), q, &list, _first, _bh))
65 		entry = (struct fw_msg_entry *)list;
66 
67 	return entry;
68 }
69 
_fw_msg_init(struct rtw_hal_com_t * hal_com)70 static bool _fw_msg_init(struct rtw_hal_com_t *hal_com)
71 {
72 	void *d = halcom_to_drvpriv(hal_com);
73 	struct btc_fw_msg *fw_msg = &hal_com->btc_msg;
74 	struct fw_msg_entry *entry = NULL;
75 	u16 i = 0;
76 
77 	_os_spinlock_init(d, &fw_msg->lock);
78 	fw_msg->fev_cnt = 0;
79 
80 	_bt_msg_init(hal_com, &fw_msg->btinfo);
81 	_bt_msg_init(hal_com, &fw_msg->scbd);
82 
83 	pq_init(d, &fw_msg->idleq);
84 	pq_init(d, &fw_msg->waitq);
85 	for (i = 0; i < BTC_FWBUF_NUM; i++) {
86 		entry = (struct fw_msg_entry *)_os_kmem_alloc(d,
87 					sizeof(struct fw_msg_entry));
88 		if (entry)
89 			_msg_enq(hal_com, &fw_msg->idleq, entry);
90 		else
91 			return false;
92 	}
93 
94 	return true;
95 }
96 
_fw_msg_free(struct rtw_hal_com_t * hal_com)97 static void _fw_msg_free(struct rtw_hal_com_t *hal_com)
98 {
99 	void *d = halcom_to_drvpriv(hal_com);
100 	struct btc_fw_msg *fw_msg = &hal_com->btc_msg;
101 	struct fw_msg_entry *entry = NULL;
102 
103 	_bt_msg_deinit(hal_com, &fw_msg->btinfo);
104 	_bt_msg_deinit(hal_com, &fw_msg->scbd);
105 
106 	while (1) {
107 		entry = _msg_deq(hal_com, &fw_msg->waitq);
108 		if (entry)
109 			_os_kmem_free(d, entry, sizeof(struct fw_msg_entry));
110 		else
111 			break;
112 	}
113 	pq_deinit(d, &fw_msg->waitq);
114 
115 	while (1) {
116 		entry = _msg_deq(hal_com, &fw_msg->idleq);
117 		if (entry)
118 			_os_kmem_free(d, entry, sizeof(struct fw_msg_entry));
119 		else
120 			break;
121 	}
122 	pq_deinit(d, &fw_msg->idleq);
123 
124 	_os_spinlock_free(d, &fw_msg->lock);
125 }
126 
_copy_btmsg(struct rtw_hal_com_t * hal_com,struct hal_bt_msg * msg,u16 len,u8 * buf)127 static void _copy_btmsg(struct rtw_hal_com_t *hal_com,
128 			struct hal_bt_msg *msg, u16 len, u8 *buf)
129 {
130 	void *d = halcom_to_drvpriv(hal_com);
131 
132 	if (len > RTW_BTC_OVERWRITE_BUF_LEN)
133 		return;
134 
135 	_os_spinlock(d, &msg->lock, _bh, NULL);
136 	msg->cnt++;
137 	msg->len = len;
138 	_os_mem_cpy(d, &msg->latest[0], buf, len);
139 	_os_spinunlock(d, &msg->lock, _bh, NULL);
140 }
141 
_fw_evnt_enq(struct rtw_hal_com_t * hal_com,u8 cls,u8 func,u16 len,u8 * buf)142 static bool _fw_evnt_enq(struct rtw_hal_com_t *hal_com,
143 			u8 cls, u8 func, u16 len, u8 *buf)
144 {
145 	struct btc_fw_msg *fmsg = &hal_com->btc_msg;
146 	void *d = halcom_to_drvpriv(hal_com);
147 	struct fw_msg_entry *entry = NULL;
148 
149 	entry = _msg_deq(hal_com, &fmsg->idleq);
150 	if (!entry)
151 		return false;
152 
153 	entry->c2h_class = cls;
154 	entry->c2h_func = func;
155 	entry->len = len;
156 	_os_mem_cpy(d, &entry->buf[0], buf, len);
157 	_msg_enq(hal_com, &fmsg->waitq, entry);
158 
159 	return true;
160 }
161 
rtw_hal_btc_init(struct rtw_phl_com_t * phl_com,struct hal_info_t * hal_info)162 enum rtw_hal_status rtw_hal_btc_init(struct rtw_phl_com_t *phl_com,
163 					struct hal_info_t *hal_info)
164 {
165 	enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
166 	struct btc_t *btc = NULL;
167 	void *drv_priv = NULL;
168 
169 	PHL_TRACE(COMP_PHL_BTC, _PHL_DEBUG_, "%s\n", __FUNCTION__);
170 
171 	drv_priv = halcom_to_drvpriv(hal_info->hal_com);
172 	btc = _os_mem_alloc(drv_priv, sizeof(struct btc_t));
173 	if (!btc) {
174 		hal_status = RTW_HAL_STATUS_RESOURCE;
175 		goto error_btc_init;
176 	}
177 
178 	/* assign phl_com & hal_com */
179 	btc->phl = phl_com;
180 	btc->hal = hal_info->hal_com;
181 
182 	if (!hal_btc_init(btc)) {
183 		hal_status = RTW_HAL_STATUS_BTC_INIT_FAILURE;
184 		goto error_btc_init;
185 	}
186 
187 	if (!_fw_msg_init(hal_info->hal_com)) {
188 		hal_status = RTW_HAL_STATUS_BTC_INIT_FAILURE;
189 		goto error_msg_init;
190 	}
191 
192 
193 	hal_status = RTW_HAL_STATUS_SUCCESS;
194 	hal_info->btc = btc;
195 
196 	return hal_status;
197 
198 error_msg_init:
199 	_fw_msg_free(hal_info->hal_com);
200 
201 error_btc_init:
202 	if (btc) {
203 		_os_mem_free(drv_priv, (void *)btc, sizeof(struct btc_t));
204 		hal_info->btc = NULL;
205 	}
206 
207 	return hal_status;
208 }
209 
rtw_hal_btc_deinit(struct rtw_phl_com_t * phl_com,struct hal_info_t * hal_info)210 void rtw_hal_btc_deinit(struct rtw_phl_com_t *phl_com,
211 				struct hal_info_t *hal_info)
212 {
213 	struct btc_t *btc = hal_info->btc;
214 	void *drv_priv = NULL;
215 
216 	_fw_msg_free(hal_info->hal_com);
217 
218 	drv_priv = halcom_to_drvpriv(hal_info->hal_com);
219 	if (drv_priv && btc) {
220 		hal_btc_deinit(btc);
221 		_os_mem_free(drv_priv, (void *)btc, sizeof(struct btc_t));
222 	}
223 }
224 
225 /**********************/
226 /* called by non-hal layers */
227 /**********************/
rtw_hal_btc_update_role_info_ntfy(void * hinfo,u8 role_id,struct rtw_wifi_role_t * wrole,struct rtw_phl_stainfo_t * sta,enum role_state rstate)228 void rtw_hal_btc_update_role_info_ntfy(void *hinfo,  u8 role_id,
229 						struct rtw_wifi_role_t *wrole,
230 						struct rtw_phl_stainfo_t *sta,
231 						enum role_state rstate)
232 {
233 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
234 	struct btc_t *btc = (struct btc_t *)h->btc;
235 	struct btc_ops *ops = btc->ops;
236 	struct btc_wl_link_info r = {0};
237 #ifdef CONFIG_PHL_P2PPS
238 	u8 i =0;
239 #endif /* CONFIG_PHL_P2PPS */
240 
241 	if (role_id >= MAX_WIFI_ROLE_NUMBER)
242 		return;
243 
244 
245 	if (wrole) {
246 		r.role = wrole->type;
247 #ifdef RTW_WKARD_ROLE_TYPE
248 		if (wrole->mstate != MLME_NO_LINK &&
249 			wrole->real_type != PHL_RTYPE_NONE) {
250 			r.role = wrole->real_type;
251 			PHL_INFO("[BTC], rtw_hal_btc_update_role_info_ntfy(): set r.role from type(%d) to real_type(%d)\n",
252 				wrole->type, wrole->real_type);
253 		}
254 #endif /* RTW_WKARD_ROLE_TYPE */
255 #ifdef CONFIG_PHL_P2PPS
256 		r.noa = 0;
257 		r.noa_duration = 0;
258 		for (i = 0; i < MAX_NOA_DESC; i++) {
259 			if (wrole->noa_desc[i].enable) {
260 				r.noa = 1;
261 				r.noa_duration = wrole->noa_desc[i].duration;
262 				break;
263 			}
264 		}
265 #endif /* CONFIG_PHL_P2PPS */
266 		r.phy = wrole->hw_band;
267 		r.pid = wrole->hw_port;
268 		r.active = wrole->active;
269 		r.connected = wrole->mstate;
270 		r.mode = wrole->cap.wmode;
271 		r.client_cnt = wrole->assoc_sta_queue.cnt;
272 		#ifdef RTW_PHL_BCN
273 		r.bcn_period = wrole->bcn_cmn.bcn_interval;
274 		r.dtim_period = wrole->dtim_period;
275 		#endif
276 		/* Remove it after btc ready */
277 		r.band = wrole->chandef.band;
278 		r.ch = wrole->chandef.center_ch;
279 		r.bw = wrole->chandef.bw;
280 		hal_mem_cpy(h->hal_com, &r.chdef, &wrole->chandef,
281 			    sizeof(struct rtw_chan_def));
282 		hal_mem_cpy(h->hal_com, r.mac_addr, wrole->mac_addr, MAC_ALEN);
283 	}
284 
285 	if (sta && wrole->type == PHL_RTYPE_STATION) {/*associated node info??*/
286 		r.mac_id = sta->macid;
287 		r.mode = (u8)sta->wmode;
288 	}
289 
290 	if (ops && ops->ntfy_role_info)
291 		ops->ntfy_role_info(btc, role_id, &r, rstate);
292 }
293 
rtw_hal_btc_power_on_ntfy(void * hinfo)294 void rtw_hal_btc_power_on_ntfy(void *hinfo)
295 {
296 }
297 
rtw_hal_btc_power_off_ntfy(void * hinfo)298 void rtw_hal_btc_power_off_ntfy(void *hinfo)
299 {
300 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
301 	struct btc_t *btc = (struct btc_t *)h->btc;
302 	struct btc_ops *ops = btc->ops;
303 
304 	if (ops && ops->ntfy_power_off)
305 		ops->ntfy_power_off(btc);
306 }
307 
rtw_hal_btc_init_coex_cfg_ntfy(void * hinfo)308 void rtw_hal_btc_init_coex_cfg_ntfy(void *hinfo)
309 {
310 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
311 	struct btc_t *btc = (struct btc_t *)h->btc;
312 	struct btc_ops *ops = btc->ops;
313 	u8 mode = btc->phl->dev_cap.btc_mode;
314 
315 	if (ops && ops->ntfy_init_coex)
316 		ops->ntfy_init_coex(btc, mode);
317 }
318 
rtw_hal_btc_scan_start_ntfy(void * hinfo,enum phl_phy_idx phy_idx,enum band_type band)319 void rtw_hal_btc_scan_start_ntfy(void *hinfo, enum phl_phy_idx phy_idx,
320 				  enum band_type band)
321 {
322 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
323 	struct btc_t *btc = (struct btc_t *)h->btc;
324 	struct btc_ops *ops = btc->ops;
325 
326 	if (ops && ops->ntfy_scan_start)
327 		ops->ntfy_scan_start(btc, phy_idx, band);
328 }
329 
rtw_hal_btc_scan_finish_ntfy(void * hinfo,enum phl_phy_idx phy_idx)330 void rtw_hal_btc_scan_finish_ntfy(void *hinfo, enum phl_phy_idx phy_idx)
331 {
332 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
333 	struct btc_t *btc = (struct btc_t *)h->btc;
334 	struct btc_ops *ops = btc->ops;
335 
336 	if (ops && ops->ntfy_scan_finish)
337 		ops->ntfy_scan_finish(btc, phy_idx);
338 }
339 
rtw_hal_btc_switch_band_ntfy(void * hinfo,enum phl_phy_idx phy_idx,enum band_type band)340 void rtw_hal_btc_switch_band_ntfy(void *hinfo, enum phl_phy_idx phy_idx,
341 				  enum band_type band)
342 {
343 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
344 	struct btc_t *btc = (struct btc_t *)h->btc;
345 	struct btc_ops *ops = btc->ops;
346 
347 	if (ops && ops->ntfy_switch_band)
348 		ops->ntfy_switch_band(btc, phy_idx, band);
349 }
350 
rtw_hal_btc_packet_event_ntfy(void * hinfo,u8 pkt_evt_type)351 void rtw_hal_btc_packet_event_ntfy(void *hinfo, u8 pkt_evt_type)
352 {
353 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
354 	struct btc_t *btc = (struct btc_t *)h->btc;
355 	struct btc_ops *ops = btc->ops;
356 
357 	if (ops && ops->ntfy_specific_packet)
358 		ops->ntfy_specific_packet(btc, pkt_evt_type);
359 }
360 
rtw_hal_btc_radio_state_ntfy(void * hinfo,u8 rf_state)361 void rtw_hal_btc_radio_state_ntfy(void *hinfo, u8 rf_state)
362 {
363 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
364 	struct btc_t *btc = (struct btc_t *)h->btc;
365 	struct btc_ops *ops = btc->ops;
366 
367 	if (ops && ops->ntfy_radio_state)
368 		ops->ntfy_radio_state(btc, rf_state);
369 }
370 
rtw_hal_btc_customerize_ntfy(void * hinfo,u8 type,u16 len,u8 * buf)371 void rtw_hal_btc_customerize_ntfy(void *hinfo, u8 type, u16 len, u8 *buf)
372 {
373 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
374 	struct btc_t *btc = (struct btc_t *)h->btc;
375 	struct btc_ops *ops = btc->ops;
376 
377 	if (ops && ops->ntfy_customerize)
378 		ops->ntfy_customerize(btc, type, len, buf);
379 }
380 
rtw_hal_btc_wl_rfk_ntfy(struct rtw_hal_com_t * hal_com,u8 phy_idx,u8 rfk_type,u8 rfk_process)381 u8 rtw_hal_btc_wl_rfk_ntfy(struct rtw_hal_com_t *hal_com, u8 phy_idx, u8 rfk_type, u8 rfk_process)
382 {
383 	struct hal_info_t *h = hal_com->hal_priv;
384 	struct btc_t *btc = (struct btc_t *)h->btc;
385 	struct btc_ops *ops = btc->ops;
386 	u8 val = 0;
387 
388 	if (ops && ops->ntfy_wl_rfk)
389 		val = ops->ntfy_wl_rfk(btc, phy_idx, rfk_type, rfk_process);
390 
391 	return val;
392 }
393 
rtw_hal_btc_wl_status_ntfy(void * hinfo,struct rtw_phl_com_t * phl_com,u8 ntfy_num,struct rtw_phl_stainfo_t * sta[],u8 reason)394 void rtw_hal_btc_wl_status_ntfy(void *hinfo, struct rtw_phl_com_t *phl_com, u8 ntfy_num,
395 				struct rtw_phl_stainfo_t *sta[], u8 reason)
396 {
397 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
398 	struct btc_t *btc = (struct btc_t *)h->btc;
399 	struct btc_ops *ops = btc->ops;
400 	struct btc_wl_stat_info stat_info[MAX_WIFI_ROLE_NUMBER] = {0};
401 	struct btc_traffic *t;
402 	struct rtw_stats *phl_stats = &phl_com->phl_stats;
403 	struct rtw_phl_rainfo ra_info = {0};
404 	u8 i;
405 
406 	if(ntfy_num == 0)
407 		return;
408 
409 	for (i = 0; i < ntfy_num; i++) {
410 		_os_mem_set(halcom_to_drvpriv(h->hal_com), &ra_info, 0,
411 			    sizeof(ra_info));
412 
413 		stat_info[i].pid = sta[i]->wrole->id;
414 		stat_info[i].stat.rssi = sta[i]->hal_sta->rssi_stat.rssi >> 1;
415 
416 		t = &stat_info[i].stat.traffic;
417 		t->tx_lvl = phl_stats->tx_traffic.lvl;
418 		t->tx_sts = phl_stats->tx_traffic.sts;
419 		t->tx_1ss_limit = sta[i]->hal_sta->ra_info.ra_nss_limit;
420 
421 		t->rx_lvl = phl_stats->rx_traffic.lvl;
422 		t->rx_sts = phl_stats->rx_traffic.sts;
423 
424 	        if (RTW_HAL_STATUS_SUCCESS ==
425 		    rtw_hal_bb_query_rainfo(h, sta[i]->hal_sta, &ra_info))
426 			t->tx_rate = ra_info.rate;
427 		else
428 			t->tx_rate = RTW_DATA_RATE_MAX;
429 
430 		t->rx_rate = h->hal_com->trx_stat.rx_rate_plurality;
431 	}
432 
433 	if (ops && ops->ntfy_wl_sta)
434 		ops->ntfy_wl_sta(btc, ntfy_num, stat_info, reason);
435 
436 }
437 
rtw_hal_btc_fwinfo_ntfy(void * hinfo)438 void rtw_hal_btc_fwinfo_ntfy(void *hinfo)
439 {
440 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
441 	struct btc_t *btc = (struct btc_t *)h->btc;
442 	struct btc_ops *ops = btc->ops;
443 	struct rtw_hal_com_t *hal_com = h->hal_com;
444 	void *d = halcom_to_drvpriv(hal_com);
445 	struct btc_fw_msg *fmsg = &hal_com->btc_msg;
446 	struct hal_bt_msg *bmsg = NULL;
447 	struct fw_msg_entry *entry = NULL;
448 
449 	_os_spinlock(d, &fmsg->lock, _bh, NULL);
450 	fmsg->fev_cnt = 0;
451 	_os_spinunlock(d, &fmsg->lock, _bh, NULL);
452 
453 	if (!ops || !ops->ntfy_fwinfo)
454 		return;
455 
456 	/* bt score board notification */
457 	while (1) {
458 		bmsg = &fmsg->scbd;
459 		if (bmsg->cnt) {
460 			_os_spinlock(d, &bmsg->lock, _bh, NULL);
461 			bmsg->cnt = 0;
462 			_os_mem_cpy(d, &bmsg->working[0],
463 				&bmsg->latest[0], bmsg->len);
464 			_os_spinunlock(d, &bmsg->lock, _bh, NULL);
465 			PHL_TRACE(COMP_PHL_BTC, _PHL_DEBUG_,
466 				  "[BTC], scoreboard notify !! \n");
467 			ops->ntfy_fwinfo(btc, &bmsg->working[0], bmsg->len,
468 					BTC_CLASS_FEV, BTC_FEV_BT_SCBD);
469 		} else
470 			break;
471 	}
472 
473 	/* bt info notification */
474 	while (1) {
475 		bmsg = &fmsg->btinfo;
476 		if (bmsg->cnt) {
477 			_os_spinlock(d, &bmsg->lock, _bh, NULL);
478 			bmsg->cnt = 0;
479 			_os_mem_cpy(d, &bmsg->working[0],
480 				&bmsg->latest[0], bmsg->len);
481 			_os_spinunlock(d, &bmsg->lock, _bh, NULL);
482 			PHL_TRACE(COMP_PHL_BTC, _PHL_DEBUG_,
483 				  "[BTC], bt info notify !! \n");
484 			ops->ntfy_fwinfo(btc, &bmsg->working[0], bmsg->len,
485 					BTC_CLASS_FEV, BTC_FEV_BT_INFO);
486 		} else
487 			break;
488 	}
489 
490 	/* common btc fw events */
491 	while (1) {
492 		entry = _msg_deq(hal_com, &fmsg->waitq);
493 		if (entry) {
494 			PHL_TRACE(COMP_PHL_BTC, _PHL_DEBUG_,
495 				  "[BTC], fw event notify !! \n");
496 			ops->ntfy_fwinfo(btc, entry->buf, entry->len,
497 					entry->c2h_class, entry->c2h_func);
498 			_msg_enq(hal_com, &fmsg->idleq, entry);
499 		}
500 		else
501 			break;
502 	}
503 }
504 
rtw_hal_btc_timer(void * hinfo,void * timer)505 void rtw_hal_btc_timer(void *hinfo, void *timer)
506 {
507 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
508 	struct btc_t *btc = (struct btc_t *)h->btc;
509 	struct btc_ops *ops = btc->ops;
510 	struct btc_tmr *btmr = NULL;
511 	u8 i = 0;
512 	bool found = false;
513 
514 	PHL_TRACE(COMP_PHL_BTC, _PHL_DEBUG_,
515 		"[BTC], %s(), timer = 0x%p !!\n", __func__, timer);
516 
517 	if (!hinfo || !timer)
518 		return;
519 
520 	btmr = (struct btc_tmr *)timer;
521 
522 	for (i = 0; i < BTC_TIMER_MAX; i++) {
523 		PHL_TRACE(COMP_PHL_BTC, _PHL_DEBUG_,
524 			"[BTC], %s(): btmr = 0x%p, &btc->timer[%d] = 0x%p \n",
525 				__func__, btmr, i, &btc->timer[i]);
526 		if (btmr == &btc->timer[i]) {
527 			found = true;
528 			PHL_TRACE(COMP_PHL_BTC, _PHL_DEBUG_,
529 				"[BTC], %s(): found timer %p, id = %d \n",
530 				__func__, btmr, btmr->id);
531 			break;
532 		}
533 	}
534 
535 	if (ops && found) {
536 		if (btmr->id == BTC_TIMER_PERIODIC) {
537 			struct rtw_wifi_role_t *wrole = NULL;
538 			struct rtw_phl_stainfo_t *sta = NULL;
539 			struct rtw_phl_stainfo_t *wrole_sta[MAX_WIFI_ROLE_NUMBER] = {0};
540 			u8 ntfy_num = 0;
541 
542 			for (i = 0; i < MAX_WIFI_ROLE_NUMBER; i++) {
543 				wrole = &(btc->phl->wifi_roles[i]);
544 				if(wrole->mstate == MLME_LINKED) {
545 					sta = rtw_phl_get_stainfo_self(
546 						btc->phl->phl_priv, wrole);
547 					if(sta != NULL) {
548 						wrole_sta[ntfy_num] = sta;
549 						ntfy_num++;
550 					}
551 				}
552 			}
553 			rtw_hal_btc_wl_status_ntfy(hinfo, btc->phl, ntfy_num,
554 					wrole_sta, PHL_BTC_NTFY_RSN_PERIOTIC);
555 		}
556 		PHL_TRACE(COMP_PHL_BTC, _PHL_DEBUG_,
557 			"[BTC], %s(): btmr->id = %d \n",
558 			__func__, btmr->id);
559 		if(ops->ntfy_timer)
560 			ops->ntfy_timer(btc, btmr->id);
561 	} else {
562 		PHL_INFO("[BTC], %s(): not found, ops = 0x%p, found = %d \n",
563 				__func__, ops, found);
564 	}
565 }
566 
rtw_hal_btc_req_bt_slot_t(void * hinfo)567 u32 rtw_hal_btc_req_bt_slot_t(void *hinfo)
568 {
569 	struct hal_info_t *h = (struct hal_info_t *)hinfo;
570 	struct btc_t *btc = (struct btc_t *)h->btc;
571 
572 	return btc->bt_req_len;
573 }
574 
575 /***********************/
576 /* Called by BTC submodule */
577 /***********************/
hal_btc_send_event(struct btc_t * btc,u8 * buf,u32 len,u16 ev_id)578 void hal_btc_send_event(struct btc_t *btc, u8 *buf, u32 len, u16 ev_id)
579 {
580 #ifdef CONFIG_PHL_CMD_BTC
581 	rtw_phl_btc_send_cmd(btc->phl, buf, len, ev_id);
582 #endif
583 }
584 
hal_btc_notify_ps_tdma(struct btc_t * btc,bool tdma_start)585 void hal_btc_notify_ps_tdma(struct btc_t *btc, bool tdma_start)
586 {
587 #ifdef CONFIG_POWER_SAVE
588 	enum rtw_hal_status hstatus;
589 
590 	hstatus = rtw_hal_ps_pwr_req(btc->phl, HAL_BTC_PWR_REQ, (tdma_start ? true : false));
591 	if (hstatus != RTW_HAL_STATUS_SUCCESS) {
592 		PHL_ERR("[BTC], %s, TDMA (%d) request pwr fail, status: %d \n",
593 			__func__, tdma_start, hstatus);
594 	}
595 #endif
596 }
597 
rtw_hal_btc_proc_cmd(struct hal_info_t * hal_info,struct rtw_proc_cmd * incmd,char * output,u32 out_len)598 bool rtw_hal_btc_proc_cmd(struct hal_info_t *hal_info, struct rtw_proc_cmd *incmd,
599 						char *output, u32 out_len)
600 {
601 	if(incmd->in_type == RTW_ARG_TYPE_BUF)
602 		halbtc_cmd(hal_info->btc, incmd->in.buf, output, out_len);
603 	else if(incmd->in_type == RTW_ARG_TYPE_ARRAY){
604 		halbtc_cmd_parser(hal_info->btc, incmd->in.vector,
605 					incmd->in_cnt_len, output, out_len);
606 	}
607 
608 	return true;
609 }
610 
611 
612 #endif
613 
614 enum rtw_hal_status
rtw_hal_btc_get_efuse_info(struct rtw_hal_com_t * hal_com,u8 * efuse_map,enum rtw_efuse_info info_type,void * value,u8 size,u8 map_valid)615 rtw_hal_btc_get_efuse_info(struct rtw_hal_com_t *hal_com,
616 	u8 *efuse_map, enum rtw_efuse_info info_type, void *value,
617 	u8 size, u8 map_valid)
618 {
619 	PHL_TRACE(COMP_PHL_BTC, _PHL_DEBUG_, "%s\n", __FUNCTION__);
620 	return RTW_HAL_STATUS_SUCCESS;
621 }
622 
rtw_hal_btc_process_c2h(void * hal,struct rtw_c2h_info * c2h)623 u32 rtw_hal_btc_process_c2h(void *hal, struct rtw_c2h_info *c2h)
624 {
625 	struct hal_info_t *h = (struct hal_info_t *)hal;
626 	struct btc_t *btc = (struct btc_t *)h->btc;
627 	struct rtw_hal_com_t *hal_com = h->hal_com;
628 	struct btc_fw_msg *fmsg = &hal_com->btc_msg;
629 	void *d = halcom_to_drvpriv(hal_com);
630 	u8 cls = c2h->c2h_class;
631 	u8 func = c2h->c2h_func;
632 	u16 len = c2h->content_len;
633 	u8 *buf = c2h->content;
634 
635 	if (len && len < RTW_PHL_BTC_FWINFO_BUF) {
636 		if (cls == BTC_CLASS_FEV && func == BTC_FEV_BT_INFO)
637 			_copy_btmsg(hal_com, &fmsg->btinfo, len, buf);
638 		else if (cls == BTC_CLASS_FEV && func == BTC_FEV_BT_SCBD)
639 			_copy_btmsg(hal_com, &fmsg->scbd, len, buf);
640 		else
641 			_fw_evnt_enq(hal_com, cls, func, len, buf);
642 
643 		_os_spinlock(d, &fmsg->lock, _bh, NULL);
644 		if (fmsg->fev_cnt == 0) {
645 			if (rtw_phl_btc_send_cmd(btc->phl, NULL, 0,
646 						BTC_HMSG_FW_EV))
647 				fmsg->fev_cnt++;
648 		}
649 		_os_spinunlock(d, &fmsg->lock, _bh, NULL);
650 	} else {
651 		PHL_TRACE(COMP_PHL_BTC, _PHL_ERR_, "[BTC], %s(): Invalid c2h packet len : %d\n",
652 			  __func__, len);
653 	}
654 
655 	return 0;
656 }
657 
658