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