1 /******************************************************************************
2 *
3 * Copyright(c) 2019 - 2021 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 _RTW_PHL_C_
16 #include <drv_types.h>
17
18
19 /***************** export API to osdep/core*****************/
20
21 static const char *const _band_cap_str[] = {
22 /* BIT0 */"2G",
23 /* BIT1 */"5G",
24 /* BIT2 */"6G",
25 };
26
27 static const char *const _bw_cap_str[] = {
28 /* BIT0 */"20M",
29 /* BIT1 */"40M",
30 /* BIT2 */"80M",
31 /* BIT3 */"160M",
32 /* BIT4 */"80_80M",
33 /* BIT5 */"5M",
34 /* BIT6 */"10M",
35 };
36
37 static const char *const _proto_cap_str[] = {
38 /* BIT0 */"b",
39 /* BIT1 */"g",
40 /* BIT2 */"n",
41 /* BIT3 */"ac",
42 };
43
44 static const char *const _wl_func_str[] = {
45 /* BIT0 */"P2P",
46 /* BIT1 */"MIRACAST",
47 /* BIT2 */"TDLS",
48 /* BIT3 */"FTM",
49 };
50
51 static const char *const hw_cap_str = "[HW-CAP]";
rtw_hw_dump_hal_spec(void * sel,struct dvobj_priv * dvobj)52 void rtw_hw_dump_hal_spec(void *sel, struct dvobj_priv *dvobj)
53 {
54 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj);
55 int i;
56
57 RTW_PRINT_SEL(sel, "%s ic_name:%s\n", hw_cap_str, hal_spec->ic_name);
58 RTW_PRINT_SEL(sel, "%s macid_num:%u\n", hw_cap_str, hal_spec->macid_num);
59 RTW_PRINT_SEL(sel, "%s sec_cap:0x%02x\n", hw_cap_str, hal_spec->sec_cap);
60 RTW_PRINT_SEL(sel, "%s sec_cam_ent_num:%u\n", hw_cap_str, hal_spec->sec_cam_ent_num);
61
62 RTW_PRINT_SEL(sel, "%s rfpath_num_2g:%u\n", hw_cap_str, hal_spec->rfpath_num_2g);
63 RTW_PRINT_SEL(sel, "%s rfpath_num_5g:%u\n", hw_cap_str, hal_spec->rfpath_num_5g);
64 RTW_PRINT_SEL(sel, "%s rf_reg_path_num:%u\n", hw_cap_str, hal_spec->rf_reg_path_num);
65 RTW_PRINT_SEL(sel, "%s max_tx_cnt:%u\n", hw_cap_str, hal_spec->max_tx_cnt);
66
67 RTW_PRINT_SEL(sel, "%s band_cap:", hw_cap_str);
68 for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
69 if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
70 _RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
71 }
72 _RTW_PRINT_SEL(sel, "\n");
73
74 RTW_PRINT_SEL(sel, "%s bw_cap:", hw_cap_str);
75 for (i = 0; i < BW_CAP_BIT_NUM; i++) {
76 if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
77 _RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
78 }
79 _RTW_PRINT_SEL(sel, "\n");
80
81 RTW_PRINT_SEL(sel, "%s proto_cap:", hw_cap_str);
82 for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
83 if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
84 _RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
85 }
86 _RTW_PRINT_SEL(sel, "\n");
87
88 #if 0 /*GEORGIA_TODO_FIXIT*/
89 RTW_PRINT_SEL(sel, "%s txgi_max:%u\n", hw_cap_str, hal_spec->txgi_max);
90 RTW_PRINT_SEL(sel, "%s txgi_pdbm:%u\n", hw_cap_str, hal_spec->txgi_pdbm);
91 #endif
92 RTW_PRINT_SEL(sel, "%s wl_func:", hw_cap_str);
93 for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
94 if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
95 _RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
96 }
97 _RTW_PRINT_SEL(sel, "\n");
98
99 #if 0 /*GEORGIA_TODO_FIXIT*/
100
101 RTW_PRINT_SEL(sel, "%s pg_txpwr_saddr:0x%X\n", hw_cap_str, hal_spec->pg_txpwr_saddr);
102 RTW_PRINT_SEL(sel, "%s pg_txgi_diff_factor:%u\n", hw_cap_str, hal_spec->pg_txgi_diff_factor);
103 #endif
104 }
105
rtw_dump_phl_sta_info(void * sel,struct sta_info * sta)106 void rtw_dump_phl_sta_info(void *sel, struct sta_info *sta)
107 {
108 struct rtw_phl_stainfo_t *phl_sta = sta->phl_sta;
109
110 RTW_PRINT_SEL(sel, "[PHL STA]- role-idx: %d\n", phl_sta->wrole->id);
111
112 RTW_PRINT_SEL(sel, "[PHL STA]- mac_addr:"MAC_FMT"\n", MAC_ARG(phl_sta->mac_addr));
113 RTW_PRINT_SEL(sel, "[PHL STA]- aid: %d\n", phl_sta->aid);
114 RTW_PRINT_SEL(sel, "[PHL STA]- macid: %d\n", phl_sta->macid);
115
116 RTW_PRINT_SEL(sel, "[PHL STA]- wifi_band: %d\n", phl_sta->chandef.band);
117 RTW_PRINT_SEL(sel, "[PHL STA]- bw: %d\n", phl_sta->chandef.bw);
118 RTW_PRINT_SEL(sel, "[PHL STA]- chan: %d\n", phl_sta->chandef.chan);
119 RTW_PRINT_SEL(sel, "[PHL STA]- offset: %d\n", phl_sta->chandef.offset);
120 }
121
rtw_hw_chk_band_cap(struct dvobj_priv * dvobj,u8 cap)122 inline bool rtw_hw_chk_band_cap(struct dvobj_priv *dvobj, u8 cap)
123 {
124 return GET_HAL_SPEC(dvobj)->band_cap & cap;
125 }
126
rtw_hw_chk_bw_cap(struct dvobj_priv * dvobj,u8 cap)127 inline bool rtw_hw_chk_bw_cap(struct dvobj_priv *dvobj, u8 cap)
128 {
129 return GET_HAL_SPEC(dvobj)->bw_cap & cap;
130 }
131
rtw_hw_chk_proto_cap(struct dvobj_priv * dvobj,u8 cap)132 inline bool rtw_hw_chk_proto_cap(struct dvobj_priv *dvobj, u8 cap)
133 {
134 return GET_HAL_SPEC(dvobj)->proto_cap & cap;
135 }
136
rtw_hw_chk_wl_func(struct dvobj_priv * dvobj,u8 func)137 inline bool rtw_hw_chk_wl_func(struct dvobj_priv *dvobj, u8 func)
138 {
139 return GET_HAL_SPEC(dvobj)->wl_func & func;
140 }
141
rtw_hw_is_band_support(struct dvobj_priv * dvobj,u8 band)142 inline bool rtw_hw_is_band_support(struct dvobj_priv *dvobj, u8 band)
143 {
144 return GET_HAL_SPEC(dvobj)->band_cap & band_to_band_cap(band);
145 }
146
rtw_hw_is_bw_support(struct dvobj_priv * dvobj,u8 bw)147 inline bool rtw_hw_is_bw_support(struct dvobj_priv *dvobj, u8 bw)
148 {
149 return GET_HAL_SPEC(dvobj)->bw_cap & ch_width_to_bw_cap(bw);
150 }
151
rtw_hw_is_wireless_mode_support(struct dvobj_priv * dvobj,u8 mode)152 inline bool rtw_hw_is_wireless_mode_support(struct dvobj_priv *dvobj, u8 mode)
153 {
154 u8 proto_cap = GET_HAL_SPEC(dvobj)->proto_cap;
155
156 if (mode == WLAN_MD_11B)
157 if ((proto_cap & PROTO_CAP_11B) && rtw_hw_chk_band_cap(dvobj, BAND_CAP_2G))
158 return 1;
159
160 if (mode == WLAN_MD_11G)
161 if ((proto_cap & PROTO_CAP_11G) && rtw_hw_chk_band_cap(dvobj, BAND_CAP_2G))
162 return 1;
163
164 if (mode == WLAN_MD_11A)
165 if ((proto_cap & PROTO_CAP_11G) && rtw_hw_chk_band_cap(dvobj, BAND_CAP_5G))
166 return 1;
167
168 #ifdef CONFIG_80211N_HT
169 if (mode == WLAN_MD_11N)
170 if (proto_cap & PROTO_CAP_11N)
171 return 1;
172 #endif
173
174 #ifdef CONFIG_80211AC_VHT
175 if (mode == WLAN_MD_11AC)
176 if ((proto_cap & PROTO_CAP_11AC) && rtw_hw_chk_band_cap(dvobj, BAND_CAP_5G))
177 return 1;
178 #endif
179
180 #ifdef CONFIG_80211AX_HE
181 if (mode == WLAN_MD_11AX)
182 if (proto_cap & PROTO_CAP_11AX)
183 return 1;
184 #endif
185 return 0;
186 }
187
188
rtw_hw_get_wireless_mode(struct dvobj_priv * dvobj)189 inline u8 rtw_hw_get_wireless_mode(struct dvobj_priv *dvobj)
190 {
191 u8 proto_cap = GET_HAL_SPEC(dvobj)->proto_cap;
192 u8 band_cap = GET_HAL_SPEC(dvobj)->band_cap;
193 u8 wireless_mode = 0;
194
195 if(proto_cap & PROTO_CAP_11B)
196 wireless_mode |= WLAN_MD_11B;
197
198 if(proto_cap & PROTO_CAP_11G)
199 wireless_mode |= WLAN_MD_11G;
200
201 if(band_cap & BAND_CAP_5G)
202 wireless_mode |= WLAN_MD_11A;
203
204 #ifdef CONFIG_80211N_HT
205 if(proto_cap & PROTO_CAP_11N)
206 wireless_mode |= WLAN_MD_11N;
207 #endif
208
209 #ifdef CONFIG_80211AC_VHT
210 if(proto_cap & PROTO_CAP_11AC)
211 wireless_mode |= WLAN_MD_11AC;
212 #endif
213
214 #ifdef CONFIG_80211AX_HE
215 if(proto_cap & PROTO_CAP_11AX) {
216 wireless_mode |= WLAN_MD_11AX;
217 }
218 #endif
219
220 return wireless_mode;
221 }
222
rtw_hw_get_band_type(struct dvobj_priv * dvobj)223 inline u8 rtw_hw_get_band_type(struct dvobj_priv *dvobj)
224 {
225 u8 band_cap = GET_HAL_SPEC(dvobj)->band_cap;
226 u8 band_type = 0;
227
228 if(band_cap & BAND_CAP_2G)
229 band_type |= BAND_CAP_2G;
230
231 #if CONFIG_IEEE80211_BAND_5GHZ
232 if(band_cap & BAND_CAP_5G)
233 band_type |= BAND_CAP_5G;
234 #endif
235
236 #if CONFIG_IEEE80211_BAND_6GHZ
237 if(band_cap & BAND_CAP_6G)
238 band_type |= BAND_CAP_6G;
239 #endif
240
241 return band_type;
242 }
243
rtw_hw_is_mimo_support(_adapter * adapter)244 inline bool rtw_hw_is_mimo_support(_adapter *adapter)
245 {
246 if ((get_phy_tx_nss(adapter) == 1) &&
247 (get_phy_rx_nss(adapter) == 1))
248 return 0;
249 return 1;
250 }
251
252 /*
253 * rtw_hw_largest_bw - starting from in_bw, get largest bw supported by HAL
254 * @adapter:
255 * @in_bw: starting bw, value of enum channel_width
256 *
257 * Returns: value of enum channel_width
258 */
rtw_hw_largest_bw(struct dvobj_priv * dvobj,u8 in_bw)259 u8 rtw_hw_largest_bw(struct dvobj_priv *dvobj, u8 in_bw)
260 {
261 for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
262 if (rtw_hw_is_bw_support(dvobj, in_bw))
263 break;
264 }
265
266 if (!rtw_hw_is_bw_support(dvobj, in_bw))
267 rtw_warn_on(1);
268
269 return in_bw;
270 }
271
rtw_hw_get_mac_addr(struct dvobj_priv * dvobj,u8 * hw_mac_addr)272 u8 rtw_hw_get_mac_addr(struct dvobj_priv *dvobj, u8 *hw_mac_addr)
273 {
274 if (rtw_phl_get_mac_addr_efuse(dvobj->phl, hw_mac_addr) != RTW_PHL_STATUS_SUCCESS) {
275 RTW_ERR("%s failed\n", __func__);
276 return _FAIL;
277 }
278 return _SUCCESS;
279 }
280
281
282 /***************** register hw *****************/
283 #if 0 /*GEORGIA_TODO_ADDIT*/
284
285 #define hal_trx_error_msg(ops_fun) \
286 RTW_PRINT("### %s - Error : Please hook hal_trx_ops.%s ###\n", __FUNCTION__, ops_fun)
287 static u8 rtw_hw_trx_ops_check(struct hal_com_t *hal_com)
288 {
289 u8 rst = _SUCCESS;
290
291 if (!hal_com->trx_ops.intf_hal_configure) {
292 hal_trx_error_msg("intf_hal_configure");
293 rst = _FAIL;
294 }
295
296 if (!hal_com->trx_ops.get_txdesc_len) {
297 hal_trx_error_msg("get_txdesc_len");
298 rst = _FAIL;
299 }
300 if (!hal_com->trx_ops.fill_txdesc_h2c) {
301 hal_trx_error_msg("fill_txdesc_h2c");
302 rst = _FAIL;
303 }
304 if (!hal_com->trx_ops.fill_txdesc_fwdl) {
305 hal_trx_error_msg("fill_txdesc_fwdl");
306 rst = _FAIL;
307 }
308 if (!hal_com->trx_ops.fill_txdesc_pkt) {
309 hal_trx_error_msg("fill_txdesc_pkt");
310 rst = _FAIL;
311 }
312
313 #if defined(CONFIG_USB_HCI)
314 if (!hal_com->trx_ops.get_bulkout_id) {
315 hal_trx_error_msg("get_bulkout_id");
316 rst = _FAIL;
317 }
318 #endif
319
320 #if 0 /*GEORGIA_TODO_ADDIT*/
321 if (!hal_com->trx_ops.init_xmit) {
322 hal_trx_error_msg("init_xmit");
323 rst = _FAIL;
324 }
325
326 if (!hal_com->trx_ops.init_recv) {
327 hal_trx_error_msg("init_recv");
328 rst = _FAIL;
329 }
330
331 #if defined(CONFIG_PCI_HCI)
332 if (!hal_com->trx_ops.check_enough_txdesc) {
333 hal_trx_error_msg("check_enough_txdesc");
334 rst = _FAIL;
335 }
336 if (!hal_com->trx_ops.trxbd_init) {
337 hal_trx_error_msg("trxbd_init");
338 rst = _FAIL;
339 }
340 if (!hal_com->trx_ops.trxbd_deinit) {
341 hal_trx_error_msg("trxbd_deinit");
342 rst = _FAIL;
343 }
344 if (!hal_com->trx_ops.trxbd_reset) {
345 hal_trx_error_msg("trxbd_reset");
346 rst = _FAIL;
347 }
348 if (!hal_com->trx_ops.interrupt_handler) {
349 hal_trx_error_msg("interrupt_handler");
350 rst = _FAIL;
351 }
352 #endif
353
354 #if defined(CONFIG_USB_HCI)
355 #ifdef CONFIG_SUPPORT_USB_INT
356 if (!hal_com->trx_ops.interrupt_handler) {
357 hal_trx_error_msg("interrupt_handler");
358 rst = _FAIL;
359 }
360 #endif
361 #endif
362
363 if (!hal_com->trx_ops.enable_interrupt) {
364 hal_trx_error_msg("enable_interrupt");
365 rst = _FAIL;
366 }
367 if (!hal_com->trx_ops.disable_interrupt) {
368 hal_trx_error_msg("disable_interrupt");
369 rst = _FAIL;
370 }
371
372 #if defined(CONFIG_SDIO_HCI)
373 if (!hal_com->trx_ops.interrupt_handler) {
374 hal_trx_error_msg("interrupt_handler");
375 rst = _FAIL;
376 }
377 if (!hal_com->trx_ops.get_tx_addr) {
378 hal_trx_error_msg("get_tx_addr");
379 rst = _FAIL;
380 }
381 #endif
382 #endif
383 return rst;
384 }
385 #endif
386
rtw_core_deregister_phl_msg(struct dvobj_priv * dvobj)387 u8 rtw_core_deregister_phl_msg(struct dvobj_priv *dvobj)
388 {
389 enum rtw_phl_status psts = RTW_PHL_STATUS_FAILURE;
390
391 psts = rtw_phl_msg_hub_deregister_recver(dvobj->phl, MSG_RECV_CORE);
392 if(psts == RTW_PHL_STATUS_FAILURE) {
393 RTW_ERR("%s failed\n", __func__);
394 return _FAIL;
395 }
396 return _SUCCESS;
397 }
398
rtw_hw_deinit(struct dvobj_priv * dvobj)399 void rtw_hw_deinit(struct dvobj_priv *dvobj)
400 {
401 if (dvobj->phl) {
402 rtw_phl_trx_free(dvobj->phl);
403 rtw_core_deregister_phl_msg(dvobj);
404 rtw_phl_watchdog_deinit(dvobj->phl);
405 rtw_clear_phl_regulation_ctx(dvobj);
406 rtw_phl_deinit(dvobj->phl);
407 }
408
409 #ifdef DBG_PHL_MEM_ALLOC
410 RTW_INFO("[PHL-MEM] %s PHL memory :%d\n", __func__,
411 ATOMIC_READ(&(dvobj->phl_mem)));
412 #endif
413 }
414
415 #if 0
416 void dump_ic_spec(struct dvobj_priv *dvobj)
417 {
418 struct hal_com_t *hal_com = dvobj->hal_com;
419 struct hal_spec_t *hal_spec = &hal_com->hal_spec;
420
421 RTW_INFO("dvobj:%p,hal:%p(size:%d), hal_com:%p, hal_spec:%p\n",
422 dvobj, dvobj->hal_info, dvobj->hal_info_sz, hal_com, hal_spec);
423 RTW_INFO("dvobj:%p, hal_com:%p, hal_spec:%p\n", dvobj, GET_PHL_COM(dvobj), GET_HAL_SPEC(dvobj));
424
425 RTW_INFO("[IC-SPEC]- band_cap: %x\n", GET_HAL_SPEC(dvobj)->band_cap);
426 }
427 #endif
428
429 #if 0 /*GEORGIA_TODO_FIXIT*/
430 void rtw_hw_intf_cfg(struct dvobj_priv *dvobj, struct hal_com_t *hal_com)
431 {
432 struct hci_info_st hci_info;
433
434 #ifdef CONFIG_PCI_HCI
435 if (dvobj->interface_type == RTW_HCI_PCIE) {
436 PPCI_DATA pci = dvobj_to_pci(dvobj);
437 //hci_info.
438 }
439 #endif
440
441 #ifdef CONFIG_USB_HCI
442 if (dvobj->interface_type == RTW_HCI_USB) {
443 PUSB_DATA usb = dvobj_to_usb(dvobj);
444 #if 0
445 u8 usb_speed; /* 1.1, 2.0 or 3.0 */
446 u16 usb_bulkout_size;
447 u8 nr_endpoint; /*MAX_ENDPOINT_NUM*/
448
449 /* Bulk In , Out Pipe information */
450 int RtInPipe[MAX_BULKIN_NUM];
451 u8 RtNumInPipes;
452 int RtOutPipe[MAX_BULKOUT_NUM];
453 u8 RtNumOutPipes;
454 #endif
455 //hci_info
456 }
457 #endif
458
459 #ifdef CONFIG_SDIO_HCI
460 if (dvobj->interface_type == RTW_HCI_SDIO) {
461 PSDIO_DATA sdio = dvobj_to_sdio(dvobj);
462
463 hci_info.clock = sdio->clock;
464 hci_info.timing = sdio->timing;
465 hci_info.sd3_bus_mode = sdio->sd3_bus_mode;
466 hci_info.block_sz = sdio->block_transfer_len;
467 hci_info.align_sz = sdio->block_transfer_len;
468 }
469 #endif
470
471 rtw_hal_intf_config(hal_com, &hci_info);
472 }
473 #endif
474
_hw_ic_info_cfg(struct dvobj_priv * dvobj,struct rtw_ic_info * ic_info)475 static void _hw_ic_info_cfg(struct dvobj_priv *dvobj, struct rtw_ic_info *ic_info)
476 {
477 _rtw_memset(ic_info, 0,sizeof(struct rtw_ic_info));
478
479 ic_info->ic_id = dvobj->ic_id;
480 ic_info->hci_type = dvobj->interface_type;
481
482 #ifdef CONFIG_PCI_HCI
483 if (dvobj->interface_type == RTW_HCI_PCIE) {
484 PPCI_DATA pci = dvobj_to_pci(dvobj);
485
486 }
487 #endif
488
489 #ifdef CONFIG_USB_HCI
490 if (dvobj->interface_type == RTW_HCI_USB) {
491 PUSB_DATA usb = dvobj_to_usb(dvobj);
492
493 ic_info->usb_info.usb_speed = usb->usb_speed;
494 ic_info->usb_info.usb_bulkout_size = usb->usb_bulkout_size;
495 ic_info->usb_info.inep_num = usb->RtNumInPipes;
496 ic_info->usb_info.outep_num = usb->RtNumOutPipes;
497 }
498 #endif
499
500 #ifdef CONFIG_SDIO_HCI
501 if (dvobj->interface_type == RTW_HCI_SDIO) {
502 PSDIO_DATA sdio = dvobj_to_sdio(dvobj);
503
504 ic_info->sdio_info.clock = sdio->clock;
505 ic_info->sdio_info.timing = sdio->timing;
506 ic_info->sdio_info.sd3_bus_mode = sdio->sd3_bus_mode;
507 ic_info->sdio_info.io_align_sz = 4;
508 ic_info->sdio_info.block_sz = sdio->block_transfer_len;
509 ic_info->sdio_info.tx_align_sz = sdio->block_transfer_len;
510 ic_info->sdio_info.tx_512_by_byte_mode =
511 (sdio->max_byte_size >= 512) ? true : false;
512 }
513 #endif
514 }
core_hdl_phl_evt(struct dvobj_priv * dvobj,u16 evt_id)515 static void core_hdl_phl_evt(struct dvobj_priv *dvobj, u16 evt_id)
516 {
517 _adapter *iface;
518 u8 i = 0;
519
520 if(evt_id == MSG_EVT_BCN_RESEND) {
521 for (i = 0; i < dvobj->iface_nums; i++) {
522 iface = dvobj->padapters[i];
523 if(!rtw_is_adapter_up(iface))
524 continue;
525
526 if(MLME_IS_MESH(iface)
527 || MLME_IS_AP(iface)
528 || MLME_IS_ADHOC_MASTER(iface)) {
529 if (send_beacon(iface) == _FAIL)
530 RTW_ERR(ADPT_FMT" issue_beacon, fail!\n",
531 ADPT_ARG(iface));
532 }
533 }
534 }
535 else if (evt_id == MSG_EVT_SER_L2) {
536 RTW_INFO("RECV PHL MSG_EVT_SER_L2\n");
537 }
538 #ifdef CONFIG_XMIT_ACK
539 else if (evt_id == MSG_EVT_CCX_REPORT_TX_OK) {
540 iface = dvobj_get_primary_adapter(dvobj);
541 rtw_ack_tx_done(&iface->xmitpriv, RTW_SCTX_DONE_SUCCESS);
542 }
543 else if (evt_id == MSG_EVT_CCX_REPORT_TX_FAIL) {
544 iface = dvobj_get_primary_adapter(dvobj);
545 rtw_ack_tx_done(&iface->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
546 }
547 #endif
548 else {
549 RTW_INFO("%s evt_id :%d\n", __func__, evt_id);
550 }
551 }
552
core_handler_phl_msg(void * drv_priv,struct phl_msg * msg)553 void core_handler_phl_msg(void *drv_priv, struct phl_msg *msg)
554 {
555 struct dvobj_priv *dvobj = (struct dvobj_priv *)drv_priv;
556 u8 mdl_id = MSG_MDL_ID_FIELD(msg->msg_id);
557 u16 evt_id = MSG_EVT_ID_FIELD(msg->msg_id);
558
559 switch(mdl_id) {
560 case PHL_MDL_RX:
561 case PHL_MDL_SER:
562 case PHL_MDL_WOW:
563 core_hdl_phl_evt(dvobj, evt_id);
564 break;
565 default:
566 RTW_ERR("%s mdl_id :%d not support\n", __func__, mdl_id);
567 break;
568 }
569 }
570
rtw_core_register_phl_msg(struct dvobj_priv * dvobj)571 u8 rtw_core_register_phl_msg(struct dvobj_priv *dvobj)
572 {
573 struct phl_msg_receiver ctx = {0};
574 u8 imr[] = {PHL_MDL_RX, PHL_MDL_SER, PHL_MDL_WOW};
575 enum rtw_phl_status psts = RTW_PHL_STATUS_FAILURE;
576
577 ctx.incoming_evt_notify = core_handler_phl_msg;
578 ctx.priv = (void*)dvobj;
579
580 psts = rtw_phl_msg_hub_register_recver(dvobj->phl, &ctx, MSG_RECV_CORE);
581 if(psts == RTW_PHL_STATUS_FAILURE) {
582 RTW_ERR("phl_msg_hub_register failed\n");
583 return _FAIL;
584 }
585
586 psts = rtw_phl_msg_hub_update_recver_mask(dvobj->phl,
587 MSG_RECV_CORE, imr, sizeof(imr), false);
588 if(psts == RTW_PHL_STATUS_FAILURE) {
589 RTW_ERR("phl_msg_hub_update_recver_mask failed\n");
590 return _FAIL;
591 }
592 return _SUCCESS;
593 }
594
595 /*RTW_WKARD_CORE_RSSI_V1*/
rtw_phl_rssi_to_dbm(u8 rssi)596 s8 rtw_phl_rssi_to_dbm(u8 rssi)
597 {
598 return rssi - PHL_MAX_RSSI;
599 }
600
601
602 #ifdef CONFIG_MCC_MODE
rtw_hw_mcc_chk_inprogress(struct _ADAPTER * a)603 u8 rtw_hw_mcc_chk_inprogress(struct _ADAPTER *a)
604 {
605 struct dvobj_priv *d;
606 void *phl;
607 u8 ret = _FALSE;
608
609 d = adapter_to_dvobj(a);
610 phl = GET_PHL_INFO(d);
611 if (!phl)
612 goto exit;
613
614 ret = rtw_phl_mr_query_mcc_inprogress(phl, a->phl_role, RTW_PHL_MCC_CHK_INPROGRESS);
615
616 exit:
617 return ret;
618 }
619
620 #ifdef CONFIG_P2P_PS
_mcc_update_noa(void * priv,struct rtw_phl_mcc_noa * param)621 static int _mcc_update_noa(void *priv, struct rtw_phl_mcc_noa *param)
622 {
623 struct dvobj_priv *dvobj = (struct dvobj_priv *) priv;
624 struct rtw_wifi_role_t *wrole = NULL;
625 struct _ADAPTER *a = NULL;
626 struct wifidirect_info *wdinfo;
627 u8 id = 0;
628 u8 ret = _SUCCESS;
629 #ifdef CONFIG_PHL_P2PPS
630 struct rtw_phl_noa_desc desc= {0};
631 #endif
632 wrole = param->wrole;
633 if (wrole == NULL) {
634 RTW_ERR("%s wrole is NULL\n", __func__);
635 ret = _FAIL;
636 goto exit;
637 }
638
639 id = wrole->id;
640 if (id >= CONFIG_IFACE_NUMBER) {
641 RTW_ERR("%s error id (%d)\n", __func__, id);
642 ret = _FAIL;
643 goto exit;
644 }
645
646 a = dvobj->padapters[id];
647 if (a == NULL) {
648 RTW_ERR("%s adapter(%d) is NULL\n", __func__, id);
649 ret = _FAIL;
650 goto exit;
651 }
652
653 /* by pass non-GO case */
654 if (!MLME_IS_GO(a))
655 goto exit;
656
657 wdinfo = &a->wdinfo;
658 RTW_INFO(FUNC_ADPT_FMT":(%d)\n", FUNC_ADPT_ARG(a), id);
659 RTW_INFO("start_t_h=0x%02x,start_t_l=0x%02x\n", param->start_t_h, param->start_t_l);
660 RTW_INFO("dur=0x%d,cnt=0x%d,interval=0x%d\n", param->dur, param->cnt, param->interval);
661
662 #ifdef CONFIG_PHL_P2PPS
663 /* enable TSF32 toggle */
664 desc.tag = P2PPS_TRIG_MCC;
665 desc.enable = true;
666 desc.duration = param->dur * NET80211_TU_TO_US;
667 desc.interval = param->interval * NET80211_TU_TO_US;
668 desc.start_t_h = param->start_t_h;
669 desc.start_t_l = param->start_t_l;
670 desc.count = param->cnt;
671 desc.w_role = param->wrole;
672 if (rtw_phl_p2pps_noa_update(dvobj->phl, &desc) != RTW_PHL_STATUS_SUCCESS) {
673 RTW_ERR("%s rtw_phl_p2pps_noa_update fail\n", __func__);
674 ret = _FAIL;
675 goto exit;
676 }
677 #endif
678
679 /* update NoA IE */
680 wdinfo->noa_index = wdinfo->noa_index + 1;
681 wdinfo->noa_num = 1;
682 wdinfo->noa_count[0] = param->cnt;
683 wdinfo->noa_duration[0] =param->dur * NET80211_TU_TO_US;
684 wdinfo->noa_interval[0] = param->interval * NET80211_TU_TO_US;
685 wdinfo->noa_start_time[0] = param->start_t_l;
686
687 rtw_update_beacon(a, _VENDOR_SPECIFIC_IE_, P2P_OUI, _TRUE, RTW_CMDF_DIRECTLY);
688 exit:
689 return ret;
690 }
691 #endif
692
693 /* default setting */
_mcc_get_setting(void * priv,struct rtw_phl_mcc_setting_info * param)694 static int _mcc_get_setting(void *priv, struct rtw_phl_mcc_setting_info *param)
695 {
696 struct dvobj_priv *dvobj = (struct dvobj_priv *) priv;
697 struct rtw_wifi_role_t *wrole = NULL;
698 struct _ADAPTER *a = NULL;
699 struct wifidirect_info *wdinfo;
700 u8 id = 0;
701 u8 ret = _SUCCESS;
702
703 wrole = param->wrole;
704 if (wrole == NULL) {
705 RTW_ERR("%s wrole is NULL\n", __func__);
706 ret = _FAIL;
707 goto exit;
708 }
709
710 id = wrole->id;
711 if (id >= CONFIG_IFACE_NUMBER) {
712 RTW_ERR("%s error id (%d)\n", __func__, id);
713 ret = _FAIL;
714 goto exit;
715 }
716
717 a = dvobj->padapters[id];
718 if (a == NULL) {
719 RTW_ERR("%s adapter(%d) is NULL\n", __func__, id);
720 ret = _FAIL;
721 goto exit;
722 }
723
724 if (MLME_IS_GO(a) || MLME_IS_GC(a))
725 param->dur = 50;
726 else
727 param->dur = 50;
728
729 if (MLME_IS_STA(a) || MLME_IS_GC(a))
730 param->tx_null_early = 5;
731 else
732 param->tx_null_early = NONSPECIFIC_SETTING;
733
734 RTW_INFO("%s: adapter(%d) dur=%d, tx_null_early=%d\n", __func__, id, param->dur, param->tx_null_early);
735
736 exit:
737 return ret;
738 }
739
740 struct rtw_phl_mcc_ops rtw_mcc_ops = {
741 .priv = NULL,
742 .mcc_update_noa = _mcc_update_noa,
743 .mcc_get_setting = _mcc_get_setting,
744 };
745 #endif
746
747 struct rtw_phl_mr_ops rtw_mr_ops = {
748 #ifdef CONFIG_MCC_MODE
749 .mcc_ops = &rtw_mcc_ops,
750 #endif
751 };
752
rtw_core_register_mr_config(struct dvobj_priv * dvobj)753 void rtw_core_register_mr_config(struct dvobj_priv *dvobj)
754 {
755 #ifdef CONFIG_MCC_MODE
756 rtw_mr_ops.mcc_ops->priv = (void *)dvobj;
757 #endif
758 rtw_phl_mr_ops_init(dvobj->phl, &rtw_mr_ops);
759 }
760
761 #if CONFIG_DFS
762 #ifdef CONFIG_ECSA_PHL
rtw_core_set_ecsa_ops(struct dvobj_priv * d)763 static void rtw_core_set_ecsa_ops(struct dvobj_priv *d)
764 {
765 struct rtw_phl_ecsa_ops ops = {0};
766
767 ops.priv = (void *)d;
768 ops.update_beacon = rtw_ecsa_update_beacon;
769 ops.update_chan_info = rtw_ecsa_mr_update_chan_info_by_role;
770 ops.check_ecsa_allow = rtw_ap_check_ecsa_allow;
771 ops.ecsa_complete = rtw_ecsa_complete;
772 ops.check_tx_resume_allow = rtw_ecsa_check_tx_resume_allow;
773 rtw_phl_ecsa_init_ops(GET_PHL_INFO(d), &ops);
774 }
775 #endif
776 #endif
777
rtw_hw_init(struct dvobj_priv * dvobj)778 u8 rtw_hw_init(struct dvobj_priv *dvobj)
779 {
780 u8 rst = _FAIL;
781 enum rtw_phl_status phl_status;
782 struct rtw_ic_info ic_info;
783 struct rtw_phl_evt_ops *evt_ops;
784
785 #ifdef DBG_PHL_MEM_ALLOC
786 ATOMIC_SET(&dvobj->phl_mem, 0);
787 #endif
788
789 _hw_ic_info_cfg(dvobj, &ic_info);
790 phl_status = rtw_phl_init(dvobj, &(dvobj->phl), &ic_info);
791
792 if ((phl_status != RTW_PHL_STATUS_SUCCESS) || (dvobj->phl == NULL)) {
793 RTW_ERR("%s - rtw_phl_init failed status(%d), dvobj->phl(%p)\n",
794 __func__, phl_status, dvobj->phl);
795 goto _free_hal;
796 }
797
798 dvobj->phl_com = rtw_phl_get_com(dvobj->phl);
799
800 /*init sw cap from registary*/
801 rtw_core_update_default_setting(dvobj);
802
803 /* sw & hw cap*/
804 rtw_phl_cap_pre_config(dvobj->phl);
805
806 #ifdef CONFIG_RX_PSTS_PER_PKT
807 rtw_phl_init_ppdu_sts_para(dvobj->phl_com,
808 _TRUE, _FALSE,
809 RTW_PHL_PSTS_FLTR_MGNT | RTW_PHL_PSTS_FLTR_DATA /*| RTW_PHL_PSTS_FLTR_CTRL*/
810 );
811 #endif
812 /*init datapath section*/
813 rtw_phl_trx_alloc(dvobj->phl);
814 evt_ops = &(dvobj->phl_com->evt_ops);
815 evt_ops->rx_process = rtw_core_rx_process;
816 evt_ops->tx_recycle = rtw_core_tx_recycle;
817 #ifdef CONFIG_RTW_IPS
818 evt_ops->set_rf_state = rtw_core_set_ips_state;
819 #endif
820 #ifdef CONFIG_GTK_OL
821 evt_ops->wow_handle_sec_info_update = rtw_update_gtk_ofld_info;
822 #endif
823
824 rtw_core_register_phl_msg(dvobj);
825
826 /* load wifi feature or capability from efuse*/
827 rtw_phl_preload(dvobj->phl);
828
829 rtw_phl_final_cap_decision(dvobj->phl);
830
831 /* after final cap decision */
832 rtw_core_register_mr_config(dvobj);
833
834 #if CONFIG_DFS
835 #ifdef CONFIG_ECSA_PHL
836 rtw_core_set_ecsa_ops(dvobj);
837 #endif
838 #endif
839
840 rtw_hw_dump_hal_spec(RTW_DBGDUMP, dvobj);
841
842 #ifdef CONFIG_CMD_GENERAL
843 rtw_phl_watchdog_init(dvobj->phl,
844 0,
845 rtw_core_watchdog_sw_hdlr,
846 rtw_core_watchdog_hw_hdlr);
847 #else
848 rtw_phl_job_reg_wdog(dvobj->phl,
849 rtw_dynamic_check_handlder,
850 dvobj, NULL, 0, "rtw_dm", PWR_BASIC_IO);
851 #endif
852
853 rtw_set_phl_regulation_ctx(dvobj);
854
855 rst = _SUCCESS;
856 return rst;
857
858 _free_hal :
859 rtw_hw_deinit(dvobj);
860 return rst;
861 }
862
rtw_hw_start(struct dvobj_priv * dvobj)863 u8 rtw_hw_start(struct dvobj_priv *dvobj)
864 {
865 if (dev_is_hw_start(dvobj))
866 return _FAIL;
867
868 if (rtw_phl_start(GET_PHL_INFO(dvobj)) != RTW_PHL_STATUS_SUCCESS)
869 return _FAIL;
870
871 #ifdef CONFIG_PCI_HCI
872 //intr init flag
873 dvobj_to_pci(dvobj)->irq_enabled = 1;
874 #endif
875 #ifdef CONFIG_CMD_GENERAL
876 rtw_phl_watchdog_start(dvobj->phl);
877 #endif
878
879 dev_set_hw_start(dvobj);
880
881 return _SUCCESS;
882 }
rtw_hw_stop(struct dvobj_priv * dvobj)883 void rtw_hw_stop(struct dvobj_priv *dvobj)
884 {
885 if (!dev_is_hw_start(dvobj))
886 return;
887
888 #ifdef CONFIG_CMD_GENERAL
889 rtw_phl_watchdog_stop(dvobj->phl);
890 #endif
891 rtw_phl_stop(GET_PHL_INFO(dvobj));
892
893 #ifdef CONFIG_PCI_HCI
894 //intr init flag
895 dvobj_to_pci(dvobj)->irq_enabled = 0;
896 #endif
897
898 dev_clr_hw_start(dvobj);
899 }
900
rtw_hw_get_init_completed(struct dvobj_priv * dvobj)901 bool rtw_hw_get_init_completed(struct dvobj_priv *dvobj)
902 {
903 return rtw_phl_is_init_completed(GET_PHL_INFO(dvobj));
904 }
905
rtw_hw_is_init_completed(struct dvobj_priv * dvobj)906 bool rtw_hw_is_init_completed(struct dvobj_priv *dvobj)
907 {
908 return (rtw_phl_is_init_completed(GET_PHL_INFO(dvobj))) ? _TRUE : _FALSE;
909 }
910
911 #define NSS_VALID(nss) (nss > 0)
rtw_hw_cap_init(struct dvobj_priv * dvobj)912 void rtw_hw_cap_init(struct dvobj_priv *dvobj)
913 {
914 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj);
915 struct rtw_phl_com_t *phl_com = GET_PHL_COM(dvobj);
916 struct phy_cap_t *phy_cap = phl_com->phy_cap;
917 struct registry_priv *regpriv =
918 &(dvobj_get_primary_adapter(dvobj)->registrypriv);
919
920 #ifdef DIRTY_FOR_WORK
921 dvobj->phl_com->rf_path_num = hal_spec->rf_reg_path_num; /*GET_HAL_RFPATH_NUM*/
922 dvobj->phl_com->rf_type = RF_2T2R; /*GET_HAL_RFPATH*/
923
924 /* GEORGIA_TODO move related control module to phl layer*/
925 /* macid_ctl moved to phl */
926 /* dvobj->macid_ctl.num = rtw_min(hal_spec->macid_num, MACID_NUM_SW_LIMIT); */
927 // Freddie ToDo: check macid_number from PHL?
928 dvobj->wow_ctl.wow_cap = hal_spec->wow_cap;
929
930 dvobj->cam_ctl.sec_cap = hal_spec->sec_cap;
931 dvobj->cam_ctl.num = rtw_min(hal_spec->sec_cam_ent_num, SEC_CAM_ENT_NUM_SW_LIMIT);
932 #endif
933 }
934
935
936 /*
937 * _ch_offset_drv2phl() - Convert driver channel offset to PHL type
938 * @ch_offset: channel offset, ref: HAL_PRIME_CHNL_OFFSET_*
939 *
940 * Return PHL channel offset type "enum chan_offset"
941 */
_ch_offset_drv2phl(u8 ch_offset)942 static enum chan_offset _ch_offset_drv2phl(u8 ch_offset)
943 {
944 if (ch_offset == CHAN_OFFSET_UPPER)
945 return CHAN_OFFSET_UPPER;
946 if (ch_offset == CHAN_OFFSET_LOWER)
947 return CHAN_OFFSET_LOWER;
948
949 return CHAN_OFFSET_NO_EXT;
950 }
951
952 /*
953 * rtw_hw_set_ch_bw() - Set channel, bandwidth and channel offset
954 * @a: pointer of struct _ADAPTER
955 * @ch: channel
956 * @bw: bandwidth
957 * @offset: channel offset, ref: HAL_PRIME_CHNL_OFFSET_*
958 *
959 * Set channel, bandwidth and channel offset.
960 *
961 * Return 0 for success, otherwise fail
962 */
rtw_hw_set_ch_bw(struct _ADAPTER * a,u8 ch,enum channel_width bw,u8 offset,u8 do_rfk)963 int rtw_hw_set_ch_bw(struct _ADAPTER *a, u8 ch, enum channel_width bw,
964 u8 offset, u8 do_rfk)
965 {
966 enum rtw_phl_status status = RTW_PHL_STATUS_SUCCESS;
967 struct dvobj_priv *dvobj = adapter_to_dvobj(a);
968 int err = 0;
969 struct rtw_chan_def chdef = {0};
970 enum phl_cmd_type cmd_type = PHL_CMD_DIRECTLY;
971 u32 cmd_timeout = 0;
972
973 #ifdef CONFIG_MCC_MODE
974 if (rtw_hw_mcc_chk_inprogress(a)) {
975 RTW_WARN("under mcc, skip ch setting\n");
976 return err;
977 }
978 #endif
979
980 chdef.chan = ch;
981 chdef.bw = bw;
982 chdef.offset = offset;
983 chdef.band = (ch > 14) ? BAND_ON_5G : BAND_ON_24G;
984
985 _rtw_mutex_lock_interruptible(&dvobj->setch_mutex);
986 #ifdef DBG_CONFIG_CMD_DISP
987 if (a->cmd_type == 0xFF) {
988 cmd_type = PHL_CMD_DIRECTLY;
989 cmd_timeout = 0;
990 }
991 else {
992 cmd_type = a->cmd_type;
993 cmd_timeout = a->cmd_timeout;
994 }
995 #endif
996 status = rtw_phl_cmd_set_ch_bw(a->phl_role,
997 &chdef, do_rfk,
998 cmd_type, cmd_timeout);
999
1000 if (status == RTW_PHL_STATUS_SUCCESS) {
1001 if (a->bNotifyChannelChange)
1002 RTW_INFO("[%s] ch = %d, offset = %d, bwmode = %d, success\n",
1003 __FUNCTION__, ch, offset, bw);
1004
1005 } else {
1006 err = -1;
1007 RTW_ERR("%s: set ch(%u) bw(%u) offset(%u) FAIL!\n",
1008 __func__, ch, bw, offset);
1009 }
1010
1011 _rtw_mutex_unlock(&dvobj->setch_mutex);
1012
1013 return err;
1014 }
1015
rtw_hw_update_chan_def(_adapter * adapter)1016 void rtw_hw_update_chan_def(_adapter *adapter)
1017 {
1018 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
1019 struct rtw_phl_stainfo_t *phl_sta_self = NULL;
1020
1021 /*update chan_def*/
1022 adapter->phl_role->chandef.band =
1023 (mlmeext->chandef.chan > 14) ? BAND_ON_5G : BAND_ON_24G;
1024 adapter->phl_role->chandef.chan = mlmeext->chandef.chan;
1025 adapter->phl_role->chandef.bw = mlmeext->chandef.bw;
1026 adapter->phl_role->chandef.offset = mlmeext->chandef.offset;
1027 adapter->phl_role->chandef.center_ch = rtw_phl_get_center_ch(mlmeext->chandef.chan,
1028 mlmeext->chandef.bw, mlmeext->chandef.offset);
1029 /* ToDo: 80+80 BW & 160 BW */
1030
1031 phl_sta_self = rtw_phl_get_stainfo_self(adapter_to_dvobj(adapter)->phl, adapter->phl_role);
1032 _rtw_memcpy(&phl_sta_self->chandef, &adapter->phl_role->chandef, sizeof(struct rtw_chan_def));
1033 }
1034
_dump_phl_role_info(struct rtw_wifi_role_t * wrole)1035 static void _dump_phl_role_info(struct rtw_wifi_role_t *wrole)
1036 {
1037 RTW_INFO("[WROLE]- role-idx: %d\n", wrole->id);
1038
1039 RTW_INFO("[WROLE]- type: %d\n", wrole->type);
1040 RTW_INFO("[WROLE]- mstate: %d\n", wrole->mstate);
1041 RTW_INFO("[WROLE]- mac_addr:"MAC_FMT"\n", MAC_ARG(wrole->mac_addr));
1042 RTW_INFO("[WROLE]- hw_band: %d\n", wrole->hw_band);
1043 RTW_INFO("[WROLE]- hw_port: %d\n", wrole->hw_port);
1044 RTW_INFO("[WROLE]- hw_wmm: %d\n", wrole->hw_wmm);
1045
1046 RTW_INFO("[WROLE]- band: %d\n", wrole->chandef.band);
1047 RTW_INFO("[WROLE]- chan: %d\n", wrole->chandef.chan);
1048 RTW_INFO("[WROLE]- bw: %d\n", wrole->chandef.bw);
1049 RTW_INFO("[WROLE]- offset: %d\n", wrole->chandef.offset);
1050 // Freddie ToDo: MBSSID
1051 }
rtw_hw_iface_init(_adapter * adapter)1052 u8 rtw_hw_iface_init(_adapter *adapter)
1053 {
1054 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1055 u8 phl_role_idx = INVALID_WIFI_ROLE_IDX;
1056 u8 rst = _FAIL;
1057 int chctx_num = 0;
1058 #if defined(CONFIG_RTW_IPS) || defined(CONFIG_RTW_LPS)
1059 bool ps_allow = _FALSE;
1060
1061 rtw_phl_ps_set_rt_cap(GET_PHL_INFO(dvobj), HW_BAND_0, ps_allow, PS_RT_CORE_INIT);
1062 #endif
1063 // Freddie ToDo: For AP mode, net type should be set to net device already.
1064
1065 /* will allocate phl self sta info */
1066 phl_role_idx = rtw_phl_wifi_role_alloc(GET_PHL_INFO(dvobj),
1067 adapter_mac_addr(adapter), PHL_RTYPE_STATION,
1068 adapter->iface_id, &(adapter->phl_role), _FALSE);
1069
1070 if ((phl_role_idx == INVALID_WIFI_ROLE_IDX) ||
1071 (adapter->phl_role == NULL)) {
1072 RTW_ERR("rtw_phl_wifi_role_alloc failed\n");
1073 rtw_warn_on(1);
1074 goto _error;
1075 }
1076
1077 /*init default value*/
1078 #ifdef DBG_CONFIG_CMD_DISP
1079 adapter->cmd_type = 0xFF;
1080 adapter->cmd_timeout = 0;
1081 #endif
1082 rtw_hw_update_chan_def(adapter);
1083 chctx_num = rtw_phl_mr_get_chanctx_num(GET_PHL_INFO(dvobj), adapter->phl_role);
1084
1085 if (chctx_num == 0) {
1086 if (rtw_phl_cmd_set_ch_bw(adapter->phl_role,
1087 &(adapter->phl_role->chandef),
1088 _FALSE,
1089 PHL_CMD_WAIT, 0) != RTW_PHL_STATUS_SUCCESS) {
1090 RTW_ERR("%s init ch failed\n", __func__);
1091 }
1092 }
1093
1094 _dump_phl_role_info(adapter->phl_role);
1095
1096 /* init self staion info after wifi role alloc */
1097 rst = rtw_init_self_stainfo(adapter);
1098
1099 #if defined (CONFIG_PCI_HCI) && defined (CONFIG_PCIE_TRX_MIT)
1100 rtw_pcie_trx_mit_cmd(adapter, 0, 0,
1101 PCIE_RX_INT_MIT_TIMER, 0, 1);
1102 #endif
1103 #if defined(CONFIG_RTW_IPS) || defined(CONFIG_RTW_LPS)
1104 ps_allow = _TRUE;
1105 rtw_phl_ps_set_rt_cap(GET_PHL_INFO(dvobj), HW_BAND_0, ps_allow, PS_RT_CORE_INIT);
1106 #endif
1107
1108 return rst;
1109
1110 _error:
1111 return rst;
1112 }
1113
rtw_hw_iface_type_change(_adapter * adapter,u8 iface_type)1114 u8 rtw_hw_iface_type_change(_adapter *adapter, u8 iface_type)
1115 {
1116 void *phl = GET_PHL_INFO(adapter_to_dvobj(adapter));
1117 #ifdef CONFIG_WIFI_MONITOR
1118 struct rtw_phl_com_t *phl_com = GET_PHL_COM(adapter_to_dvobj(adapter));
1119 #endif
1120 struct rtw_wifi_role_t *wrole = adapter->phl_role;
1121 enum role_type rtype = PHL_RTYPE_NONE;
1122 enum rtw_phl_status status;
1123 struct sta_info *sta = NULL;
1124
1125 if (wrole == NULL) {
1126 RTW_ERR("%s - wrole = NULL\n", __func__);
1127 rtw_warn_on(1);
1128 return _FAIL;
1129 }
1130
1131 switch (iface_type) {
1132 case _HW_STATE_ADHOC_:
1133 rtype = PHL_RTYPE_ADHOC;
1134 break;
1135 case _HW_STATE_STATION_:
1136 rtype = PHL_RTYPE_STATION;
1137 break;
1138 case _HW_STATE_AP_:
1139 rtype = PHL_RTYPE_AP;
1140 break;
1141 case _HW_STATE_MONITOR_:
1142 rtype = PHL_RTYPE_MONITOR;
1143 break;
1144 case _HW_STATE_NOLINK_:
1145 default:
1146 /* TBD */
1147 break;
1148 }
1149
1150 status = rtw_phl_cmd_wrole_change(phl, wrole,
1151 WR_CHG_TYPE, (u8*)&rtype, sizeof(enum role_type),
1152 PHL_CMD_DIRECTLY, 0);
1153
1154 if (status != RTW_PHL_STATUS_SUCCESS) {
1155 RTW_ERR("%s - change to phl role type = %d fail with error = %d\n",
1156 __func__, rtype, status);
1157 rtw_warn_on(1);
1158 return _FAIL;
1159 }
1160
1161 #ifdef CONFIG_WIFI_MONITOR
1162 if (rtype == PHL_RTYPE_MONITOR) {
1163 phl_com->append_fcs = false; /* This need to check again by yiwei*/
1164 rtw_phl_enter_mon_mode(phl, wrole);
1165 } else {
1166 phl_com->append_fcs = true; /* This need to check again by yiwei*/
1167 rtw_phl_leave_mon_mode(phl, wrole);
1168 }
1169 #endif
1170
1171 /* AP allocates self-station and changes broadcast-station before hostapd adds key */
1172 if (rtype == PHL_RTYPE_AP) {
1173 sta = rtw_get_stainfo(&adapter->stapriv, adapter_mac_addr(adapter));
1174 if (sta == NULL) {
1175 sta = rtw_alloc_stainfo(&adapter->stapriv, adapter_mac_addr(adapter));
1176 if (sta == NULL) {
1177 RTW_ERR("%s - allocate AP self-station failed\n", __func__);
1178 rtw_warn_on(1);
1179 return _FAIL;
1180 }
1181 }
1182 }
1183
1184 RTW_INFO("%s - change to type = %d success !\n", __func__, iface_type);
1185
1186 return _SUCCESS;
1187 }
1188
rtw_hw_iface_deinit(_adapter * adapter)1189 void rtw_hw_iface_deinit(_adapter *adapter)
1190 {
1191 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1192 #if defined(CONFIG_RTW_IPS) || defined(CONFIG_RTW_LPS)
1193 bool ps_allow = _FALSE;
1194
1195 rtw_phl_ps_set_rt_cap(GET_PHL_INFO(dvobj), HW_BAND_0, ps_allow, PS_RT_CORE_INIT);
1196 #endif
1197 if (adapter->phl_role) {
1198 rtw_free_self_stainfo(adapter);
1199 rtw_phl_wifi_role_free(GET_PHL_INFO(dvobj), adapter->phl_role->id);
1200 adapter->phl_role = NULL;
1201 }
1202 #if defined(CONFIG_RTW_IPS) || defined(CONFIG_RTW_LPS)
1203 ps_allow = _TRUE;
1204 rtw_phl_ps_set_rt_cap(GET_PHL_INFO(dvobj), HW_BAND_0, ps_allow, PS_RT_CORE_INIT);
1205 #endif
1206 }
1207
1208 /*
1209 * _sec_algo_drv2phl() - Convert security algorithm to PHL's definition
1210 * @drv_algo: security algorithm
1211 * @phl_algo: security algorithm for PHL, ref to enum rtw_enc_algo
1212 * @phl_key_len: key length
1213 *
1214 * Convert driver's security algorithm defintion to PHL's type.
1215 *
1216 */
_sec_algo_drv2phl(enum security_type drv_algo,u8 * algo,u8 * key_len)1217 static void _sec_algo_drv2phl(enum security_type drv_algo,
1218 u8 *algo, u8 *key_len)
1219 {
1220 u8 phl_algo = RTW_ENC_NONE;
1221 u8 phl_key_len = 0;
1222
1223 switch(drv_algo) {
1224 case _NO_PRIVACY_:
1225 phl_algo = RTW_ENC_NONE;
1226 phl_key_len = 0;
1227 break;
1228 case _WEP40_:
1229 phl_algo = RTW_ENC_WEP40;
1230 phl_key_len = 5;
1231 break;
1232 case _TKIP_:
1233 case _TKIP_WTMIC_:
1234 phl_algo = RTW_ENC_TKIP;
1235 phl_key_len = 16;
1236 break;
1237 case _AES_:
1238 phl_algo = RTW_ENC_CCMP;
1239 phl_key_len = 16;
1240 break;
1241 case _WEP104_:
1242 phl_algo = RTW_ENC_WEP104;
1243 phl_key_len = 13;
1244 break;
1245 case _SMS4_:
1246 phl_algo = RTW_ENC_WAPI;
1247 phl_key_len = 32;
1248 break;
1249 case _GCMP_:
1250 phl_algo = RTW_ENC_GCMP;
1251 phl_key_len = 16;
1252 break;
1253 case _CCMP_256_:
1254 phl_algo = RTW_ENC_CCMP256;
1255 phl_key_len = 32;
1256 break;
1257 case _GCMP_256_:
1258 phl_algo = RTW_ENC_GCMP256;
1259 phl_key_len = 32;
1260 break;
1261 #ifdef CONFIG_IEEE80211W
1262 case _BIP_CMAC_128_:
1263 phl_algo = RTW_ENC_BIP_CCMP128;
1264 phl_key_len = 16;
1265 break;
1266 #endif /* CONFIG_IEEE80211W */
1267 default:
1268 RTW_ERR("%s: No rule to covert drv algo(0x%x) to phl!!\n",
1269 __func__, drv_algo);
1270 phl_algo = RTW_ENC_MAX;
1271 phl_key_len = 0;
1272 break;
1273 }
1274
1275 if(algo)
1276 *algo = phl_algo;
1277 if(key_len)
1278 *key_len = phl_key_len;
1279 }
1280
1281 /*
1282 * _sec_algo_phl2drv() - Convert security algorithm to core layer definition
1283 * @drv_algo: security algorithm for core layer, ref to enum security_type
1284 * @phl_algo: security algorithm for PHL, ref to enum rtw_enc_algo
1285 * @drv_key_len: key length
1286 *
1287 * Convert PHL's security algorithm defintion to core layer definition.
1288 *
1289 */
_sec_algo_phl2drv(enum rtw_enc_algo phl_algo,u8 * algo,u8 * key_len)1290 static void _sec_algo_phl2drv(enum rtw_enc_algo phl_algo,
1291 u8 *algo, u8 *key_len)
1292 {
1293 u8 drv_algo = RTW_ENC_NONE;
1294 u8 drv_key_len = 0;
1295
1296 switch(phl_algo) {
1297 case RTW_ENC_NONE:
1298 drv_algo = _NO_PRIVACY_;
1299 drv_key_len = 0;
1300 break;
1301 case RTW_ENC_WEP40:
1302 drv_algo = _WEP40_;
1303 drv_key_len = 5;
1304 break;
1305 case RTW_ENC_TKIP:
1306 /* drv_algo = _TKIP_WTMIC_ */
1307 drv_algo = _TKIP_;
1308 drv_key_len = 16;
1309 break;
1310 case RTW_ENC_CCMP:
1311 drv_algo = _AES_;
1312 drv_key_len = 16;
1313 break;
1314 case RTW_ENC_WEP104:
1315 drv_algo = _WEP104_;
1316 drv_key_len = 13;
1317 break;
1318 case RTW_ENC_WAPI:
1319 drv_algo = _SMS4_;
1320 drv_key_len = 32;
1321 break;
1322 case RTW_ENC_GCMP:
1323 drv_algo = _GCMP_;
1324 drv_key_len = 16;
1325 break;
1326 case RTW_ENC_CCMP256:
1327 drv_algo = _CCMP_256_;
1328 drv_key_len = 32;
1329 break;
1330 case RTW_ENC_GCMP256:
1331 drv_algo = _GCMP_256_;
1332 drv_key_len = 32;
1333 break;
1334 #ifdef CONFIG_IEEE80211W
1335 case RTW_ENC_BIP_CCMP128:
1336 drv_algo = _BIP_CMAC_128_;
1337 drv_key_len = 16;
1338 break;
1339 #endif /* CONFIG_IEEE80211W */
1340 default:
1341 RTW_ERR("%s: No rule to covert phl algo(0x%x) to drv!!\n",
1342 __func__, phl_algo);
1343 drv_algo = _SEC_TYPE_MAX_;
1344 drv_key_len = 0;
1345 break;
1346 }
1347
1348 if(algo)
1349 *algo = drv_algo;
1350 if(key_len)
1351 *key_len = drv_key_len;
1352 }
1353
rtw_sec_algo_drv2phl(enum security_type drv_algo)1354 u8 rtw_sec_algo_drv2phl(enum security_type drv_algo)
1355 {
1356 u8 algo = 0;
1357
1358 _sec_algo_drv2phl(drv_algo, &algo, NULL);
1359 return algo;
1360 }
1361
rtw_sec_algo_phl2drv(enum rtw_enc_algo phl_algo)1362 u8 rtw_sec_algo_phl2drv(enum rtw_enc_algo phl_algo)
1363 {
1364 u8 algo = 0;
1365
1366 _sec_algo_phl2drv(phl_algo, &algo, NULL);
1367 return algo;
1368 }
1369
rtw_hw_chk_sec_mode(struct _ADAPTER * a,struct sta_info * sta,enum phl_cmd_type cmd_type,u32 cmd_timeout)1370 static int rtw_hw_chk_sec_mode(struct _ADAPTER *a, struct sta_info *sta,
1371 enum phl_cmd_type cmd_type, u32 cmd_timeout)
1372 {
1373 struct dvobj_priv *d;
1374 void *phl;
1375 enum rtw_phl_status status;
1376 u8 sec_mode = 0;
1377 struct security_priv *psecuritypriv = &a->securitypriv;
1378
1379 d = adapter_to_dvobj(a);
1380 phl = GET_PHL_INFO(d);
1381
1382 if (!phl)
1383 return _FAIL;
1384
1385 sec_mode = rtw_phl_trans_sec_mode(
1386 rtw_sec_algo_drv2phl(psecuritypriv->dot11PrivacyAlgrthm),
1387 rtw_sec_algo_drv2phl(psecuritypriv->dot118021XGrpPrivacy));
1388
1389 RTW_INFO("After phl trans_sec_mode = %d\n", sec_mode);
1390
1391 if (sec_mode != sta->phl_sta->sec_mode) {
1392 RTW_INFO("%s: original sec_mode =%d update sec mode to %d.\n",
1393 __func__, sta->phl_sta->sec_mode, sec_mode);
1394 status = rtw_phl_cmd_change_stainfo(phl, sta->phl_sta, STA_CHG_SEC_MODE,
1395 &sec_mode, sizeof(u8), cmd_type, cmd_timeout);
1396 /* To Do: check the return status */
1397 } else {
1398 RTW_INFO("%s: sec mode remains the same. skip update.\n", __func__);
1399 }
1400 return _SUCCESS;
1401 }
1402
1403 /*
1404 * rtw_hw_add_key() - Add security key
1405 * @a: pointer of struct _ADAPTER
1406 * @sta: pointer of struct sta_info
1407 * @keyid: key index
1408 * @keyalgo: key algorithm
1409 * @keytype: 0: unicast / 1: multicast / 2: bip (ref: enum SEC_CAM_KEY_TYPE)
1410 * @key: key content
1411 * @spp: spp mode
1412 *
1413 * Add security key.
1414 *
1415 * Return 0 for success, otherwise fail.
1416 */
rtw_hw_add_key(struct _ADAPTER * a,struct sta_info * sta,u8 keyid,enum security_type keyalgo,u8 keytype,u8 * key,u8 spp,enum phl_cmd_type cmd_type,u32 cmd_timeout)1417 int rtw_hw_add_key(struct _ADAPTER *a, struct sta_info *sta,
1418 u8 keyid, enum security_type keyalgo, u8 keytype, u8 *key,
1419 u8 spp, enum phl_cmd_type cmd_type, u32 cmd_timeout)
1420 {
1421 struct dvobj_priv *d;
1422 void *phl;
1423 struct phl_sec_param_h crypt = {0};
1424 enum rtw_phl_status status;
1425
1426
1427 d = adapter_to_dvobj(a);
1428 phl = GET_PHL_INFO(d);
1429 if (!phl)
1430 return -1;
1431
1432 if (rtw_hw_chk_sec_mode(a, sta, cmd_type, cmd_timeout) == _FAIL)
1433 return -1;
1434
1435 crypt.keyid = keyid;
1436 crypt.key_type= keytype;
1437 crypt.spp = spp;
1438 _sec_algo_drv2phl(keyalgo, &crypt.enc_type, &crypt.key_len);
1439
1440 /* delete key before adding key */
1441 rtw_phl_cmd_del_key(phl, sta->phl_sta, &crypt, cmd_type, cmd_timeout);
1442 status = rtw_phl_cmd_add_key(phl, sta->phl_sta, &crypt, key, cmd_type, cmd_timeout);
1443 if (status != RTW_PHL_STATUS_SUCCESS)
1444 return -1;
1445
1446 return 0;
1447 }
1448
1449 /*
1450 * rtw_hw_del_key() - Delete security key
1451 * @a: pointer of struct _ADAPTER
1452 * @sta: pointer of struct sta_info
1453 * @keyid: key index
1454 * @keytype: 0: unicast / 1: multicast / 2: bip (ref: enum SEC_CAM_KEY_TYPE)
1455 *
1456 * Delete security key by macid, keyid and keytype.
1457 *
1458 * Return 0 for success, otherwise fail.
1459 */
rtw_hw_del_key(struct _ADAPTER * a,struct sta_info * sta,u8 keyid,u8 keytype,enum phl_cmd_type cmd_type,u32 cmd_timeout)1460 int rtw_hw_del_key(struct _ADAPTER *a, struct sta_info *sta,
1461 u8 keyid, u8 keytype, enum phl_cmd_type cmd_type, u32 cmd_timeout)
1462 {
1463 struct dvobj_priv *d;
1464 void *phl;
1465 struct phl_sec_param_h crypt = {0};
1466 enum rtw_phl_status status;
1467
1468
1469 d = adapter_to_dvobj(a);
1470 phl = GET_PHL_INFO(d);
1471 if (!phl)
1472 return -1;
1473
1474 crypt.keyid = keyid;
1475 crypt.key_type= keytype;
1476
1477 status = rtw_phl_cmd_del_key(phl, sta->phl_sta, &crypt, cmd_type, cmd_timeout);
1478 if (status != RTW_PHL_STATUS_SUCCESS)
1479 return -1;
1480
1481 return 0;
1482 }
1483
1484 /*
1485 * rtw_hw_del_all_key() - Delete all security key for this STA
1486 * @a: pointer of struct _ADAPTER
1487 * @sta: pointer of struct sta_info
1488 *
1489 * Delete all security keys belong to this STA.
1490 *
1491 * Return 0 for success, otherwise fail.
1492 */
rtw_hw_del_all_key(struct _ADAPTER * a,struct sta_info * sta,enum phl_cmd_type cmd_type,u32 cmd_timeout)1493 int rtw_hw_del_all_key(struct _ADAPTER *a, struct sta_info *sta,
1494 enum phl_cmd_type cmd_type, u32 cmd_timeout)
1495 {
1496 struct dvobj_priv *d;
1497 void *phl;
1498 u8 keyid;
1499 u8 keytype;
1500 struct phl_sec_param_h crypt = {0};
1501 enum rtw_phl_status status;
1502
1503
1504 d = adapter_to_dvobj(a);
1505 phl = GET_PHL_INFO(d);
1506 if (!phl)
1507 return -1;
1508
1509 /* Delete Group and Pairwise key */
1510 for (keytype = 0; keytype < 2; keytype++) {
1511 for (keyid = 0; keyid < 4; keyid++) {
1512 crypt.keyid = keyid;
1513 crypt.key_type = keytype;
1514 rtw_phl_cmd_del_key(phl, sta->phl_sta, &crypt, cmd_type, cmd_timeout);
1515 }
1516 }
1517
1518 /* Delete BIP key */
1519 crypt.key_type = 2;
1520 for (keyid = 4; keyid <= BIP_MAX_KEYID; keyid++) {
1521 crypt.keyid = keyid;
1522 rtw_phl_cmd_del_key(phl, sta->phl_sta, &crypt, cmd_type, cmd_timeout);
1523 }
1524
1525 return 0;
1526 }
1527
rtw_hw_start_bss_network(struct _ADAPTER * a)1528 int rtw_hw_start_bss_network(struct _ADAPTER *a)
1529 {
1530 /* some hw related ap settings */
1531 if (rtw_phl_ap_started(adapter_to_dvobj(a)->phl, a->phl_role) !=
1532 RTW_PHL_STATUS_SUCCESS)
1533 return _FAIL;
1534
1535 return _SUCCESS;
1536 }
1537
1538 /* connect */
rtw_hw_prepare_connect(struct _ADAPTER * a,struct sta_info * sta,u8 * target_addr)1539 int rtw_hw_prepare_connect(struct _ADAPTER *a, struct sta_info *sta, u8 *target_addr)
1540 {
1541 /*adapter->phl_role.mac_addr*/
1542 struct dvobj_priv *d;
1543 void *phl;
1544 enum rtw_phl_status status;
1545
1546
1547 d = adapter_to_dvobj(a);
1548 phl = GET_PHL_INFO(d);
1549
1550 status = rtw_phl_connect_prepare(phl, a->phl_role, target_addr);
1551 if (status != RTW_PHL_STATUS_SUCCESS) {
1552 RTW_ERR("%s: Fail to setup hardware for connecting!(%d)\n",
1553 __func__, status);
1554 return -1;
1555 }
1556 /* Todo: Enable TSF update */
1557 /* Todo: Set support short preamble or not by beacon capability */
1558 /* Todo: Set slot time */
1559
1560 return 0;
1561 }
1562
1563 /* Handle connect fail case */
rtw_hw_connect_abort(struct _ADAPTER * a,struct sta_info * sta)1564 int rtw_hw_connect_abort(struct _ADAPTER *a, struct sta_info *sta)
1565 {
1566 struct dvobj_priv *d;
1567 void *phl;
1568 enum rtw_phl_status status;
1569
1570
1571 d = adapter_to_dvobj(a);
1572 phl = GET_PHL_INFO(d);
1573 if (!phl)
1574 return -1;
1575
1576 rtw_hw_del_all_key(a, sta, PHL_CMD_DIRECTLY, 0);
1577
1578 status = rtw_phl_cmd_update_media_status(phl, sta->phl_sta, NULL, false,
1579 PHL_CMD_DIRECTLY, 0);
1580 if (status != RTW_PHL_STATUS_SUCCESS)
1581 return -1;
1582
1583 #ifndef CONFIG_STA_CMD_DISPR
1584 /*
1585 * In CONFIG_STA_CMD_DISPR case, connect abort hw setting has been moved
1586 * to MSG_EVT_DISCONNECT@PHL_FG_MDL_CONNECT .
1587 */
1588
1589 /* disconnect hw setting */
1590 rtw_phl_disconnect(phl, a->phl_role);
1591
1592 /* delete sta channel ctx */
1593 rtw_phl_chanctx_del(adapter_to_dvobj(a)->phl, a->phl_role, NULL);
1594 /* restore orig union ch */
1595 rtw_join_done_chk_ch(a, -1);
1596
1597 /* free connecting AP sta info */
1598 rtw_free_stainfo(a, sta);
1599 rtw_init_self_stainfo(a);
1600 #endif /* !CONFIG_STA_CMD_DISPR */
1601
1602 return 0;
1603 }
1604
1605 #ifdef RTW_WKARD_UPDATE_PHL_ROLE_CAP
1606 /**
1607 * rtw_update_phl_cap_by_rgstry() - Update cap & proto_role_cap of phl_role
1608 * @a: struct _ADAPTER*
1609 *
1610 * Update cap & proto_role_cap of a->phl_role by registry/driver parameters.
1611 *
1612 */
rtw_update_phl_cap_by_rgstry(struct _ADAPTER * a)1613 void rtw_update_phl_cap_by_rgstry(struct _ADAPTER *a)
1614 {
1615 struct registry_priv *rgstry;
1616 struct role_cap_t *cap;
1617 struct protocol_cap_t *prtcl;
1618
1619 rgstry = &a->registrypriv;
1620 cap = &a->phl_role->cap;
1621 prtcl = &a->phl_role->proto_role_cap;
1622
1623 /* LDPC */
1624 prtcl->ht_ldpc &= (TEST_FLAG(rgstry->ldpc_cap, BIT4) ? 1 : 0);
1625 cap->tx_ht_ldpc &= (TEST_FLAG(rgstry->ldpc_cap, BIT5) ? 1 : 0);
1626 prtcl->vht_ldpc &= (TEST_FLAG(rgstry->ldpc_cap, BIT0) ? 1 : 0);
1627 cap->tx_vht_ldpc &= (TEST_FLAG(rgstry->ldpc_cap, BIT1) ? 1 : 0);
1628 /* no HE LDPC control setting in registry, follow PHL default */
1629 }
1630 #endif /* RTW_WKARD_UPDATE_PHL_ROLE_CAP */
1631
_dump_phl_sta_asoc_cap(struct sta_info * sta)1632 static void _dump_phl_sta_asoc_cap(struct sta_info *sta)
1633 {
1634 struct rtw_phl_stainfo_t *phl_sta = sta->phl_sta;
1635 struct protocol_cap_t *asoc_cap = &phl_sta->asoc_cap;
1636 #define _loc_dbg_func RTW_DBG
1637 #define _loc_dbg(f) _loc_dbg_func(#f ": %u\n", asoc_cap->f)
1638
1639
1640 _loc_dbg_func("[PHL STA ASOC CAP]- mac_addr: " MAC_FMT "\n",
1641 MAC_ARG(phl_sta->mac_addr));
1642 _loc_dbg(ht_ldpc);
1643 _loc_dbg(vht_ldpc);
1644 _loc_dbg(he_ldpc);
1645 _loc_dbg(stbc_ht_rx);
1646 _loc_dbg(stbc_vht_rx);
1647 _loc_dbg(stbc_he_rx);
1648 _loc_dbg(vht_su_bfmr);
1649 _loc_dbg(vht_su_bfme);
1650 _loc_dbg(vht_mu_bfmr);
1651 _loc_dbg(vht_mu_bfme);
1652 _loc_dbg(bfme_sts);
1653 _loc_dbg(num_snd_dim);
1654 _loc_dbg_func("[PHL STA ASOC CAP]- end\n");
1655 }
1656
1657 #ifdef CONFIG_80211N_HT
1658 #ifdef CONFIG_80211AC_VHT
update_phl_sta_cap_vht(struct _ADAPTER * a,struct sta_info * sta,struct protocol_cap_t * cap)1659 static void update_phl_sta_cap_vht(struct _ADAPTER *a, struct sta_info *sta,
1660 struct protocol_cap_t *cap)
1661 {
1662 struct vht_priv *vht;
1663
1664
1665 vht = &sta->vhtpriv;
1666
1667 if (cap->ampdu_len_exp < vht->ampdu_len)
1668 cap->ampdu_len_exp = vht->ampdu_len;
1669 if (cap->max_amsdu_len < vht->max_mpdu_len)
1670 cap->max_amsdu_len = vht->max_mpdu_len;
1671
1672 cap->sgi_80 = (vht->sgi_80m == _TRUE) ? 1 : 0;
1673
1674 _rtw_memcpy(cap->vht_rx_mcs, vht->vht_mcs_map, 2);
1675 /* Todo: cap->vht_tx_mcs[2]; */
1676 if (vht->op_present)
1677 _rtw_memcpy(cap->vht_basic_mcs, &vht->vht_op[3], 2);
1678 }
1679 #endif /* CONFIG_80211AC_VHT */
update_phl_sta_cap_ht(struct _ADAPTER * a,struct sta_info * sta,struct protocol_cap_t * cap)1680 static void update_phl_sta_cap_ht(struct _ADAPTER *a, struct sta_info *sta,
1681 struct protocol_cap_t *cap)
1682 {
1683 struct mlme_ext_info *info;
1684 struct ht_priv *ht;
1685
1686
1687 info = &a->mlmeextpriv.mlmext_info;
1688 ht = &sta->htpriv;
1689
1690 cap->num_ampdu = 0xFF; /* Set to MAX */
1691
1692 cap->ampdu_density = ht->rx_ampdu_min_spacing;
1693 cap->ampdu_len_exp = GET_HT_CAP_ELE_MAX_AMPDU_LEN_EXP(&ht->ht_cap);
1694 cap->amsdu_in_ampdu = 1;
1695 cap->max_amsdu_len = GET_HT_CAP_ELE_MAX_AMSDU_LENGTH(&ht->ht_cap);
1696
1697 /*GET_HT_CAP_ELE_SM_PS(&info->HT_caps.u.HT_cap_element.HT_caps_info);*/
1698 cap->sm_ps = info->SM_PS;
1699
1700 cap->sgi_20 = (ht->sgi_20m == _TRUE) ? 1 : 0;
1701 cap->sgi_40 = (ht->sgi_40m == _TRUE) ? 1 : 0;
1702
1703 _rtw_memcpy(cap->ht_rx_mcs, ht->ht_cap.supp_mcs_set, 4);
1704 /* Todo: cap->ht_tx_mcs[4]; */
1705 if (info->HT_info_enable)
1706 _rtw_memcpy(cap->ht_basic_mcs, info->HT_info.MCS_rate, 4);
1707 }
1708 #endif /* CONFIG_80211N_HT */
1709
rtw_update_phl_sta_cap(struct _ADAPTER * a,struct sta_info * sta,struct protocol_cap_t * cap)1710 void rtw_update_phl_sta_cap(struct _ADAPTER *a, struct sta_info *sta,
1711 struct protocol_cap_t *cap)
1712 {
1713 struct mlme_ext_info *info;
1714
1715
1716 info = &a->mlmeextpriv.mlmext_info;
1717
1718 /* MAC related */
1719 /* update beacon interval */
1720 cap->bcn_interval = info->bcn_interval;
1721 #if 0
1722 cap->num_ampdu; /* HT, VHT, HE */
1723 cap->ampdu_density:3; /* HT, VHT, HE */
1724 cap->ampdu_len_exp; /* HT, VHT, HE */
1725 cap->amsdu_in_ampdu:1; /* HT, VHT, HE */
1726 cap->max_amsdu_len:2; /* HT, VHT, HE */
1727 cap->htc_rx:1;
1728 cap->sm_ps:2; /* HT */
1729 cap->trig_padding:2;
1730 cap->twt:6;
1731 cap->all_ack:1;
1732 cap->a_ctrl:3;
1733 cap->ops:1;
1734 cap->ht_vht_trig_rx:1;
1735 #endif
1736 cap->short_slot = (info->slotTime == SHORT_SLOT_TIME) ? 1 : 0;
1737 cap->preamble = (info->preamble_mode == PREAMBLE_SHORT) ? 1 : 0;
1738 #if 0
1739 cap->sgi_20:1; /* HT */
1740 cap->sgi_40:1; /* HT */
1741 cap->sgi_80:1; /* VHT */
1742 cap->sgi_160:1 /* VHT, HE */
1743
1744 /* BB related */
1745 cap->ht_ldpc:1; /* HT, HT_caps_handler() */
1746 cap->vht_ldpc:1; /* VHT, VHT_caps_handler() */
1747 cap->he_ldpc:1; /* HE, HE_phy_caps_handler() */
1748 cap->sgi:1;
1749 cap->su_bfmr:1;
1750 cap->su_bfme:1;
1751 cap->mu_bfmr:1;
1752 cap->mu_bfme:1;
1753 cap->bfme_sts:3;
1754 cap->num_snd_dim:3;
1755 #endif
1756 _rtw_memset(cap->supported_rates, 0, 12);
1757 _rtw_memcpy(cap->supported_rates, sta->bssrateset,
1758 sta->bssratelen < 12 ? sta->bssratelen : 12);
1759 #if 0
1760 cap->ht_rx_mcs[4]; /* HT */
1761 cap->ht_tx_mcs[4]; /* HT */
1762 cap->ht_basic_mcs[4]; /* Basic rate of HT */
1763 cap->vht_rx_mcs[2]; /* VHT */
1764 cap->vht_tx_mcs[2]; /* VHT */
1765 cap->vht_basic_mcs[2]; /* Basic rate of VHT */
1766 #endif
1767 #if 0
1768 /* HE done */
1769 cap->he_rx_mcs[2];
1770 cap->he_tx_mcs[2];
1771 cap->he_basic_mcs[2]; /* Basic rate of HE */
1772 cap->stbc_ht_rx:2; /* HT_caps_handler() */
1773 cap->stbc_vht_rx:3; /* VHT_caps_handler() */
1774 cap->stbc_he_rx:1; /* HE_phy_caps_handler() */
1775 cap->stbc_tx:1;
1776 cap->ltf_gi;
1777 cap->doppler_tx:1;
1778 cap->doppler_rx:1;
1779 cap->dcm_max_const_tx:2;
1780 cap->dcm_max_nss_tx:1;
1781 cap->dcm_max_const_rx:2;
1782 cap->dcm_max_nss_rx:1;
1783 cap->partial_bw_su_in_mu:1;
1784 cap->bfme_sts_greater_80mhz:3;
1785 cap->num_snd_dim_greater_80mhz:3;
1786 cap->stbc_tx_greater_80mhz:1;
1787 cap->stbc_rx_greater_80mhz:1;
1788 cap->ng_16_su_fb:1;
1789 cap->ng_16_mu_fb:1;
1790 cap->cb_sz_su_fb:1;
1791 cap->cb_sz_mu_fb:1;
1792 cap->trig_su_bfm_fb:1;
1793 cap->trig_mu_bfm_fb:1;
1794 cap->trig_cqi_fb:1;
1795 cap->partial_bw_su_er:1;
1796 cap->pkt_padding:2;
1797 cap->ppe_th[24];
1798 cap->pwr_bst_factor:1;
1799 cap->max_nc:3;
1800 cap->dcm_max_ru:2;
1801 cap->long_sigb_symbol:1;
1802 cap->non_trig_cqi_fb:1;
1803 cap->tx_1024q_ru:1;
1804 cap->rx_1024q_ru:1;
1805 cap->fbw_su_using_mu_cmprs_sigb:1;
1806 cap->fbw_su_using_mu_non_cmprs_sigb:1;
1807 cap->er_su:1;
1808 cap->tb_pe:3;
1809 cap->txop_du_rts_th;
1810 #endif
1811
1812 #ifdef CONFIG_80211N_HT
1813 if (sta->htpriv.ht_option) {
1814 update_phl_sta_cap_ht(a, sta, cap);
1815 #ifdef CONFIG_80211AC_VHT
1816 if (sta->vhtpriv.vht_option)
1817 update_phl_sta_cap_vht(a, sta, cap);;
1818 #endif /* CONFIG_80211AC_VHT */
1819 }
1820 #endif /* CONFIG_80211N_HT */
1821 }
1822
1823 /**
1824 * rtw_hw_set_edca() - setup WMM EDCA parameter
1825 * @a: struct _ADAPTER *
1826 * @ac: Access Category, 0:BE, 1:BK, 2:VI, 3:VO
1827 * @param: AIFS:BIT[7:0], CWMIN:BIT[11:8], CWMAX:BIT[15:12],
1828 * TXOP:BIT[31:16]
1829 *
1830 * Setup WMM EDCA parameter set.
1831 *
1832 * Return 0 for SUCCESS, otherwise fail.
1833 */
rtw_hw_set_edca(struct _ADAPTER * a,u8 ac,u32 param)1834 int rtw_hw_set_edca(struct _ADAPTER *a, u8 ac, u32 param)
1835 {
1836 struct dvobj_priv *d;
1837 void *phl;
1838 struct rtw_edca_param edca = {0};
1839 enum rtw_phl_status status;
1840
1841
1842 d = adapter_to_dvobj(a);
1843 phl = GET_PHL_INFO(d);
1844 if (!phl)
1845 return -1;
1846
1847 edca.ac = ac;
1848 edca.param = param;
1849
1850 status = rtw_phl_cmd_wrole_change(phl, a->phl_role,
1851 WR_CHG_EDCA_PARAM, (u8*)&edca, sizeof(struct rtw_edca_param),
1852 PHL_CMD_DIRECTLY, 0);
1853
1854 if (status != RTW_PHL_STATUS_SUCCESS) {
1855 RTW_ERR("%s: fail to set edca parameter, ac(%u), "
1856 "param(0x%08x)\n",
1857 __func__, ac, param);
1858 return -1;
1859 }
1860
1861 return 0;
1862 }
1863
rtw_hw_connected(struct _ADAPTER * a,struct sta_info * sta)1864 int rtw_hw_connected(struct _ADAPTER *a, struct sta_info *sta)
1865 {
1866
1867 struct dvobj_priv *d;
1868 void *phl;
1869 enum rtw_phl_status status;
1870 struct security_priv *psecuritypriv = &a->securitypriv;
1871 #ifdef CONFIG_STA_MULTIPLE_BSSID
1872 struct mlme_ext_priv *pmlmeext = &a->mlmeextpriv;
1873 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1874 #endif
1875
1876 d = adapter_to_dvobj(a);
1877 phl = GET_PHL_INFO(d);
1878 if (!phl)
1879 return -1;
1880
1881 rtw_update_phl_sta_cap(a, sta, &sta->phl_sta->asoc_cap);
1882 _dump_phl_sta_asoc_cap(sta);
1883
1884 #ifdef CONFIG_STA_MULTIPLE_BSSID
1885 /*use addr cam mask 0x1F to receive byte0~byte4 the same BSSID address == STA_CHG_MBSSID*/
1886 if (pmlmeinfo->network.is_mbssid) {
1887 sta->phl_sta->addr_sel = 3; /*MAC_AX_BSSID_MSK*/
1888 sta->phl_sta->addr_msk = 0x1F; /*MAC_AX_BYTE5*/
1889 }
1890 #endif
1891
1892 status = rtw_phl_cmd_update_media_status(phl, sta->phl_sta,
1893 sta->phl_sta->mac_addr, true,
1894 PHL_CMD_DIRECTLY, 0);
1895 if (status != RTW_PHL_STATUS_SUCCESS)
1896 return -1;
1897 rtw_dump_phl_sta_info(RTW_DBGDUMP, sta);
1898
1899 /* Todo: update IOT-releated issue */
1900 #if 0
1901 update_IOT_info(a);
1902 #endif
1903 /* Todo: RTS full bandwidth setting */
1904 #if 0
1905 #ifdef CONFIG_RTS_FULL_BW
1906 rtw_set_rts_bw(a);
1907 #endif /* CONFIG_RTS_FULL_BW */
1908 #endif
1909 /* Todo: Basic rate setting */
1910 #if 0
1911 rtw_hal_set_hwreg(a, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
1912 #endif
1913 /* Todo: udpate capability: short preamble, slot time */
1914 update_capinfo(a, a->mlmeextpriv.mlmext_info.capability);
1915
1916 WMMOnAssocRsp(a);
1917
1918 /* Todo: HT: AMPDU factor, min space, max time and related parameters */
1919 #if 0
1920 #ifdef CONFIG_80211N_HT
1921 HTOnAssocRsp(a);
1922 #endif /* CONFIG_80211N_HT */
1923 #endif
1924 /* Todo: VHT */
1925 #if 0
1926 #ifdef CONFIG_80211AC_VHT
1927 VHTOnAssocRsp(a);
1928 #endif
1929 #endif
1930 /* Todo: Set Data rate and RA */
1931 #if 0
1932 set_sta_rate(a, psta);
1933 #endif
1934 /* Todo: Firmware media status report */
1935 #if 0
1936 rtw_sta_media_status_rpt(a, psta, 1);
1937 #endif
1938 /* Todo: IC specific hardware setting */
1939 #if 0
1940 join_type = 2;
1941 rtw_hal_set_hwreg(a, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
1942 #endif
1943 if ((a->mlmeextpriv.mlmext_info.state & 0x03) == WIFI_FW_STATION_STATE) {
1944 /* Todo: Correct TSF */
1945 #if 0
1946 correct_TSF(a, MLME_STA_CONNECTED);
1947 #endif
1948 }
1949
1950 /* Todo: btcoex connect event notify */
1951 #if 0
1952 rtw_btcoex_connect_notify(a, join_type);
1953 #endif
1954 /* Todo: Beamforming setting */
1955 #if 0
1956 beamforming_wk_cmd(a, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
1957 #endif
1958
1959 rtw_join_done_chk_ch(a, 1);
1960 rtw_phl_connected(phl, a->phl_role, sta->phl_sta);
1961 #ifdef CONFIG_80211AX_HE
1962 rtw_he_init_om_info(a);
1963 #endif
1964 ATOMIC_SET(&a->need_tsf_sync_done, _TRUE);
1965 return 0;
1966 }
1967
rtw_hw_disconnect(struct _ADAPTER * a,struct sta_info * sta)1968 int rtw_hw_disconnect(struct _ADAPTER *a, struct sta_info *sta)
1969 {
1970 struct dvobj_priv *d;
1971 void *phl;
1972 enum rtw_phl_status status;
1973 int tid;
1974 u8 is_ap_self = _FALSE;
1975
1976 d = adapter_to_dvobj(a);
1977 phl = GET_PHL_INFO(d);
1978 if (!phl)
1979 return -1;
1980
1981 if (MLME_IS_AP(a) &&
1982 _rtw_memcmp(a->phl_role->mac_addr, sta->phl_sta->mac_addr, ETH_ALEN))
1983 is_ap_self = _TRUE;
1984
1985 /* Check and reset setting related to rx ampdu resources of PHL. */
1986 for (tid = 0; tid < TID_NUM; tid++) {
1987 if(sta->recvreorder_ctrl[tid].enable == _TRUE) {
1988 sta->recvreorder_ctrl[tid].enable =_FALSE;
1989 rtw_phl_stop_rx_ba_session(phl, sta->phl_sta, tid);
1990 RTW_INFO(FUNC_ADPT_FMT"stop process tid %d \n",
1991 FUNC_ADPT_ARG(a), tid);
1992 }
1993 }
1994
1995 /*reset sec setting and clean all connection setting*/
1996 rtw_hw_del_all_key(a, sta, PHL_CMD_DIRECTLY, 0);
1997
1998 if (is_ap_self == _FALSE) {
1999 status = rtw_phl_cmd_update_media_status(phl, sta->phl_sta, NULL, false,
2000 PHL_CMD_DIRECTLY, 0);
2001 if (status != RTW_PHL_STATUS_SUCCESS)
2002 return -1;
2003
2004 rtw_dump_phl_sta_info(RTW_DBGDUMP, sta);
2005 }
2006
2007 if (MLME_IS_STA(a)) {
2008 /*
2009 * the following flow only for STA
2010 * bypass client disconnect from softAP
2011 */
2012 #ifndef CONFIG_STA_CMD_DISPR
2013 rtw_phl_disconnect(phl, a->phl_role);
2014 #endif /* !CONFIG_STA_CMD_DISPR */
2015 rtw_disconnect_ch_switch(a);
2016 }
2017
2018 return 0;
2019 }
2020
rtw_hw_connected_apmode(struct _ADAPTER * a,struct sta_info * sta)2021 int rtw_hw_connected_apmode(struct _ADAPTER *a, struct sta_info *sta)
2022 {
2023 struct dvobj_priv *d;
2024 void *phl;
2025
2026 d = adapter_to_dvobj(a);
2027 phl = GET_PHL_INFO(d);
2028 if (!phl)
2029 return -1;
2030
2031 rtw_ap_set_sta_wmode(a, sta);
2032 update_sta_ra_info(a, sta);
2033 rtw_update_phl_sta_cap(a, sta, &sta->phl_sta->asoc_cap);
2034
2035 if (RTW_PHL_STATUS_SUCCESS != rtw_phl_cmd_update_media_status(
2036 phl, sta->phl_sta, sta->phl_sta->mac_addr, true,
2037 PHL_CMD_DIRECTLY, 0))
2038 return -1;
2039
2040 rtw_dump_phl_sta_info(RTW_DBGDUMP, sta);
2041
2042 return 0;
2043 }
2044
rtw_hal_get_def_var(struct _ADAPTER * a,enum _HAL_DEF_VARIABLE def_var,void * val)2045 u8 rtw_hal_get_def_var(struct _ADAPTER *a,
2046 enum _HAL_DEF_VARIABLE def_var, void *val)
2047 {
2048 switch (def_var) {
2049 case HAL_DEF_IS_SUPPORT_ANT_DIV:
2050 *(u8*)val = _FALSE;
2051 break;
2052 case HAL_DEF_DBG_DUMP_RXPKT:
2053 *(u8*)val = 0;
2054 break;
2055 case HAL_DEF_BEAMFORMER_CAP:
2056 *(u8*)val = a->phl_role->proto_role_cap.num_snd_dim;
2057 break;
2058 case HAL_DEF_BEAMFORMEE_CAP:
2059 *(u8*)val = a->phl_role->proto_role_cap.bfme_sts;
2060 break;
2061 case HW_VAR_MAX_RX_AMPDU_FACTOR:
2062 /* HT only */
2063 *(enum _HT_CAP_AMPDU_FACTOR*)val = MAX_AMPDU_FACTOR_64K;
2064 break;
2065 case HW_DEF_RA_INFO_DUMP:
2066 /* do nothing */
2067 break;
2068 case HAL_DEF_DBG_DUMP_TXPKT:
2069 *(u8*)val = 0;
2070 break;
2071 case HAL_DEF_TX_PAGE_SIZE:
2072 /* would be removed later */
2073 break;
2074 case HW_VAR_BEST_AMPDU_DENSITY:
2075 *(u8*)val = 0;
2076 break;
2077 default:
2078 break;
2079 }
2080
2081 return 0;
2082 }
2083
2084 #ifdef RTW_DETECT_HANG
2085 #define HANG_DETECT_THR 3
rtw_is_rxff_hang(_adapter * padapter,struct rxff_hang_info * prxff_hang_info)2086 void rtw_is_rxff_hang(_adapter *padapter, struct rxff_hang_info *prxff_hang_info)
2087 {
2088 struct dvobj_priv *pdvobjpriv = padapter->dvobj;
2089 void *phl = GET_PHL_INFO(pdvobjpriv);
2090 enum rtw_rx_status rx_sts;
2091
2092 rx_sts = rtw_phl_get_rx_status(phl);
2093 if (rx_sts == RTW_STATUS_RXDMA_HANG ||
2094 rx_sts == RTW_STATUS_RXFIFO_HANG) {
2095 if (prxff_hang_info->rx_ff_hang_cnt < HANG_DETECT_THR)
2096 prxff_hang_info->rx_ff_hang_cnt++;
2097 } else {
2098 prxff_hang_info->rx_ff_hang_cnt = 0;
2099 }
2100
2101 if (prxff_hang_info->rx_ff_hang_cnt == HANG_DETECT_THR)
2102 prxff_hang_info->dbg_is_rxff_hang = _TRUE;
2103 else
2104 prxff_hang_info->dbg_is_rxff_hang = _FALSE;
2105 }
2106
rtw_is_fw_hang(_adapter * padapter,struct fw_hang_info * pfw_hang_info)2107 void rtw_is_fw_hang(_adapter *padapter, struct fw_hang_info *pfw_hang_info)
2108 {
2109 struct dvobj_priv *pdvobjpriv = padapter->dvobj;
2110 void *phl = GET_PHL_INFO(pdvobjpriv);
2111 enum rtw_fw_status fw_sts;
2112
2113 fw_sts = rtw_phl_get_fw_status(phl);
2114
2115 if (fw_sts == RTW_FW_STATUS_NOFW) {
2116 pfw_hang_info->dbg_is_fw_gone = _TRUE;
2117 pfw_hang_info->dbg_is_fw_hang = _FALSE;
2118 } else {
2119 pfw_hang_info->dbg_is_fw_gone = _FALSE;
2120
2121 if (fw_sts == RTW_FW_STATUS_ASSERT ||
2122 fw_sts == RTW_FW_STATUS_EXCEP ||
2123 fw_sts == RTW_FW_STATUS_RXI300 ||
2124 fw_sts == RTW_FW_STATUS_HANG)
2125 pfw_hang_info->dbg_is_fw_hang = _TRUE;
2126 else
2127 pfw_hang_info->dbg_is_fw_hang = _FALSE;
2128 }
2129 }
2130
rtw_is_hang_check(_adapter * padapter)2131 void rtw_is_hang_check(_adapter *padapter)
2132 {
2133 u32 start_time = rtw_get_current_time();
2134 struct dvobj_priv *pdvobjpriv = padapter->dvobj;
2135 struct debug_priv *pdbgpriv = &pdvobjpriv->drv_dbg;
2136 struct hang_info *phang_info = &pdbgpriv->dbg_hang_info;
2137 /* struct fw_hang_info *pfw_hang_info = &phang_info->dbg_fw_hang_info; */
2138 struct rxff_hang_info *prxff_hang_info = &phang_info->dbg_rxff_hang_info;
2139 struct fw_hang_info *pfw_hang_info = &phang_info->dbg_fw_hang_info;
2140 u8 is_fw_in_ps_mode = _FALSE;
2141 u8 is_fw_ps_awake = _TRUE;
2142
2143 if (rtw_hw_get_init_completed(pdvobjpriv) && (!is_fw_in_ps_mode) &&
2144 is_fw_ps_awake) {
2145 phang_info->enter_cnt++;
2146
2147 rtw_is_rxff_hang(padapter, prxff_hang_info);
2148 rtw_is_fw_hang(padapter, pfw_hang_info);
2149 }
2150 }
2151 #endif /* RTW_DETECT_HANG */
2152
2153 #ifdef CONFIG_RTW_ACS
rtw_acs_get_channel_by_idx(struct _ADAPTER * a,u8 idx)2154 u16 rtw_acs_get_channel_by_idx(struct _ADAPTER *a, u8 idx)
2155 {
2156 struct dvobj_priv *d = adapter_to_dvobj(a);
2157 void *phl = GET_PHL_INFO(d);
2158
2159 if (phl)
2160 return rtw_phl_acs_get_channel_by_idx(phl, idx);
2161 else
2162 return 0;
2163 }
2164
rtw_acs_get_clm_ratio_by_idx(struct _ADAPTER * a,u8 idx)2165 u8 rtw_acs_get_clm_ratio_by_idx(struct _ADAPTER *a, u8 idx)
2166 {
2167 struct dvobj_priv *d = adapter_to_dvobj(a);
2168 void *phl = GET_PHL_INFO(d);
2169
2170 if (phl)
2171 return rtw_phl_acs_get_clm_ratio_by_idx(phl, idx);
2172 else
2173 return 0;
2174 }
2175
rtw_noise_query_by_idx(struct _ADAPTER * a,u8 idx)2176 s8 rtw_noise_query_by_idx(struct _ADAPTER *a, u8 idx)
2177 {
2178 struct dvobj_priv *d = adapter_to_dvobj(a);
2179 void *phl = GET_PHL_INFO(d);
2180
2181 if (phl)
2182 return rtw_phl_noise_query_by_idx(phl, idx);
2183 else
2184 return 0;
2185 }
2186 #endif /* CONFIG_RTW_ACS */
2187
rtw_dump_env_rpt(struct _ADAPTER * a,void * sel)2188 void rtw_dump_env_rpt(struct _ADAPTER *a, void *sel)
2189 {
2190 struct dvobj_priv *d = adapter_to_dvobj(a);
2191 struct rtw_phl_com_t *phl_com = GET_PHL_COM(d);
2192 void *phl = GET_PHL_INFO(d);
2193 struct rtw_env_report rpt;
2194
2195 rtw_phl_get_env_rpt(phl, &rpt, a->phl_role);
2196
2197 RTW_PRINT_SEL(sel, "clm_ratio:%d (%%)\n", rpt.nhm_cca_ratio);
2198 RTW_PRINT_SEL(sel, "nhm_ratio:%d (%%)\n", rpt.nhm_ratio);
2199 }
2200
2201 #ifdef CONFIG_WOWLAN
_cfg_keep_alive_info(struct _ADAPTER * a,u8 enable)2202 static u8 _cfg_keep_alive_info(struct _ADAPTER *a, u8 enable)
2203 {
2204 struct rtw_keep_alive_info info;
2205 struct dvobj_priv *d;
2206 void *phl;
2207 enum rtw_phl_status status;
2208 u8 check_period = 5;
2209
2210 d = adapter_to_dvobj(a);
2211 phl = GET_PHL_INFO(d);
2212
2213 _rtw_memset(&info, 0, sizeof(struct rtw_keep_alive_info));
2214
2215 info.keep_alive_en = enable;
2216 info.keep_alive_period = check_period;
2217
2218 RTW_INFO("%s: keep_alive_en=%d, keep_alive_period=%d\n",
2219 __func__, info.keep_alive_en, info.keep_alive_period);
2220
2221 status = rtw_phl_cfg_keep_alive_info(phl, &info);
2222 if (status != RTW_PHL_STATUS_SUCCESS) {
2223 RTW_INFO("%s fail(%d)\n", __func__, status);
2224 return _FAIL;
2225 }
2226
2227 return _SUCCESS;
2228 }
2229
_cfg_disc_det_info(struct _ADAPTER * a,u8 enable)2230 static u8 _cfg_disc_det_info(struct _ADAPTER *a, u8 enable)
2231 {
2232 struct wow_priv *wowpriv = adapter_to_wowlan(a);
2233 struct rtw_disc_det_info *wow_disc = &wowpriv->wow_disc;
2234 struct dvobj_priv *d;
2235 void *phl;
2236 enum rtw_phl_status status;
2237 struct registry_priv *registry_par;
2238 u8 check_period = 100, trypkt_num = 5;
2239
2240 d = adapter_to_dvobj(a);
2241 phl = GET_PHL_INFO(d);
2242 registry_par = &a->registrypriv;
2243
2244 wow_disc->disc_det_en = enable;
2245
2246 /* wake up event includes deauth wake up */
2247 if (registry_par->wakeup_event & BIT(2))
2248 wow_disc->disc_wake_en = _TRUE;
2249 else
2250 wow_disc->disc_wake_en = _FALSE;
2251 wow_disc->try_pkt_count = trypkt_num;
2252 wow_disc->check_period = check_period;
2253
2254 wow_disc->cnt_bcn_lost_en = 0;
2255 wow_disc->cnt_bcn_lost_limit = 0;
2256
2257 status = rtw_phl_cfg_disc_det_info(phl, wow_disc);
2258 if (status != RTW_PHL_STATUS_SUCCESS) {
2259 RTW_INFO("%s fail(%d)\n", __func__, status);
2260 return _FAIL;
2261 }
2262
2263 return _SUCCESS;
2264 }
2265
_cfg_arp_ofld_info(struct _ADAPTER * a)2266 static u8 _cfg_arp_ofld_info(struct _ADAPTER *a)
2267 {
2268 struct rtw_arp_ofld_info info;
2269 struct dvobj_priv *d;
2270 struct registry_priv *registry_par;
2271 void *phl;
2272 struct mlme_ext_priv *pmlmeext = &(a->mlmeextpriv);
2273 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2274 /* struct mlme_priv *pmlmepriv = &(a->mlmepriv); */
2275 /* u8 *target_ip = NULL, *target_mac = NULL; */
2276
2277 d = adapter_to_dvobj(a);
2278 phl = GET_PHL_INFO(d);
2279 registry_par = &a->registrypriv;
2280 _rtw_memset(&info, 0, sizeof(struct rtw_arp_ofld_info));
2281
2282 if (registry_par->wakeup_event)
2283 info.arp_en = 1;
2284 else
2285 info.arp_en = 0;
2286
2287 if (info.arp_en) {
2288 /* Sender IP address */
2289 _rtw_memcpy(info.arp_ofld_content.host_ipv4_addr,
2290 pmlmeinfo->ip_addr,
2291 IPV4_ADDRESS_LENGTH);
2292
2293 /* TODO : FW doesn't support arp keep alive */
2294 /* #ifdef CONFIG_ARP_KEEP_ALIVE */
2295 #if 0
2296 if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
2297 target_ip = pmlmepriv->gw_ip;
2298 target_mac = pmlmepriv->gw_mac_addr;
2299 RTW_INFO("Enabel CONFIG_ARP_KEEP_ALIVE\n");
2300 } else
2301 #endif
2302
2303 /* No need to fill Target IP & Target MAC address.
2304 * FW will fill correct Target IP & Target MAC address. */
2305 #if 0
2306 {
2307 target_ip = pmlmeinfo->ip_addr;
2308 target_mac = get_my_bssid(&(pmlmeinfo->network));
2309 }
2310
2311 /* Targe IP address */
2312 _rtw_memcpy(info.arp_ofld_content.remote_ipv4_addr, target_ip,
2313 IPV4_ADDRESS_LENGTH);
2314
2315 /* PHL doesn't use this variable */
2316 _rtw_memcpy(&(info.arp_ofld_content.mac_addr[0]), target_mac,
2317 MAC_ADDRESS_LENGTH);
2318 #endif
2319 }
2320
2321 rtw_phl_cfg_arp_ofld_info(phl, &info);
2322
2323 return _SUCCESS;
2324 }
2325
_cfg_ndp_ofld_info(struct _ADAPTER * a)2326 static u8 _cfg_ndp_ofld_info(struct _ADAPTER *a)
2327 {
2328 struct rtw_ndp_ofld_info info;
2329 struct dvobj_priv *d;
2330 void *phl;
2331 enum rtw_phl_status status;
2332
2333 d = adapter_to_dvobj(a);
2334 phl = GET_PHL_INFO(d);
2335
2336 _rtw_memset(&info, 0, sizeof(struct rtw_ndp_ofld_info));
2337
2338 rtw_phl_cfg_ndp_ofld_info(phl, &info);
2339
2340 return _SUCCESS;
2341 }
2342
2343 #ifdef CONFIG_GTK_OL
_cfg_gtk_ofld_info(struct _ADAPTER * a)2344 static u8 _cfg_gtk_ofld_info(struct _ADAPTER *a)
2345 {
2346 struct dvobj_priv *d;
2347 void *phl;
2348 enum rtw_phl_status status;
2349 struct rtw_gtk_ofld_info gtk_ofld_info = {0};
2350 struct rtw_gtk_ofld_content *gtk_ofld_content = NULL;
2351 struct security_priv *securitypriv = &a->securitypriv;
2352 struct sta_info *sta = NULL;
2353
2354 d = adapter_to_dvobj(a);
2355 phl = GET_PHL_INFO(d);
2356 sta = rtw_get_stainfo(&a->stapriv, get_bssid(&a->mlmepriv));
2357 gtk_ofld_content = >k_ofld_info.gtk_ofld_content;
2358
2359 if (securitypriv->binstallKCK_KEK) {
2360 gtk_ofld_info.gtk_en = _TRUE;
2361
2362 gtk_ofld_info.akmtype_byte3 = securitypriv->rsn_akm_suite_type;
2363
2364 gtk_ofld_content->kck_len = RTW_KCK_LEN;
2365 _rtw_memcpy(gtk_ofld_content->kck, sta->kck, RTW_KCK_LEN);
2366
2367 gtk_ofld_content->kek_len = RTW_KEK_LEN;
2368 _rtw_memcpy(gtk_ofld_content->kek, sta->kek, RTW_KEK_LEN);
2369
2370 if (securitypriv->dot11PrivacyAlgrthm == _TKIP_) {
2371 gtk_ofld_info.tkip_en = _TRUE;
2372 /* The driver offloads the Tx MIC key here, which is
2373 * actually the Rx MIC key, but the driver definition is
2374 * the opposite of the correct definition.
2375 */
2376 _rtw_memcpy(gtk_ofld_content->rxmickey,
2377 sta->dot11tkiptxmickey.skey, RTW_TKIP_MIC_LEN);
2378 }
2379
2380 _rtw_memcpy(gtk_ofld_content->replay_cnt, sta->replay_ctr,
2381 RTW_REPLAY_CTR_LEN);
2382 }
2383
2384 #ifdef CONFIG_IEEE80211W
2385 if (SEC_IS_BIP_KEY_INSTALLED(securitypriv)) {
2386 gtk_ofld_info.ieee80211w_en = 1;
2387 RTW_PUT_LE32(gtk_ofld_content->igtk_keyid,
2388 securitypriv->dot11wBIPKeyid);
2389 RTW_PUT_LE64(gtk_ofld_content->ipn,
2390 securitypriv->dot11wBIPrxpn.val);
2391 _rtw_memcpy(gtk_ofld_content->igtk[0],
2392 securitypriv->dot11wBIPKey[4].skey, RTW_IGTK_LEN);
2393 _rtw_memcpy(gtk_ofld_content->igtk[1],
2394 securitypriv->dot11wBIPKey[5].skey, RTW_IGTK_LEN);
2395 gtk_ofld_content->igtk_len = RTW_IGTK_LEN;
2396
2397 _rtw_memcpy(gtk_ofld_content->psk,
2398 sta->dot118021x_UncstKey.skey, RTW_PTK_LEN);
2399 gtk_ofld_content->psk_len = RTW_PTK_LEN;
2400 }
2401 #endif
2402
2403 rtw_phl_cfg_gtk_ofld_info(phl, >k_ofld_info);
2404
2405 return _SUCCESS;
2406 }
2407 #endif
2408
_cfg_realwow_info(struct _ADAPTER * a)2409 static u8 _cfg_realwow_info(struct _ADAPTER *a)
2410 {
2411 struct rtw_realwow_info info;
2412 struct dvobj_priv *d;
2413 void *phl;
2414 enum rtw_phl_status status;
2415
2416 d = adapter_to_dvobj(a);
2417 phl = GET_PHL_INFO(d);
2418
2419 /* default disable */
2420 _rtw_memset(&info, 0, sizeof(struct rtw_realwow_info));
2421 status = rtw_phl_cfg_realwow_info(phl, &info);
2422 if (status != RTW_PHL_STATUS_SUCCESS) {
2423 RTW_INFO("%s fail(%d)\n", __func__, status);
2424 return _FAIL;
2425 }
2426
2427 return _SUCCESS;
2428 }
2429
_cfg_wow_wake(struct _ADAPTER * a,u8 wow_en)2430 static u8 _cfg_wow_wake(struct _ADAPTER *a, u8 wow_en)
2431 {
2432 struct dvobj_priv *d;
2433 void *phl;
2434 enum rtw_phl_status status;
2435 struct rtw_wow_wake_info wow_wake_event;
2436 struct security_priv *securitypriv;
2437 struct registry_priv *registry_par = &a->registrypriv;
2438
2439 d = adapter_to_dvobj(a);
2440 phl = GET_PHL_INFO(d);
2441 securitypriv = &a->securitypriv;
2442
2443 wow_wake_event.wow_en = _TRUE;
2444 /* wake up by magic packet */
2445 if (registry_par->wakeup_event & BIT(0))
2446 wow_wake_event.magic_pkt_en = _TRUE;
2447 else
2448 wow_wake_event.magic_pkt_en = _FALSE;
2449 /* wake up by deauth packet */
2450 if (registry_par->wakeup_event & BIT(2))
2451 wow_wake_event.deauth_wakeup = _TRUE;
2452 else
2453 wow_wake_event.deauth_wakeup = _FALSE;
2454 /* wake up by pattern match packet */
2455 if (registry_par->wakeup_event & (BIT(1) | BIT(3))) {
2456 wow_wake_event.pattern_match_en = _TRUE;
2457
2458 rtw_wow_pattern_clean(a, RTW_DEFAULT_PATTERN);
2459
2460 if (registry_par->wakeup_event & BIT(1))
2461 rtw_set_default_pattern(a);
2462
2463 if (!(registry_par->wakeup_event & BIT(3)))
2464 rtw_wow_pattern_clean(a, RTW_CUSTOMIZED_PATTERN);
2465 } else {
2466 wow_wake_event.pattern_match_en = _FALSE;
2467 }
2468 /* wake up by ptk rekey */
2469 if (registry_par->wakeup_event & BIT(4))
2470 wow_wake_event.rekey_wakeup = _TRUE;
2471 else
2472 wow_wake_event.rekey_wakeup = _FALSE;
2473
2474 wow_wake_event.pairwise_sec_algo = rtw_sec_algo_drv2phl(securitypriv->dot11PrivacyAlgrthm);
2475 wow_wake_event.group_sec_algo = rtw_sec_algo_drv2phl(securitypriv->dot118021XGrpPrivacy);
2476 #ifdef CONFIG_IEEE80211W
2477 if (SEC_IS_BIP_KEY_INSTALLED(securitypriv))
2478 wow_wake_event.bip_sec_algo = rtw_sec_algo_drv2phl(securitypriv->dot11wCipher);
2479 #endif
2480
2481 rtw_construct_remote_control_info(a, &wow_wake_event.remote_wake_ctrl_info);
2482
2483 status = rtw_phl_cfg_wow_wake(phl, &wow_wake_event);
2484 if (status != RTW_PHL_STATUS_SUCCESS) {
2485 RTW_INFO("%s fail(%d)\n", __func__, status);
2486 return _FAIL;
2487 }
2488
2489 return _SUCCESS;
2490 }
2491
_cfg_wow_gpio(struct _ADAPTER * a)2492 static u8 _cfg_wow_gpio(struct _ADAPTER *a)
2493 {
2494 struct rtw_wow_wake_info info;
2495 struct dvobj_priv *d;
2496 void *phl;
2497 enum rtw_phl_status status;
2498 struct wow_priv *wowpriv = adapter_to_wowlan(a);
2499 struct rtw_wow_gpio_info *wow_gpio = &wowpriv->wow_gpio;
2500 struct registry_priv *registry_par = &a->registrypriv;
2501
2502 d = adapter_to_dvobj(a);
2503 phl = GET_PHL_INFO(d);
2504 #ifdef CONFIG_GPIO_WAKEUP
2505 wow_gpio->dev2hst_gpio_en = _TRUE;
2506
2507 /* ToDo: fw/halmac do not support so far
2508 pwrctrlpriv->hst2dev_high_active = HIGH_ACTIVE_HST2DEV;
2509 */
2510 #ifdef CONFIG_RTW_ONE_PIN_GPIO
2511 wow_gpio->dev2hst_gpio_mode = RTW_AX_SW_IO_MODE_INPUT;
2512 status = rtw_phl_cfg_wow_set_sw_gpio_mode(phl, gpio);
2513 #else
2514 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
2515 wow_gpio->dev2hst_gpio_mode = RTW_AX_SW_IO_MODE_OUTPUT_OD;
2516 wow_gpio->gpio_output_input = _TRUE;
2517 #else
2518 wow_gpio->dev2hst_gpio_mode = RTW_AX_SW_IO_MODE_OUTPUT_PP;
2519 wow_gpio->gpio_output_input = _FALSE;
2520 #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
2521 /* switch GPIO to open-drain or push-pull */
2522 status = rtw_phl_cfg_wow_set_sw_gpio_mode(phl, wow_gpio);
2523 /*default low active, gpio_active and dev2hst_high is the same thing
2524 , but two halmac implementation. FW and halmac need to refine */
2525 status = rtw_phl_cfg_wow_sw_gpio_ctrl(phl, wow_gpio);
2526 RTW_INFO("%s: set GPIO_%d %d as default. status=%d\n",
2527 __func__, WAKEUP_GPIO_IDX, wow_gpio->dev2hst_high, status);
2528 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
2529
2530 /* SDIO inband wake sdio_wakeup_enable
2531 wow_gpio->data_pin_wakeup = info->data_pin_wakeup;
2532 */
2533 /* two halmac implementation. FW and halmac need to refine */
2534 wow_gpio->dev2hst_gpio = WAKEUP_GPIO_IDX;
2535 wow_gpio->gpio_num = WAKEUP_GPIO_IDX;
2536
2537 status = rtw_phl_cfg_gpio_wake_pulse(phl, wow_gpio);
2538 if (status != RTW_PHL_STATUS_SUCCESS) {
2539 RTW_INFO("%s fail(%d)\n", __func__, status);
2540 return _FAIL;
2541 }
2542 #endif /* CONFIG_GPIO_WAKEUP */
2543 return _SUCCESS;
2544 }
2545
_wow_cfg(struct _ADAPTER * a,u8 wow_en)2546 static u8 _wow_cfg(struct _ADAPTER *a, u8 wow_en)
2547 {
2548 struct dvobj_priv *d;
2549 void *phl;
2550 struct rtw_phl_stainfo_t *phl_sta;
2551 enum rtw_phl_status status;
2552
2553 d = adapter_to_dvobj(a);
2554 phl = GET_PHL_INFO(d);
2555
2556 if (!_cfg_keep_alive_info(a, wow_en))
2557 return _FAIL;
2558
2559 if(!_cfg_disc_det_info(a, wow_en))
2560 return _FAIL;
2561
2562 if (!_cfg_arp_ofld_info(a))
2563 return _FAIL;
2564
2565 if (!_cfg_ndp_ofld_info(a))
2566 return _FAIL;
2567
2568 #ifdef CONFIG_GTK_OL
2569 if (!_cfg_gtk_ofld_info(a))
2570 return _FAIL;
2571 #endif
2572
2573 if (!_cfg_realwow_info(a))
2574 return _FAIL;
2575
2576 if (!_cfg_wow_wake(a, wow_en))
2577 return _FAIL;
2578
2579 if(!_cfg_wow_gpio(a))
2580 return _FAIL;
2581
2582 return _SUCCESS;
2583 }
2584
2585 #ifdef CONFIG_PNO_SUPPORT
_cfg_nlo_info(struct _ADAPTER * a)2586 static u8 _cfg_nlo_info(struct _ADAPTER *a)
2587 {
2588 struct dvobj_priv *d;
2589 struct wow_priv *wowpriv;
2590 struct rtw_nlo_info *wow_nlo;
2591 void *phl;
2592 enum rtw_phl_status status;
2593 int i;
2594
2595 d = adapter_to_dvobj(a);
2596 phl = GET_PHL_INFO(d);
2597 wowpriv = adapter_to_wowlan(a);
2598
2599 rtw_phl_cfg_nlo_info(phl, &wowpriv->wow_nlo);
2600
2601 return _SUCCESS;
2602 }
2603
_cfg_wow_nlo_wake(struct _ADAPTER * a)2604 static u8 _cfg_wow_nlo_wake(struct _ADAPTER *a)
2605 {
2606 struct dvobj_priv *d;
2607 void *phl;
2608 enum rtw_phl_status status;
2609 struct rtw_wow_wake_info wow_wake_event = {0};
2610 struct registry_priv *registry_par = &a->registrypriv;
2611
2612 d = adapter_to_dvobj(a);
2613 phl = GET_PHL_INFO(d);
2614
2615 wow_wake_event.wow_en = _TRUE;
2616 /* wake up by magic packet */
2617 if (registry_par->wakeup_event & BIT(0))
2618 wow_wake_event.magic_pkt_en = _TRUE;
2619 else
2620 wow_wake_event.magic_pkt_en = _FALSE;
2621
2622 status = rtw_phl_cfg_wow_wake(phl, &wow_wake_event);
2623 if (status != RTW_PHL_STATUS_SUCCESS) {
2624 RTW_INFO("%s fail(%d)\n", __func__, status);
2625 return _FAIL;
2626 }
2627
2628 return _SUCCESS;
2629 }
2630
_wow_nlo_cfg(struct _ADAPTER * a)2631 static u8 _wow_nlo_cfg(struct _ADAPTER *a)
2632 {
2633 struct dvobj_priv *d;
2634 void *phl;
2635
2636 d = adapter_to_dvobj(a);
2637 phl = GET_PHL_INFO(d);
2638
2639 if (!_cfg_nlo_info(a))
2640 return _FAIL;
2641
2642 if (!_cfg_wow_nlo_wake(a))
2643 return _FAIL;
2644
2645 if(!_cfg_wow_gpio(a))
2646 return _FAIL;
2647
2648 return _SUCCESS;
2649 }
2650 #endif
2651
rtw_hw_wow(struct _ADAPTER * a,u8 wow_en)2652 u8 rtw_hw_wow(struct _ADAPTER *a, u8 wow_en)
2653 {
2654 struct dvobj_priv *d;
2655 void *phl;
2656 struct pwrctrl_priv *pwrpriv;
2657 struct rtw_phl_stainfo_t *phl_sta;
2658 enum rtw_phl_status status;
2659
2660 pwrpriv = adapter_to_pwrctl(a);
2661 d = adapter_to_dvobj(a);
2662 phl = GET_PHL_INFO(d);
2663
2664 rtw_wow_lps_level_decide(a, _TRUE);
2665
2666 #ifdef CONFIG_PNO_SUPPORT
2667 if (pwrpriv->wowlan_pno_enable) {
2668 if (!_wow_nlo_cfg(a))
2669 return _FAIL;
2670 } else
2671 #endif
2672 {
2673 if (!_wow_cfg(a, wow_en))
2674 return _FAIL;
2675 }
2676
2677
2678 phl_sta = rtw_phl_get_stainfo_self(phl, a->phl_role);
2679
2680 if (wow_en)
2681 status = rtw_phl_suspend(phl, phl_sta, wow_en);
2682 else
2683 status = rtw_phl_resume(phl, phl_sta, &wow_en);
2684
2685 if (status != RTW_PHL_STATUS_SUCCESS) {
2686 RTW_ERR("%s wow %s fail(status: %d)\n", __func__, wow_en ? "enable" : "disable", status);
2687 return _FAIL;
2688 }
2689
2690 return _SUCCESS;
2691 }
2692 #endif
2693
rtw_edcca_mode_to_phl(enum rtw_edcca_mode_t mode)2694 static enum rtw_edcca_mode rtw_edcca_mode_to_phl(enum rtw_edcca_mode_t mode)
2695 {
2696 switch (mode) {
2697 case RTW_EDCCA_NORM:
2698 return RTW_EDCCA_NORMAL;
2699 case RTW_EDCCA_ADAPT:
2700 return RTW_EDCCA_ETSI;
2701 case RTW_EDCCA_CS:
2702 return RTW_EDCCA_JP;
2703 default:
2704 return RTW_EDCCA_MAX;
2705 }
2706 }
2707
rtw_update_phl_edcca_mode(struct _ADAPTER * a)2708 void rtw_update_phl_edcca_mode(struct _ADAPTER *a)
2709 {
2710 struct dvobj_priv *d = adapter_to_dvobj(a);
2711 void *phl = GET_PHL_INFO(d);
2712 struct rf_ctl_t *rfctl = dvobj_to_rfctl(d);
2713 struct rtw_chan_def chdef;
2714 enum band_type band;
2715 u8 mode = RTW_EDCCA_NORM;
2716 enum rtw_edcca_mode phl_mode = rtw_edcca_mode_to_phl(mode);
2717
2718 if (!a->phl_role)
2719 goto exit;
2720
2721 if (rtw_phl_mr_get_chandef(phl, a->phl_role, &chdef) != RTW_PHL_STATUS_SUCCESS) {
2722 RTW_ERR("%s get union chandef failed\n", __func__);
2723 rtw_warn_on(1);
2724 goto exit;
2725 }
2726
2727 if (chdef.chan != 0 && rtw_mi_check_fwstate(a, WIFI_ASOC_STATE)) {
2728 band = chdef.band;
2729 rfctl->last_edcca_mode_op_band = band;
2730 } else if (rfctl->last_edcca_mode_op_band != BAND_MAX)
2731 band = rfctl->last_edcca_mode_op_band;
2732 else {
2733 rtw_phl_get_cur_hal_chdef(a->phl_role, &chdef);
2734 band = chdef.band;
2735 }
2736
2737 mode = rtw_get_edcca_mode(d, band);
2738 /*
2739 * may get band not existing in current channel plan
2740 * then edcca mode RTW_EDCCA_MODE_NUM is got
2741 * this is not a real problem because this band is not used for TX
2742 * change to RTW_EDCCA_NORM to avoid warning calltrace below
2743 */
2744 if (mode == RTW_EDCCA_MODE_NUM)
2745 mode = RTW_EDCCA_NORM;
2746
2747 phl_mode = rtw_edcca_mode_to_phl(mode);
2748 if (phl_mode == RTW_EDCCA_MAX) {
2749 RTW_WARN("%s can't get valid phl mode from %s(%d)\n", __func__, rtw_edcca_mode_str(mode), mode);
2750 rtw_warn_on(1);
2751 return;
2752 }
2753
2754 exit:
2755 if (rtw_phl_get_edcca_mode(phl) != phl_mode)
2756 rtw_phl_set_edcca_mode(phl, phl_mode);
2757 }
2758
rtw_dump_phl_tx_power_ext_info(void * sel,_adapter * adapter)2759 void rtw_dump_phl_tx_power_ext_info(void *sel, _adapter *adapter)
2760 {
2761 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2762 void *phl_info = GET_PHL_INFO(dvobj);
2763 struct rtw_phl_com_t *phl_com = GET_PHL_COM(dvobj);
2764 u8 band_idx;
2765
2766 if (!adapter->phl_role)
2767 return;
2768
2769 band_idx = adapter->phl_role->hw_band;
2770
2771 RTW_PRINT_SEL(sel, "tx_power_by_rate: %s, %s, %s\n"
2772 , phl_com->dev_cap.pwrbyrate_off == RTW_PW_BY_RATE_ON ? "enabled" : "disabled"
2773 , phl_com->dev_cap.pwrbyrate_off == RTW_PW_BY_RATE_ON ? "loaded" : "unloaded"
2774 , phl_com->phy_sw_cap[0].rf_txpwr_byrate_info.para_src == RTW_PARA_SRC_EXTNAL ? "file" : "default"
2775 );
2776
2777 RTW_PRINT_SEL(sel, "tx_power_limit: %s, %s, %s\n"
2778 , rtw_phl_get_pwr_lmt_en(phl_info, band_idx) ? "enabled" : "disabled"
2779 , rtw_phl_get_pwr_lmt_en(phl_info, band_idx) ? "loaded" : "unloaded"
2780 , phl_com->phy_sw_cap[0].rf_txpwrlmt_info.para_src == RTW_PARA_SRC_EXTNAL ? "file" : "default"
2781 );
2782
2783 RTW_PRINT_SEL(sel, "tx_power_limit_ru: %s, %s, %s\n"
2784 , rtw_phl_get_pwr_lmt_en(phl_info, band_idx) ? "enabled" : "disabled"
2785 , rtw_phl_get_pwr_lmt_en(phl_info, band_idx) ? "loaded" : "unloaded"
2786 , phl_com->phy_sw_cap[0].rf_txpwrlmt_ru_info.para_src == RTW_PARA_SRC_EXTNAL ? "file" : "default"
2787 );
2788 }
2789
rtw_update_phl_txpwr_level(_adapter * adapter)2790 void rtw_update_phl_txpwr_level(_adapter *adapter)
2791 {
2792 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2793
2794 rtw_phl_set_tx_power(GET_PHL_INFO(dvobj), adapter->phl_role->hw_band);
2795 rtw_rfctl_update_op_mode(adapter_to_rfctl(adapter), 0, 0);
2796 }
2797
get_phy_tx_nss(_adapter * adapter)2798 inline u8 get_phy_tx_nss(_adapter *adapter)
2799 {
2800 u8 txss = 0;
2801
2802 if (adapter->phl_role)
2803 txss = GET_PHY_TX_NSS_BY_BAND(adapter, adapter->phl_role->hw_band);
2804 else
2805 rtw_warn_on(1);
2806
2807 return txss;
2808 }
2809
get_phy_rx_nss(_adapter * adapter)2810 inline u8 get_phy_rx_nss(_adapter *adapter)
2811 {
2812 u8 rxss = 0;
2813
2814 if (adapter->phl_role)
2815 rxss = GET_PHY_RX_NSS_BY_BAND(adapter, adapter->phl_role->hw_band);
2816 else
2817 rtw_warn_on(1);
2818
2819 return rxss;
2820 }