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_INIT_C_
16 #include "phl_headers.h"
17
_phl_com_init_rssi_stat(struct rtw_phl_com_t * phl_com)18 void _phl_com_init_rssi_stat(struct rtw_phl_com_t *phl_com)
19 {
20 u8 i = 0, j = 0;
21 for (i = 0; i < RTW_RSSI_TYPE_MAX; i++) {
22 phl_com->rssi_stat.ma_rssi_ele_idx[i] = 0;
23 phl_com->rssi_stat.ma_rssi_ele_cnt[i] = 0;
24 phl_com->rssi_stat.ma_rssi_ele_sum[i] = 0;
25 phl_com->rssi_stat.ma_rssi[i] = 0;
26 for (j = 0; j < PHL_RSSI_MAVG_NUM; j++)
27 phl_com->rssi_stat.ma_rssi_ele[i][j] = 0;
28 }
29 _os_spinlock_init(phl_com->drv_priv, &(phl_com->rssi_stat.lock));
30 }
31
_phl_com_deinit_rssi_stat(struct rtw_phl_com_t * phl_com)32 void _phl_com_deinit_rssi_stat(struct rtw_phl_com_t *phl_com)
33 {
34 _os_spinlock_free(phl_com->drv_priv, &(phl_com->rssi_stat.lock));
35 }
36
37 /**
38 * rtw_phl_init_ppdu_sts_para(...)
39 * Description:
40 * 1. Do not call this api after rx started.
41 * 2. PPDU Status per PKT settings
42 **/
rtw_phl_init_ppdu_sts_para(struct rtw_phl_com_t * phl_com,bool en_psts_per_pkt,bool psts_ampdu,u8 rx_fltr)43 void rtw_phl_init_ppdu_sts_para(struct rtw_phl_com_t *phl_com,
44 bool en_psts_per_pkt, bool psts_ampdu,
45 u8 rx_fltr)
46 {
47 #ifdef CONFIG_PHL_RX_PSTS_PER_PKT
48 phl_com->ppdu_sts_info.en_psts_per_pkt = en_psts_per_pkt;
49 phl_com->ppdu_sts_info.psts_ampdu = psts_ampdu;
50 #ifdef RTW_WKARD_DISABLE_PSTS_PER_PKT_DATA
51 /* Forced disable PSTS for DATA frame, to avoid unknown performance issue */
52 rx_fltr &= (~RTW_PHL_PSTS_FLTR_DATA);
53 #endif
54 phl_com->ppdu_sts_info.ppdu_sts_filter = rx_fltr;
55 #else
56 return;
57 #endif
58 }
59
_phl_com_deinit_ppdu_sts(struct rtw_phl_com_t * phl_com)60 void _phl_com_deinit_ppdu_sts(struct rtw_phl_com_t *phl_com)
61 {
62 #ifdef CONFIG_PHL_RX_PSTS_PER_PKT
63 u8 i = 0;
64 u8 j = 0;
65 for (j = 0; j < HW_BAND_MAX; j++) {
66 for (i = 0; i < PHL_MAX_PPDU_CNT; i++) {
67 if (phl_com->ppdu_sts_info.sts_ent[j][i].frames.cnt != 0) {
68 PHL_INFO("[Error] deinit_ppdu_sts : frame queue is not empty\n");
69 }
70 pq_deinit(phl_com->drv_priv,
71 &(phl_com->ppdu_sts_info.sts_ent[j][i].frames));
72 }
73 }
74 #else
75 return;
76 #endif
77 }
78
_phl_com_init_ppdu_sts(struct rtw_phl_com_t * phl_com)79 void _phl_com_init_ppdu_sts(struct rtw_phl_com_t *phl_com)
80 {
81 #ifdef CONFIG_PHL_RX_PSTS_PER_PKT
82 u8 i = 0;
83 #endif
84 u8 j = 0;
85 for (j = 0; j < HW_BAND_MAX; j++) {
86 phl_com->ppdu_sts_info.cur_rx_ppdu_cnt[j] = 0xFF;
87 }
88 #ifdef CONFIG_PHL_RX_PSTS_PER_PKT
89 /* Default enable when compile flag is set. */
90 phl_com->ppdu_sts_info.en_psts_per_pkt = true;
91 /**
92 * Filter of buffer pkt for phy status:
93 * if the correspond bit is set to 1,
94 * the pkt will be buffer till ppdu sts or next ppdu is processed.
95 **/
96 phl_com->ppdu_sts_info.ppdu_sts_filter =
97 RTW_PHL_PSTS_FLTR_MGNT | RTW_PHL_PSTS_FLTR_CTRL |
98 RTW_PHL_PSTS_FLTR_EXT_RSVD;
99
100 /* if set to false, only the first mpdu in ppdu has phy status */
101 phl_com->ppdu_sts_info.psts_ampdu = false;
102
103 phl_com->ppdu_sts_info.en_fake_psts = false;
104
105 for (j = 0; j < HW_BAND_MAX; j++) {
106 for (i = 0; i < PHL_MAX_PPDU_CNT; i++) {
107 pq_init(phl_com->drv_priv,
108 &(phl_com->ppdu_sts_info.sts_ent[j][i].frames));
109 }
110 }
111 #endif
112 #ifdef CONFIG_PHY_INFO_NTFY
113 phl_com->ppdu_sts_info.msg_aggr_cnt = 0;
114 #endif
115 }
116
phl_msg_entry(void * priv,struct phl_msg * msg)117 static void phl_msg_entry(void* priv, struct phl_msg *msg)
118 {
119 struct phl_info_t *phl_info = (struct phl_info_t *)priv;
120 u8 mdl_id = MSG_MDL_ID_FIELD(msg->msg_id);
121 u16 evt_id = MSG_EVT_ID_FIELD(msg->msg_id);
122
123 PHL_DBG("[PHL]%s, mdl_id(%d)\n", __FUNCTION__, mdl_id);
124
125 /* dispatch received PHY msg here */
126 switch(mdl_id) {
127 case PHL_MDL_PHY_MGNT:
128 phl_msg_hub_phy_mgnt_evt_hdlr(phl_info, evt_id);
129 break;
130 case PHL_MDL_TX:
131 phl_msg_hub_tx_evt_hdlr(phl_info, evt_id, msg->inbuf, msg->inlen);
132 break;
133 case PHL_MDL_RX:
134 phl_msg_hub_rx_evt_hdlr(phl_info, evt_id, msg->inbuf, msg->inlen);
135 break;
136 case PHL_MDL_BTC:
137 rtw_phl_btc_hub_msg_hdl(phl_info, msg);
138 break;
139 default:
140 break;
141 }
142 }
143
phl_register_msg_entry(struct phl_info_t * phl_info)144 static enum rtw_phl_status phl_register_msg_entry(struct phl_info_t *phl_info)
145 {
146 struct phl_msg_receiver ctx;
147 void *d = phl_to_drvpriv(phl_info);
148 u8 imr[] = {PHL_MDL_PHY_MGNT, PHL_MDL_RX, PHL_MDL_MRC, PHL_MDL_POWER_MGNT
149 , PHL_MDL_BTC, PHL_MDL_TX};
150 _os_mem_set(d, &ctx, 0, sizeof(struct phl_msg_receiver));
151 ctx.incoming_evt_notify = phl_msg_entry;
152 ctx.priv = (void*)phl_info;
153 if( phl_msg_hub_register_recver((void*)phl_info,
154 &ctx, MSG_RECV_PHL) == RTW_PHL_STATUS_SUCCESS) {
155 /* PHL layer module should set IMR for receiving
156 desired PHY msg and handle it in phl_phy_evt_entry*/
157 phl_msg_hub_update_recver_mask((void*)phl_info, MSG_RECV_PHL,
158 imr, sizeof(imr), false);
159 return RTW_PHL_STATUS_SUCCESS;
160 }
161 else
162 return RTW_PHL_STATUS_FAILURE;
163
164 }
165
phl_deregister_msg_entry(struct phl_info_t * phl_info)166 static enum rtw_phl_status phl_deregister_msg_entry(
167 struct phl_info_t *phl_info)
168 {
169 return phl_msg_hub_deregister_recver((void*)phl_info, MSG_RECV_PHL);
170 }
171
phl_fw_init(struct phl_info_t * phl_info)172 static enum rtw_phl_status phl_fw_init(struct phl_info_t *phl_info)
173 {
174 enum rtw_phl_status phl_status = RTW_PHL_STATUS_RESOURCE;
175 struct rtw_phl_com_t *phl_com = phl_info->phl_com;
176 struct rtw_fw_info_t *fw_info = &phl_com->fw_info;
177
178 FUNCIN_WSTS(phl_status);
179
180 fw_info->rom_buff = _os_mem_alloc(phl_to_drvpriv(phl_info), RTW_MAX_FW_SIZE);
181
182 if (!fw_info->rom_buff) {
183 PHL_ERR("%s : rom buff allocate fail!!\n", __func__);
184 goto mem_alloc_fail;
185 }
186
187 fw_info->ram_buff = _os_mem_alloc(phl_to_drvpriv(phl_info), RTW_MAX_FW_SIZE);
188
189 if (!fw_info->ram_buff) {
190 PHL_ERR("%s : ram buff allocate fail!!\n", __func__);
191 goto mem_alloc_fail;
192 }
193
194 #ifdef CONFIG_PHL_REUSED_FWDL_BUF
195 fw_info->buf = _os_mem_alloc(phl_to_drvpriv(phl_info), RTW_MAX_FW_SIZE);
196
197 /* if allocating failed, fw bin files will be reading every time */
198 if (!fw_info->buf)
199 PHL_WARN("%s : buf for fw storage allocate fail!!\n", __func__);
200
201 fw_info->wow_buf = _os_mem_alloc(phl_to_drvpriv(phl_info), RTW_MAX_FW_SIZE);
202
203 /* if allocating failed, fw bin files will be reading every time */
204 if (!fw_info->wow_buf)
205 PHL_WARN("%s : wow buf for wowlan fw storage allocate fail!!\n", __func__);
206 #endif
207
208 phl_status = RTW_PHL_STATUS_SUCCESS;
209
210 FUNCOUT_WSTS(phl_status);
211
212 mem_alloc_fail:
213 return phl_status;
214 }
215
phl_fw_deinit(struct phl_info_t * phl_info)216 static void phl_fw_deinit(struct phl_info_t *phl_info)
217 {
218 struct rtw_fw_info_t *fw_info = &phl_info->phl_com->fw_info;
219
220 if (fw_info->rom_buff)
221 _os_mem_free(phl_to_drvpriv(phl_info), fw_info->rom_buff,
222 RTW_MAX_FW_SIZE);
223 if (fw_info->ram_buff)
224 _os_mem_free(phl_to_drvpriv(phl_info), fw_info->ram_buff,
225 RTW_MAX_FW_SIZE);
226
227 #ifdef CONFIG_REUSED_FWDL_BUF
228 if (fw_info->buf)
229 _os_mem_free(phl_to_drvpriv(phl_info), fw_info->buf,
230 RTW_MAX_FW_SIZE);
231 if (fw_info->wow_buf)
232 _os_mem_free(phl_to_drvpriv(phl_info), fw_info->wow_buf,
233 RTW_MAX_FW_SIZE);
234 #endif
235
236 /* allocate in rtw_hal_ld_fw_symbol */
237 if (fw_info->sym_buf)
238 _os_mem_free(phl_to_drvpriv(phl_info), fw_info->sym_buf,
239 RTW_MAX_FW_SIZE);
240 }
241 static enum rtw_phl_status
phl_register_background_module_entry(struct phl_info_t * phl_info)242 phl_register_background_module_entry(struct phl_info_t *phl_info)
243 {
244 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
245 #ifdef CONFIG_CMD_DISP
246 /*
247 * setup struct phl_module_ops & call dispr_register_module
248 * to register background module instance.
249 * call dispr_deregister_module if you need to dynamically
250 * deregister the instance of background module.
251 */
252
253 /* 1,2,3 cmd controller section */
254
255
256 /* 41 ~ 70 mandatory background module section*/
257 #ifdef CONFIG_PHL_CMD_SER
258 phl_status = phl_register_ser_module(phl_info);
259 if (phl_status != RTW_PHL_STATUS_SUCCESS)
260 return phl_status;
261 #endif
262 #ifdef CONFIG_POWER_SAVE
263 phl_status = phl_register_ps_module(phl_info);
264 if (phl_status != RTW_PHL_STATUS_SUCCESS)
265 return phl_status;
266 #endif
267 /* 70 ~ 127 optional background module section*/
268 #ifdef CONFIG_PHL_CMD_BTC
269 phl_status = phl_register_btc_module(phl_info);
270 if (phl_status != RTW_PHL_STATUS_SUCCESS)
271 return phl_status;
272 #endif
273 phl_status = phl_register_custom_module(phl_info, HW_BAND_0);
274 if (phl_status != RTW_PHL_STATUS_SUCCESS)
275 return phl_status;
276
277 phl_status = phl_register_led_module(phl_info);
278 if (phl_status != RTW_PHL_STATUS_SUCCESS)
279 return phl_status;
280
281 phl_status = phl_register_cmd_general(phl_info);
282 if (phl_status != RTW_PHL_STATUS_SUCCESS)
283 return phl_status;
284
285 /* 10 ~ 40 protocol, wifi role section*/
286 phl_status = phl_register_mrc_module(phl_info);
287 if (phl_status != RTW_PHL_STATUS_SUCCESS)
288 return phl_status;
289
290 phl_status = phl_snd_cmd_register_module(phl_info);
291 if (phl_status != RTW_PHL_STATUS_SUCCESS)
292 return phl_status;
293 #else
294 phl_status = RTW_PHL_STATUS_SUCCESS;
295 #endif
296 return phl_status;
297 }
298
phl_com_init(void * drv_priv,struct phl_info_t * phl_info,struct rtw_ic_info * ic_info)299 static enum rtw_phl_status phl_com_init(void *drv_priv,
300 struct phl_info_t *phl_info,
301 struct rtw_ic_info *ic_info)
302 {
303 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
304
305 phl_info->phl_com = _os_mem_alloc(drv_priv,
306 sizeof(struct rtw_phl_com_t));
307 if (phl_info->phl_com == NULL) {
308 phl_status = RTW_PHL_STATUS_RESOURCE;
309 PHL_ERR("alloc phl_com failed\n");
310 goto error_phl_com_mem;
311 }
312
313 phl_info->phl_com->phl_priv = phl_info;
314 phl_info->phl_com->drv_priv = drv_priv;
315 phl_info->phl_com->hci_type = ic_info->hci_type;
316 phl_info->phl_com->edcca_mode = RTW_EDCCA_NORMAL;
317
318 phl_sw_cap_init(phl_info->phl_com);
319
320 _os_spinlock_init(drv_priv, &phl_info->phl_com->evt_info.evt_lock);
321
322 phl_fw_init(phl_info);
323 #ifdef CONFIG_PHL_CHANNEL_INFO
324 phl_status = phl_chaninfo_init(phl_info);
325 if (phl_status)
326 goto error_phl_com_mem;
327 #endif /* CONFIG_PHL_CHANNEL_INFO */
328
329 _phl_com_init_rssi_stat(phl_info->phl_com);
330 _phl_com_init_ppdu_sts(phl_info->phl_com);
331
332 phl_status = RTW_PHL_STATUS_SUCCESS;
333 return phl_status;
334
335 error_phl_com_mem:
336 return phl_status;
337 }
338
phl_hci_init(struct phl_info_t * phl_info,struct rtw_ic_info * ic_info)339 static enum rtw_phl_status phl_hci_init(struct phl_info_t *phl_info,
340 struct rtw_ic_info *ic_info)
341 {
342 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
343
344 phl_info->hci = _os_mem_alloc(phl_to_drvpriv(phl_info),
345 sizeof(struct hci_info_t));
346 if (phl_info->hci == NULL) {
347 phl_status = RTW_PHL_STATUS_RESOURCE;
348 goto error_hci_mem;
349 }
350 #ifdef CONFIG_USB_HCI
351 phl_info->hci->usb_bulkout_size = ic_info->usb_info.usb_bulkout_size;
352 #endif
353
354 /* init variable of hci_info_t struct */
355
356 phl_status = RTW_PHL_STATUS_SUCCESS;
357
358 error_hci_mem:
359 return phl_status;
360 }
361
phl_com_deinit(struct phl_info_t * phl_info,struct rtw_phl_com_t * phl_com)362 static void phl_com_deinit(struct phl_info_t *phl_info,
363 struct rtw_phl_com_t *phl_com)
364 {
365 void *drv_priv = phl_to_drvpriv(phl_info);
366
367 /* deinit variable or stop mechanism. */
368 if (phl_com) {
369 phl_sw_cap_deinit(phl_info->phl_com);
370 _os_spinlock_free(drv_priv, &phl_com->evt_info.evt_lock);
371 _phl_com_deinit_rssi_stat(phl_info->phl_com);
372 _phl_com_deinit_ppdu_sts(phl_info->phl_com);
373 phl_fw_deinit(phl_info);
374 #ifdef CONFIG_PHL_CHANNEL_INFO
375 phl_chaninfo_deinit(phl_info);
376 #endif /* CONFIG_PHL_CHANNEL_INFO */
377 _os_mem_free(drv_priv, phl_com, sizeof(struct rtw_phl_com_t));
378 }
379 }
380
phl_hci_deinit(struct phl_info_t * phl_info,struct hci_info_t * hci)381 static void phl_hci_deinit(struct phl_info_t *phl_info, struct hci_info_t *hci)
382 {
383
384 /* deinit variable or stop mechanism. */
385 if (hci)
386 _os_mem_free(phl_to_drvpriv(phl_info), hci,
387 sizeof(struct hci_info_t));
388 }
389
_phl_hci_ops_check(struct phl_info_t * phl_info)390 static enum rtw_phl_status _phl_hci_ops_check(struct phl_info_t *phl_info)
391 {
392 enum rtw_phl_status status = RTW_PHL_STATUS_SUCCESS;
393 struct phl_hci_trx_ops *trx_ops = phl_info->hci_trx_ops;
394
395 if (!trx_ops->hci_trx_init) {
396 phl_ops_error_msg("hci_trx_init");
397 status = RTW_PHL_STATUS_FAILURE;
398 }
399 if (!trx_ops->hci_trx_deinit) {
400 phl_ops_error_msg("hci_trx_deinit");
401 status = RTW_PHL_STATUS_FAILURE;
402 }
403 if (!trx_ops->prepare_tx) {
404 phl_ops_error_msg("prepare_tx");
405 status = RTW_PHL_STATUS_FAILURE;
406 }
407 if (!trx_ops->recycle_rx_buf) {
408 phl_ops_error_msg("recycle_rx_buf");
409 status = RTW_PHL_STATUS_FAILURE;
410 }
411 if (!trx_ops->tx) {
412 phl_ops_error_msg("tx");
413 status = RTW_PHL_STATUS_FAILURE;
414 }
415 if (!trx_ops->rx) {
416 phl_ops_error_msg("rx");
417 status = RTW_PHL_STATUS_FAILURE;
418 }
419 if (!trx_ops->trx_cfg) {
420 phl_ops_error_msg("trx_cfg");
421 status = RTW_PHL_STATUS_FAILURE;
422 }
423 if (!trx_ops->pltfm_tx) {
424 phl_ops_error_msg("pltfm_tx");
425 status = RTW_PHL_STATUS_FAILURE;
426 }
427 if (!trx_ops->alloc_h2c_pkt_buf) {
428 phl_ops_error_msg("alloc_h2c_pkt_buf");
429 status = RTW_PHL_STATUS_FAILURE;
430 }
431 if (!trx_ops->free_h2c_pkt_buf) {
432 phl_ops_error_msg("free_h2c_pkt_buf");
433 status = RTW_PHL_STATUS_FAILURE;
434 }
435 if (!trx_ops->trx_reset) {
436 phl_ops_error_msg("trx_reset");
437 status = RTW_PHL_STATUS_FAILURE;
438 }
439 if (!trx_ops->trx_resume) {
440 phl_ops_error_msg("trx_resume");
441 status = RTW_PHL_STATUS_FAILURE;
442 }
443 if (!trx_ops->req_tx_stop) {
444 phl_ops_error_msg("req_tx_stop");
445 status = RTW_PHL_STATUS_FAILURE;
446 }
447 if (!trx_ops->req_rx_stop) {
448 phl_ops_error_msg("req_rx_stop");
449 status = RTW_PHL_STATUS_FAILURE;
450 }
451 if (!trx_ops->is_tx_pause) {
452 phl_ops_error_msg("is_tx_pause");
453 status = RTW_PHL_STATUS_FAILURE;
454 }
455 if (!trx_ops->is_rx_pause) {
456 phl_ops_error_msg("is_rx_pause");
457 status = RTW_PHL_STATUS_FAILURE;
458 }
459 if (!trx_ops->get_txbd_buf) {
460 phl_ops_error_msg("get_txbd_buf");
461 status = RTW_PHL_STATUS_FAILURE;
462 }
463 if (!trx_ops->get_rxbd_buf) {
464 phl_ops_error_msg("get_rxbd_buf");
465 status = RTW_PHL_STATUS_FAILURE;
466 }
467 if (!trx_ops->recycle_rx_pkt) {
468 phl_ops_error_msg("recycle_rx_pkt");
469 status = RTW_PHL_STATUS_FAILURE;
470 }
471 if (!trx_ops->register_trx_hdlr) {
472 phl_ops_error_msg("register_trx_hdlr");
473 status = RTW_PHL_STATUS_FAILURE;
474 }
475 if (!trx_ops->rx_handle_normal) {
476 phl_ops_error_msg("rx_handle_normal");
477 status = RTW_PHL_STATUS_FAILURE;
478 }
479 if (!trx_ops->tx_watchdog) {
480 phl_ops_error_msg("tx_watchdog");
481 status = RTW_PHL_STATUS_FAILURE;
482 }
483
484 #ifdef CONFIG_PCI_HCI
485 if (!trx_ops->recycle_busy_wd) {
486 phl_ops_error_msg("recycle_busy_wd");
487 status = RTW_PHL_STATUS_FAILURE;
488 }
489 if (!trx_ops->recycle_busy_h2c) {
490 phl_ops_error_msg("recycle_busy_h2c");
491 status = RTW_PHL_STATUS_FAILURE;
492 }
493 if (!trx_ops->read_hw_rx) {
494 phl_ops_error_msg("read_hw_rx");
495 status = RTW_PHL_STATUS_FAILURE;
496 }
497
498 #endif
499
500 #ifdef CONFIG_USB_HCI
501 if (!trx_ops->pend_rxbuf) {
502 phl_ops_error_msg("pend_rxbuf");
503 status = RTW_PHL_STATUS_FAILURE;
504 }
505 if (!trx_ops->recycle_tx_buf) {
506 phl_ops_error_msg("recycle_tx_buf");
507 status = RTW_PHL_STATUS_FAILURE;
508 }
509 #endif
510
511 return status;
512 }
513
phl_set_hci_ops(struct phl_info_t * phl_info)514 static enum rtw_phl_status phl_set_hci_ops(struct phl_info_t *phl_info)
515 {
516 #ifdef CONFIG_PCI_HCI
517 if (phl_get_hci_type(phl_info->phl_com) == RTW_HCI_PCIE)
518 phl_hook_trx_ops_pci(phl_info);
519 #endif
520
521 #ifdef CONFIG_USB_HCI
522 if (phl_get_hci_type(phl_info->phl_com) == RTW_HCI_USB)
523 phl_hook_trx_ops_usb(phl_info);
524 #endif
525
526 #ifdef CONFIG_SDIO_HCI
527 if (phl_get_hci_type(phl_info->phl_com) == RTW_HCI_SDIO)
528 phl_hook_trx_ops_sdio(phl_info);
529 #endif
530
531 return _phl_hci_ops_check(phl_info);
532 }
533
534 #ifdef CONFIG_FSM
phl_cmd_init(struct phl_info_t * phl_info)535 static enum rtw_phl_status phl_cmd_init(struct phl_info_t *phl_info)
536 {
537 if (phl_info->cmd_fsm != NULL)
538 return RTW_PHL_STATUS_FAILURE;
539
540 phl_info->cmd_fsm = phl_cmd_new_fsm(phl_info->fsm_root, phl_info);
541 if (phl_info->cmd_fsm == NULL)
542 return RTW_PHL_STATUS_FAILURE;
543
544 if (phl_info->cmd_obj != NULL)
545 goto obj_fail;
546
547 phl_info->cmd_obj = phl_cmd_new_obj(phl_info->cmd_fsm, phl_info);
548 if (phl_info->cmd_obj == NULL)
549 goto obj_fail;
550
551 return RTW_PHL_STATUS_SUCCESS;
552
553 obj_fail:
554 phl_fsm_deinit_fsm(phl_info->cmd_fsm);
555 phl_info->cmd_fsm = NULL;
556 return RTW_PHL_STATUS_FAILURE;
557 }
558
phl_cmd_deinit(struct phl_info_t * phl_info)559 static void phl_cmd_deinit(struct phl_info_t *phl_info)
560 {
561 phl_cmd_destory_obj(phl_info->cmd_obj);
562 phl_info->cmd_obj = NULL;
563 phl_cmd_destory_fsm(phl_info->cmd_fsm);
564 phl_info->cmd_fsm = NULL;
565 }
566
phl_ser_init(struct phl_info_t * phl_info)567 static enum rtw_phl_status phl_ser_init(struct phl_info_t *phl_info)
568 {
569 if (phl_info->ser_fsm != NULL)
570 return RTW_PHL_STATUS_FAILURE;
571
572 phl_info->ser_fsm = phl_ser_new_fsm(phl_info->fsm_root, phl_info);
573 if (phl_info->ser_fsm == NULL)
574 return RTW_PHL_STATUS_FAILURE;
575
576 if (phl_info->ser_obj != NULL)
577 goto obj_fail;
578
579 phl_info->ser_obj = phl_ser_new_obj(phl_info->ser_fsm, phl_info);
580 if (phl_info->ser_obj == NULL)
581 goto obj_fail;
582
583 return RTW_PHL_STATUS_SUCCESS;
584
585 obj_fail:
586 phl_ser_destory_fsm(phl_info->ser_fsm);
587 phl_info->ser_fsm = NULL;
588 return RTW_PHL_STATUS_FAILURE;
589 }
590
phl_ser_deinit(struct phl_info_t * phl_info)591 static void phl_ser_deinit(struct phl_info_t *phl_info)
592 {
593 phl_ser_destory_obj(phl_info->ser_obj);
594 phl_info->ser_obj = NULL;
595
596 phl_ser_destory_fsm(phl_info->ser_fsm);
597 phl_info->ser_fsm = NULL;
598 }
599
phl_btc_init(struct phl_info_t * phl_info)600 static enum rtw_phl_status phl_btc_init(struct phl_info_t *phl_info)
601 {
602 if (phl_info->btc_fsm != NULL)
603 return RTW_PHL_STATUS_FAILURE;
604
605 phl_info->btc_fsm = phl_btc_new_fsm(phl_info->fsm_root, phl_info);
606 if (phl_info->btc_fsm == NULL)
607 return RTW_PHL_STATUS_FAILURE;
608
609 phl_info->btc_obj = phl_btc_new_obj(phl_info->btc_fsm, phl_info);
610 if (phl_info->btc_obj == NULL)
611 goto obj_fail;
612
613 return RTW_PHL_STATUS_SUCCESS;
614
615 obj_fail:
616 phl_fsm_deinit_fsm(phl_info->btc_fsm);
617 phl_info->btc_fsm = NULL;
618 return RTW_PHL_STATUS_FAILURE;
619
620 }
621
phl_btc_deinit(struct phl_info_t * phl_info)622 static void phl_btc_deinit(struct phl_info_t *phl_info)
623 {
624 phl_btc_destory_obj(phl_info->btc_obj);
625 phl_info->btc_obj = NULL;
626
627 phl_btc_destory_fsm(phl_info->btc_fsm);
628 phl_info->btc_fsm = NULL;
629 }
630
phl_scan_init(struct phl_info_t * phl_info)631 static enum rtw_phl_status phl_scan_init(struct phl_info_t *phl_info)
632 {
633 if (phl_info->scan_fsm != NULL)
634 return RTW_PHL_STATUS_FAILURE;
635
636 phl_info->scan_fsm = phl_scan_new_fsm(phl_info->fsm_root, phl_info);
637 if (phl_info->scan_fsm == NULL)
638 return RTW_PHL_STATUS_FAILURE;
639
640 if (phl_info->scan_obj != NULL)
641 goto obj_fail;
642
643 phl_info->scan_obj = phl_scan_new_obj(phl_info->scan_fsm, phl_info);
644 if (phl_info->scan_obj == NULL)
645 goto obj_fail;
646
647 return RTW_PHL_STATUS_SUCCESS;
648
649 obj_fail:
650 phl_fsm_deinit_fsm(phl_info->scan_fsm);
651 phl_info->scan_fsm = NULL;
652 return RTW_PHL_STATUS_FAILURE;
653 }
654
phl_scan_deinit(struct phl_info_t * phl_info)655 static void phl_scan_deinit(struct phl_info_t *phl_info)
656 {
657 phl_scan_destory_obj(phl_info->scan_obj);
658 phl_info->scan_obj = NULL;
659 phl_scan_destory_fsm(phl_info->scan_fsm);
660 phl_info->scan_fsm = NULL;
661 }
662
phl_sound_init(struct phl_info_t * phl_info)663 static enum rtw_phl_status phl_sound_init(struct phl_info_t *phl_info)
664 {
665 enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
666
667 if (phl_info->snd_fsm!= NULL)
668 return RTW_PHL_STATUS_FAILURE;
669
670 phl_info->snd_fsm = phl_sound_new_fsm(phl_info->fsm_root, phl_info);
671 if (phl_info->snd_fsm == NULL)
672 return RTW_PHL_STATUS_FAILURE;
673
674 pstatus = phl_snd_new_obj(phl_info->snd_fsm, phl_info);
675 if (pstatus != RTW_PHL_STATUS_SUCCESS)
676 goto obj_fail;
677
678 return pstatus;
679
680 obj_fail:
681 phl_fsm_deinit_fsm(phl_info->snd_fsm);
682 phl_info->snd_fsm = NULL;
683 return RTW_PHL_STATUS_FAILURE;
684 }
685
phl_sound_deinit(struct phl_info_t * phl_info)686 static void phl_sound_deinit(struct phl_info_t *phl_info)
687 {
688 phl_snd_destory_obj(phl_info->snd_obj);
689 phl_info->snd_obj = NULL;
690 phl_snd_destory_fsm(phl_info->snd_fsm);
691 phl_info->snd_fsm = NULL;
692 }
693
phl_fsm_init(struct phl_info_t * phl_info)694 static enum rtw_phl_status phl_fsm_init(struct phl_info_t *phl_info)
695 {
696 if (phl_info->fsm_root != NULL)
697 return RTW_PHL_STATUS_FAILURE;
698
699 /* allocate memory for fsm to do version control */
700 phl_info->fsm_root = phl_fsm_init_root(phl_info);
701 if (phl_info->fsm_root == NULL)
702 return RTW_PHL_STATUS_FAILURE;
703
704 return RTW_PHL_STATUS_SUCCESS;
705 }
706
phl_fsm_deinit(struct phl_info_t * phl_info)707 static void phl_fsm_deinit(struct phl_info_t *phl_info)
708 {
709 /* free memory for fsm */
710 phl_fsm_deinit_root(phl_info->fsm_root);
711 phl_info->fsm_root = NULL;
712 }
713
phl_fsm_module_init(struct phl_info_t * phl_info)714 static enum rtw_phl_status phl_fsm_module_init(struct phl_info_t *phl_info)
715 {
716 enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
717
718 phl_status = phl_cmd_init(phl_info);
719 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
720 PHL_ERR("phl_cmd_init failed\n");
721 goto cmd_fail;
722 }
723
724 phl_status = phl_ser_init(phl_info);
725 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
726 PHL_ERR("phl_ser_init failed\n");
727 goto ser_fail;
728 }
729
730 phl_status = phl_btc_init(phl_info);
731 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
732 PHL_ERR("phl_btc_init failed\n");
733 goto btc_fail;
734 }
735
736 phl_status = phl_scan_init(phl_info);
737 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
738 PHL_ERR("phl_scan_init failed\n");
739 goto scan_fail;
740 }
741
742 phl_status = phl_sound_init(phl_info);
743 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
744 PHL_ERR("phl_sound_init failed\n");
745 goto sound_fail;
746 }
747
748 return phl_status;
749
750 sound_fail:
751 phl_scan_deinit(phl_info);
752 scan_fail:
753 phl_btc_deinit(phl_info);
754 btc_fail:
755 phl_ser_deinit(phl_info);
756 ser_fail:
757 phl_cmd_deinit(phl_info);
758 cmd_fail:
759 return phl_status;
760 }
761
phl_fsm_module_deinit(struct phl_info_t * phl_info)762 static void phl_fsm_module_deinit(struct phl_info_t *phl_info)
763 {
764 phl_sound_deinit(phl_info);
765 phl_scan_deinit(phl_info);
766 phl_btc_deinit(phl_info);
767 phl_ser_deinit(phl_info);
768 phl_cmd_deinit(phl_info);
769 }
770
phl_fsm_start(struct phl_info_t * phl_info)771 static enum rtw_phl_status phl_fsm_start(struct phl_info_t *phl_info)
772 {
773 return phl_fsm_start_root(phl_info->fsm_root);
774 }
775
phl_fsm_stop(struct phl_info_t * phl_info)776 static enum rtw_phl_status phl_fsm_stop(struct phl_info_t *phl_info)
777 {
778 return phl_fsm_stop_root(phl_info->fsm_root);
779 }
780
phl_fsm_module_start(struct phl_info_t * phl_info)781 static enum rtw_phl_status phl_fsm_module_start(struct phl_info_t *phl_info)
782 {
783 enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
784
785 phl_status = phl_fsm_start_fsm(phl_info->ser_fsm);
786 if (phl_status != RTW_PHL_STATUS_SUCCESS)
787 goto ser_fail;
788
789 phl_status = phl_btc_start(phl_info->btc_obj);
790 if (phl_status != RTW_PHL_STATUS_SUCCESS)
791 goto btc_fail;
792
793 phl_status = phl_fsm_start_fsm(phl_info->scan_fsm);
794 if (phl_status != RTW_PHL_STATUS_SUCCESS)
795 goto scan_fail;
796
797 phl_status = phl_cmd_start(phl_info->cmd_obj);
798 if (phl_status != RTW_PHL_STATUS_SUCCESS)
799 goto cmd_fail;
800
801 phl_status = phl_fsm_start_fsm(phl_info->snd_fsm);
802 if (phl_status != RTW_PHL_STATUS_SUCCESS)
803 goto snd_fail;
804
805 return phl_status;
806
807 snd_fail:
808 phl_fsm_stop_fsm(phl_info->cmd_fsm);
809 phl_fsm_stop_fsm(phl_info->scan_fsm);
810 scan_fail:
811 phl_fsm_stop_fsm(phl_info->btc_fsm);
812 btc_fail:
813 phl_fsm_stop_fsm(phl_info->ser_fsm);
814 ser_fail:
815 phl_fsm_cmd_stop(phl_info);
816 cmd_fail:
817 return phl_status;
818 }
819
phl_fsm_module_stop(struct phl_info_t * phl_info)820 static enum rtw_phl_status phl_fsm_module_stop(struct phl_info_t *phl_info)
821 {
822 enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
823
824 phl_fsm_stop_fsm(phl_info->snd_fsm);
825 phl_fsm_stop_fsm(phl_info->scan_fsm);
826 phl_fsm_stop_fsm(phl_info->btc_fsm);
827 phl_fsm_stop_fsm(phl_info->ser_fsm);
828 phl_fsm_cmd_stop(phl_info);
829
830 return phl_status;
831 }
832
833 #endif /*CONFIG_FSM*/
phl_module_init(struct phl_info_t * phl_info)834 static enum rtw_phl_status phl_module_init(struct phl_info_t *phl_info)
835 {
836 enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
837
838 phl_status = phl_msg_hub_init(phl_info);
839 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
840 PHL_ERR("phl_msg_hub_init failed\n");
841 goto msg_hub_fail;
842 }
843
844 phl_status = phl_wow_mdl_init(phl_info);
845 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
846 PHL_ERR("phl_wow_mdl_init failed\n");
847 goto wow_init_fail;
848 }
849
850 phl_status = phl_pkt_ofld_init(phl_info);
851 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
852 PHL_ERR("phl_pkt_ofld_init failed\n");
853 goto pkt_ofld_init_fail;
854 }
855
856 if (!phl_test_module_init(phl_info)) {
857 PHL_ERR("phl_test_module_init failed\n");
858 phl_status = RTW_PHL_STATUS_FAILURE;
859 goto error_test_module_init;
860 }
861
862 phl_status = phl_p2pps_init(phl_info);
863 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
864 PHL_ERR("phl_p2pps_init failed\n");
865 goto error_p2pps_init;
866 }
867
868 phl_status = phl_disp_eng_init(phl_info, HW_BAND_MAX);
869 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
870 PHL_ERR("phl_disp_eng_init failed\n");
871 goto error_disp_eng_init;
872 }
873
874 phl_status = phl_register_background_module_entry(phl_info);
875 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
876 PHL_ERR("phl_register_disp_eng_module_entry failed\n");
877 goto error_disp_eng_reg_init;
878 }
879
880 phl_status = phl_ecsa_ctrl_init(phl_info);
881 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
882 PHL_ERR("phl_ecsa_ctrl_init failed\n");
883 goto error_ecsa_ctrl_init;
884 }
885 return phl_status;
886
887 error_ecsa_ctrl_init:
888 error_disp_eng_reg_init:
889 phl_disp_eng_deinit(phl_info);
890 error_disp_eng_init:
891 phl_p2pps_deinit(phl_info);
892 error_p2pps_init:
893 phl_test_module_deinit(phl_info->phl_com);
894 error_test_module_init:
895 phl_pkt_ofld_deinit(phl_info);
896 pkt_ofld_init_fail:
897 phl_wow_mdl_deinit(phl_info);
898 wow_init_fail:
899 phl_msg_hub_deinit(phl_info);
900 msg_hub_fail:
901 return phl_status;
902 }
903
phl_module_deinit(struct phl_info_t * phl_info)904 static void phl_module_deinit(struct phl_info_t *phl_info)
905 {
906 phl_ecsa_ctrl_deinit(phl_info);
907 phl_disp_eng_deinit(phl_info);
908 phl_test_module_deinit(phl_info->phl_com);
909 phl_pkt_ofld_deinit(phl_info);
910 phl_wow_mdl_deinit(phl_info);
911 phl_msg_hub_deinit(phl_info);
912 phl_p2pps_deinit(phl_info);
913 }
914
phl_module_start(struct phl_info_t * phl_info)915 static enum rtw_phl_status phl_module_start(struct phl_info_t *phl_info)
916 {
917 enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
918
919 if (!phl_test_module_start(phl_info->phl_com)) {
920 PHL_ERR("phl_test_module_start failed\n");
921 phl_status = RTW_PHL_STATUS_FAILURE;
922 goto error_test_mdl_start;
923 }
924
925 phl_status = phl_disp_eng_start(phl_info);
926 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
927 PHL_ERR("phl_disp_eng_start failed\n");
928 goto error_disp_eng_start;
929 }
930
931 if(phl_info->msg_hub) {
932 phl_msg_hub_start(phl_info);
933 phl_register_msg_entry(phl_info);
934 }
935
936 return phl_status;
937
938 error_disp_eng_start:
939 phl_test_module_stop(phl_info->phl_com);
940 error_test_mdl_start:
941 return phl_status;
942 }
943
phl_module_stop(struct phl_info_t * phl_info)944 static enum rtw_phl_status phl_module_stop(struct phl_info_t *phl_info)
945 {
946 enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
947
948 phl_status = phl_cmd_enqueue(phl_info, HW_BAND_0, MSG_EVT_MDL_CHECK_STOP,
949 NULL, 0, NULL, PHL_CMD_WAIT, 500);
950
951 phl_disp_eng_stop(phl_info);
952 phl_test_module_stop(phl_info->phl_com);
953
954 if(phl_info->msg_hub) {
955 phl_deregister_msg_entry(phl_info);
956 phl_msg_hub_stop(phl_info);
957 }
958
959 return phl_status;
960 }
961
phl_var_init(struct phl_info_t * phl_info)962 static enum rtw_phl_status phl_var_init(struct phl_info_t *phl_info)
963 {
964 return RTW_PHL_STATUS_SUCCESS;
965 }
966
phl_var_deinit(struct phl_info_t * phl_info)967 static void phl_var_deinit(struct phl_info_t *phl_info)
968 {
969
970 }
971
rtw_phl_get_com(void * phl)972 struct rtw_phl_com_t *rtw_phl_get_com(void *phl)
973 {
974 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
975
976 return phl_info->phl_com;
977 }
978
phl_regulation_init(void * drv_priv,void * phl)979 static void phl_regulation_init(void *drv_priv, void *phl)
980 {
981 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
982 struct rtw_regulation *rg = NULL;
983
984 if (!drv_priv || !phl)
985 return;
986
987 rg = &phl_info->regulation;
988
989 _os_spinlock_init(drv_priv, &rg->lock);
990 rg->init = 1;
991 rg->domain.code = INVALID_DOMAIN_CODE;
992 rg->domain_6g.code = INVALID_DOMAIN_CODE;
993 rg->tpo = TPO_NA;
994 }
995
phl_regulation_deinit(void * drv_priv,void * phl)996 static void phl_regulation_deinit(void *drv_priv, void *phl)
997 {
998 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
999 struct rtw_regulation *rg = NULL;
1000
1001 if (!drv_priv || !phl)
1002 return;
1003
1004 rg = &phl_info->regulation;
1005
1006 _os_spinlock_free(drv_priv, &rg->lock);
1007 }
1008
rtw_phl_init(void * drv_priv,void ** phl,struct rtw_ic_info * ic_info)1009 enum rtw_phl_status rtw_phl_init(void *drv_priv, void **phl,
1010 struct rtw_ic_info *ic_info)
1011 {
1012 struct phl_info_t *phl_info = NULL;
1013 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
1014 enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
1015
1016 FUNCIN();
1017 phl_info = _os_mem_alloc(drv_priv, sizeof(struct phl_info_t));
1018 if (phl_info == NULL) {
1019 phl_status = RTW_PHL_STATUS_RESOURCE;
1020 PHL_ERR("alloc phl_info failed\n");
1021 goto error_phl_mem;
1022 }
1023 _os_mem_set(drv_priv, phl_info, 0, sizeof(struct phl_info_t));
1024 *phl = phl_info;
1025
1026 phl_regulation_init(drv_priv, phl_info);
1027
1028 phl_status = phl_com_init(drv_priv, phl_info, ic_info);
1029 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1030 phl_status = RTW_PHL_STATUS_RESOURCE;
1031 PHL_ERR("alloc phl_com failed\n");
1032 goto error_phl_com_mem;
1033 }
1034
1035 phl_status = phl_hci_init(phl_info, ic_info);
1036 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1037 PHL_ERR("phl_hci_init failed\n");
1038 goto error_hci_init;
1039 }
1040
1041 phl_status = phl_set_hci_ops(phl_info);
1042 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1043 PHL_ERR("phl_set_hci_ops failed\n");
1044 goto error_set_hci_ops;
1045 }
1046 #ifdef CONFIG_FSM
1047 phl_status = phl_fsm_init(phl_info);
1048 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1049 PHL_ERR("phl_fsm_init failed\n");
1050 goto error_fsm_init;
1051 }
1052
1053 /* init FSM modules */
1054 phl_status = phl_fsm_module_init(phl_info);
1055 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1056 PHL_ERR("phl_fsm_module_init failed\n");
1057 goto error_fsm_module_init;
1058 }
1059 #endif
1060 phl_status = phl_twt_init(*phl);
1061 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1062 PHL_ERR("phl_twt_init failed\n");
1063 goto error_phl_twt_init;
1064 }
1065 hal_status = rtw_hal_init(drv_priv, phl_info->phl_com,
1066 &(phl_info->hal), ic_info->ic_id);
1067 if ((hal_status != RTW_HAL_STATUS_SUCCESS) || (phl_info->hal == NULL)) {
1068 phl_status = RTW_PHL_STATUS_HAL_INIT_FAILURE;
1069 PHL_ERR("rtw_hal_init failed status(%d),phl_info->hal(%p)\n",
1070 hal_status, phl_info->hal);
1071 goto error_hal_init;
1072 }
1073
1074 /*send bus info to hal*/
1075 rtw_hal_hci_cfg(phl_info->phl_com, phl_info->hal, ic_info);
1076
1077 /*get hw capability from mac/bb/rf/btc/efuse/fw-defeature-rpt*/
1078 hal_status = rtw_hal_read_chip_info(phl_info->phl_com, phl_info->hal);
1079 if (hal_status != RTW_HAL_STATUS_SUCCESS) {
1080 phl_status = RTW_PHL_STATUS_HAL_INIT_FAILURE;
1081 PHL_ERR("rtw_hal_read_chip_info failed\n");
1082 goto error_hal_read_chip_info;
1083 }
1084
1085 hal_status = rtw_hal_var_init(phl_info->phl_com, phl_info->hal);
1086 if (hal_status != RTW_HAL_STATUS_SUCCESS) {
1087 phl_status = RTW_PHL_STATUS_HAL_INIT_FAILURE;
1088 PHL_ERR("rtw_hal_var_init failed\n");
1089 goto error_hal_var_init;
1090 }
1091
1092 phl_status = phl_var_init(phl_info);
1093 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1094 PHL_ERR("phl_var_init failed\n");
1095 goto error_phl_var_init;
1096 }
1097
1098 /* init mr_ctrl, wifi_role[] */
1099 phl_status = phl_mr_ctrl_init(phl_info);
1100 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1101 PHL_ERR("phl_mr_ctrl_init failed\n");
1102 goto error_wifi_role_ctrl_init;
1103 }
1104
1105 /* init modules */
1106 phl_status = phl_module_init(phl_info);
1107 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1108 PHL_ERR("phl_module_init failed\n");
1109 goto error_module_init;
1110 }
1111
1112 /* init macid_ctrl , stainfo_ctrl*/
1113 /* init after get hw cap - macid number*/
1114 phl_status = phl_macid_ctrl_init(phl_info);
1115 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1116 PHL_ERR("phl_macid_ctrl_init failed\n");
1117 goto error_macid_ctrl_init;
1118 }
1119
1120 /*init after hal_init - hal_sta_info*/
1121 phl_status = phl_stainfo_ctrl_init(phl_info);
1122 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1123 PHL_ERR("phl_stainfo_ctrl_init failed\n");
1124 goto error_stainfo_ctrl_init;
1125 }
1126 FUNCOUT();
1127
1128 return phl_status;
1129
1130 error_stainfo_ctrl_init:
1131 phl_macid_ctrl_deinit(phl_info);
1132 error_macid_ctrl_init:
1133 phl_module_deinit(phl_info);
1134 error_module_init:
1135 phl_mr_ctrl_deinit(phl_info);
1136 error_wifi_role_ctrl_init:
1137 phl_var_deinit(phl_info);
1138 error_phl_var_init:
1139 error_hal_var_init:
1140 error_hal_read_chip_info:
1141 rtw_hal_deinit(phl_info->phl_com, phl_info->hal);
1142 error_hal_init:
1143 error_phl_twt_init:
1144 phl_twt_deinit(phl);
1145 #ifdef CONFIG_FSM
1146 phl_fsm_module_deinit(phl_info);
1147 error_fsm_module_init:
1148 phl_fsm_deinit(phl_info);
1149 error_fsm_init:
1150 /* Do nothing */
1151 #endif
1152 error_set_hci_ops:
1153 phl_hci_deinit(phl_info, phl_info->hci);
1154 error_hci_init:
1155 phl_com_deinit(phl_info, phl_info->phl_com);
1156 error_phl_com_mem:
1157 if (phl_info) {
1158 phl_regulation_deinit(drv_priv, phl_info);
1159 _os_mem_free(drv_priv, phl_info, sizeof(struct phl_info_t));
1160 *phl = phl_info = NULL;
1161 }
1162 error_phl_mem:
1163 return phl_status;
1164 }
1165
rtw_phl_deinit(void * phl)1166 void rtw_phl_deinit(void *phl)
1167 {
1168 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1169 void *drv_priv = phl_to_drvpriv(phl_info);
1170
1171 if (phl_info) {
1172 phl_twt_deinit(phl);
1173 phl_stainfo_ctrl_deinie(phl_info);
1174 phl_macid_ctrl_deinit(phl_info);
1175 /*deinit mr_ctrl, wifi_role[]*/
1176 phl_module_deinit(phl_info);
1177 phl_mr_ctrl_deinit(phl_info);
1178 rtw_hal_deinit(phl_info->phl_com, phl_info->hal);
1179 phl_var_deinit(phl_info);
1180 #ifdef CONFIG_FSM
1181 phl_fsm_module_deinit(phl_info);
1182 phl_fsm_deinit(phl_info);
1183 #endif
1184 phl_hci_deinit(phl_info, phl_info->hci);
1185 phl_com_deinit(phl_info, phl_info->phl_com);
1186 phl_regulation_deinit(drv_priv, phl_info);
1187 _os_mem_free(drv_priv, phl_info,
1188 sizeof(struct phl_info_t));
1189 }
1190 }
1191
1192 enum rtw_phl_status
rtw_phl_trx_alloc(void * phl)1193 rtw_phl_trx_alloc(void *phl)
1194 {
1195 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1196 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
1197
1198 phl_status = phl_datapath_init(phl_info);
1199 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1200 PHL_ERR("phl_datapath_init failed\n");
1201 goto error_datapath;
1202 }
1203
1204 phl_status = phl_trx_test_init(phl);
1205 if (phl_status != RTW_PHL_STATUS_SUCCESS) {
1206 PHL_ERR("phl_trx_test_init failed\n");
1207 goto error_trx_test;
1208 }
1209
1210 return phl_status;
1211
1212 error_trx_test:
1213 phl_datapath_deinit(phl_info);
1214 error_datapath:
1215 return phl_status;
1216 }
1217
1218 void
rtw_phl_trx_free_handler(void * phl)1219 rtw_phl_trx_free_handler(void *phl)
1220 {
1221 phl_trx_free_handler(phl);
1222 }
1223
1224 void
rtw_phl_trx_free_sw_rsc(void * phl)1225 rtw_phl_trx_free_sw_rsc(void *phl)
1226 {
1227 phl_trx_free_sw_rsc(phl);
1228 phl_trx_test_deinit(phl);
1229 }
1230
1231 void
rtw_phl_trx_free(void * phl)1232 rtw_phl_trx_free(void *phl)
1233 {
1234 rtw_phl_trx_free_handler(phl);
1235 rtw_phl_trx_free_sw_rsc(phl);
1236 }
1237
1238
rtw_phl_is_init_completed(void * phl)1239 bool rtw_phl_is_init_completed(void *phl)
1240 {
1241 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1242
1243 return rtw_hal_is_inited(phl_info->phl_com, phl_info->hal);
1244 }
1245
1246 #ifdef RTW_PHL_BCN
1247
1248 enum rtw_phl_status
phl_add_beacon(struct phl_info_t * phl_info,struct rtw_bcn_info_cmn * bcn_cmn)1249 phl_add_beacon(struct phl_info_t *phl_info, struct rtw_bcn_info_cmn *bcn_cmn)
1250 {
1251 struct rtw_phl_com_t *phl_com = phl_info->phl_com;
1252 void *hal = phl_info->hal;
1253
1254 if(rtw_hal_add_beacon(phl_com, hal, bcn_cmn) == RTW_HAL_STATUS_SUCCESS)
1255 return RTW_PHL_STATUS_SUCCESS;
1256 else
1257 return RTW_PHL_STATUS_FAILURE;
1258 }
1259
phl_update_beacon(struct phl_info_t * phl_info,u8 bcn_id)1260 enum rtw_phl_status phl_update_beacon(struct phl_info_t *phl_info, u8 bcn_id)
1261 {
1262 struct rtw_phl_com_t *phl_com = phl_info->phl_com;
1263 void *hal = phl_info->hal;
1264
1265 if(rtw_hal_update_beacon(phl_com, hal, bcn_id) == RTW_HAL_STATUS_SUCCESS)
1266 return RTW_PHL_STATUS_SUCCESS;
1267 else
1268 return RTW_PHL_STATUS_FAILURE;
1269 }
1270
rtw_phl_free_bcn_entry(void * phl,struct rtw_wifi_role_t * wrole)1271 enum rtw_phl_status rtw_phl_free_bcn_entry(void *phl, struct rtw_wifi_role_t *wrole)
1272 {
1273 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1274 struct rtw_phl_com_t *phl_com = phl_info->phl_com;
1275 struct rtw_bcn_info_cmn *bcn_cmn = &wrole->bcn_cmn;
1276 void *hal = phl_info->hal;
1277 enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
1278
1279 if (bcn_cmn->bcn_added == 1) {
1280 if (rtw_hal_free_beacon(phl_com, hal, bcn_cmn->bcn_id) == RTW_HAL_STATUS_SUCCESS) {
1281 bcn_cmn->bcn_added = 0;
1282 phl_status = RTW_PHL_STATUS_SUCCESS;
1283 } else {
1284 phl_status = RTW_PHL_STATUS_FAILURE;
1285 }
1286 }
1287
1288 return phl_status;
1289 }
1290
1291 enum rtw_phl_status
phl_beacon_stop(struct phl_info_t * phl_info,struct rtw_wifi_role_t * wrole,u8 stop)1292 phl_beacon_stop(struct phl_info_t *phl_info, struct rtw_wifi_role_t *wrole, u8 stop)
1293 {
1294 enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
1295 enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
1296
1297 hstatus = rtw_hal_beacon_stop(phl_info->hal, wrole, stop);
1298 if (hstatus != RTW_HAL_STATUS_SUCCESS)
1299 pstatus = RTW_PHL_STATUS_FAILURE;
1300
1301 return pstatus;
1302 }
1303
1304 enum rtw_phl_status
phl_issue_beacon(struct phl_info_t * phl_info,struct rtw_bcn_info_cmn * bcn_cmn)1305 phl_issue_beacon(struct phl_info_t *phl_info, struct rtw_bcn_info_cmn *bcn_cmn)
1306 {
1307 struct rtw_phl_com_t *phl_com = phl_info->phl_com;
1308 struct rtw_bcn_info_cmn *wrole_bcn_cmn;
1309 struct rtw_wifi_role_t *wifi_role;
1310 void *drv = phl_com->drv_priv;
1311 u8 bcn_id, role_idx, bcn_added;
1312
1313 role_idx = bcn_cmn->role_idx;
1314 if (role_idx > MAX_WIFI_ROLE_NUMBER) {
1315 PHL_ERR("%s: role idx err(%d)\n", __func__, role_idx);
1316 return RTW_PHL_STATUS_FAILURE;
1317 }
1318
1319 wifi_role = &phl_com->wifi_roles[role_idx];
1320 wrole_bcn_cmn = &wifi_role->bcn_cmn;
1321 bcn_added = wrole_bcn_cmn->bcn_added;
1322 _os_mem_cpy(drv, wrole_bcn_cmn, bcn_cmn, sizeof(struct rtw_bcn_info_cmn));
1323
1324 /* BCN add */
1325 if (!bcn_added) {
1326 if(phl_add_beacon(phl_info, wrole_bcn_cmn) == RTW_PHL_STATUS_SUCCESS) {
1327 wrole_bcn_cmn->bcn_added = true;
1328 return RTW_PHL_STATUS_SUCCESS;
1329 } else {
1330 return RTW_PHL_STATUS_FAILURE;
1331 }
1332 } else {
1333 /* BCN update */
1334 bcn_id = wrole_bcn_cmn->bcn_id;
1335 if(phl_update_beacon(phl_info, bcn_id) == RTW_PHL_STATUS_SUCCESS)
1336 return RTW_PHL_STATUS_SUCCESS;
1337 else
1338 return RTW_PHL_STATUS_FAILURE;
1339 }
1340 }
1341 #ifdef CONFIG_CMD_DISP
1342 enum rtw_phl_status
phl_cmd_issue_bcn_hdl(struct phl_info_t * phl_info,u8 * param)1343 phl_cmd_issue_bcn_hdl(struct phl_info_t *phl_info, u8 *param)
1344 {
1345 struct rtw_bcn_info_cmn *bcn_cmn = (struct rtw_bcn_info_cmn *)param;
1346
1347 return phl_issue_beacon(phl_info, bcn_cmn);
1348 }
1349
_phl_issue_bcn_done(void * drv_priv,u8 * buf,u32 buf_len,enum rtw_phl_status status)1350 static void _phl_issue_bcn_done(void *drv_priv, u8 *buf, u32 buf_len,
1351 enum rtw_phl_status status)
1352 {
1353 if (buf) {
1354 _os_kmem_free(drv_priv, buf, buf_len);
1355 buf = NULL;
1356 PHL_INFO("%s.....\n", __func__);
1357 }
1358 }
1359
1360 enum rtw_phl_status
rtw_phl_cmd_issue_beacon(void * phl,struct rtw_wifi_role_t * wifi_role,struct rtw_bcn_info_cmn * bcn_cmn,enum phl_cmd_type cmd_type,u32 cmd_timeout)1361 rtw_phl_cmd_issue_beacon(void *phl,
1362 struct rtw_wifi_role_t *wifi_role,
1363 struct rtw_bcn_info_cmn *bcn_cmn,
1364 enum phl_cmd_type cmd_type,
1365 u32 cmd_timeout)
1366 {
1367 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1368 void *drv = wifi_role->phl_com->drv_priv;
1369 enum rtw_phl_status psts = RTW_PHL_STATUS_FAILURE;
1370 struct rtw_bcn_info_cmn *param = NULL;
1371 u32 param_len;
1372
1373 if (cmd_type == PHL_CMD_DIRECTLY) {
1374 psts = phl_issue_beacon(phl_info, bcn_cmn);
1375 goto _exit;
1376 }
1377
1378 param_len = sizeof(struct rtw_bcn_info_cmn);
1379 param = _os_kmem_alloc(drv, param_len);
1380 if (param == NULL) {
1381 PHL_ERR("%s: alloc param failed!\n", __func__);
1382 goto _exit;
1383 }
1384
1385 _os_mem_cpy(drv, param, bcn_cmn, param_len);
1386
1387 psts = phl_cmd_enqueue(phl_info,
1388 wifi_role->hw_band,
1389 MSG_EVT_ISSUE_BCN,
1390 (u8 *)param, param_len,
1391 _phl_issue_bcn_done,
1392 cmd_type, cmd_timeout);
1393
1394 if (is_cmd_failure(psts)) {
1395 /* Send cmd success, but wait cmd fail*/
1396 psts = RTW_PHL_STATUS_FAILURE;
1397 } else if (psts != RTW_PHL_STATUS_SUCCESS) {
1398 /* Send cmd fail */
1399 _os_kmem_free(phl_to_drvpriv(phl_info), param, param_len);
1400 psts = RTW_PHL_STATUS_FAILURE;
1401 }
1402
1403 _exit:
1404 return psts;
1405 }
1406
1407 struct stop_bcn_param {
1408 struct rtw_wifi_role_t *wrole;
1409 u8 stop;
1410 };
1411
1412 enum rtw_phl_status
phl_cmd_stop_bcn_hdl(struct phl_info_t * phl_info,u8 * param)1413 phl_cmd_stop_bcn_hdl(struct phl_info_t *phl_info, u8 *param)
1414 {
1415 struct stop_bcn_param *bcn_param = (struct stop_bcn_param *)param;
1416
1417 return phl_beacon_stop(phl_info, bcn_param->wrole, bcn_param->stop);
1418 }
1419
1420
_phl_stop_bcn_done(void * drv_priv,u8 * buf,u32 buf_len,enum rtw_phl_status status)1421 static void _phl_stop_bcn_done(void *drv_priv, u8 *buf, u32 buf_len,
1422 enum rtw_phl_status status)
1423 {
1424 if (buf) {
1425 _os_kmem_free(drv_priv, buf, buf_len);
1426 buf = NULL;
1427 PHL_INFO("%s.....\n", __func__);
1428 }
1429 }
1430
1431
1432 enum rtw_phl_status
rtw_phl_cmd_stop_beacon(void * phl,struct rtw_wifi_role_t * wifi_role,u8 stop,enum phl_cmd_type cmd_type,u32 cmd_timeout)1433 rtw_phl_cmd_stop_beacon(void *phl,
1434 struct rtw_wifi_role_t *wifi_role,
1435 u8 stop,
1436 enum phl_cmd_type cmd_type,
1437 u32 cmd_timeout)
1438 {
1439 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1440 void *drv = wifi_role->phl_com->drv_priv;
1441 enum rtw_phl_status psts = RTW_PHL_STATUS_FAILURE;
1442 struct stop_bcn_param *param = NULL;
1443 u32 param_len;
1444
1445 if (cmd_type == PHL_CMD_DIRECTLY) {
1446 psts = phl_beacon_stop(phl_info, wifi_role, stop);
1447 goto _exit;
1448 }
1449
1450 param_len = sizeof(struct stop_bcn_param);
1451 param = _os_kmem_alloc(drv, param_len);
1452 if (param == NULL) {
1453 PHL_ERR("%s: alloc param failed!\n", __func__);
1454 goto _exit;
1455 }
1456
1457 param->wrole = wifi_role;
1458 param->stop = stop;
1459
1460 psts = phl_cmd_enqueue(phl_info,
1461 wifi_role->hw_band,
1462 MSG_EVT_STOP_BCN,
1463 (u8 *)param, param_len,
1464 _phl_stop_bcn_done,
1465 cmd_type, cmd_timeout);
1466
1467 if (is_cmd_failure(psts)) {
1468 /* Send cmd success, but wait cmd fail*/
1469 psts = RTW_PHL_STATUS_FAILURE;
1470 } else if (psts != RTW_PHL_STATUS_SUCCESS) {
1471 /* Send cmd fail */
1472 _os_kmem_free(phl_to_drvpriv(phl_info), param, param_len);
1473 psts = RTW_PHL_STATUS_FAILURE;
1474 }
1475 _exit:
1476 return psts;
1477 }
1478 #else /*for FSM*/
1479 enum rtw_phl_status
rtw_phl_cmd_stop_beacon(void * phl,struct rtw_wifi_role_t * wifi_role,u8 stop,enum phl_cmd_type cmd_type,u32 cmd_timeout)1480 rtw_phl_cmd_stop_beacon(void *phl,
1481 struct rtw_wifi_role_t *wifi_role,
1482 u8 stop,
1483 enum phl_cmd_type cmd_type,
1484 u32 cmd_timeout)
1485 {
1486 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1487
1488 return phl_beacon_stop(phl_info, wifi_role, stop);
1489 }
1490
1491 enum rtw_phl_status
rtw_phl_cmd_issue_beacon(void * phl,struct rtw_wifi_role_t * wifi_role,struct rtw_bcn_info_cmn * bcn_cmn,enum phl_cmd_type cmd_type,u32 cmd_timeout)1492 rtw_phl_cmd_issue_beacon(void *phl,
1493 struct rtw_wifi_role_t *wifi_role,
1494 struct rtw_bcn_info_cmn *bcn_cmn,
1495 enum phl_cmd_type cmd_type,
1496 u32 cmd_timeout)
1497 {
1498 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1499
1500 return phl_issue_beacon(phl_info, bcn_cmn);
1501 }
1502 #endif /*CONFIG_CMD_DISP*/
1503 #endif /*RTW_PHL_BCN*/
1504
rtw_phl_cap_pre_config(void * phl)1505 void rtw_phl_cap_pre_config(void *phl)
1506 {
1507 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1508 /* FW Pre-config */
1509 rtw_hal_fw_cap_pre_config(phl_info->phl_com,phl_info->hal);
1510 /* Bus Pre-config */
1511 rtw_hal_bus_cap_pre_config(phl_info->phl_com,phl_info->hal);
1512 }
1513
rtw_phl_preload(void * phl)1514 enum rtw_phl_status rtw_phl_preload(void *phl)
1515 {
1516 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1517 enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
1518
1519 #ifdef RTW_WKARD_PRELOAD_TRX_RESET
1520 struct phl_hci_trx_ops *ops = phl_info->hci_trx_ops;
1521 #endif
1522 FUNCIN();
1523
1524 hal_status = rtw_hal_preload(phl_info->phl_com, phl_info->hal);
1525
1526 #ifdef RTW_WKARD_PRELOAD_TRX_RESET
1527 ops->trx_reset(phl_info, PHL_CTRL_TX|PHL_CTRL_RX);
1528 #endif
1529 if (hal_status != RTW_HAL_STATUS_SUCCESS)
1530 return RTW_PHL_STATUS_FAILURE;
1531
1532 return RTW_PHL_STATUS_SUCCESS;
1533 }
1534
rtw_phl_start(void * phl)1535 enum rtw_phl_status rtw_phl_start(void *phl)
1536 {
1537 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1538 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
1539 enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
1540 #ifdef CONFIG_SYNC_INTERRUPT
1541 struct rtw_phl_evt_ops *evt_ops = &phl_info->phl_com->evt_ops;
1542 #endif /* CONFIG_SYNC_INTERRUPT */
1543
1544 hal_status = rtw_hal_start(phl_info->phl_com, phl_info->hal);
1545 if (hal_status == RTW_HAL_STATUS_MAC_INIT_FAILURE) {
1546 phl_status = RTW_PHL_STATUS_HAL_INIT_FAILURE;
1547 goto error_hal_start;
1548 } else if (hal_status == RTW_HAL_STATUS_BB_INIT_FAILURE) {
1549 phl_status = RTW_PHL_STATUS_HAL_INIT_FAILURE;
1550 goto error_hal_start;
1551 } else if (hal_status == RTW_HAL_STATUS_RF_INIT_FAILURE) {
1552 phl_status = RTW_PHL_STATUS_HAL_INIT_FAILURE;
1553 goto error_hal_start;
1554 } else if (hal_status == RTW_HAL_STATUS_BTC_INIT_FAILURE) {
1555 phl_status = RTW_PHL_STATUS_HAL_INIT_FAILURE;
1556 goto error_hal_start;
1557 } else if (hal_status != RTW_HAL_STATUS_SUCCESS) {
1558 phl_status = RTW_PHL_STATUS_HAL_INIT_FAILURE;
1559 goto error_hal_start;
1560 }
1561
1562 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
1563 /* if no need keep para buf, phl_com->dev_sw_cap->keep_para_info = false*/
1564 rtw_phl_init_free_para_buf(phl_info->phl_com);
1565 #endif
1566
1567 #ifdef CONFIG_FSM
1568 /* start FSM framework */
1569 phl_status = phl_fsm_start(phl_info);
1570 if (phl_status != RTW_PHL_STATUS_SUCCESS)
1571 goto error_phl_fsm_start;
1572
1573 /* start FSM modules */
1574 phl_status = phl_fsm_module_start(phl_info);
1575 if (phl_status != RTW_PHL_STATUS_SUCCESS)
1576 goto error_phl_fsm_module_start;
1577 #endif
1578 /* start modules */
1579 phl_status = phl_module_start(phl_info);
1580 if (phl_status != RTW_PHL_STATUS_SUCCESS)
1581 goto error_phl_module_start;
1582
1583 phl_status = phl_datapath_start(phl_info);
1584 if (phl_status != RTW_PHL_STATUS_SUCCESS)
1585 goto error_phl_datapath_start;
1586
1587 #ifdef CONFIG_SYNC_INTERRUPT
1588 evt_ops->set_interrupt_caps(phl_to_drvpriv(phl_info), true);
1589 #else
1590 rtw_hal_enable_interrupt(phl_info->phl_com, phl_info->hal);
1591 #endif /* CONFIG_SYNC_INTERRUPT */
1592
1593 phl_info->phl_com->dev_state = RTW_DEV_WORKING;
1594 phl_status = RTW_PHL_STATUS_SUCCESS;
1595
1596 return phl_status;
1597
1598 error_phl_datapath_start:
1599 phl_module_stop(phl_info);
1600 error_phl_module_start:
1601 #ifdef CONFIG_FSM
1602 phl_fsm_module_stop(phl_info);
1603 error_phl_fsm_module_start:
1604 phl_fsm_stop(phl_info);
1605 error_phl_fsm_start:
1606 #endif
1607 rtw_hal_stop(phl_info->phl_com, phl_info->hal);
1608 error_hal_start:
1609 return phl_status;
1610 }
1611
_phl_interrupt_stop(struct phl_info_t * phl_info)1612 static void _phl_interrupt_stop(struct phl_info_t *phl_info)
1613 {
1614 #ifdef CONFIG_SYNC_INTERRUPT
1615 struct rtw_phl_evt_ops *evt_ops = &phl_info->phl_com->evt_ops;
1616
1617 do {
1618 if (false == TEST_STATUS_FLAG(phl_info->phl_com->dev_state,
1619 RTW_DEV_SURPRISE_REMOVAL))
1620 evt_ops->set_interrupt_caps(phl_to_drvpriv(phl_info), false);
1621 } while (false);
1622 #else
1623 do {
1624 if (false == TEST_STATUS_FLAG(phl_info->phl_com->dev_state,
1625 RTW_DEV_SURPRISE_REMOVAL))
1626 rtw_hal_disable_interrupt(phl_info->phl_com, phl_info->hal);
1627 } while (false);
1628 #endif /* CONFIG_SYNC_INTERRUPT */
1629 }
1630
_phl_cmd_send_msg_phy_on(struct phl_info_t * phl_info)1631 static enum rtw_phl_status _phl_cmd_send_msg_phy_on(struct phl_info_t *phl_info)
1632 {
1633 enum rtw_phl_status sts = RTW_PHL_STATUS_FAILURE;
1634 #ifdef DBG_PHY_ON_TIME
1635 u32 phyon_start = 0, phyon_t = 0;
1636 #endif /* DBG_PHY_ON_TIME */
1637
1638 #ifdef DBG_PHY_ON_TIME
1639 phyon_start = _os_get_cur_time_ms();
1640 #endif /* DBG_PHY_ON_TIME */
1641
1642 sts = phl_cmd_enqueue(phl_info, HW_BAND_0, MSG_EVT_PHY_ON, NULL, 0, NULL,
1643 PHL_CMD_WAIT, 3000);
1644
1645 #ifdef DBG_PHY_ON_TIME
1646 phyon_t = phl_get_passing_time_ms(phyon_start);
1647 if (phyon_t > 1000) {
1648 PHL_TRACE(COMP_PHL_DBG, _PHL_WARNING_, "%s : phy on takes %u (ms).\n"
1649 , __func__, phyon_t);
1650 }
1651 #endif /* DBG_PHY_ON_TIME */
1652
1653 if (is_cmd_failure(sts)) {
1654 /* send cmd success, but wait cmd fail */
1655 sts = RTW_PHL_STATUS_FAILURE;
1656 } else if (sts != RTW_PHL_STATUS_SUCCESS) {
1657 /* send cmd fail */
1658 sts = RTW_PHL_STATUS_FAILURE;
1659 }
1660 return sts;
1661 }
1662
rtw_phl_stop(void * phl)1663 void rtw_phl_stop(void *phl)
1664 {
1665 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1666
1667 _phl_cmd_send_msg_phy_on(phl_info);
1668
1669 _phl_interrupt_stop(phl_info);
1670 phl_module_stop(phl_info);
1671
1672 #ifdef DBG_PHL_MR
1673 phl_mr_info_dbg(phl_info);
1674 #endif
1675
1676 #ifdef CONFIG_FSM
1677 phl_fsm_module_stop(phl_info);
1678 phl_fsm_stop(phl_info);
1679 #endif
1680
1681 rtw_hal_stop(phl_info->phl_com, phl_info->hal);
1682 phl_datapath_stop(phl_info);
1683
1684 phl_info->phl_com->dev_state = 0;
1685 }
1686
phl_wow_start(struct phl_info_t * phl_info,struct rtw_phl_stainfo_t * sta)1687 enum rtw_phl_status phl_wow_start(struct phl_info_t *phl_info, struct rtw_phl_stainfo_t *sta)
1688 {
1689 #ifdef CONFIG_WOWLAN
1690 enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
1691 enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
1692 struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
1693
1694 #ifdef CONFIG_SYNC_INTERRUPT
1695 struct rtw_phl_evt_ops *evt_ops = &phl_info->phl_com->evt_ops;
1696 #endif /* CONFIG_SYNC_INTERRUPT */
1697
1698 PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] %s enter with sta state(%d)\n.", __func__, sta->wrole->mstate);
1699
1700 phl_wow_decide_op_mode(wow_info, sta);
1701
1702 if (wow_info->op_mode == RTW_WOW_OP_PWR_DOWN) {
1703 phl_cmd_role_suspend(phl_info);
1704 rtw_phl_stop(phl_info);
1705 /* since control path stopped after rtw_phl_stop,
1706 below action don't have to migrate to general module */
1707 hstatus = rtw_hal_set_wowlan(phl_info->phl_com, phl_info->hal, true);
1708 if (RTW_HAL_STATUS_SUCCESS != hstatus)
1709 PHL_WARN("[wow] rtw_hal_set_wowlan failed, status(%u)\n", hstatus);
1710 pstatus = RTW_PHL_STATUS_SUCCESS;
1711 } else {
1712 /* stop all active features */
1713 #ifdef CONFIG_WOW_WITH_SER
1714 rtw_hal_ser_ctrl(phl_info->hal, false);
1715 #endif
1716
1717 pstatus = phl_module_stop(phl_info);
1718 if (RTW_PHL_STATUS_SUCCESS != pstatus) {
1719 PHL_ERR("[wow] phl_module_stop failed.\n");
1720 goto end;
1721 }
1722 /* since control path stopped after phl_module_stop,
1723 below action don't have to migrate to general module */
1724 #ifdef CONFIG_FSM
1725 pstatus = phl_fsm_module_stop(phl_info);
1726 if (RTW_PHL_STATUS_SUCCESS != pstatus) {
1727 PHL_ERR("[wow] phl_fsm_module_stop failed.\n");
1728 goto end;
1729 }
1730
1731 pstatus = phl_fsm_stop(phl_info);
1732 if (RTW_PHL_STATUS_SUCCESS != pstatus) {
1733 PHL_ERR("[wow] phl_fsm_stop failed.\n");
1734 goto end;
1735 }
1736 #endif
1737 hstatus = rtw_hal_set_wowlan(phl_info->phl_com, phl_info->hal, true);
1738 if (RTW_HAL_STATUS_SUCCESS != hstatus)
1739 PHL_WARN("[wow] rtw_hal_set_wowlan failed, status(%u)\n", hstatus);
1740 pstatus = phl_wow_init_precfg(wow_info);
1741 if (RTW_PHL_STATUS_SUCCESS != pstatus) {
1742 PHL_ERR("[wow] phl_wow_init_precfg failed.\n");
1743 goto end;
1744 }
1745
1746 hstatus = rtw_hal_wow_init(phl_info->phl_com, phl_info->hal, sta);
1747 if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1748 pstatus = RTW_PHL_STATUS_FAILURE;
1749 goto end;
1750 }
1751
1752 pstatus = phl_wow_func_en(wow_info);
1753 if (RTW_PHL_STATUS_SUCCESS != pstatus)
1754 goto end;
1755 #ifdef CONFIG_POWER_SAVE
1756 /* power saving */
1757 phl_wow_ps_proto_cfg(wow_info, true);
1758
1759 phl_wow_ps_pwr_ntfy(wow_info, true);
1760 #endif
1761 pstatus = phl_wow_init_postcfg(wow_info);
1762 if (RTW_PHL_STATUS_SUCCESS != pstatus) {
1763 PHL_ERR("[wow] phl_wow_init_postcfg failed.\n");
1764 goto end;
1765 }
1766 #ifdef CONFIG_WOW_WITH_SER
1767 rtw_hal_ser_ctrl(phl_info->hal, true);
1768 #endif
1769 #ifdef CONFIG_POWER_SAVE
1770 /* power saving */
1771 phl_wow_ps_pwr_cfg(wow_info, true);
1772 #endif
1773 pstatus = RTW_PHL_STATUS_SUCCESS;
1774 }
1775
1776 end:
1777 if (RTW_PHL_STATUS_SUCCESS != pstatus) {
1778 #ifdef CONFIG_SYNC_INTERRUPT
1779 evt_ops->set_interrupt_caps(phl_to_drvpriv(phl_info), false);
1780 #else
1781 rtw_hal_disable_interrupt(phl_info->phl_com, phl_info->hal);
1782 #endif /* CONFIG_SYNC_INTERRUPT */
1783 phl_role_suspend(phl_info);
1784 rtw_hal_stop(phl_info->phl_com, phl_info->hal);
1785 phl_datapath_stop(phl_info);
1786 wow_info->op_mode = RTW_WOW_OP_PWR_DOWN;
1787 PHL_ERR("[wow] %s fail, set op_mode %d!\n", __func__, wow_info->op_mode);
1788 } else {
1789 PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_,
1790 "[wow] %s success, with func_en %d, op_mode %d.\n",
1791 __func__, wow_info->func_en, wow_info->op_mode);
1792 }
1793
1794 return pstatus;
1795 #else
1796 return RTW_PHL_STATUS_SUCCESS;
1797 #endif /* CONFIG_WOWLAN */
1798 }
1799
_wow_stop_reinit(struct phl_info_t * phl_info)1800 static void _wow_stop_reinit(struct phl_info_t *phl_info)
1801 {
1802 enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
1803
1804 PHL_WARN("%s : reset hw!\n", __func__);
1805 phl_role_suspend(phl_info);
1806 rtw_hal_stop(phl_info->phl_com, phl_info->hal);
1807 phl_datapath_stop(phl_info);
1808 pstatus = rtw_phl_start(phl_info);
1809 if (pstatus)
1810 PHL_ERR("%s : rtw_phl_start fail!\n", __func__);
1811 phl_cmd_role_recover(phl_info);
1812
1813 }
1814
phl_wow_stop(struct phl_info_t * phl_info,struct rtw_phl_stainfo_t * sta,u8 * hw_reinit)1815 void phl_wow_stop(struct phl_info_t *phl_info, struct rtw_phl_stainfo_t *sta, u8 *hw_reinit)
1816 {
1817 #ifdef CONFIG_WOWLAN
1818 enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
1819 enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
1820 struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
1821 u8 reset = 0;
1822
1823 if (rtw_hal_get_pwr_state(phl_info->hal, &wow_info->mac_pwr)
1824 != RTW_HAL_STATUS_SUCCESS)
1825 return;
1826
1827 PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "%s enter with mac power %d\n.",
1828 __func__, wow_info->mac_pwr);
1829
1830 if (wow_info->mac_pwr != RTW_MAC_PWR_OFF) {
1831 #ifdef CONFIG_WOW_WITH_SER
1832 rtw_hal_ser_ctrl(phl_info->hal, false);
1833 #endif
1834 #ifdef CONFIG_POWER_SAVE
1835 /* leave clock/power gating */
1836 pstatus = phl_wow_ps_pwr_cfg(wow_info, false);
1837 if (RTW_PHL_STATUS_SUCCESS != pstatus) {
1838 PHL_ERR("[wow] HW leave power saving failed.\n");
1839 _wow_stop_reinit(phl_info);
1840 *hw_reinit = true;
1841 return;
1842 }
1843 #endif
1844 }
1845
1846 hstatus = rtw_hal_set_wowlan(phl_info->phl_com, phl_info->hal, false);
1847 if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1848 PHL_WARN("[wow] rtw_hal_set_wowlan failed, status(%u)\n", hstatus);
1849 }
1850
1851 if (wow_info->mac_pwr == RTW_MAC_PWR_OFF) {
1852 if (wow_info->op_mode == RTW_WOW_OP_PWR_DOWN) {
1853 pstatus = rtw_phl_start(phl_info);
1854 phl_role_recover(phl_info);
1855 *hw_reinit = true;
1856 } else {
1857 PHL_WARN("[wow] enter suspend with wow enabled but mac is power down\n");
1858 _wow_stop_reinit(phl_info);
1859 *hw_reinit = true;
1860 }
1861 } else if (wow_info->mac_pwr == RTW_MAC_PWR_ON ||
1862 wow_info->mac_pwr == RTW_MAC_PWR_LPS) {
1863
1864 phl_wow_handle_wake_rsn(wow_info, &reset);
1865 if (reset) {
1866 _wow_stop_reinit(phl_info);
1867 *hw_reinit = true;
1868 return;
1869 }
1870
1871 phl_wow_deinit_precfg(wow_info);
1872
1873 rtw_hal_fw_dbg_dump(phl_info->hal);
1874 #ifdef CONFIG_POWER_SAVE
1875 phl_wow_ps_pwr_ntfy(wow_info, false);
1876 /* leave power saving */
1877 phl_wow_ps_proto_cfg(wow_info, false);
1878 #endif
1879 phl_wow_func_dis(wow_info);
1880
1881 hstatus = rtw_hal_wow_deinit(phl_info->phl_com, phl_info->hal, sta);
1882 if (hstatus)
1883 PHL_ERR("%s : rtw_hal_wow_deinit failed.\n", __func__);
1884
1885 phl_module_start(phl_info);
1886 #ifdef CONFIG_FSM
1887 phl_fsm_start(phl_info);
1888 phl_fsm_module_start(phl_info);
1889 #endif
1890 phl_wow_deinit_postcfg(wow_info);
1891 #ifdef CONFIG_WOW_WITH_SER
1892 rtw_hal_ser_ctrl(phl_info->hal, true);
1893 #endif
1894 *hw_reinit = false;
1895 } else {
1896 PHL_ERR("%s : unexpected mac pwr state %d.\n", __func__, wow_info->mac_pwr);
1897 }
1898
1899 #endif /* CONFIG_WOWLAN */
1900 }
1901
rtw_phl_rf_on(void * phl)1902 enum rtw_phl_status rtw_phl_rf_on(void *phl)
1903 {
1904 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1905 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
1906 enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
1907 #ifdef CONFIG_SYNC_INTERRUPT
1908 struct rtw_phl_evt_ops *evt_ops = &phl_info->phl_com->evt_ops;
1909 #endif /* CONFIG_SYNC_INTERRUPT */
1910 struct phl_data_ctl_t ctl = {0};
1911
1912 hal_status = rtw_hal_start(phl_info->phl_com, phl_info->hal);
1913 if (hal_status == RTW_HAL_STATUS_MAC_INIT_FAILURE) {
1914 phl_status = RTW_PHL_STATUS_HAL_INIT_FAILURE;
1915 goto error_hal_start;
1916 } else if (hal_status == RTW_HAL_STATUS_BB_INIT_FAILURE) {
1917 phl_status = RTW_PHL_STATUS_HAL_INIT_FAILURE;
1918 goto error_hal_start;
1919 } else if (hal_status == RTW_HAL_STATUS_RF_INIT_FAILURE) {
1920 phl_status = RTW_PHL_STATUS_HAL_INIT_FAILURE;
1921 goto error_hal_start;
1922 } else if (hal_status == RTW_HAL_STATUS_BTC_INIT_FAILURE) {
1923 phl_status = RTW_PHL_STATUS_HAL_INIT_FAILURE;
1924 goto error_hal_start;
1925 }
1926
1927 phl_role_recover(phl_info);
1928 #ifdef CONFIG_SYNC_INTERRUPT
1929 evt_ops->set_interrupt_caps(phl_to_drvpriv(phl_info), true);
1930 #else
1931 rtw_hal_enable_interrupt(phl_info->phl_com, phl_info->hal);
1932 #endif /* CONFIG_SYNC_INTERRUPT */
1933
1934 ctl.id = PHL_MDL_POWER_MGNT;
1935 ctl.cmd = PHL_DATA_CTL_SW_TX_RESUME;
1936 if (phl_data_ctrler(phl_info, &ctl, NULL) != RTW_PHL_STATUS_SUCCESS)
1937 PHL_WARN("%s: tx resume fail!\n", __func__);
1938 ctl.cmd = PHL_DATA_CTL_SW_RX_RESUME;
1939 if (phl_data_ctrler(phl_info, &ctl, NULL) != RTW_PHL_STATUS_SUCCESS)
1940 PHL_WARN("%s: rx resume fail!\n", __func__);
1941
1942 return RTW_PHL_STATUS_SUCCESS;
1943 error_hal_start:
1944 PHL_ERR("error_hal_start\n");
1945 return phl_status;
1946 }
1947
1948 #define MAX_RF_OFF_STOP_TRX_TIME 100 /* ms */
rtw_phl_rf_off(void * phl)1949 enum rtw_phl_status rtw_phl_rf_off(void *phl)
1950 {
1951 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1952 #ifdef CONFIG_SYNC_INTERRUPT
1953 struct rtw_phl_evt_ops *evt_ops = &phl_info->phl_com->evt_ops;
1954 #endif /* CONFIG_SYNC_INTERRUPT */
1955 struct phl_data_ctl_t ctl = {0};
1956
1957 #ifdef CONFIG_SYNC_INTERRUPT
1958 evt_ops->set_interrupt_caps(phl_to_drvpriv(phl_info), false);
1959 #else
1960 rtw_hal_disable_interrupt(phl_info->phl_com, phl_info->hal);
1961 #endif /* CONFIG_SYNC_INTERRUPT */
1962
1963 ctl.id = PHL_MDL_POWER_MGNT;
1964 ctl.cmd = PHL_DATA_CTL_SW_TX_PAUSE;
1965 if (phl_data_ctrler(phl_info, &ctl, NULL) != RTW_PHL_STATUS_SUCCESS)
1966 PHL_WARN("%s: tx pause fail!\n", __func__);
1967 ctl.cmd = PHL_DATA_CTL_SW_RX_PAUSE;
1968 if (phl_data_ctrler(phl_info, &ctl, NULL) != RTW_PHL_STATUS_SUCCESS)
1969 PHL_WARN("%s: rx pause fail!\n", __func__);
1970
1971 phl_role_suspend(phl_info);
1972 rtw_hal_stop(phl_info->phl_com, phl_info->hal);
1973
1974 ctl.cmd = PHL_DATA_CTL_SW_TX_RESET;
1975 if (phl_data_ctrler(phl_info, &ctl, NULL) != RTW_PHL_STATUS_SUCCESS)
1976 PHL_WARN("%s: tx reset fail!\n", __func__);
1977 ctl.cmd = PHL_DATA_CTL_SW_RX_RESET;
1978 if (phl_data_ctrler(phl_info, &ctl, NULL) != RTW_PHL_STATUS_SUCCESS)
1979 PHL_WARN("%s: rx reset fail!\n", __func__);
1980
1981 return RTW_PHL_STATUS_SUCCESS;
1982 }
1983
rtw_phl_suspend(void * phl,struct rtw_phl_stainfo_t * sta,u8 wow_en)1984 enum rtw_phl_status rtw_phl_suspend(void *phl, struct rtw_phl_stainfo_t *sta, u8 wow_en)
1985 {
1986 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1987 enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
1988
1989 PHL_INFO("%s enter with wow_en(%d)\n.", __func__, wow_en);
1990 #ifdef CONFIG_WOWLAN
1991 pstatus = _phl_cmd_send_msg_phy_on(phl_info);
1992 if (RTW_PHL_STATUS_SUCCESS != pstatus) {
1993 PHL_ERR("[wow] _phl_cmd_send_msg_phy_on fail!\n");
1994 wow_en = false;
1995 }
1996
1997 if (wow_en) {
1998 pstatus = phl_wow_start(phl_info, sta);
1999 } else {
2000 phl_cmd_role_suspend(phl_info);
2001 rtw_phl_stop(phl);
2002 }
2003 #else
2004 PHL_INFO("%s enter with wow_en(%d)\n.", __func__, wow_en);
2005
2006 phl_cmd_role_suspend(phl_info);
2007 rtw_phl_stop(phl);
2008 #endif
2009
2010 FUNCOUT_WSTS(pstatus);
2011
2012 return pstatus;
2013 }
2014
rtw_phl_resume(void * phl,struct rtw_phl_stainfo_t * sta,u8 * hw_reinit)2015 enum rtw_phl_status rtw_phl_resume(void *phl, struct rtw_phl_stainfo_t *sta, u8 *hw_reinit)
2016 {
2017 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2018 enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
2019 #ifdef CONFIG_WOWLAN
2020 struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
2021 #endif
2022
2023 /**
2024 * Since some platforms require performance when device resuming, we need
2025 * to finish "rtw_phl_resume" as fast as possible. In this situation, we
2026 * prevent ps module entering any power saving mechanisms and try to do I/O
2027 * operations directly without issue commands to cmd dispatcher. Therefore,
2028 * ps module will not enter power saving if device state "RTW_DEV_RESUMING"
2029 * is set. If device state "RTW_DEV_RESUMING" is set, operations of I/O
2030 * should check whether the current power state can perform I/O or not and
2031 * perform I/O directly without issuing commands to cmd dispatcher if device
2032 * power state is I/O allowable. This kind of flow is only suitable for
2033 * "rtw_phl_resume" because core layer will not perform any other tasks when
2034 * calling rtw_phl_resume which is relatively simple enough.
2035 */
2036 PHL_INFO("%s enter...\n.", __func__);
2037 SET_STATUS_FLAG(phl_info->phl_com->dev_state, RTW_DEV_RESUMING);
2038
2039 #ifdef CONFIG_WOWLAN
2040 if (wow_info->op_mode != RTW_WOW_OP_NONE) {
2041 phl_wow_stop(phl_info, sta, hw_reinit);
2042 } else {
2043 pstatus = rtw_phl_start(phl);
2044 #ifdef CONFIG_POWER_SAVE
2045 if (phl_ps_get_cur_pwr_lvl(phl_info) == PS_PWR_LVL_PWRON)
2046 #endif
2047 phl_role_recover(phl_info);
2048 *hw_reinit = true;
2049 }
2050 #if defined(RTW_WKARD_WOW_L2_PWR) && defined(CONFIG_PCI_HCI)
2051 rtw_hal_set_l2_leave(phl_info->hal);
2052 #endif
2053 phl_record_wow_stat(wow_info);
2054 phl_reset_wow_info(wow_info);
2055 #else
2056 pstatus = rtw_phl_start(phl);
2057 #ifdef CONFIG_POWER_SAVE
2058 if (phl_ps_get_cur_pwr_lvl(phl_info) == PS_PWR_LVL_PWRON)
2059 #endif
2060 phl_role_recover(phl_info);
2061 *hw_reinit = true;
2062 #endif
2063
2064 CLEAR_STATUS_FLAG(phl_info->phl_com->dev_state, RTW_DEV_RESUMING);
2065
2066 PHL_INFO("%s exit with hw_reinit %d.\n.", __func__, *hw_reinit);
2067
2068 return pstatus;
2069 }
2070
rtw_phl_reset(void * phl)2071 enum rtw_phl_status rtw_phl_reset(void *phl)
2072 {
2073 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2074 struct phl_hci_trx_ops *ops = phl_info->hci_trx_ops;
2075 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
2076
2077 if(rtw_phl_is_init_completed(phl_info))
2078 phl_status = RTW_PHL_STATUS_SUCCESS;
2079
2080 rtw_hal_stop(phl_info->phl_com, phl_info->hal);
2081
2082 ops->trx_reset(phl_info, PHL_CTRL_TX|PHL_CTRL_RX);
2083 ops->trx_resume(phl_info, PHL_CTRL_TX|PHL_CTRL_RX);
2084
2085 rtw_hal_start(phl_info->phl_com, phl_info->hal);
2086 /* Leave power save */
2087 /* scan abort */
2088 /* STA disconnect/stop AP/Stop p2p function */
2089
2090 return phl_status;
2091 }
2092
rtw_phl_restart(void * phl)2093 enum rtw_phl_status rtw_phl_restart(void *phl)
2094 {
2095 enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
2096
2097 phl_status = RTW_PHL_STATUS_SUCCESS;
2098
2099 return phl_status;
2100 }
2101
2102
2103 /******************* IO APIs *******************/
rtw_phl_read8(void * phl,u32 addr)2104 u8 rtw_phl_read8(void *phl, u32 addr)
2105 {
2106 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2107
2108 return rtw_hal_read8(phl_info->hal, addr);
2109 }
rtw_phl_read16(void * phl,u32 addr)2110 u16 rtw_phl_read16(void *phl, u32 addr)
2111 {
2112 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2113
2114 return rtw_hal_read16(phl_info->hal, addr);
2115 }
rtw_phl_read32(void * phl,u32 addr)2116 u32 rtw_phl_read32(void *phl, u32 addr)
2117 {
2118 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2119
2120 return rtw_hal_read32(phl_info->hal, addr);
2121 }
rtw_phl_write8(void * phl,u32 addr,u8 val)2122 void rtw_phl_write8(void *phl, u32 addr, u8 val)
2123 {
2124 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2125
2126 rtw_hal_write8(phl_info->hal, addr, val);
2127 }
rtw_phl_write16(void * phl,u32 addr,u16 val)2128 void rtw_phl_write16(void *phl, u32 addr, u16 val)
2129 {
2130 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2131
2132 rtw_hal_write16(phl_info->hal, addr, val);
2133 }
rtw_phl_write32(void * phl,u32 addr,u32 val)2134 void rtw_phl_write32(void *phl, u32 addr, u32 val)
2135 {
2136 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2137
2138 rtw_hal_write32(phl_info->hal, addr, val);
2139 }
rtw_phl_read_macreg(void * phl,u32 offset,u32 bit_mask)2140 u32 rtw_phl_read_macreg(void *phl, u32 offset, u32 bit_mask)
2141 {
2142 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2143
2144 return rtw_hal_read_macreg(phl_info->hal, offset, bit_mask);
2145 }
rtw_phl_write_macreg(void * phl,u32 offset,u32 bit_mask,u32 data)2146 void rtw_phl_write_macreg(void *phl,
2147 u32 offset, u32 bit_mask, u32 data)
2148 {
2149 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2150
2151 rtw_hal_write_macreg(phl_info->hal, offset, bit_mask, data);
2152
2153 }
rtw_phl_read_bbreg(void * phl,u32 offset,u32 bit_mask)2154 u32 rtw_phl_read_bbreg(void *phl, u32 offset, u32 bit_mask)
2155 {
2156 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2157
2158 return rtw_hal_read_bbreg(phl_info->hal, offset, bit_mask);
2159 }
rtw_phl_write_bbreg(void * phl,u32 offset,u32 bit_mask,u32 data)2160 void rtw_phl_write_bbreg(void *phl,
2161 u32 offset, u32 bit_mask, u32 data)
2162 {
2163 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2164
2165 rtw_hal_write_bbreg(phl_info->hal, offset, bit_mask, data);
2166
2167 }
rtw_phl_read_rfreg(void * phl,enum rf_path path,u32 offset,u32 bit_mask)2168 u32 rtw_phl_read_rfreg(void *phl,
2169 enum rf_path path, u32 offset, u32 bit_mask)
2170 {
2171 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2172
2173 return rtw_hal_read_rfreg(phl_info->hal, path, offset, bit_mask);
2174 }
rtw_phl_write_rfreg(void * phl,enum rf_path path,u32 offset,u32 bit_mask,u32 data)2175 void rtw_phl_write_rfreg(void *phl,
2176 enum rf_path path, u32 offset, u32 bit_mask, u32 data)
2177 {
2178 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2179
2180 rtw_hal_write_rfreg(phl_info->hal, path, offset, bit_mask, data);
2181
2182 }
2183
rtw_phl_restore_interrupt(void * phl)2184 void rtw_phl_restore_interrupt(void *phl)
2185 {
2186 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2187 rtw_hal_restore_interrupt(phl_info->phl_com, phl_info->hal);
2188 }
2189
rtw_phl_interrupt_handler(void * phl)2190 enum rtw_phl_status rtw_phl_interrupt_handler(void *phl)
2191 {
2192 enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
2193 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2194 u32 int_hdler_msk = 0x0;
2195 #ifdef CONFIG_SYNC_INTERRUPT
2196 struct rtw_phl_evt_ops *ops = &phl_info->phl_com->evt_ops;
2197 #endif /* CONFIG_SYNC_INTERRUPT */
2198 int_hdler_msk = rtw_hal_interrupt_handler(phl_info->hal);
2199
2200 if (!int_hdler_msk) {
2201 PHL_WARN("%s : 0x%x\n", __func__, int_hdler_msk);
2202 phl_status = RTW_PHL_STATUS_FAILURE;
2203 goto end;
2204 }
2205
2206 PHL_DBG("%s : 0x%x\n", __func__, int_hdler_msk);
2207 /* beacon interrupt */
2208 if (int_hdler_msk & BIT0)
2209 ;/* todo */
2210
2211 /* rx interrupt */
2212 if (int_hdler_msk & BIT1) {
2213 #if defined(CONFIG_SDIO_HCI) && defined(CONFIG_PHL_SDIO_READ_RXFF_IN_INT)
2214 phl_info->hci_trx_ops->recv_rxfifo(phl);
2215 #else
2216
2217 #if defined(CONFIG_PCI_HCI)
2218 phl_info->hci_trx_ops->read_hw_rx(phl, RX_CH);
2219 #endif
2220 phl_status = rtw_phl_start_rx_process(phl);
2221 #endif
2222 }
2223
2224 /* tx interrupt */
2225 if (int_hdler_msk & BIT2)
2226 ;
2227
2228 /* cmd interrupt */
2229 if (int_hdler_msk & BIT3)
2230 ;/* todo */
2231
2232 /* halt c2h interrupt */
2233 if (int_hdler_msk & BIT4)
2234 phl_schedule_handler(phl_info->phl_com,
2235 &phl_info->phl_ser_handler);
2236
2237 /* halt c2h interrupt */
2238 if (int_hdler_msk & BIT5)
2239 phl_status = phl_fw_watchdog_timeout_notify(phl);
2240
2241 /* halt c2h interrupt - send msg to SER FSM to check ser event */
2242 if (int_hdler_msk & BIT6)
2243 phl_schedule_handler(phl_info->phl_com,
2244 &phl_info->phl_ser_handler);
2245
2246 if (int_hdler_msk & BIT7) {
2247 #if defined(CONFIG_PCI_HCI)
2248 phl_info->hci_trx_ops->read_hw_rx(phl, RP_CH);
2249 #endif
2250 phl_status = rtw_phl_start_rx_process(phl);
2251 phl_schedule_handler(phl_info->phl_com,
2252 &phl_info->phl_tx_handler);
2253 }
2254
2255 if (phl_status != RTW_PHL_STATUS_SUCCESS)
2256 PHL_INFO("rtw_phl_interrupt_handler fail !!\n");
2257
2258 end:
2259
2260 #ifdef CONFIG_SYNC_INTERRUPT
2261 ops->interrupt_restore(phl_to_drvpriv(phl_info), false);
2262 #endif
2263 return phl_status;
2264 }
2265
rtw_phl_enable_interrupt(void * phl)2266 void rtw_phl_enable_interrupt(void *phl)
2267 {
2268 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2269 rtw_hal_enable_interrupt(phl_info->phl_com, phl_info->hal);
2270 }
2271
rtw_phl_disable_interrupt(void * phl)2272 void rtw_phl_disable_interrupt(void *phl)
2273 {
2274 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2275 rtw_hal_disable_interrupt(phl_info->phl_com, phl_info->hal);
2276 }
2277
rtw_phl_recognize_interrupt(void * phl)2278 bool rtw_phl_recognize_interrupt(void *phl)
2279 {
2280 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2281
2282 return rtw_hal_recognize_interrupt(phl_info->hal);
2283 }
2284
rtw_phl_clear_interrupt(void * phl)2285 void rtw_phl_clear_interrupt(void *phl)
2286 {
2287 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2288
2289 rtw_hal_clear_interrupt(phl_info->hal);
2290 }
2291
rtw_phl_msg_hub_register_recver(void * phl,struct phl_msg_receiver * ctx,enum phl_msg_recver_layer layer)2292 enum rtw_phl_status rtw_phl_msg_hub_register_recver(void* phl,
2293 struct phl_msg_receiver* ctx, enum phl_msg_recver_layer layer)
2294 {
2295 return phl_msg_hub_register_recver(phl, ctx, layer);
2296 }
rtw_phl_msg_hub_update_recver_mask(void * phl,enum phl_msg_recver_layer layer,u8 * mdl_id,u32 len,u8 clr)2297 enum rtw_phl_status rtw_phl_msg_hub_update_recver_mask(void* phl,
2298 enum phl_msg_recver_layer layer, u8* mdl_id, u32 len, u8 clr)
2299 {
2300 return phl_msg_hub_update_recver_mask(phl, layer, mdl_id, len, clr);
2301 }
rtw_phl_msg_hub_deregister_recver(void * phl,enum phl_msg_recver_layer layer)2302 enum rtw_phl_status rtw_phl_msg_hub_deregister_recver(void* phl,
2303 enum phl_msg_recver_layer layer)
2304 {
2305 return phl_msg_hub_deregister_recver(phl, layer);
2306 }
rtw_phl_msg_hub_send(void * phl,struct phl_msg_attribute * attr,struct phl_msg * msg)2307 enum rtw_phl_status rtw_phl_msg_hub_send(void* phl,
2308 struct phl_msg_attribute* attr, struct phl_msg* msg)
2309 {
2310 return phl_msg_hub_send((struct phl_info_t*)phl, attr, msg);
2311 }
2312 #ifdef PHL_PLATFORM_LINUX
rtw_phl_mac_reg_dump(void * sel,void * phl)2313 void rtw_phl_mac_reg_dump(void *sel, void *phl)
2314 {
2315 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2316
2317 rtw_hal_mac_reg_dump(sel, phl_info->hal);
2318 }
2319
rtw_phl_bb_reg_dump(void * sel,void * phl)2320 void rtw_phl_bb_reg_dump(void *sel, void *phl)
2321 {
2322 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2323
2324 rtw_hal_bb_reg_dump(sel, phl_info->hal);
2325 }
2326
rtw_phl_bb_reg_dump_ex(void * sel,void * phl)2327 void rtw_phl_bb_reg_dump_ex(void *sel, void *phl)
2328 {
2329 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2330
2331 rtw_hal_bb_reg_dump_ex(sel, phl_info->hal);
2332 }
2333
rtw_phl_rf_reg_dump(void * sel,void * phl)2334 void rtw_phl_rf_reg_dump(void *sel, void *phl)
2335 {
2336 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2337
2338 rtw_hal_rf_reg_dump(sel, phl_info->hal);
2339 }
2340 #endif
2341
2342 /**
2343 * rtw_phl_get_sec_cam() - get the security cam raw data from HW
2344 * @phl: struct phl_info_t *
2345 * @num: How many cam you wnat to dump from the first one.
2346 * @buf: ptr to buffer which store the content from HW.
2347 * If buf is NULL, use console as debug path.
2348 * @size Size of allocated memroy for @buf.
2349 * The size should be @num * size of security cam offset(0x20).
2350 *
2351 * Return true when function successfully works, otherwise, return fail.
2352 */
rtw_phl_get_sec_cam(void * phl,u16 num,u8 * buf,u16 size)2353 bool rtw_phl_get_sec_cam(void *phl, u16 num, u8 *buf, u16 size)
2354 {
2355 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2356 enum rtw_hal_status ret = RTW_HAL_STATUS_SUCCESS;
2357
2358 ret = rtw_hal_get_sec_cam(phl_info->hal, num, buf, size);
2359 if (ret != RTW_HAL_STATUS_SUCCESS)
2360 return false;
2361
2362 return true;
2363 }
2364
2365 /**
2366 * rtw_phl_get_addr_cam() - get the address cam raw data from HW
2367 * @phl: struct phl_info_t *
2368 * @num: How many cam you wnat to dump from the first one.
2369 * @buf: ptr to buffer which store the content from HW.
2370 * If buf is NULL, use console as debug path.
2371 * @size Size of allocated memroy for @buf.
2372 * The size should be @num * size of Addr cam offset(0x40).
2373 *
2374 * Return true when function successfully works, otherwise, return fail.
2375 */
rtw_phl_get_addr_cam(void * phl,u16 num,u8 * buf,u16 size)2376 bool rtw_phl_get_addr_cam(void *phl, u16 num, u8 *buf, u16 size)
2377 {
2378 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2379 enum rtw_hal_status ret = RTW_HAL_STATUS_SUCCESS;
2380
2381 ret = rtw_hal_get_addr_cam(phl_info->hal, num, buf, size);
2382 if (ret != RTW_HAL_STATUS_SUCCESS)
2383 return false;
2384
2385 return true;
2386 }
2387
rtw_phl_mac_dbg_status_dump(void * phl,u32 * val,u8 * en)2388 void rtw_phl_mac_dbg_status_dump(void *phl, u32 *val, u8 *en)
2389 {
2390 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2391 struct hal_mac_dbg_dump_cfg cfg = {0};
2392
2393 cfg.ss_dbg_0 = val[0];
2394 cfg.ss_dbg_1 = val[1];
2395
2396 cfg.ss_dbg = (*en & BIT0);
2397 cfg.dle_dbg = (*en & BIT1) >> 1;
2398 cfg.dmac_dbg = (*en & BIT2) >> 2;
2399 cfg.cmac_dbg = (*en & BIT3) >> 3;
2400 cfg.mac_dbg_port = (*en & BIT4) >> 4;
2401 cfg.plersvd_dbg = (*en & BIT5) >> 5;
2402 cfg.tx_flow_dbg = (*en & BIT6) >> 6;
2403
2404 rtw_hal_dbg_status_dump(phl_info->hal, &cfg);
2405 }
2406
rtw_phl_get_mac_addr_efuse(void * phl,u8 * addr)2407 enum rtw_phl_status rtw_phl_get_mac_addr_efuse(void* phl, u8 *addr)
2408 {
2409 enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
2410 enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
2411 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2412 void *d = phl_to_drvpriv(phl_info);
2413 u8 addr_efuse[MAC_ADDRESS_LENGTH] = {0};
2414
2415 hstatus = rtw_hal_get_efuse_info(phl_info->hal,
2416 EFUSE_INFO_MAC_ADDR,
2417 (void *)addr_efuse,
2418 MAC_ADDRESS_LENGTH);
2419 if (is_broadcast_mac_addr(addr_efuse)) {
2420 PHL_INFO("[WARNING] MAC Address from EFUSE is FF:FF:FF:FF:FF:FF\n");
2421 hstatus = RTW_HAL_STATUS_FAILURE;
2422 }
2423 if (RTW_HAL_STATUS_SUCCESS != hstatus) {
2424 pstatus = RTW_PHL_STATUS_FAILURE;
2425 } else {
2426 _os_mem_cpy(d, addr, addr_efuse, MAC_ADDRESS_LENGTH);
2427 PHL_INFO("%s : 0x%2x - 0x%2x - 0x%2x - 0x%2x - 0x%2x - 0x%2x\n",
2428 __func__, addr[0], addr[1], addr[2],
2429 addr[3], addr[4], addr[5]);
2430
2431 }
2432 return pstatus;
2433 }
2434
2435 enum rtw_phl_status
rtw_phl_cfg_trx_path(void * phl,enum rf_path tx,u8 tx_nss,enum rf_path rx,u8 rx_nss)2436 rtw_phl_cfg_trx_path(void* phl, enum rf_path tx, u8 tx_nss,
2437 enum rf_path rx, u8 rx_nss)
2438 {
2439 enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
2440 enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
2441 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2442
2443 hstatus = rtw_hal_cfg_trx_path(phl_info->hal, tx, tx_nss, rx, rx_nss);
2444
2445 if (RTW_HAL_STATUS_SUCCESS != hstatus)
2446 pstatus = RTW_PHL_STATUS_FAILURE;
2447
2448 return pstatus;
2449 }
2450
2451
rtw_phl_reset_stat_ma_rssi(struct rtw_phl_com_t * phl_com)2452 void rtw_phl_reset_stat_ma_rssi(struct rtw_phl_com_t *phl_com)
2453 {
2454 u8 i = 0, j = 0;
2455 PHL_INFO("--> %s\n", __func__);
2456 do{
2457 if (NULL == phl_com)
2458 break;
2459
2460 _os_spinlock(phl_com->drv_priv,
2461 &(phl_com->rssi_stat.lock), _bh, NULL);
2462 for (i = 0; i < RTW_RSSI_TYPE_MAX; i++) {
2463 phl_com->rssi_stat.ma_rssi_ele_idx[i] = 0;
2464 phl_com->rssi_stat.ma_rssi_ele_cnt[i] = 0;
2465 phl_com->rssi_stat.ma_rssi_ele_sum[i] = 0;
2466 phl_com->rssi_stat.ma_rssi[i] = 0;
2467 for (j = 0; j < PHL_RSSI_MAVG_NUM; j++)
2468 phl_com->rssi_stat.ma_rssi_ele[i][j] = 0;
2469 }
2470 _os_spinunlock(phl_com->drv_priv,
2471 &(phl_com->rssi_stat.lock), _bh, NULL);
2472 } while (0);
2473
2474 PHL_INFO("<-- %s\n", __func__);
2475 }
2476
2477 u8
rtw_phl_get_ma_rssi(struct rtw_phl_com_t * phl_com,enum rtw_rssi_type rssi_type)2478 rtw_phl_get_ma_rssi(struct rtw_phl_com_t *phl_com,
2479 enum rtw_rssi_type rssi_type)
2480 {
2481
2482 u8 ret = 0;
2483 if (NULL == phl_com)
2484 return ret;
2485
2486 _os_spinlock(phl_com->drv_priv,
2487 &(phl_com->rssi_stat.lock), _bh, NULL);
2488 ret = phl_com->rssi_stat.ma_rssi[rssi_type];
2489 _os_spinunlock(phl_com->drv_priv,
2490 &(phl_com->rssi_stat.lock), _bh, NULL);
2491
2492 return ret;
2493 }
2494
2495 #ifdef RTW_WKARD_DYNAMIC_BFEE_CAP
2496 enum rtw_phl_status
rtw_phl_bfee_ctrl(void * phl,struct rtw_wifi_role_t * wrole,bool ctrl)2497 rtw_phl_bfee_ctrl(void *phl, struct rtw_wifi_role_t *wrole, bool ctrl)
2498 {
2499 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
2500 enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
2501 if (RTW_HAL_STATUS_SUCCESS !=
2502 rtw_hal_bf_bfee_ctrl(phl_info->hal, wrole->hw_band, ctrl)) {
2503 pstatus = RTW_PHL_STATUS_FAILURE;
2504 }
2505 return pstatus;
2506 }
2507 #endif
2508
2509 u8
rtw_phl_get_sta_mgnt_rssi(struct rtw_phl_stainfo_t * psta)2510 rtw_phl_get_sta_mgnt_rssi(struct rtw_phl_stainfo_t *psta)
2511 {
2512 u8 ret = PHL_MAX_RSSI;
2513
2514 if (psta != NULL) {
2515 ret = psta->hal_sta->rssi_stat.ma_rssi_mgnt;
2516 }
2517
2518 return ret;
2519 }
2520