xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/core/rtw_phl.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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_dump_rfe_type(dvobj);
841 	rtw_hw_dump_hal_spec(RTW_DBGDUMP, dvobj);
842 
843 	#ifdef CONFIG_CMD_GENERAL
844 	rtw_phl_watchdog_init(dvobj->phl,
845 				0,
846 				rtw_core_watchdog_sw_hdlr,
847 				rtw_core_watchdog_hw_hdlr);
848 	#else
849 	rtw_phl_job_reg_wdog(dvobj->phl,
850 			rtw_dynamic_check_handlder,
851                         dvobj, NULL, 0, "rtw_dm", PWR_BASIC_IO);
852 	#endif
853 
854 	rtw_set_phl_regulation_ctx(dvobj);
855 
856 	rtw_efuse_dbg_raw_dump(dvobj);
857 
858 	rst = _SUCCESS;
859 	return rst;
860 
861 _free_hal :
862 	rtw_hw_deinit(dvobj);
863 	return rst;
864 }
865 
rtw_hw_start(struct dvobj_priv * dvobj)866 u8 rtw_hw_start(struct dvobj_priv *dvobj)
867 {
868 	if (dev_is_hw_start(dvobj))
869 		return _FAIL;
870 
871 	if (rtw_phl_start(GET_PHL_INFO(dvobj)) != RTW_PHL_STATUS_SUCCESS)
872 		return _FAIL;
873 
874 	#ifdef CONFIG_PCI_HCI
875 	//intr init flag
876 	dvobj_to_pci(dvobj)->irq_enabled = 1;
877 	#endif
878 	#ifdef CONFIG_CMD_GENERAL
879 	rtw_phl_watchdog_start(dvobj->phl);
880 	#endif
881 
882 	dev_set_hw_start(dvobj);
883 
884 	return _SUCCESS;
885 }
rtw_hw_stop(struct dvobj_priv * dvobj)886 void rtw_hw_stop(struct dvobj_priv *dvobj)
887 {
888 	if (!dev_is_hw_start(dvobj))
889 		return;
890 
891 	#ifdef CONFIG_CMD_GENERAL
892 	rtw_phl_watchdog_stop(dvobj->phl);
893 	#endif
894 	rtw_phl_stop(GET_PHL_INFO(dvobj));
895 
896 	#ifdef CONFIG_PCI_HCI
897 	//intr init flag
898 	dvobj_to_pci(dvobj)->irq_enabled = 0;
899 	#endif
900 
901 	dev_clr_hw_start(dvobj);
902 }
903 
rtw_hw_get_init_completed(struct dvobj_priv * dvobj)904 bool rtw_hw_get_init_completed(struct dvobj_priv *dvobj)
905 {
906 	return rtw_phl_is_init_completed(GET_PHL_INFO(dvobj));
907 }
908 
rtw_hw_is_init_completed(struct dvobj_priv * dvobj)909 bool rtw_hw_is_init_completed(struct dvobj_priv *dvobj)
910 {
911 	return (rtw_phl_is_init_completed(GET_PHL_INFO(dvobj))) ? _TRUE : _FALSE;
912 }
913 
914 #define NSS_VALID(nss) (nss > 0)
rtw_hw_cap_init(struct dvobj_priv * dvobj)915 void rtw_hw_cap_init(struct dvobj_priv *dvobj)
916 {
917 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj);
918 	struct rtw_phl_com_t *phl_com = GET_PHL_COM(dvobj);
919 	struct phy_cap_t *phy_cap = phl_com->phy_cap;
920 	struct registry_priv  *regpriv =
921 		&(dvobj_get_primary_adapter(dvobj)->registrypriv);
922 
923 #ifdef DIRTY_FOR_WORK
924 	dvobj->phl_com->rf_path_num = hal_spec->rf_reg_path_num; /*GET_HAL_RFPATH_NUM*/
925 	dvobj->phl_com->rf_type = RF_2T2R; /*GET_HAL_RFPATH*/
926 
927 	/* GEORGIA_TODO move related control module to phl layer*/
928 	/* macid_ctl moved to phl */
929 	/* dvobj->macid_ctl.num = rtw_min(hal_spec->macid_num, MACID_NUM_SW_LIMIT); */
930 	// Freddie ToDo: check macid_number from PHL?
931 	dvobj->wow_ctl.wow_cap = hal_spec->wow_cap;
932 
933 	dvobj->cam_ctl.sec_cap = hal_spec->sec_cap;
934 	dvobj->cam_ctl.num = rtw_min(hal_spec->sec_cam_ent_num, SEC_CAM_ENT_NUM_SW_LIMIT);
935 #endif
936 }
937 
938 
939 /*
940  * _ch_offset_drv2phl() - Convert driver channel offset to PHL type
941  * @ch_offset:	channel offset, ref: HAL_PRIME_CHNL_OFFSET_*
942  *
943  * Return PHL channel offset type "enum chan_offset"
944  */
_ch_offset_drv2phl(u8 ch_offset)945 static enum chan_offset _ch_offset_drv2phl(u8 ch_offset)
946 {
947 	if (ch_offset == CHAN_OFFSET_UPPER)
948 		return CHAN_OFFSET_UPPER;
949 	if (ch_offset == CHAN_OFFSET_LOWER)
950 		return CHAN_OFFSET_LOWER;
951 
952 	return CHAN_OFFSET_NO_EXT;
953 }
954 
955 /*
956  * rtw_hw_set_ch_bw() - Set channel, bandwidth and channel offset
957  * @a:		pointer of struct _ADAPTER
958  * @ch:		channel
959  * @bw:		bandwidth
960  * @offset:	channel offset, ref: HAL_PRIME_CHNL_OFFSET_*
961  *
962  * Set channel, bandwidth and channel offset.
963  *
964  * Return 0 for success, otherwise fail
965  */
rtw_hw_set_ch_bw(struct _ADAPTER * a,u8 ch,enum channel_width bw,u8 offset,u8 do_rfk)966 int rtw_hw_set_ch_bw(struct _ADAPTER *a, u8 ch, enum channel_width bw,
967 		      u8 offset, u8 do_rfk)
968 {
969 	enum rtw_phl_status status = RTW_PHL_STATUS_SUCCESS;
970 	struct dvobj_priv *dvobj = adapter_to_dvobj(a);
971 	int err = 0;
972 	struct rtw_chan_def chdef = {0};
973 	enum phl_cmd_type cmd_type = PHL_CMD_DIRECTLY;
974 	u32 cmd_timeout = 0;
975 
976 #ifdef CONFIG_MCC_MODE
977 	if (rtw_hw_mcc_chk_inprogress(a)) {
978 		RTW_WARN("under mcc, skip ch setting\n");
979 		return err;
980 	}
981 #endif
982 
983 	chdef.chan = ch;
984 	chdef.bw = bw;
985 	chdef.offset = offset;
986 	chdef.band = (ch > 14) ? BAND_ON_5G : BAND_ON_24G;
987 
988 	_rtw_mutex_lock_interruptible(&dvobj->setch_mutex);
989 #ifdef DBG_CONFIG_CMD_DISP
990 	if (a->cmd_type == 0xFF) {
991 		cmd_type = PHL_CMD_DIRECTLY;
992 		cmd_timeout = 0;
993 	}
994 	else {
995 		cmd_type = a->cmd_type;
996 		cmd_timeout = a->cmd_timeout;
997 	}
998 #endif
999 	status = rtw_phl_cmd_set_ch_bw(a->phl_role,
1000 					&chdef, do_rfk,
1001 					cmd_type, cmd_timeout);
1002 
1003 	if (status == RTW_PHL_STATUS_SUCCESS) {
1004 		if (a->bNotifyChannelChange)
1005 			RTW_INFO("[%s] ch = %d, offset = %d, bwmode = %d, success\n",
1006 				__FUNCTION__, ch, offset, bw);
1007 
1008 	} else {
1009 		err = -1;
1010 		RTW_ERR("%s: set ch(%u) bw(%u) offset(%u) FAIL!\n",
1011 			__func__, ch, bw, offset);
1012 	}
1013 
1014 	_rtw_mutex_unlock(&dvobj->setch_mutex);
1015 
1016 	return err;
1017 }
1018 
rtw_hw_update_chan_def(_adapter * adapter)1019 void rtw_hw_update_chan_def(_adapter *adapter)
1020 {
1021 	struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
1022 	struct rtw_phl_stainfo_t *phl_sta_self = NULL;
1023 
1024 	/*update chan_def*/
1025 	adapter->phl_role->chandef.band =
1026 		(mlmeext->chandef.chan > 14) ? BAND_ON_5G : BAND_ON_24G;
1027 	adapter->phl_role->chandef.chan = mlmeext->chandef.chan;
1028 	adapter->phl_role->chandef.bw = mlmeext->chandef.bw;
1029 	adapter->phl_role->chandef.offset = mlmeext->chandef.offset;
1030 	adapter->phl_role->chandef.center_ch = rtw_phl_get_center_ch(mlmeext->chandef.chan,
1031 										mlmeext->chandef.bw, mlmeext->chandef.offset);
1032 	/* ToDo: 80+80 BW & 160 BW */
1033 
1034 	phl_sta_self = rtw_phl_get_stainfo_self(adapter_to_dvobj(adapter)->phl, adapter->phl_role);
1035 	_rtw_memcpy(&phl_sta_self->chandef, &adapter->phl_role->chandef, sizeof(struct rtw_chan_def));
1036 }
1037 
_dump_phl_role_info(struct rtw_wifi_role_t * wrole)1038 static void _dump_phl_role_info(struct rtw_wifi_role_t *wrole)
1039 {
1040 	RTW_INFO("[WROLE]- role-idx: %d\n", wrole->id);
1041 
1042 	RTW_INFO("[WROLE]- type: %d\n", wrole->type);
1043 	RTW_INFO("[WROLE]- mstate: %d\n", wrole->mstate);
1044 	RTW_INFO("[WROLE]- mac_addr:"MAC_FMT"\n", MAC_ARG(wrole->mac_addr));
1045 	RTW_INFO("[WROLE]- hw_band: %d\n", wrole->hw_band);
1046 	RTW_INFO("[WROLE]- hw_port: %d\n", wrole->hw_port);
1047 	RTW_INFO("[WROLE]- hw_wmm: %d\n", wrole->hw_wmm);
1048 
1049 	RTW_INFO("[WROLE]- band: %d\n", wrole->chandef.band);
1050 	RTW_INFO("[WROLE]- chan: %d\n", wrole->chandef.chan);
1051 	RTW_INFO("[WROLE]- bw: %d\n", wrole->chandef.bw);
1052 	RTW_INFO("[WROLE]- offset: %d\n", wrole->chandef.offset);
1053 	// Freddie ToDo: MBSSID
1054 }
rtw_hw_iface_init(_adapter * adapter)1055 u8 rtw_hw_iface_init(_adapter *adapter)
1056 {
1057 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1058 	u8 phl_role_idx = INVALID_WIFI_ROLE_IDX;
1059 	u8 rst = _FAIL;
1060 	int chctx_num = 0;
1061 #if defined(CONFIG_RTW_IPS) || defined(CONFIG_RTW_LPS)
1062 	bool ps_allow = _FALSE;
1063 
1064 	rtw_phl_ps_set_rt_cap(GET_PHL_INFO(dvobj), HW_BAND_0, ps_allow, PS_RT_CORE_INIT);
1065 #endif
1066 	// Freddie ToDo: For AP mode, net type should be set to net device already.
1067 
1068 	/* will allocate phl self sta info */
1069 	phl_role_idx = rtw_phl_wifi_role_alloc(GET_PHL_INFO(dvobj),
1070 			adapter_mac_addr(adapter), PHL_RTYPE_STATION,
1071 			adapter->iface_id, &(adapter->phl_role), _FALSE);
1072 
1073 	if ((phl_role_idx == INVALID_WIFI_ROLE_IDX) ||
1074 		(adapter->phl_role == NULL)) {
1075 		RTW_ERR("rtw_phl_wifi_role_alloc failed\n");
1076 		rtw_warn_on(1);
1077 		goto _error;
1078 	}
1079 
1080 	/*init default value*/
1081 	#ifdef DBG_CONFIG_CMD_DISP
1082 	adapter->cmd_type = 0xFF;
1083 	adapter->cmd_timeout = 0;
1084 	#endif
1085 	rtw_hw_update_chan_def(adapter);
1086 	chctx_num = rtw_phl_mr_get_chanctx_num(GET_PHL_INFO(dvobj), adapter->phl_role);
1087 
1088 	if (chctx_num == 0) {
1089 		if (rtw_phl_cmd_set_ch_bw(adapter->phl_role,
1090 					&(adapter->phl_role->chandef),
1091 					_FALSE,
1092 					PHL_CMD_WAIT, 0) != RTW_PHL_STATUS_SUCCESS) {
1093 			RTW_ERR("%s init ch failed\n", __func__);
1094 		}
1095 	}
1096 
1097 	_dump_phl_role_info(adapter->phl_role);
1098 
1099 	/* init self staion info after wifi role alloc */
1100 	rst = rtw_init_self_stainfo(adapter);
1101 
1102 	#if defined (CONFIG_PCI_HCI) && defined (CONFIG_PCIE_TRX_MIT_FIX)
1103 	rtw_pcie_trx_mit_cmd(adapter, 0, 0,
1104 			     PCIE_RX_INT_MIT_TIMER, 0, 1);
1105 	#endif
1106 #if defined(CONFIG_RTW_IPS) || defined(CONFIG_RTW_LPS)
1107 	ps_allow = _TRUE;
1108 	rtw_phl_ps_set_rt_cap(GET_PHL_INFO(dvobj), HW_BAND_0, ps_allow, PS_RT_CORE_INIT);
1109 #endif
1110 
1111 	return rst;
1112 
1113 _error:
1114 	return rst;
1115 }
1116 
rtw_hw_iface_type_change(_adapter * adapter,u8 iface_type)1117 u8 rtw_hw_iface_type_change(_adapter *adapter, u8 iface_type)
1118 {
1119 	void *phl = GET_PHL_INFO(adapter_to_dvobj(adapter));
1120 #ifdef CONFIG_WIFI_MONITOR
1121 	struct rtw_phl_com_t *phl_com = GET_PHL_COM(adapter_to_dvobj(adapter));
1122 #endif
1123 	struct rtw_wifi_role_t *wrole = adapter->phl_role;
1124 	enum role_type rtype = PHL_RTYPE_NONE;
1125 	enum rtw_phl_status status;
1126 	struct sta_info *sta = NULL;
1127 
1128 	if (wrole == NULL) {
1129 		RTW_ERR("%s - wrole = NULL\n", __func__);
1130 		rtw_warn_on(1);
1131 		return _FAIL;
1132 	}
1133 
1134 	switch (iface_type) {
1135 	case _HW_STATE_ADHOC_:
1136 		rtype = PHL_RTYPE_ADHOC;
1137 		break;
1138 	case _HW_STATE_STATION_:
1139 		rtype = PHL_RTYPE_STATION;
1140 		break;
1141 	case _HW_STATE_AP_:
1142 		rtype = PHL_RTYPE_AP;
1143 		break;
1144 	case _HW_STATE_MONITOR_:
1145 		rtype = PHL_RTYPE_MONITOR;
1146 		break;
1147 	case _HW_STATE_NOLINK_:
1148 	default:
1149 		/* TBD */
1150 		break;
1151 	}
1152 
1153 	status = rtw_phl_cmd_wrole_change(phl, wrole,
1154 				WR_CHG_TYPE, (u8*)&rtype, sizeof(enum role_type),
1155 				PHL_CMD_DIRECTLY, 0);
1156 
1157 	if (status != RTW_PHL_STATUS_SUCCESS) {
1158 		RTW_ERR("%s - change to phl role type = %d fail with error = %d\n",
1159 			__func__, rtype, status);
1160 		rtw_warn_on(1);
1161 		return _FAIL;
1162 	}
1163 
1164 #ifdef CONFIG_WIFI_MONITOR
1165 	if (rtype == PHL_RTYPE_MONITOR) {
1166 		phl_com->append_fcs = false; /* This need to check again by yiwei*/
1167 		rtw_phl_enter_mon_mode(phl, wrole);
1168 	} else {
1169 		phl_com->append_fcs = true; /* This need to check again by yiwei*/
1170 		rtw_phl_leave_mon_mode(phl, wrole);
1171 	}
1172 #endif
1173 
1174 	/* AP allocates self-station and changes broadcast-station before hostapd adds key */
1175 	if (rtype == PHL_RTYPE_AP) {
1176 		sta = rtw_get_stainfo(&adapter->stapriv, adapter_mac_addr(adapter));
1177 		if (sta == NULL) {
1178 			sta = rtw_alloc_stainfo(&adapter->stapriv, adapter_mac_addr(adapter));
1179 			if (sta == NULL) {
1180 				RTW_ERR("%s - allocate AP self-station failed\n", __func__);
1181 				rtw_warn_on(1);
1182 				return _FAIL;
1183 			}
1184 		}
1185 	}
1186 
1187 	RTW_INFO("%s - change to type = %d success !\n", __func__, iface_type);
1188 
1189 	return _SUCCESS;
1190 }
1191 
rtw_hw_iface_deinit(_adapter * adapter)1192 void rtw_hw_iface_deinit(_adapter *adapter)
1193 {
1194 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1195 #if defined(CONFIG_RTW_IPS) || defined(CONFIG_RTW_LPS)
1196 	bool ps_allow = _FALSE;
1197 
1198 	rtw_phl_ps_set_rt_cap(GET_PHL_INFO(dvobj), HW_BAND_0, ps_allow, PS_RT_CORE_INIT);
1199 #endif
1200 	if (adapter->phl_role) {
1201 		rtw_free_self_stainfo(adapter);
1202 		rtw_phl_wifi_role_free(GET_PHL_INFO(dvobj), adapter->phl_role->id);
1203 		adapter->phl_role = NULL;
1204 	}
1205 #if defined(CONFIG_RTW_IPS) || defined(CONFIG_RTW_LPS)
1206 	ps_allow = _TRUE;
1207 	rtw_phl_ps_set_rt_cap(GET_PHL_INFO(dvobj), HW_BAND_0, ps_allow, PS_RT_CORE_INIT);
1208 #endif
1209 }
1210 
1211 /*
1212  * _sec_algo_drv2phl() - Convert security algorithm to PHL's definition
1213  * @drv_algo:		security algorithm
1214  * @phl_algo:		security algorithm for PHL, ref to enum rtw_enc_algo
1215  * @phl_key_len:	key length
1216  *
1217  * Convert driver's security algorithm defintion to PHL's type.
1218  *
1219  */
_sec_algo_drv2phl(enum security_type drv_algo,u8 * algo,u8 * key_len)1220 static void _sec_algo_drv2phl(enum security_type drv_algo,
1221 			      u8 *algo, u8 *key_len)
1222 {
1223 	u8 phl_algo = RTW_ENC_NONE;
1224 	u8 phl_key_len = 0;
1225 
1226 	switch(drv_algo) {
1227 	case _NO_PRIVACY_:
1228 		phl_algo = RTW_ENC_NONE;
1229 		phl_key_len = 0;
1230 		break;
1231 	case _WEP40_:
1232 		phl_algo = RTW_ENC_WEP40;
1233 		phl_key_len = 5;
1234 		break;
1235 	case _TKIP_:
1236 	case _TKIP_WTMIC_:
1237 		phl_algo = RTW_ENC_TKIP;
1238 		phl_key_len = 16;
1239 		break;
1240 	case _AES_:
1241 		phl_algo = RTW_ENC_CCMP;
1242 		phl_key_len = 16;
1243 		break;
1244 	case _WEP104_:
1245 		phl_algo = RTW_ENC_WEP104;
1246 		phl_key_len = 13;
1247 		break;
1248 	case _SMS4_:
1249 		phl_algo = RTW_ENC_WAPI;
1250 		phl_key_len = 32;
1251 		break;
1252 	case _GCMP_:
1253 		phl_algo = RTW_ENC_GCMP;
1254 		phl_key_len = 16;
1255 		break;
1256 	case _CCMP_256_:
1257 		phl_algo = RTW_ENC_CCMP256;
1258 		phl_key_len = 32;
1259 		break;
1260 	case _GCMP_256_:
1261 		phl_algo = RTW_ENC_GCMP256;
1262 		phl_key_len = 32;
1263 		break;
1264 #ifdef CONFIG_IEEE80211W
1265 	case _BIP_CMAC_128_:
1266 		phl_algo = RTW_ENC_BIP_CCMP128;
1267 		phl_key_len = 16;
1268 		break;
1269 #endif /* CONFIG_IEEE80211W */
1270 	default:
1271 		RTW_ERR("%s: No rule to covert drv algo(0x%x) to phl!!\n",
1272 			__func__, drv_algo);
1273 		phl_algo = RTW_ENC_MAX;
1274 		phl_key_len = 0;
1275 		break;
1276 	}
1277 
1278 	if(algo)
1279 		*algo = phl_algo;
1280 	if(key_len)
1281 		*key_len = phl_key_len;
1282 }
1283 
1284 /*
1285  * _sec_algo_phl2drv() - Convert security algorithm to core layer definition
1286  * @drv_algo:		security algorithm for core layer, ref to enum security_type
1287  * @phl_algo:		security algorithm for PHL, ref to enum rtw_enc_algo
1288  * @drv_key_len:	key length
1289  *
1290  * Convert PHL's security algorithm defintion to core layer definition.
1291  *
1292  */
_sec_algo_phl2drv(enum rtw_enc_algo phl_algo,u8 * algo,u8 * key_len)1293 static void _sec_algo_phl2drv(enum rtw_enc_algo phl_algo,
1294 			      u8 *algo, u8 *key_len)
1295 {
1296 	u8 drv_algo = RTW_ENC_NONE;
1297 	u8 drv_key_len = 0;
1298 
1299 	switch(phl_algo) {
1300 	case RTW_ENC_NONE:
1301 		drv_algo = _NO_PRIVACY_;
1302 		drv_key_len = 0;
1303 		break;
1304 	case RTW_ENC_WEP40:
1305 		drv_algo = _WEP40_;
1306 		drv_key_len = 5;
1307 		break;
1308 	case RTW_ENC_TKIP:
1309 		/* drv_algo = _TKIP_WTMIC_ */
1310 		drv_algo = _TKIP_;
1311 		drv_key_len = 16;
1312 		break;
1313 	case RTW_ENC_CCMP:
1314 		drv_algo = _AES_;
1315 		drv_key_len = 16;
1316 		break;
1317 	case RTW_ENC_WEP104:
1318 		drv_algo = _WEP104_;
1319 		drv_key_len = 13;
1320 		break;
1321 	case RTW_ENC_WAPI:
1322 		drv_algo = _SMS4_;
1323 		drv_key_len = 32;
1324 		break;
1325 	case RTW_ENC_GCMP:
1326 		drv_algo = _GCMP_;
1327 		drv_key_len = 16;
1328 		break;
1329 	case RTW_ENC_CCMP256:
1330 		drv_algo = _CCMP_256_;
1331 		drv_key_len = 32;
1332 		break;
1333 	case RTW_ENC_GCMP256:
1334 		drv_algo = _GCMP_256_;
1335 		drv_key_len = 32;
1336 		break;
1337 #ifdef CONFIG_IEEE80211W
1338 	case RTW_ENC_BIP_CCMP128:
1339 		drv_algo = _BIP_CMAC_128_;
1340 		drv_key_len = 16;
1341 		break;
1342 #endif /* CONFIG_IEEE80211W */
1343 	default:
1344 		RTW_ERR("%s: No rule to covert phl algo(0x%x) to drv!!\n",
1345 			__func__, phl_algo);
1346 		drv_algo = _SEC_TYPE_MAX_;
1347 		drv_key_len = 0;
1348 		break;
1349 	}
1350 
1351 	if(algo)
1352 		*algo = drv_algo;
1353 	if(key_len)
1354 		*key_len = drv_key_len;
1355 }
1356 
rtw_sec_algo_drv2phl(enum security_type drv_algo)1357 u8 rtw_sec_algo_drv2phl(enum security_type drv_algo)
1358 {
1359 	u8 algo = 0;
1360 
1361 	_sec_algo_drv2phl(drv_algo, &algo, NULL);
1362 	return algo;
1363 }
1364 
rtw_sec_algo_phl2drv(enum rtw_enc_algo phl_algo)1365 u8 rtw_sec_algo_phl2drv(enum rtw_enc_algo phl_algo)
1366 {
1367 	u8 algo = 0;
1368 
1369 	_sec_algo_phl2drv(phl_algo, &algo, NULL);
1370 	return algo;
1371 }
1372 
rtw_hw_chk_sec_mode(struct _ADAPTER * a,struct sta_info * sta,enum phl_cmd_type cmd_type,u32 cmd_timeout)1373 static int rtw_hw_chk_sec_mode(struct _ADAPTER *a, struct sta_info *sta,
1374 			enum phl_cmd_type cmd_type,  u32 cmd_timeout)
1375 {
1376 	struct dvobj_priv *d;
1377 	void *phl;
1378 	enum rtw_phl_status status;
1379 	u8 sec_mode = 0;
1380 	struct security_priv *psecuritypriv = &a->securitypriv;
1381 
1382 	d = adapter_to_dvobj(a);
1383 	phl = GET_PHL_INFO(d);
1384 
1385 	if (!phl)
1386 		return _FAIL;
1387 
1388 	sec_mode = rtw_phl_trans_sec_mode(
1389 		rtw_sec_algo_drv2phl(psecuritypriv->dot11PrivacyAlgrthm),
1390 		rtw_sec_algo_drv2phl(psecuritypriv->dot118021XGrpPrivacy));
1391 
1392 	RTW_INFO("After phl trans_sec_mode = %d\n", sec_mode);
1393 
1394 	if (sec_mode != sta->phl_sta->sec_mode) {
1395 		RTW_INFO("%s: original sec_mode =%d update sec mode to %d.\n",
1396 			__func__, sta->phl_sta->sec_mode, sec_mode);
1397 		status = rtw_phl_cmd_change_stainfo(phl, sta->phl_sta, STA_CHG_SEC_MODE,
1398 				&sec_mode, sizeof(u8), cmd_type, cmd_timeout);
1399 	/* To Do: check the return status */
1400 	} else {
1401 		RTW_INFO("%s: sec mode remains the same. skip update.\n", __func__);
1402 	}
1403 	return _SUCCESS;
1404 }
1405 
1406 /*
1407  * rtw_hw_add_key() - Add security key
1408  * @a:		pointer of struct _ADAPTER
1409  * @sta:	pointer of struct sta_info
1410  * @keyid:	key index
1411  * @keyalgo:	key algorithm
1412  * @keytype:	0: unicast / 1: multicast / 2: bip (ref: enum SEC_CAM_KEY_TYPE)
1413  * @key:	key content
1414  * @spp:	spp mode
1415  *
1416  * Add security key.
1417  *
1418  * Return 0 for success, otherwise fail.
1419  */
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)1420 int rtw_hw_add_key(struct _ADAPTER *a, struct sta_info *sta,
1421 		u8 keyid, enum security_type keyalgo, u8 keytype, u8 *key,
1422 		u8 spp, enum phl_cmd_type cmd_type,  u32 cmd_timeout)
1423 {
1424 	struct dvobj_priv *d;
1425 	void *phl;
1426 	struct phl_sec_param_h crypt = {0};
1427 	enum rtw_phl_status status;
1428 
1429 
1430 	d = adapter_to_dvobj(a);
1431 	phl = GET_PHL_INFO(d);
1432 	if (!phl)
1433 		return -1;
1434 
1435 	if (rtw_hw_chk_sec_mode(a, sta, cmd_type, cmd_timeout) == _FAIL)
1436 		return -1;
1437 
1438 	crypt.keyid = keyid;
1439 	crypt.key_type= keytype;
1440 	crypt.spp = spp;
1441 	_sec_algo_drv2phl(keyalgo, &crypt.enc_type, &crypt.key_len);
1442 
1443 	/* delete key before adding key */
1444 	rtw_phl_cmd_del_key(phl, sta->phl_sta, &crypt, cmd_type, cmd_timeout);
1445 	status = rtw_phl_cmd_add_key(phl, sta->phl_sta, &crypt, key, cmd_type, cmd_timeout);
1446 	if (status != RTW_PHL_STATUS_SUCCESS)
1447 		return -1;
1448 
1449 	return 0;
1450 }
1451 
1452 /*
1453  * rtw_hw_del_key() - Delete security key
1454  * @a:		pointer of struct _ADAPTER
1455  * @sta:	pointer of struct sta_info
1456  * @keyid:	key index
1457  * @keytype:	0: unicast / 1: multicast / 2: bip (ref: enum SEC_CAM_KEY_TYPE)
1458  *
1459  * Delete security key by macid, keyid and keytype.
1460  *
1461  * Return 0 for success, otherwise fail.
1462  */
rtw_hw_del_key(struct _ADAPTER * a,struct sta_info * sta,u8 keyid,u8 keytype,enum phl_cmd_type cmd_type,u32 cmd_timeout)1463 int rtw_hw_del_key(struct _ADAPTER *a, struct sta_info *sta,
1464 		u8 keyid, u8 keytype, enum phl_cmd_type cmd_type, u32 cmd_timeout)
1465 {
1466 	struct dvobj_priv *d;
1467 	void *phl;
1468 	struct phl_sec_param_h crypt = {0};
1469 	enum rtw_phl_status status;
1470 
1471 
1472 	d = adapter_to_dvobj(a);
1473 	phl = GET_PHL_INFO(d);
1474 	if (!phl)
1475 		return -1;
1476 
1477 	crypt.keyid = keyid;
1478 	crypt.key_type= keytype;
1479 
1480 	status = rtw_phl_cmd_del_key(phl, sta->phl_sta, &crypt, cmd_type, cmd_timeout);
1481 	if (status != RTW_PHL_STATUS_SUCCESS)
1482 		return -1;
1483 
1484 	return 0;
1485 }
1486 
1487 /*
1488  * rtw_hw_del_all_key() - Delete all security key for this STA
1489  * @a:		pointer of struct _ADAPTER
1490  * @sta:	pointer of struct sta_info
1491  *
1492  * Delete all security keys belong to this STA.
1493  *
1494  * Return 0 for success, otherwise fail.
1495  */
rtw_hw_del_all_key(struct _ADAPTER * a,struct sta_info * sta,enum phl_cmd_type cmd_type,u32 cmd_timeout)1496 int rtw_hw_del_all_key(struct _ADAPTER *a, struct sta_info *sta,
1497 			enum phl_cmd_type cmd_type, u32 cmd_timeout)
1498 {
1499 	struct dvobj_priv *d;
1500 	void *phl;
1501 	u8 keyid;
1502 	u8 keytype;
1503 	struct phl_sec_param_h crypt = {0};
1504 	enum rtw_phl_status status;
1505 
1506 
1507 	d = adapter_to_dvobj(a);
1508 	phl = GET_PHL_INFO(d);
1509 	if (!phl)
1510 		return -1;
1511 
1512 	/* Delete Group and Pairwise key */
1513 	for (keytype = 0; keytype < 2; keytype++) {
1514 		for (keyid = 0; keyid < 4; keyid++) {
1515 			crypt.keyid = keyid;
1516 			crypt.key_type = keytype;
1517 			rtw_phl_cmd_del_key(phl, sta->phl_sta, &crypt, cmd_type, cmd_timeout);
1518 		}
1519 	}
1520 
1521 	/* Delete BIP key */
1522 	crypt.key_type = 2;
1523 	for (keyid = 4; keyid <= BIP_MAX_KEYID; keyid++) {
1524 		crypt.keyid = keyid;
1525 		rtw_phl_cmd_del_key(phl, sta->phl_sta, &crypt, cmd_type, cmd_timeout);
1526 	}
1527 
1528 	return 0;
1529 }
1530 
rtw_hw_start_bss_network(struct _ADAPTER * a)1531 int rtw_hw_start_bss_network(struct _ADAPTER *a)
1532 {
1533 	/* some hw related ap settings */
1534 	if (rtw_phl_ap_started(adapter_to_dvobj(a)->phl, a->phl_role) !=
1535 		RTW_PHL_STATUS_SUCCESS)
1536 		return _FAIL;
1537 
1538 	return _SUCCESS;
1539 }
1540 
1541 /* connect */
rtw_hw_prepare_connect(struct _ADAPTER * a,struct sta_info * sta,u8 * target_addr)1542 int rtw_hw_prepare_connect(struct _ADAPTER *a, struct sta_info *sta, u8 *target_addr)
1543 {
1544 	/*adapter->phl_role.mac_addr*/
1545 	struct dvobj_priv *d;
1546 	void *phl;
1547 	enum rtw_phl_status status;
1548 
1549 
1550 	d = adapter_to_dvobj(a);
1551 	phl = GET_PHL_INFO(d);
1552 
1553 	status = rtw_phl_connect_prepare(phl, a->phl_role, target_addr);
1554 	if (status != RTW_PHL_STATUS_SUCCESS) {
1555 		RTW_ERR("%s: Fail to setup hardware for connecting!(%d)\n",
1556 			__func__, status);
1557 		return -1;
1558 	}
1559 	/* Todo: Enable TSF update */
1560 	/* Todo: Set support short preamble or not by beacon capability */
1561 	/* Todo: Set slot time */
1562 
1563 	return 0;
1564 }
1565 
1566 /* Handle connect fail case */
rtw_hw_connect_abort(struct _ADAPTER * a,struct sta_info * sta)1567 int rtw_hw_connect_abort(struct _ADAPTER *a, struct sta_info *sta)
1568 {
1569 	struct dvobj_priv *d;
1570 	void *phl;
1571 	enum rtw_phl_status status;
1572 
1573 
1574 	d = adapter_to_dvobj(a);
1575 	phl = GET_PHL_INFO(d);
1576 	if (!phl)
1577 		return -1;
1578 
1579 	rtw_hw_del_all_key(a, sta, PHL_CMD_DIRECTLY, 0);
1580 
1581 	status = rtw_phl_cmd_update_media_status(phl, sta->phl_sta, NULL, false,
1582 							PHL_CMD_DIRECTLY, 0);
1583 	if (status != RTW_PHL_STATUS_SUCCESS)
1584 		return -1;
1585 
1586 #ifndef CONFIG_STA_CMD_DISPR
1587 	/*
1588 	 * In CONFIG_STA_CMD_DISPR case, connect abort hw setting has been moved
1589 	 * to MSG_EVT_DISCONNECT@PHL_FG_MDL_CONNECT .
1590 	 */
1591 
1592 	/* disconnect hw setting */
1593 	rtw_phl_disconnect(phl, a->phl_role);
1594 
1595 	/* delete sta channel ctx */
1596 	rtw_phl_chanctx_del(adapter_to_dvobj(a)->phl, a->phl_role, NULL);
1597 	/* restore orig union ch */
1598 	rtw_join_done_chk_ch(a, -1);
1599 
1600 	/* free connecting AP sta info */
1601 	rtw_free_stainfo(a, sta);
1602 	rtw_init_self_stainfo(a);
1603 #endif /* !CONFIG_STA_CMD_DISPR */
1604 
1605 	return 0;
1606 }
1607 
1608 #ifdef RTW_WKARD_UPDATE_PHL_ROLE_CAP
1609 /**
1610  * rtw_update_phl_cap_by_rgstry() - Update cap & proto_role_cap of phl_role
1611  * @a:		struct _ADAPTER*
1612  *
1613  * Update cap & proto_role_cap of a->phl_role by registry/driver parameters.
1614  *
1615  */
rtw_update_phl_cap_by_rgstry(struct _ADAPTER * a)1616 void rtw_update_phl_cap_by_rgstry(struct _ADAPTER *a)
1617 {
1618 	struct registry_priv *rgstry;
1619 	struct role_cap_t *cap;
1620 	struct protocol_cap_t *prtcl;
1621 
1622 	rgstry = &a->registrypriv;
1623 	cap = &a->phl_role->cap;
1624 	prtcl = &a->phl_role->proto_role_cap;
1625 
1626 	/* LDPC */
1627 	prtcl->ht_ldpc &= (TEST_FLAG(rgstry->ldpc_cap, BIT4) ? 1 : 0);
1628 	cap->tx_ht_ldpc &= (TEST_FLAG(rgstry->ldpc_cap, BIT5) ? 1 : 0);
1629 	prtcl->vht_ldpc &= (TEST_FLAG(rgstry->ldpc_cap, BIT0) ? 1 : 0);
1630 	cap->tx_vht_ldpc &= (TEST_FLAG(rgstry->ldpc_cap, BIT1) ? 1 : 0);
1631 	prtcl->he_ldpc &= (TEST_FLAG(rgstry->ldpc_cap, BIT2) ? 1 : 0);
1632 	cap->tx_he_ldpc &= (TEST_FLAG(rgstry->ldpc_cap, BIT3) ? 1 : 0);
1633 }
1634 #endif /* RTW_WKARD_UPDATE_PHL_ROLE_CAP */
1635 
_dump_phl_sta_asoc_cap(struct sta_info * sta)1636 static void _dump_phl_sta_asoc_cap(struct sta_info *sta)
1637 {
1638 	struct rtw_phl_stainfo_t *phl_sta = sta->phl_sta;
1639 	struct protocol_cap_t *asoc_cap = &phl_sta->asoc_cap;
1640 #define _loc_dbg_func	RTW_DBG
1641 #define _loc_dbg(f)     _loc_dbg_func(#f ": %u\n", asoc_cap->f)
1642 
1643 
1644 	_loc_dbg_func("[PHL STA ASOC CAP]- mac_addr: " MAC_FMT "\n",
1645 		      MAC_ARG(phl_sta->mac_addr));
1646 	_loc_dbg(ht_ldpc);
1647 	_loc_dbg(vht_ldpc);
1648 	_loc_dbg(he_ldpc);
1649 	_loc_dbg(stbc_ht_rx);
1650 	_loc_dbg(stbc_vht_rx);
1651 	_loc_dbg(stbc_he_rx);
1652 	_loc_dbg(vht_su_bfmr);
1653 	_loc_dbg(vht_su_bfme);
1654 	_loc_dbg(vht_mu_bfmr);
1655 	_loc_dbg(vht_mu_bfme);
1656 	_loc_dbg(bfme_sts);
1657 	_loc_dbg(num_snd_dim);
1658 	_loc_dbg_func("[PHL STA ASOC CAP]- end\n");
1659 }
1660 
1661 #ifdef CONFIG_80211N_HT
1662 #ifdef CONFIG_80211AC_VHT
update_phl_sta_cap_vht(struct _ADAPTER * a,struct sta_info * sta,struct protocol_cap_t * cap)1663 static void update_phl_sta_cap_vht(struct _ADAPTER *a, struct sta_info *sta,
1664 			           struct protocol_cap_t *cap)
1665 {
1666 	struct vht_priv *vht;
1667 
1668 
1669 	vht = &sta->vhtpriv;
1670 
1671 	if (cap->ampdu_len_exp < vht->ampdu_len)
1672 		cap->ampdu_len_exp = vht->ampdu_len;
1673 	if (cap->max_amsdu_len < vht->max_mpdu_len)
1674 		cap->max_amsdu_len = vht->max_mpdu_len;
1675 
1676 	cap->sgi_80 = (vht->sgi_80m == _TRUE) ? 1 : 0;
1677 
1678 	_rtw_memcpy(cap->vht_rx_mcs, vht->vht_mcs_map, 2);
1679 	/* Todo: cap->vht_tx_mcs[2]; */
1680 	if (vht->op_present)
1681 		_rtw_memcpy(cap->vht_basic_mcs, &vht->vht_op[3], 2);
1682 }
1683 #endif /* CONFIG_80211AC_VHT */
update_phl_sta_cap_ht(struct _ADAPTER * a,struct sta_info * sta,struct protocol_cap_t * cap)1684 static void update_phl_sta_cap_ht(struct _ADAPTER *a, struct sta_info *sta,
1685 			          struct protocol_cap_t *cap)
1686 {
1687 	struct mlme_ext_info *info;
1688 	struct ht_priv *ht;
1689 
1690 
1691 	info = &a->mlmeextpriv.mlmext_info;
1692 	ht = &sta->htpriv;
1693 
1694 	cap->num_ampdu = 0xFF;	/* Set to MAX */
1695 
1696 	cap->ampdu_density = ht->rx_ampdu_min_spacing;
1697 	cap->ampdu_len_exp = GET_HT_CAP_ELE_MAX_AMPDU_LEN_EXP(&ht->ht_cap);
1698 	cap->amsdu_in_ampdu = 1;
1699 	cap->max_amsdu_len = GET_HT_CAP_ELE_MAX_AMSDU_LENGTH(&ht->ht_cap);
1700 
1701 	/*GET_HT_CAP_ELE_SM_PS(&info->HT_caps.u.HT_cap_element.HT_caps_info);*/
1702 	cap->sm_ps = info->SM_PS;
1703 
1704 	cap->sgi_20 = (ht->sgi_20m == _TRUE) ? 1 : 0;
1705 	cap->sgi_40 = (ht->sgi_40m == _TRUE) ? 1 : 0;
1706 
1707 	_rtw_memcpy(cap->ht_rx_mcs, ht->ht_cap.supp_mcs_set, 4);
1708 	/* Todo: cap->ht_tx_mcs[4]; */
1709 	if (info->HT_info_enable)
1710 		_rtw_memcpy(cap->ht_basic_mcs, info->HT_info.MCS_rate, 4);
1711 }
1712 #endif /* CONFIG_80211N_HT */
1713 
rtw_update_phl_sta_cap(struct _ADAPTER * a,struct sta_info * sta,struct protocol_cap_t * cap)1714 void rtw_update_phl_sta_cap(struct _ADAPTER *a, struct sta_info *sta,
1715 			    struct protocol_cap_t *cap)
1716 {
1717 	struct mlme_ext_info *info;
1718 
1719 
1720 	info = &a->mlmeextpriv.mlmext_info;
1721 
1722 	/* MAC related */
1723 	/* update beacon interval */
1724 	cap->bcn_interval = info->bcn_interval;
1725 #if 0
1726 	cap->num_ampdu;		/* HT, VHT, HE */
1727 	cap->ampdu_density:3;	/* HT, VHT, HE */
1728 	cap->ampdu_len_exp;	/* HT, VHT, HE */
1729 	cap->amsdu_in_ampdu:1;	/* HT, VHT, HE */
1730 	cap->max_amsdu_len:2;	/* HT, VHT, HE */
1731 	cap->htc_rx:1;
1732 	cap->sm_ps:2;		/* HT */
1733 	cap->trig_padding:2;
1734 	cap->twt:6;
1735 	cap->all_ack:1;
1736 	cap->a_ctrl:3;
1737 	cap->ops:1;
1738 	cap->ht_vht_trig_rx:1;
1739 #endif
1740 	cap->short_slot = (info->slotTime == SHORT_SLOT_TIME) ? 1 : 0;
1741 	cap->preamble = (info->preamble_mode == PREAMBLE_SHORT) ? 1 : 0;
1742 #if 0
1743 	cap->sgi_20:1;		/* HT */
1744 	cap->sgi_40:1;		/* HT */
1745 	cap->sgi_80:1;		/* VHT */
1746 	cap->sgi_160:1		/* VHT, HE */
1747 
1748 	/* BB related */
1749 	cap->ht_ldpc:1;		/* HT, HT_caps_handler() */
1750 	cap->vht_ldpc:1;	/* VHT, VHT_caps_handler() */
1751 	cap->he_ldpc:1;		/* HE, HE_phy_caps_handler() */
1752 	cap->sgi:1;
1753 	cap->su_bfmr:1;
1754 	cap->su_bfme:1;
1755 	cap->mu_bfmr:1;
1756 	cap->mu_bfme:1;
1757 	cap->bfme_sts:3;
1758 	cap->num_snd_dim:3;
1759 #endif
1760 	_rtw_memset(cap->supported_rates, 0, 12);
1761 	_rtw_memcpy(cap->supported_rates, sta->bssrateset,
1762 		    sta->bssratelen < 12 ? sta->bssratelen : 12);
1763 #if 0
1764 	cap->ht_rx_mcs[4];	/* HT */
1765 	cap->ht_tx_mcs[4];	/* HT */
1766 	cap->ht_basic_mcs[4];	/* Basic rate of HT */
1767 	cap->vht_rx_mcs[2];	/* VHT */
1768 	cap->vht_tx_mcs[2];	/* VHT */
1769 	cap->vht_basic_mcs[2];	/* Basic rate of VHT */
1770 #endif
1771 #if 0
1772 	/* HE done */
1773 	cap->he_rx_mcs[2];
1774 	cap->he_tx_mcs[2];
1775 	cap->he_basic_mcs[2];	/* Basic rate of HE */
1776 	cap->stbc_ht_rx:2;	/* HT_caps_handler() */
1777 	cap->stbc_vht_rx:3;	/* VHT_caps_handler() */
1778 	cap->stbc_he_rx:1;	/* HE_phy_caps_handler() */
1779 	cap->stbc_tx:1;
1780 	cap->ltf_gi;
1781 	cap->doppler_tx:1;
1782 	cap->doppler_rx:1;
1783 	cap->dcm_max_const_tx:2;
1784 	cap->dcm_max_nss_tx:1;
1785 	cap->dcm_max_const_rx:2;
1786 	cap->dcm_max_nss_rx:1;
1787 	cap->partial_bw_su_in_mu:1;
1788 	cap->bfme_sts_greater_80mhz:3;
1789 	cap->num_snd_dim_greater_80mhz:3;
1790 	cap->stbc_tx_greater_80mhz:1;
1791 	cap->stbc_rx_greater_80mhz:1;
1792 	cap->ng_16_su_fb:1;
1793 	cap->ng_16_mu_fb:1;
1794 	cap->cb_sz_su_fb:1;
1795 	cap->cb_sz_mu_fb:1;
1796 	cap->trig_su_bfm_fb:1;
1797 	cap->trig_mu_bfm_fb:1;
1798 	cap->trig_cqi_fb:1;
1799 	cap->partial_bw_su_er:1;
1800 	cap->pkt_padding:2;
1801 	cap->ppe_th[24];
1802 	cap->pwr_bst_factor:1;
1803 	cap->max_nc:3;
1804 	cap->dcm_max_ru:2;
1805 	cap->long_sigb_symbol:1;
1806 	cap->non_trig_cqi_fb:1;
1807 	cap->tx_1024q_ru:1;
1808 	cap->rx_1024q_ru:1;
1809 	cap->fbw_su_using_mu_cmprs_sigb:1;
1810 	cap->fbw_su_using_mu_non_cmprs_sigb:1;
1811 	cap->er_su:1;
1812 	cap->tb_pe:3;
1813 	cap->txop_du_rts_th;
1814 #endif
1815 
1816 #ifdef CONFIG_80211N_HT
1817 	if (sta->htpriv.ht_option) {
1818 		update_phl_sta_cap_ht(a, sta, cap);
1819 #ifdef CONFIG_80211AC_VHT
1820 		if (sta->vhtpriv.vht_option)
1821 			update_phl_sta_cap_vht(a, sta, cap);;
1822 #endif /* CONFIG_80211AC_VHT */
1823 	}
1824 #endif /* CONFIG_80211N_HT */
1825 }
1826 
1827 /**
1828  * rtw_hw_set_edca() - setup WMM EDCA parameter
1829  * @a:		struct _ADAPTER *
1830  * @ac:		Access Category, 0:BE, 1:BK, 2:VI, 3:VO
1831  * @param:	AIFS:BIT[7:0], CWMIN:BIT[11:8], CWMAX:BIT[15:12],
1832  *		TXOP:BIT[31:16]
1833  *
1834  * Setup WMM EDCA parameter set.
1835  *
1836  * Return 0 for SUCCESS, otherwise fail.
1837  */
rtw_hw_set_edca(struct _ADAPTER * a,u8 ac,u32 param)1838 int rtw_hw_set_edca(struct _ADAPTER *a, u8 ac, u32 param)
1839 {
1840 	struct dvobj_priv *d;
1841 	void *phl;
1842 	struct rtw_edca_param edca = {0};
1843 	enum rtw_phl_status status;
1844 
1845 
1846 	d = adapter_to_dvobj(a);
1847 	phl = GET_PHL_INFO(d);
1848 	if (!phl)
1849 		return -1;
1850 
1851 	edca.ac = ac;
1852 	edca.param = param;
1853 
1854 	status = rtw_phl_cmd_wrole_change(phl, a->phl_role,
1855 				WR_CHG_EDCA_PARAM, (u8*)&edca, sizeof(struct rtw_edca_param),
1856 				PHL_CMD_DIRECTLY, 0);
1857 
1858 	if (status != RTW_PHL_STATUS_SUCCESS) {
1859 		RTW_ERR("%s: fail to set edca parameter, ac(%u), "
1860 			"param(0x%08x)\n",
1861 			__func__, ac, param);
1862 		return -1;
1863 	}
1864 
1865 	return 0;
1866 }
1867 
rtw_hw_connected(struct _ADAPTER * a,struct sta_info * sta)1868 int rtw_hw_connected(struct _ADAPTER *a, struct sta_info *sta)
1869 {
1870 
1871 	struct dvobj_priv *d;
1872 	void *phl;
1873 	enum rtw_phl_status status;
1874 	struct security_priv *psecuritypriv = &a->securitypriv;
1875 #ifdef CONFIG_STA_MULTIPLE_BSSID
1876 	struct mlme_ext_priv	*pmlmeext = &a->mlmeextpriv;
1877 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
1878 #endif
1879 
1880 	d = adapter_to_dvobj(a);
1881 	phl = GET_PHL_INFO(d);
1882 	if (!phl)
1883 		return -1;
1884 
1885 	rtw_update_phl_sta_cap(a, sta, &sta->phl_sta->asoc_cap);
1886 	_dump_phl_sta_asoc_cap(sta);
1887 
1888 #ifdef CONFIG_STA_MULTIPLE_BSSID
1889 	/*use addr cam mask 0x1F to receive byte0~byte4 the same BSSID address == STA_CHG_MBSSID*/
1890 	if (pmlmeinfo->network.is_mbssid) {
1891 		sta->phl_sta->addr_sel = 3; /*MAC_AX_BSSID_MSK*/
1892 		sta->phl_sta->addr_msk = 0x1F; /*MAC_AX_BYTE5*/
1893 	}
1894 #endif
1895 
1896 	status = rtw_phl_cmd_update_media_status(phl, sta->phl_sta,
1897 					sta->phl_sta->mac_addr, true,
1898 					PHL_CMD_DIRECTLY, 0);
1899 	if (status != RTW_PHL_STATUS_SUCCESS)
1900 		return -1;
1901 	rtw_dump_phl_sta_info(RTW_DBGDUMP, sta);
1902 
1903 	/* Todo: update IOT-releated issue */
1904 #if 0
1905 	update_IOT_info(a);
1906 #endif
1907 	/* Todo: RTS full bandwidth setting */
1908 #if 0
1909 #ifdef CONFIG_RTS_FULL_BW
1910 	rtw_set_rts_bw(a);
1911 #endif /* CONFIG_RTS_FULL_BW */
1912 #endif
1913 	/* Todo: Basic rate setting */
1914 #if 0
1915 	rtw_hal_set_hwreg(a, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
1916 #endif
1917 	/* Todo: udpate capability: short preamble, slot time */
1918 	update_capinfo(a, a->mlmeextpriv.mlmext_info.capability);
1919 
1920 	WMMOnAssocRsp(a);
1921 
1922 	/* Todo: HT: AMPDU factor, min space, max time and related parameters */
1923 #if 0
1924 #ifdef CONFIG_80211N_HT
1925 	HTOnAssocRsp(a);
1926 #endif /* CONFIG_80211N_HT */
1927 #endif
1928 	/* Todo: VHT */
1929 #if 0
1930 #ifdef CONFIG_80211AC_VHT
1931 	VHTOnAssocRsp(a);
1932 #endif
1933 #endif
1934 	/* Todo: Set Data rate and RA */
1935 #if 0
1936 	set_sta_rate(a, psta);
1937 #endif
1938 	/* Todo: Firmware media status report */
1939 #if 0
1940 	rtw_sta_media_status_rpt(a, psta, 1);
1941 #endif
1942 	/* Todo: IC specific hardware setting */
1943 #if 0
1944 	join_type = 2;
1945 	rtw_hal_set_hwreg(a, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
1946 #endif
1947 	if ((a->mlmeextpriv.mlmext_info.state & 0x03) == WIFI_FW_STATION_STATE) {
1948 		/* Todo: Correct TSF */
1949 #if 0
1950 		correct_TSF(a, MLME_STA_CONNECTED);
1951 #endif
1952 	}
1953 
1954 	/* Todo: btcoex connect event notify */
1955 #if 0
1956 	rtw_btcoex_connect_notify(a, join_type);
1957 #endif
1958 	/* Todo: Beamforming setting */
1959 #if 0
1960 	beamforming_wk_cmd(a, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
1961 #endif
1962 
1963 	rtw_join_done_chk_ch(a, 1);
1964 	rtw_phl_connected(phl, a->phl_role, sta->phl_sta);
1965 #ifdef CONFIG_80211AX_HE
1966 	rtw_he_init_om_info(a);
1967 #endif
1968 	ATOMIC_SET(&a->need_tsf_sync_done, _TRUE);
1969 	return 0;
1970 }
1971 
rtw_hw_disconnect(struct _ADAPTER * a,struct sta_info * sta)1972 int rtw_hw_disconnect(struct _ADAPTER *a, struct sta_info *sta)
1973 {
1974 	struct dvobj_priv *d;
1975 	void *phl;
1976 	enum rtw_phl_status status;
1977 	int tid;
1978 	u8 is_ap_self = _FALSE;
1979 
1980 	d = adapter_to_dvobj(a);
1981 	phl = GET_PHL_INFO(d);
1982 	if (!phl)
1983 		return -1;
1984 
1985 	if (MLME_IS_AP(a) &&
1986 		_rtw_memcmp(a->phl_role->mac_addr, sta->phl_sta->mac_addr, ETH_ALEN))
1987 		is_ap_self = _TRUE;
1988 
1989 	/* Check and reset setting related to rx ampdu resources of PHL. */
1990 	for (tid = 0; tid < TID_NUM; tid++) {
1991 		if(sta->recvreorder_ctrl[tid].enable == _TRUE) {
1992 			sta->recvreorder_ctrl[tid].enable =_FALSE;
1993 			rtw_phl_stop_rx_ba_session(phl, sta->phl_sta, tid);
1994 			RTW_INFO(FUNC_ADPT_FMT"stop process tid %d \n",
1995 				FUNC_ADPT_ARG(a), tid);
1996 		}
1997 	}
1998 
1999 	/*reset sec setting and clean all connection setting*/
2000 	rtw_hw_del_all_key(a, sta, PHL_CMD_DIRECTLY, 0);
2001 
2002 	if (is_ap_self == _FALSE) {
2003 		status = rtw_phl_cmd_update_media_status(phl, sta->phl_sta, NULL, false,
2004 						PHL_CMD_DIRECTLY, 0);
2005 		if (status != RTW_PHL_STATUS_SUCCESS)
2006 			return -1;
2007 
2008 		rtw_dump_phl_sta_info(RTW_DBGDUMP, sta);
2009 	}
2010 
2011 	if (MLME_IS_STA(a)) {
2012 		/*
2013 		 * the following flow only for STA
2014 		 * bypass client disconnect from softAP
2015 		 */
2016 #ifndef CONFIG_STA_CMD_DISPR
2017 		rtw_phl_disconnect(phl, a->phl_role);
2018 #endif /* !CONFIG_STA_CMD_DISPR */
2019 		rtw_disconnect_ch_switch(a);
2020 	}
2021 
2022 	return 0;
2023 }
2024 
rtw_hw_connected_apmode(struct _ADAPTER * a,struct sta_info * sta)2025 int rtw_hw_connected_apmode(struct _ADAPTER *a, struct sta_info *sta)
2026 {
2027 	struct dvobj_priv *d;
2028 	void *phl;
2029 
2030 	d = adapter_to_dvobj(a);
2031 	phl = GET_PHL_INFO(d);
2032 	if (!phl)
2033 		return -1;
2034 
2035 	rtw_ap_set_sta_wmode(a, sta);
2036 	update_sta_ra_info(a, sta);
2037 	rtw_update_phl_sta_cap(a, sta, &sta->phl_sta->asoc_cap);
2038 
2039 	if (RTW_PHL_STATUS_SUCCESS != rtw_phl_cmd_update_media_status(
2040 		phl, sta->phl_sta, sta->phl_sta->mac_addr, true,
2041 		PHL_CMD_DIRECTLY, 0))
2042 		return -1;
2043 
2044 	rtw_dump_phl_sta_info(RTW_DBGDUMP, sta);
2045 
2046 	return 0;
2047 }
2048 
rtw_hal_get_def_var(struct _ADAPTER * a,enum _HAL_DEF_VARIABLE def_var,void * val)2049 u8 rtw_hal_get_def_var(struct _ADAPTER *a,
2050 		       enum _HAL_DEF_VARIABLE def_var, void *val)
2051 {
2052 	switch (def_var) {
2053 	case HAL_DEF_IS_SUPPORT_ANT_DIV:
2054 		*(u8*)val = _FALSE;
2055 		break;
2056 	case HAL_DEF_DBG_DUMP_RXPKT:
2057 		*(u8*)val = 0;
2058 		break;
2059 	case HAL_DEF_BEAMFORMER_CAP:
2060 		*(u8*)val = a->phl_role->proto_role_cap.num_snd_dim;
2061 		break;
2062 	case HAL_DEF_BEAMFORMEE_CAP:
2063 		*(u8*)val = a->phl_role->proto_role_cap.bfme_sts;
2064 		break;
2065 	case HW_VAR_MAX_RX_AMPDU_FACTOR:
2066 		/* HT only */
2067 		*(enum _HT_CAP_AMPDU_FACTOR*)val = MAX_AMPDU_FACTOR_64K;
2068 		break;
2069 	case HW_DEF_RA_INFO_DUMP:
2070 		/* do nothing */
2071 		break;
2072 	case HAL_DEF_DBG_DUMP_TXPKT:
2073 		*(u8*)val = 0;
2074 		break;
2075 	case HAL_DEF_TX_PAGE_SIZE:
2076 		/* would be removed later */
2077 		break;
2078 	case HW_VAR_BEST_AMPDU_DENSITY:
2079 		*(u8*)val = 0;
2080 		break;
2081 	default:
2082 		break;
2083 	}
2084 
2085 	return 0;
2086 }
2087 
2088 #ifdef RTW_DETECT_HANG
2089 #define HANG_DETECT_THR 3
rtw_is_rxff_hang(_adapter * padapter,struct rxff_hang_info * prxff_hang_info)2090 void rtw_is_rxff_hang(_adapter *padapter, struct rxff_hang_info *prxff_hang_info)
2091 {
2092 	struct dvobj_priv *pdvobjpriv = padapter->dvobj;
2093 	void *phl = GET_PHL_INFO(pdvobjpriv);
2094 	enum rtw_rx_status rx_sts;
2095 
2096 	rx_sts = rtw_phl_get_rx_status(phl);
2097 	if (rx_sts == RTW_STATUS_RXDMA_HANG ||
2098 	    rx_sts == RTW_STATUS_RXFIFO_HANG) {
2099 		if (prxff_hang_info->rx_ff_hang_cnt < HANG_DETECT_THR)
2100 			prxff_hang_info->rx_ff_hang_cnt++;
2101 	} else {
2102 		prxff_hang_info->rx_ff_hang_cnt = 0;
2103 	}
2104 
2105 	if (prxff_hang_info->rx_ff_hang_cnt == HANG_DETECT_THR)
2106 		prxff_hang_info->dbg_is_rxff_hang = _TRUE;
2107 	else
2108 		prxff_hang_info->dbg_is_rxff_hang = _FALSE;
2109 }
2110 
rtw_is_fw_hang(_adapter * padapter,struct fw_hang_info * pfw_hang_info)2111 void rtw_is_fw_hang(_adapter *padapter, struct fw_hang_info *pfw_hang_info)
2112 {
2113 	struct dvobj_priv *pdvobjpriv = padapter->dvobj;
2114 	void *phl = GET_PHL_INFO(pdvobjpriv);
2115 	enum rtw_fw_status fw_sts;
2116 
2117 	fw_sts = rtw_phl_get_fw_status(phl);
2118 
2119 	if (fw_sts == RTW_FW_STATUS_NOFW) {
2120 		pfw_hang_info->dbg_is_fw_gone = _TRUE;
2121 		pfw_hang_info->dbg_is_fw_hang = _FALSE;
2122 	} else {
2123 		pfw_hang_info->dbg_is_fw_gone = _FALSE;
2124 
2125 		if (fw_sts == RTW_FW_STATUS_ASSERT ||
2126 		    fw_sts == RTW_FW_STATUS_EXCEP ||
2127 		    fw_sts == RTW_FW_STATUS_RXI300 ||
2128 		    fw_sts == RTW_FW_STATUS_HANG)
2129 			pfw_hang_info->dbg_is_fw_hang = _TRUE;
2130 		else
2131 			pfw_hang_info->dbg_is_fw_hang = _FALSE;
2132 	}
2133 }
2134 
rtw_is_hang_check(_adapter * padapter)2135 void rtw_is_hang_check(_adapter *padapter)
2136 {
2137 	u32 start_time = rtw_get_current_time();
2138 	struct dvobj_priv *pdvobjpriv = padapter->dvobj;
2139 	struct debug_priv *pdbgpriv = &pdvobjpriv->drv_dbg;
2140 	struct hang_info *phang_info = &pdbgpriv->dbg_hang_info;
2141 	/* struct fw_hang_info *pfw_hang_info = &phang_info->dbg_fw_hang_info; */
2142 	struct rxff_hang_info *prxff_hang_info = &phang_info->dbg_rxff_hang_info;
2143 	struct fw_hang_info *pfw_hang_info = &phang_info->dbg_fw_hang_info;
2144 	u8 is_fw_in_ps_mode = _FALSE;
2145 	u8 is_fw_ps_awake = _TRUE;
2146 
2147 	if (rtw_hw_get_init_completed(pdvobjpriv) && (!is_fw_in_ps_mode) &&
2148 	    is_fw_ps_awake) {
2149 		phang_info->enter_cnt++;
2150 
2151 		rtw_is_rxff_hang(padapter, prxff_hang_info);
2152 		rtw_is_fw_hang(padapter, pfw_hang_info);
2153 	}
2154 }
2155 #endif /* RTW_DETECT_HANG */
2156 
2157 #ifdef CONFIG_RTW_ACS
rtw_acs_get_channel_by_idx(struct _ADAPTER * a,u8 idx)2158 u16 rtw_acs_get_channel_by_idx(struct _ADAPTER *a, u8 idx)
2159 {
2160 	struct dvobj_priv *d = adapter_to_dvobj(a);
2161 	void *phl = GET_PHL_INFO(d);
2162 
2163 	if (phl)
2164 		return rtw_phl_acs_get_channel_by_idx(phl, idx);
2165 	else
2166 		return 0;
2167 }
2168 
rtw_acs_get_clm_ratio_by_idx(struct _ADAPTER * a,u8 idx)2169 u8 rtw_acs_get_clm_ratio_by_idx(struct _ADAPTER *a, u8 idx)
2170 {
2171 	struct dvobj_priv *d = adapter_to_dvobj(a);
2172 	void *phl = GET_PHL_INFO(d);
2173 
2174 	if (phl)
2175 		return rtw_phl_acs_get_clm_ratio_by_idx(phl, idx);
2176 	else
2177 		return 0;
2178 }
2179 
rtw_noise_query_by_idx(struct _ADAPTER * a,u8 idx)2180 s8 rtw_noise_query_by_idx(struct _ADAPTER *a, u8 idx)
2181 {
2182 	struct dvobj_priv *d = adapter_to_dvobj(a);
2183 	void *phl = GET_PHL_INFO(d);
2184 
2185 	if (phl)
2186 		return rtw_phl_noise_query_by_idx(phl, idx);
2187 	else
2188 		return 0;
2189 }
2190 #endif /* CONFIG_RTW_ACS */
2191 
rtw_dump_env_rpt(struct _ADAPTER * a,void * sel)2192 void rtw_dump_env_rpt(struct _ADAPTER *a, void *sel)
2193 {
2194 	struct dvobj_priv *d = adapter_to_dvobj(a);
2195 	struct rtw_phl_com_t *phl_com = GET_PHL_COM(d);
2196 	void *phl = GET_PHL_INFO(d);
2197 	struct rtw_env_report rpt;
2198 
2199 	rtw_phl_get_env_rpt(phl, &rpt, a->phl_role);
2200 
2201 	RTW_PRINT_SEL(sel, "clm_ratio:%d (%%)\n", rpt.nhm_cca_ratio);
2202 	RTW_PRINT_SEL(sel, "nhm_ratio:%d (%%)\n", rpt.nhm_ratio);
2203 }
2204 
rtw_dump_rfe_type(struct dvobj_priv * d)2205 void rtw_dump_rfe_type(struct dvobj_priv *d)
2206 {
2207 	struct rtw_phl_com_t *phl_com = GET_PHL_COM(d);
2208 
2209 	RTW_INFO("RFE Type: %d\n", phl_com->dev_cap.rfe_type);
2210 }
2211 
2212 #ifdef CONFIG_WOWLAN
_cfg_keep_alive_info(struct _ADAPTER * a,u8 enable)2213 static u8 _cfg_keep_alive_info(struct _ADAPTER *a, u8 enable)
2214 {
2215 	struct rtw_keep_alive_info info;
2216 	struct dvobj_priv *d;
2217 	void *phl;
2218 	enum rtw_phl_status status;
2219 	u8 check_period = 5;
2220 
2221 	d = adapter_to_dvobj(a);
2222 	phl = GET_PHL_INFO(d);
2223 
2224 	_rtw_memset(&info, 0, sizeof(struct rtw_keep_alive_info));
2225 
2226 	info.keep_alive_en = enable;
2227 	info.keep_alive_period = check_period;
2228 
2229 	RTW_INFO("%s: keep_alive_en=%d, keep_alive_period=%d\n",
2230 				__func__, info.keep_alive_en, info.keep_alive_period);
2231 
2232 	status = rtw_phl_cfg_keep_alive_info(phl, &info);
2233 	if (status != RTW_PHL_STATUS_SUCCESS) {
2234 		RTW_INFO("%s fail(%d)\n", __func__, status);
2235 		return _FAIL;
2236 	}
2237 
2238 	return _SUCCESS;
2239 }
2240 
_cfg_disc_det_info(struct _ADAPTER * a,u8 enable)2241 static u8 _cfg_disc_det_info(struct _ADAPTER *a, u8 enable)
2242 {
2243 	struct wow_priv *wowpriv = adapter_to_wowlan(a);
2244 	struct rtw_disc_det_info *wow_disc = &wowpriv->wow_disc;
2245 	struct dvobj_priv *d;
2246 	void *phl;
2247 	enum rtw_phl_status status;
2248 	struct registry_priv *registry_par;
2249 	u8 check_period = 100, trypkt_num = 5;
2250 
2251 	d = adapter_to_dvobj(a);
2252 	phl = GET_PHL_INFO(d);
2253 	registry_par = &a->registrypriv;
2254 
2255 	wow_disc->disc_det_en = enable;
2256 
2257 	/* wake up event includes deauth wake up */
2258 	if (registry_par->wakeup_event & BIT(2))
2259 		wow_disc->disc_wake_en = _TRUE;
2260 	else
2261 		wow_disc->disc_wake_en = _FALSE;
2262 	wow_disc->try_pkt_count = trypkt_num;
2263 	wow_disc->check_period = check_period;
2264 
2265 	wow_disc->cnt_bcn_lost_en = 0;
2266 	wow_disc->cnt_bcn_lost_limit = 0;
2267 
2268 	status = rtw_phl_cfg_disc_det_info(phl, wow_disc);
2269 	if (status != RTW_PHL_STATUS_SUCCESS) {
2270 		RTW_INFO("%s fail(%d)\n", __func__, status);
2271 		return _FAIL;
2272 	}
2273 
2274 	return _SUCCESS;
2275 }
2276 
_cfg_arp_ofld_info(struct _ADAPTER * a)2277 static u8 _cfg_arp_ofld_info(struct _ADAPTER *a)
2278 {
2279 	struct rtw_arp_ofld_info info;
2280 	struct dvobj_priv *d;
2281 	struct registry_priv *registry_par;
2282 	void *phl;
2283 	struct mlme_ext_priv *pmlmeext = &(a->mlmeextpriv);
2284 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2285 	/* struct mlme_priv *pmlmepriv = &(a->mlmepriv); */
2286 	/* u8 *target_ip = NULL, *target_mac = NULL; */
2287 
2288 	d = adapter_to_dvobj(a);
2289 	phl = GET_PHL_INFO(d);
2290 	registry_par = &a->registrypriv;
2291 	_rtw_memset(&info, 0, sizeof(struct rtw_arp_ofld_info));
2292 
2293 	if (registry_par->wakeup_event)
2294 		info.arp_en = 1;
2295 	else
2296 		info.arp_en = 0;
2297 
2298 	if (info.arp_en) {
2299 		/* Sender IP address */
2300 		_rtw_memcpy(info.arp_ofld_content.host_ipv4_addr,
2301 			pmlmeinfo->ip_addr,
2302 			IPV4_ADDRESS_LENGTH);
2303 
2304 /* TODO : FW doesn't support arp keep alive */
2305 /* #ifdef CONFIG_ARP_KEEP_ALIVE */
2306 #if 0
2307 		if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
2308 			target_ip = pmlmepriv->gw_ip;
2309 			target_mac = pmlmepriv->gw_mac_addr;
2310 			RTW_INFO("Enabel CONFIG_ARP_KEEP_ALIVE\n");
2311 		} else
2312 #endif
2313 
2314 /* No need to fill Target IP & Target MAC address.
2315  * FW will fill correct Target IP & Target MAC address. */
2316 #if 0
2317 		{
2318 			target_ip = pmlmeinfo->ip_addr;
2319 			target_mac = get_my_bssid(&(pmlmeinfo->network));
2320 		}
2321 
2322 		/* Targe IP address */
2323 		_rtw_memcpy(info.arp_ofld_content.remote_ipv4_addr, target_ip,
2324 			IPV4_ADDRESS_LENGTH);
2325 
2326 		/* PHL doesn't use this variable */
2327 		_rtw_memcpy(&(info.arp_ofld_content.mac_addr[0]), target_mac,
2328 			MAC_ADDRESS_LENGTH);
2329 #endif
2330 	}
2331 
2332 	rtw_phl_cfg_arp_ofld_info(phl, &info);
2333 
2334 	return _SUCCESS;
2335 }
2336 
_cfg_ndp_ofld_info(struct _ADAPTER * a)2337 static u8 _cfg_ndp_ofld_info(struct _ADAPTER *a)
2338 {
2339 	struct rtw_ndp_ofld_info info;
2340 	struct dvobj_priv *d;
2341 	void *phl;
2342 	enum rtw_phl_status status;
2343 
2344 	d = adapter_to_dvobj(a);
2345 	phl = GET_PHL_INFO(d);
2346 
2347 	_rtw_memset(&info, 0, sizeof(struct rtw_ndp_ofld_info));
2348 
2349 	rtw_phl_cfg_ndp_ofld_info(phl, &info);
2350 
2351 	return _SUCCESS;
2352 }
2353 
2354 #ifdef CONFIG_GTK_OL
_cfg_gtk_ofld_info(struct _ADAPTER * a)2355 static u8 _cfg_gtk_ofld_info(struct _ADAPTER *a)
2356 {
2357 	struct dvobj_priv *d;
2358 	void *phl;
2359 	enum rtw_phl_status status;
2360 	struct rtw_gtk_ofld_info gtk_ofld_info = {0};
2361 	struct rtw_gtk_ofld_content *gtk_ofld_content = NULL;
2362 	struct security_priv *securitypriv = &a->securitypriv;
2363 	struct sta_info *sta = NULL;
2364 
2365 	d = adapter_to_dvobj(a);
2366 	phl = GET_PHL_INFO(d);
2367 	sta = rtw_get_stainfo(&a->stapriv, get_bssid(&a->mlmepriv));
2368 	gtk_ofld_content = &gtk_ofld_info.gtk_ofld_content;
2369 
2370 	if (securitypriv->binstallKCK_KEK) {
2371 		gtk_ofld_info.gtk_en = _TRUE;
2372 
2373 		gtk_ofld_info.akmtype_byte3 = securitypriv->rsn_akm_suite_type;
2374 
2375 		gtk_ofld_content->kck_len = RTW_KCK_LEN;
2376 		_rtw_memcpy(gtk_ofld_content->kck, sta->kck, RTW_KCK_LEN);
2377 
2378 		gtk_ofld_content->kek_len = RTW_KEK_LEN;
2379 		_rtw_memcpy(gtk_ofld_content->kek, sta->kek, RTW_KEK_LEN);
2380 
2381 		if (securitypriv->dot11PrivacyAlgrthm == _TKIP_) {
2382 			gtk_ofld_info.tkip_en = _TRUE;
2383 			/* The driver offloads the Tx MIC key here, which is
2384 			 * actually the Rx MIC key, but the driver definition is
2385 			 * the opposite of the correct definition.
2386 			 */
2387 			_rtw_memcpy(gtk_ofld_content->rxmickey,
2388 				    sta->dot11tkiptxmickey.skey, RTW_TKIP_MIC_LEN);
2389 		}
2390 
2391 		_rtw_memcpy(gtk_ofld_content->replay_cnt, sta->replay_ctr,
2392 			    RTW_REPLAY_CTR_LEN);
2393 	}
2394 
2395 #ifdef CONFIG_IEEE80211W
2396 	if (SEC_IS_BIP_KEY_INSTALLED(securitypriv)) {
2397 		gtk_ofld_info.ieee80211w_en = 1;
2398 		RTW_PUT_LE32(gtk_ofld_content->igtk_keyid,
2399 			     securitypriv->dot11wBIPKeyid);
2400 		RTW_PUT_LE64(gtk_ofld_content->ipn,
2401 			     securitypriv->dot11wBIPrxpn.val);
2402 		_rtw_memcpy(gtk_ofld_content->igtk[0],
2403 			    securitypriv->dot11wBIPKey[4].skey, RTW_IGTK_LEN);
2404 		_rtw_memcpy(gtk_ofld_content->igtk[1],
2405 			    securitypriv->dot11wBIPKey[5].skey, RTW_IGTK_LEN);
2406 		gtk_ofld_content->igtk_len = RTW_IGTK_LEN;
2407 
2408 		_rtw_memcpy(gtk_ofld_content->psk,
2409 			    sta->dot118021x_UncstKey.skey, RTW_PTK_LEN);
2410 		gtk_ofld_content->psk_len = RTW_PTK_LEN;
2411 	}
2412 #endif
2413 
2414 	rtw_phl_cfg_gtk_ofld_info(phl, &gtk_ofld_info);
2415 
2416 	return _SUCCESS;
2417 }
2418 #endif
2419 
_cfg_realwow_info(struct _ADAPTER * a)2420 static u8 _cfg_realwow_info(struct _ADAPTER *a)
2421 {
2422 	struct rtw_realwow_info info;
2423 	struct dvobj_priv *d;
2424 	void *phl;
2425 	enum rtw_phl_status status;
2426 
2427 	d = adapter_to_dvobj(a);
2428 	phl = GET_PHL_INFO(d);
2429 
2430 	/* default disable */
2431 	_rtw_memset(&info, 0, sizeof(struct rtw_realwow_info));
2432 	status = rtw_phl_cfg_realwow_info(phl, &info);
2433 	if (status != RTW_PHL_STATUS_SUCCESS) {
2434 		RTW_INFO("%s fail(%d)\n", __func__, status);
2435 		return _FAIL;
2436 	}
2437 
2438 	return _SUCCESS;
2439 }
2440 
_cfg_wow_wake(struct _ADAPTER * a,u8 wow_en)2441 static u8 _cfg_wow_wake(struct _ADAPTER *a, u8 wow_en)
2442 {
2443 	struct dvobj_priv *d;
2444 	void *phl;
2445 	enum rtw_phl_status status;
2446 	struct rtw_wow_wake_info wow_wake_event;
2447 	struct security_priv *securitypriv;
2448 	struct registry_priv  *registry_par = &a->registrypriv;
2449 
2450 	d = adapter_to_dvobj(a);
2451 	phl = GET_PHL_INFO(d);
2452 	securitypriv = &a->securitypriv;
2453 
2454 	wow_wake_event.wow_en = _TRUE;
2455 	/* wake up by magic packet */
2456 	if (registry_par->wakeup_event & BIT(0))
2457 		wow_wake_event.magic_pkt_en = _TRUE;
2458 	else
2459 		wow_wake_event.magic_pkt_en = _FALSE;
2460 	/* wake up by deauth packet */
2461 	if (registry_par->wakeup_event & BIT(2))
2462 		wow_wake_event.deauth_wakeup = _TRUE;
2463 	else
2464 		wow_wake_event.deauth_wakeup = _FALSE;
2465 	/* wake up by pattern match packet */
2466 	if (registry_par->wakeup_event & (BIT(1) | BIT(3))) {
2467 		wow_wake_event.pattern_match_en = _TRUE;
2468 
2469 		rtw_wow_pattern_clean(a, RTW_DEFAULT_PATTERN);
2470 
2471 		if (registry_par->wakeup_event & BIT(1))
2472 			rtw_set_default_pattern(a);
2473 
2474 		if (!(registry_par->wakeup_event & BIT(3)))
2475 			rtw_wow_pattern_clean(a, RTW_CUSTOMIZED_PATTERN);
2476 	} else {
2477 		wow_wake_event.pattern_match_en = _FALSE;
2478 	}
2479 	/* wake up by ptk rekey */
2480 	if (registry_par->wakeup_event & BIT(4))
2481 		wow_wake_event.rekey_wakeup = _TRUE;
2482 	else
2483 		wow_wake_event.rekey_wakeup = _FALSE;
2484 
2485 	wow_wake_event.pairwise_sec_algo = rtw_sec_algo_drv2phl(securitypriv->dot11PrivacyAlgrthm);
2486 	wow_wake_event.group_sec_algo = rtw_sec_algo_drv2phl(securitypriv->dot118021XGrpPrivacy);
2487 #ifdef CONFIG_IEEE80211W
2488 	if (SEC_IS_BIP_KEY_INSTALLED(securitypriv))
2489 		wow_wake_event.bip_sec_algo = rtw_sec_algo_drv2phl(securitypriv->dot11wCipher);
2490 #endif
2491 
2492 	rtw_construct_remote_control_info(a, &wow_wake_event.remote_wake_ctrl_info);
2493 
2494 	status = rtw_phl_cfg_wow_wake(phl, &wow_wake_event);
2495 	if (status != RTW_PHL_STATUS_SUCCESS) {
2496 		RTW_INFO("%s fail(%d)\n", __func__, status);
2497 		return _FAIL;
2498 	}
2499 
2500 	return _SUCCESS;
2501 }
2502 
_cfg_wow_gpio(struct _ADAPTER * a)2503 static u8 _cfg_wow_gpio(struct _ADAPTER *a)
2504 {
2505 	struct rtw_wow_wake_info info;
2506 	struct dvobj_priv *d;
2507 	void *phl;
2508 	enum rtw_phl_status status;
2509 	struct wow_priv *wowpriv = adapter_to_wowlan(a);
2510 	struct rtw_wow_gpio_info *wow_gpio = &wowpriv->wow_gpio;
2511 	struct registry_priv  *registry_par = &a->registrypriv;
2512 	struct rtw_dev2hst_gpio_info *d2h_gpio_info = &wow_gpio->d2h_gpio_info;
2513 
2514 	d = adapter_to_dvobj(a);
2515 	phl = GET_PHL_INFO(d);
2516 #ifdef CONFIG_GPIO_WAKEUP
2517 	d2h_gpio_info->dev2hst_gpio_en = _TRUE;
2518 
2519 	/* ToDo: fw/halmac do not support so far
2520 	pwrctrlpriv->hst2dev_high_active = HIGH_ACTIVE_HST2DEV;
2521 	*/
2522 #ifdef CONFIG_RTW_ONE_PIN_GPIO
2523 	wow_gpio->dev2hst_gpio_mode = RTW_AX_SW_IO_MODE_INPUT;
2524 	status = rtw_phl_cfg_wow_set_sw_gpio_mode(phl, gpio);
2525 #else
2526 	#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
2527 	wow_gpio->dev2hst_gpio_mode = RTW_AX_SW_IO_MODE_OUTPUT_OD;
2528 	d2h_gpio_info->gpio_output_input = _TRUE;
2529 	#else
2530 	wow_gpio->dev2hst_gpio_mode = RTW_AX_SW_IO_MODE_OUTPUT_PP;
2531 	d2h_gpio_info->gpio_output_input = _FALSE;
2532 	#endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
2533 	/* switch GPIO to open-drain or push-pull */
2534 	status = rtw_phl_cfg_wow_set_sw_gpio_mode(phl, wow_gpio);
2535 	/*default low active, gpio_active and dev2hst_high is the same thing
2536 	, but two halmac implementation. FW and halmac need to refine */
2537 	status = rtw_phl_cfg_wow_sw_gpio_ctrl(phl, wow_gpio);
2538 	RTW_INFO("%s: set GPIO_%d %d as default. status=%d\n",
2539 		 __func__, WAKEUP_GPIO_IDX, wow_gpio->dev2hst_high, status);
2540 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
2541 
2542 	/* SDIO inband wake sdio_wakeup_enable
2543 	d2h_gpio_info->data_pin_wakeup = info->data_pin_wakeup;
2544 	*/
2545 	/* two halmac implementation. FW and halmac need to refine */
2546 	wow_gpio->dev2hst_gpio = WAKEUP_GPIO_IDX;
2547 	d2h_gpio_info->gpio_num = WAKEUP_GPIO_IDX;
2548 
2549 	status = rtw_phl_cfg_gpio_wake_pulse(phl, wow_gpio);
2550 	if (status != RTW_PHL_STATUS_SUCCESS) {
2551 		RTW_INFO("%s fail(%d)\n", __func__, status);
2552 		return _FAIL;
2553 	}
2554 #endif /* CONFIG_GPIO_WAKEUP */
2555 	return _SUCCESS;
2556 }
2557 
_wow_cfg(struct _ADAPTER * a,u8 wow_en)2558 static u8 _wow_cfg(struct _ADAPTER *a, u8 wow_en)
2559 {
2560 	struct dvobj_priv *d;
2561 	void *phl;
2562 	struct rtw_phl_stainfo_t *phl_sta;
2563 	enum rtw_phl_status status;
2564 
2565 	d = adapter_to_dvobj(a);
2566 	phl = GET_PHL_INFO(d);
2567 
2568 	if (!_cfg_keep_alive_info(a, wow_en))
2569 		return _FAIL;
2570 
2571 	if(!_cfg_disc_det_info(a, wow_en))
2572 		return _FAIL;
2573 
2574 	if (!_cfg_arp_ofld_info(a))
2575 		return _FAIL;
2576 
2577 	if (!_cfg_ndp_ofld_info(a))
2578 		return _FAIL;
2579 
2580 #ifdef CONFIG_GTK_OL
2581 	if (!_cfg_gtk_ofld_info(a))
2582 		return _FAIL;
2583 #endif
2584 
2585 	if (!_cfg_realwow_info(a))
2586 		return _FAIL;
2587 
2588 	if (!_cfg_wow_wake(a, wow_en))
2589 		return _FAIL;
2590 
2591 	if(!_cfg_wow_gpio(a))
2592 		return _FAIL;
2593 
2594 	return _SUCCESS;
2595 }
2596 
2597 #ifdef CONFIG_PNO_SUPPORT
_cfg_nlo_info(struct _ADAPTER * a)2598 static u8 _cfg_nlo_info(struct _ADAPTER *a)
2599 {
2600 	struct dvobj_priv *d;
2601 	struct wow_priv *wowpriv;
2602 	struct rtw_nlo_info *wow_nlo;
2603 	void *phl;
2604 	enum rtw_phl_status status;
2605 	int i;
2606 
2607 	d = adapter_to_dvobj(a);
2608 	phl = GET_PHL_INFO(d);
2609 	wowpriv = adapter_to_wowlan(a);
2610 
2611 	rtw_phl_cfg_nlo_info(phl, &wowpriv->wow_nlo);
2612 
2613 	return _SUCCESS;
2614 }
2615 
_cfg_wow_nlo_wake(struct _ADAPTER * a)2616 static u8 _cfg_wow_nlo_wake(struct _ADAPTER *a)
2617 {
2618 	struct dvobj_priv *d;
2619 	void *phl;
2620 	enum rtw_phl_status status;
2621 	struct rtw_wow_wake_info wow_wake_event = {0};
2622 	struct registry_priv  *registry_par = &a->registrypriv;
2623 
2624 	d = adapter_to_dvobj(a);
2625 	phl = GET_PHL_INFO(d);
2626 
2627 	wow_wake_event.wow_en = _TRUE;
2628 	/* wake up by magic packet */
2629 	if (registry_par->wakeup_event & BIT(0))
2630 		wow_wake_event.magic_pkt_en = _TRUE;
2631 	else
2632 		wow_wake_event.magic_pkt_en = _FALSE;
2633 
2634 	status = rtw_phl_cfg_wow_wake(phl, &wow_wake_event);
2635 	if (status != RTW_PHL_STATUS_SUCCESS) {
2636 		RTW_INFO("%s fail(%d)\n", __func__, status);
2637 		return _FAIL;
2638 	}
2639 
2640 	return _SUCCESS;
2641 }
2642 
_wow_nlo_cfg(struct _ADAPTER * a)2643 static u8 _wow_nlo_cfg(struct _ADAPTER *a)
2644 {
2645 	struct dvobj_priv *d;
2646 	void *phl;
2647 
2648 	d = adapter_to_dvobj(a);
2649 	phl = GET_PHL_INFO(d);
2650 
2651 	if (!_cfg_nlo_info(a))
2652 		return _FAIL;
2653 
2654 	if (!_cfg_wow_nlo_wake(a))
2655 		return _FAIL;
2656 
2657 	if(!_cfg_wow_gpio(a))
2658 		return _FAIL;
2659 
2660 	return _SUCCESS;
2661 }
2662 #endif
2663 
rtw_hw_wow(struct _ADAPTER * a,u8 wow_en)2664 u8 rtw_hw_wow(struct _ADAPTER *a, u8 wow_en)
2665 {
2666 	struct dvobj_priv *d;
2667 	void *phl;
2668 	struct pwrctrl_priv *pwrpriv;
2669 	struct rtw_phl_stainfo_t *phl_sta;
2670 	enum rtw_phl_status status;
2671 
2672 	pwrpriv = adapter_to_pwrctl(a);
2673 	d = adapter_to_dvobj(a);
2674 	phl = GET_PHL_INFO(d);
2675 
2676 	rtw_wow_lps_level_decide(a, _TRUE);
2677 
2678 #ifdef CONFIG_PNO_SUPPORT
2679 	if (pwrpriv->wowlan_pno_enable) {
2680 		if (!_wow_nlo_cfg(a))
2681 			return _FAIL;
2682 	} else
2683 #endif
2684 	{
2685 		if (!_wow_cfg(a, wow_en))
2686 			return _FAIL;
2687 	}
2688 
2689 
2690 	phl_sta = rtw_phl_get_stainfo_self(phl, a->phl_role);
2691 
2692 	if (wow_en)
2693 		status = rtw_phl_suspend(phl, phl_sta, wow_en);
2694 	else
2695 		status = rtw_phl_resume(phl, phl_sta, &wow_en);
2696 
2697 	if (status != RTW_PHL_STATUS_SUCCESS) {
2698 		RTW_ERR("%s wow %s fail(status: %d)\n", __func__, wow_en ? "enable" : "disable", status);
2699 		return _FAIL;
2700 	}
2701 
2702 	return _SUCCESS;
2703 }
2704 #endif /* CONFIG_WOWLAN */
2705 
rtw_tx_sts_total(u32 * tx_sts,u8 num)2706 static u32 rtw_tx_sts_total(u32 *tx_sts, u8 num)
2707 {
2708 	u32 ret = 0;
2709 	int i = 0;
2710 
2711 	for (i = 0; i < num; i++)
2712 		ret += tx_sts[i];
2713 	return ret;
2714 }
2715 
rtw_get_sta_tx_stat(_adapter * adapter,struct sta_info * psta)2716 int rtw_get_sta_tx_stat(_adapter *adapter, struct sta_info *psta)
2717 {
2718 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
2719 	struct stainfo_stats	*pstats = NULL;
2720 
2721 	u32 tx_retry_cnt[PHL_AC_QUEUE_TOTAL] = {0};
2722 	u32 tx_fail_cnt[PHL_AC_QUEUE_TOTAL] = {0};
2723 	u32 tx_ok_cnt[PHL_AC_QUEUE_TOTAL] = {0};
2724 
2725 	rtw_phl_get_tx_retry_rpt(GET_PHL_INFO(adapter_to_dvobj(adapter)),psta->phl_sta,
2726 		tx_retry_cnt, PHL_AC_QUEUE_TOTAL);
2727 	rtw_phl_get_tx_fail_rpt(GET_PHL_INFO(adapter_to_dvobj(adapter)), psta->phl_sta,
2728 		tx_fail_cnt, PHL_AC_QUEUE_TOTAL);
2729 	rtw_phl_get_tx_ok_rpt(GET_PHL_INFO(adapter_to_dvobj(adapter)), psta->phl_sta,
2730 		tx_ok_cnt, PHL_AC_QUEUE_TOTAL);
2731 	pstats = &psta->sta_stats;
2732 	pstats->tx_retry_cnt = rtw_tx_sts_total(tx_retry_cnt, PHL_AC_QUEUE_TOTAL);
2733 	pstats->tx_fail_cnt = rtw_tx_sts_total(tx_fail_cnt, PHL_AC_QUEUE_TOTAL);
2734 	pstats->tx_ok_cnt =  rtw_tx_sts_total(tx_ok_cnt, PHL_AC_QUEUE_TOTAL);
2735 	pstats->total_tx_retry_cnt += pstats->tx_retry_cnt;
2736 
2737 	pstats->tx_fail_cnt_sum += pstats->tx_fail_cnt;
2738 	pstats->tx_retry_cnt_sum += pstats->tx_retry_cnt;
2739 #else
2740 	RTW_INFO("%s() not support\n", __func__);
2741 #endif
2742 	return 0;
2743 }
2744 
rtw_edcca_mode_to_phl(enum rtw_edcca_mode_t mode)2745 static enum rtw_edcca_mode rtw_edcca_mode_to_phl(enum rtw_edcca_mode_t mode)
2746 {
2747 	switch (mode) {
2748 	case RTW_EDCCA_NORM:
2749 		return RTW_EDCCA_NORMAL;
2750 	case RTW_EDCCA_ADAPT:
2751 		return RTW_EDCCA_ETSI;
2752 	case RTW_EDCCA_CS:
2753 		return RTW_EDCCA_JP;
2754 	default:
2755 		return RTW_EDCCA_MAX;
2756 	}
2757 }
2758 
rtw_update_phl_edcca_mode(struct _ADAPTER * a)2759 void rtw_update_phl_edcca_mode(struct _ADAPTER *a)
2760 {
2761 	struct dvobj_priv *d = adapter_to_dvobj(a);
2762 	void *phl = GET_PHL_INFO(d);
2763 	struct rf_ctl_t *rfctl = dvobj_to_rfctl(d);
2764 	struct rtw_chan_def chdef;
2765 	enum band_type band;
2766 	u8 mode = RTW_EDCCA_NORM;
2767 	enum rtw_edcca_mode phl_mode = rtw_edcca_mode_to_phl(mode);
2768 
2769 	if (!a->phl_role)
2770 		goto exit;
2771 
2772 	if (rtw_phl_mr_get_chandef(phl, a->phl_role, &chdef) != RTW_PHL_STATUS_SUCCESS) {
2773 		RTW_ERR("%s get union chandef failed\n", __func__);
2774 		rtw_warn_on(1);
2775 		goto exit;
2776 	}
2777 
2778 	if (chdef.chan != 0 && rtw_mi_check_fwstate(a, WIFI_ASOC_STATE)) {
2779 		band = chdef.band;
2780 		rfctl->last_edcca_mode_op_band = band;
2781 	} else if (rfctl->last_edcca_mode_op_band != BAND_MAX)
2782 		band = rfctl->last_edcca_mode_op_band;
2783 	else {
2784 		rtw_phl_get_cur_hal_chdef(a->phl_role, &chdef);
2785 		band = chdef.band;
2786 	}
2787 
2788 	mode = rtw_get_edcca_mode(d, band);
2789 	/*
2790 	* may get band not existing in current channel plan
2791 	* then edcca mode RTW_EDCCA_MODE_NUM is got
2792 	* this is not a real problem because this band is not used for TX
2793 	* change to RTW_EDCCA_NORM to avoid warning calltrace below
2794 	*/
2795 	if (mode == RTW_EDCCA_MODE_NUM)
2796 		mode = RTW_EDCCA_NORM;
2797 
2798 	phl_mode = rtw_edcca_mode_to_phl(mode);
2799 	if (phl_mode == RTW_EDCCA_MAX) {
2800 		RTW_WARN("%s can't get valid phl mode from %s(%d)\n", __func__, rtw_edcca_mode_str(mode), mode);
2801 		rtw_warn_on(1);
2802 		return;
2803 	}
2804 
2805 exit:
2806 	if (rtw_phl_get_edcca_mode(phl) != phl_mode)
2807 		rtw_phl_set_edcca_mode(phl, phl_mode);
2808 }
2809 
rtw_dump_phl_tx_power_ext_info(void * sel,_adapter * adapter)2810 void rtw_dump_phl_tx_power_ext_info(void *sel, _adapter *adapter)
2811 {
2812 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2813 	void *phl_info = GET_PHL_INFO(dvobj);
2814 	struct rtw_phl_com_t *phl_com = GET_PHL_COM(dvobj);
2815 	u8 band_idx;
2816 
2817 	if (!adapter->phl_role)
2818 		return;
2819 
2820 	band_idx = adapter->phl_role->hw_band;
2821 
2822 	RTW_PRINT_SEL(sel, "tx_power_by_rate: %s, %s, %s\n"
2823 		, phl_com->dev_cap.pwrbyrate_off == RTW_PW_BY_RATE_ON ? "enabled" : "disabled"
2824 		, phl_com->dev_cap.pwrbyrate_off == RTW_PW_BY_RATE_ON ? "loaded" : "unloaded"
2825 		, phl_com->phy_sw_cap[0].rf_txpwr_byrate_info.para_src == RTW_PARA_SRC_EXTNAL ? "file" : "default"
2826 	);
2827 
2828 	RTW_PRINT_SEL(sel, "tx_power_limit: %s, %s, %s\n"
2829 		, rtw_phl_get_pwr_lmt_en(phl_info, band_idx) ? "enabled" : "disabled"
2830 		, rtw_phl_get_pwr_lmt_en(phl_info, band_idx) ? "loaded" : "unloaded"
2831 		, phl_com->phy_sw_cap[0].rf_txpwrlmt_info.para_src == RTW_PARA_SRC_EXTNAL ? "file" : "default"
2832 	);
2833 
2834 	RTW_PRINT_SEL(sel, "tx_power_limit_ru: %s, %s, %s\n"
2835 		, rtw_phl_get_pwr_lmt_en(phl_info, band_idx) ? "enabled" : "disabled"
2836 		, rtw_phl_get_pwr_lmt_en(phl_info, band_idx) ? "loaded" : "unloaded"
2837 		, phl_com->phy_sw_cap[0].rf_txpwrlmt_ru_info.para_src == RTW_PARA_SRC_EXTNAL ? "file" : "default"
2838 	);
2839 }
2840 
rtw_update_phl_txpwr_level(_adapter * adapter)2841 void rtw_update_phl_txpwr_level(_adapter *adapter)
2842 {
2843 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2844 
2845 	rtw_phl_set_tx_power(GET_PHL_INFO(dvobj), adapter->phl_role->hw_band);
2846 	rtw_rfctl_update_op_mode(adapter_to_rfctl(adapter), 0, 0);
2847 }
2848 
get_phy_tx_nss(_adapter * adapter)2849 inline u8 get_phy_tx_nss(_adapter *adapter)
2850 {
2851 	u8 txss = 0;
2852 
2853 	if (adapter->phl_role)
2854 		txss = GET_PHY_TX_NSS_BY_BAND(adapter, adapter->phl_role->hw_band);
2855 	else
2856 		rtw_warn_on(1);
2857 
2858 	return txss;
2859 }
2860 
get_phy_rx_nss(_adapter * adapter)2861 inline u8 get_phy_rx_nss(_adapter *adapter)
2862 {
2863 	u8 rxss = 0;
2864 
2865 	if (adapter->phl_role)
2866 		rxss = GET_PHY_RX_NSS_BY_BAND(adapter, adapter->phl_role->hw_band);
2867 	else
2868 		rtw_warn_on(1);
2869 
2870 	return rxss;
2871 }
2872