xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8723ds/hal/hal_com.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2017 Realtek Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of version 2 of the GNU General Public License as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  *****************************************************************************/
16 #define _HAL_COM_C_
17 
18 #include <drv_types.h>
19 #include "hal_com_h2c.h"
20 
21 #include "hal_data.h"
22 
23 #ifdef RTW_HALMAC
24 #include "../../hal/hal_halmac.h"
25 #endif
26 
rtw_dump_fw_info(void * sel,_adapter * adapter)27 void rtw_dump_fw_info(void *sel, _adapter *adapter)
28 {
29 	HAL_DATA_TYPE	*hal_data = NULL;
30 
31 	if (!adapter)
32 		return;
33 
34 	hal_data = GET_HAL_DATA(adapter);
35 	if (hal_data->bFWReady)
36 		RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);
37 	else
38 		RTW_PRINT_SEL(sel, "FW not ready\n");
39 }
40 
rsvd_page_cache_update_all(struct rsvd_page_cache_t * cache,u8 loc,u8 txdesc_len,u32 page_size,u8 * info,u32 info_len)41 bool rsvd_page_cache_update_all(struct rsvd_page_cache_t *cache, u8 loc
42 	, u8 txdesc_len, u32 page_size, u8 *info, u32 info_len)
43 {
44 	u8 page_num;
45 	bool modified = 0;
46 	bool loc_mod = 0, size_mod = 0, page_num_mod = 0;
47 
48 	page_num = info_len ? (u8)PageNum(txdesc_len + info_len, page_size) : 0;
49 	if (!info_len)
50 		loc = 0;
51 
52 	if (cache->loc != loc) {
53 		RTW_INFO("%s %s loc change (%u -> %u)\n"
54 			, __func__, cache->name, cache->loc, loc);
55 		loc_mod = 1;
56 	}
57 	if (cache->size != info_len) {
58 		RTW_INFO("%s %s size change (%u -> %u)\n"
59 			, __func__, cache->name, cache->size, info_len);
60 		size_mod = 1;
61 	}
62 	if (cache->page_num != page_num) {
63 		RTW_INFO("%s %s page_num change (%u -> %u)\n"
64 			, __func__, cache->name, cache->page_num, page_num);
65 		page_num_mod = 1;
66 	}
67 
68 	if (info && info_len) {
69 		if (cache->data) {
70 			if (cache->size == info_len) {
71 				if (_rtw_memcmp(cache->data, info, info_len) != _TRUE) {
72 					RTW_INFO("%s %s data change\n", __func__, cache->name);
73 					modified = 1;
74 				}
75 			} else
76 				rsvd_page_cache_free_data(cache);
77 		}
78 
79 		if (!cache->data) {
80 			cache->data = rtw_malloc(info_len);
81 			if (!cache->data) {
82 				RTW_ERR("%s %s alloc data with size(%u) fail\n"
83 					, __func__, cache->name, info_len);
84 				rtw_warn_on(1);
85 			} else {
86 				RTW_INFO("%s %s alloc data with size(%u)\n"
87 					, __func__, cache->name, info_len);
88 			}
89 			modified = 1;
90 		}
91 
92 		if (cache->data && modified)
93 			_rtw_memcpy(cache->data, info, info_len);
94 	} else {
95 		if (cache->data && size_mod)
96 			rsvd_page_cache_free_data(cache);
97 	}
98 
99 	cache->loc = loc;
100 	cache->page_num = page_num;
101 	cache->size = info_len;
102 
103 	return modified | loc_mod | size_mod | page_num_mod;
104 }
105 
rsvd_page_cache_update_data(struct rsvd_page_cache_t * cache,u8 * info,u32 info_len)106 bool rsvd_page_cache_update_data(struct rsvd_page_cache_t *cache, u8 *info, u32 info_len)
107 {
108 	bool modified = 0;
109 
110 	if (!info || !info_len) {
111 		RTW_WARN("%s %s invalid input(info:%p, info_len:%u)\n"
112 			, __func__, cache->name, info, info_len);
113 		goto exit;
114 	}
115 
116 	if (!cache->loc || !cache->page_num || !cache->size) {
117 		RTW_ERR("%s %s layout not ready(loc:%u, page_num:%u, size:%u)\n"
118 			, __func__, cache->name, cache->loc, cache->page_num, cache->size);
119 		rtw_warn_on(1);
120 		goto exit;
121 	}
122 
123 	if (cache->size != info_len) {
124 		RTW_ERR("%s %s size(%u) differ with info_len(%u)\n"
125 			, __func__, cache->name, cache->size, info_len);
126 		rtw_warn_on(1);
127 		goto exit;
128 	}
129 
130 	if (!cache->data) {
131 		cache->data = rtw_zmalloc(cache->size);
132 		if (!cache->data) {
133 			RTW_ERR("%s %s alloc data with size(%u) fail\n"
134 				, __func__, cache->name, cache->size);
135 			rtw_warn_on(1);
136 			goto exit;
137 		} else {
138 			RTW_INFO("%s %s alloc data with size(%u)\n"
139 				, __func__, cache->name, info_len);
140 		}
141 		modified = 1;
142 	}
143 
144 	if (_rtw_memcmp(cache->data, info, cache->size) == _FALSE) {
145 		RTW_INFO("%s %s data change\n", __func__, cache->name);
146 		_rtw_memcpy(cache->data, info, cache->size);
147 		modified = 1;
148 	}
149 
150 exit:
151 	return modified;
152 }
153 
rsvd_page_cache_free_data(struct rsvd_page_cache_t * cache)154 void rsvd_page_cache_free_data(struct rsvd_page_cache_t *cache)
155 {
156 	if (cache->data) {
157 		rtw_mfree(cache->data, cache->size);
158 		cache->data = NULL;
159 	}
160 }
161 
rsvd_page_cache_free(struct rsvd_page_cache_t * cache)162 void rsvd_page_cache_free(struct rsvd_page_cache_t *cache)
163 {
164 	cache->loc = 0;
165 	cache->page_num = 0;
166 	rsvd_page_cache_free_data(cache);
167 	cache->size = 0;
168 }
169 
170 /* #define CONFIG_GTK_OL_DBG */
171 
172 /*#define DBG_SEC_CAM_MOVE*/
173 #ifdef DBG_SEC_CAM_MOVE
rtw_hal_move_sta_gk_to_dk(_adapter * adapter)174 void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
175 {
176 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
177 	int cam_id, index = 0;
178 	u8 *addr = NULL;
179 
180 	if (!MLME_IS_STA(adapter))
181 		return;
182 
183 	addr = get_bssid(pmlmepriv);
184 
185 	if (addr == NULL) {
186 		RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
187 		return;
188 	}
189 
190 	rtw_clean_dk_section(adapter);
191 
192 	do {
193 		cam_id = rtw_camid_search(adapter, addr, index, 1);
194 
195 		if (cam_id == -1)
196 			RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
197 		else
198 			rtw_sec_cam_swap(adapter, cam_id, index);
199 
200 		index++;
201 	} while (index < 4);
202 
203 }
204 
rtw_hal_read_sta_dk_key(_adapter * adapter,u8 key_id)205 void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
206 {
207 	struct security_priv *psecuritypriv = &adapter->securitypriv;
208 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
209 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
210 	_irqL irqL;
211 	u8 get_key[16];
212 
213 	_rtw_memset(get_key, 0, sizeof(get_key));
214 
215 	if (key_id > 4) {
216 		RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
217 		rtw_warn_on(1);
218 		return;
219 	}
220 	rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
221 
222 	/*update key into related sw variable*/
223 	_enter_critical_bh(&cam_ctl->lock, &irqL);
224 	if (_rtw_camid_is_gk(adapter, key_id)) {
225 		RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
226 		RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
227 	}
228 	_exit_critical_bh(&cam_ctl->lock, &irqL);
229 
230 }
231 #endif
232 
233 
234 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
235 	char	rtw_phy_para_file_path[PATH_LENGTH_MAX];
236 #endif
237 
dump_chip_info(HAL_VERSION ChipVersion)238 void dump_chip_info(HAL_VERSION	ChipVersion)
239 {
240 	int cnt = 0;
241 	u8 buf[128] = {0};
242 
243 	if (IS_8188E(ChipVersion))
244 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
245 	else if (IS_8188F(ChipVersion))
246 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
247 	else if (IS_8188GTV(ChipVersion))
248 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188GTV_");
249 	else if (IS_8812_SERIES(ChipVersion))
250 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
251 	else if (IS_8192E(ChipVersion))
252 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
253 	else if (IS_8821_SERIES(ChipVersion))
254 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
255 	else if (IS_8723B_SERIES(ChipVersion))
256 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
257 	else if (IS_8703B_SERIES(ChipVersion))
258 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
259 	else if (IS_8723D_SERIES(ChipVersion))
260 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
261 	else if (IS_8814A_SERIES(ChipVersion))
262 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
263 	else if (IS_8822B_SERIES(ChipVersion))
264 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
265 	else if (IS_8821C_SERIES(ChipVersion))
266 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
267 	else if (IS_8710B_SERIES(ChipVersion))
268 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8710B_");
269 	else if (IS_8192F_SERIES(ChipVersion))
270 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192F_");
271 	else if (IS_8822C_SERIES(ChipVersion))
272 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822C_");
273 	else
274 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
275 
276 	cnt += sprintf((buf + cnt), "%s", IS_NORMAL_CHIP(ChipVersion) ? "" : "T_");
277 
278 	if (IS_CHIP_VENDOR_TSMC(ChipVersion))
279 		cnt += sprintf((buf + cnt), "%s", "T");
280 	else if (IS_CHIP_VENDOR_UMC(ChipVersion))
281 		cnt += sprintf((buf + cnt), "%s", "U");
282 	else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
283 		cnt += sprintf((buf + cnt), "%s", "S");
284 
285 	if (IS_A_CUT(ChipVersion))
286 		cnt += sprintf((buf + cnt), "1_");
287 	else if (IS_B_CUT(ChipVersion))
288 		cnt += sprintf((buf + cnt), "2_");
289 	else if (IS_C_CUT(ChipVersion))
290 		cnt += sprintf((buf + cnt), "3_");
291 	else if (IS_D_CUT(ChipVersion))
292 		cnt += sprintf((buf + cnt), "4_");
293 	else if (IS_E_CUT(ChipVersion))
294 		cnt += sprintf((buf + cnt), "5_");
295 	else if (IS_F_CUT(ChipVersion))
296 		cnt += sprintf((buf + cnt), "6_");
297 	else if (IS_I_CUT(ChipVersion))
298 		cnt += sprintf((buf + cnt), "9_");
299 	else if (IS_J_CUT(ChipVersion))
300 		cnt += sprintf((buf + cnt), "10_");
301 	else if (IS_K_CUT(ChipVersion))
302 		cnt += sprintf((buf + cnt), "11_");
303 	else
304 		cnt += sprintf((buf + cnt), "UNKNOWN_Cv(%d)_", ChipVersion.CUTVersion);
305 
306 	if (IS_1T1R(ChipVersion))
307 		cnt += sprintf((buf + cnt), "1T1R_");
308 	else if (IS_1T2R(ChipVersion))
309 		cnt += sprintf((buf + cnt), "1T2R_");
310 	else if (IS_2T2R(ChipVersion))
311 		cnt += sprintf((buf + cnt), "2T2R_");
312 	else if (IS_3T3R(ChipVersion))
313 		cnt += sprintf((buf + cnt), "3T3R_");
314 	else if (IS_3T4R(ChipVersion))
315 		cnt += sprintf((buf + cnt), "3T4R_");
316 	else if (IS_4T4R(ChipVersion))
317 		cnt += sprintf((buf + cnt), "4T4R_");
318 	else
319 		cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
320 
321 	cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
322 
323 	RTW_INFO("%s", buf);
324 }
325 
rtw_hal_get_port(_adapter * adapter)326 u8 rtw_hal_get_port(_adapter *adapter)
327 {
328 	u8 hw_port = get_hw_port(adapter);
329 #ifdef CONFIG_CLIENT_PORT_CFG
330 	u8 clt_port = get_clt_port(adapter);
331 
332 	if (clt_port)
333 		hw_port = clt_port;
334 
335 #ifdef DBG_HW_PORT
336 	if (MLME_IS_STA(adapter) && (adapter->client_id != MAX_CLIENT_PORT_NUM)) {
337 		if(hw_port == CLT_PORT_INVALID) {
338 			RTW_ERR(ADPT_FMT" @@@@@ Client port == 0 @@@@@\n", ADPT_ARG(adapter));
339 			rtw_warn_on(1);
340 		}
341 	}
342 	else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
343 		if (hw_port != HW_PORT0) {
344 			RTW_ERR(ADPT_FMT" @@@@@ AP / MESH port != 0 @@@@@\n", ADPT_ARG(adapter));
345 			rtw_warn_on(1);
346 		}
347 	}
348 	if (0)
349 		RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter));
350 #endif /*DBG_HW_PORT*/
351 
352 #endif/*CONFIG_CLIENT_PORT_CFG*/
353 
354 	return hw_port;
355 }
356 
357 #define	EEPROM_CHANNEL_PLAN_BY_HW_MASK	0x80
358 
359 /*
360  * Description:
361  *	Use hardware(efuse), driver parameter(registry) and default channel plan
362  *	to decide which one should be used.
363  *
364  * Parameters:
365  *	padapter			pointer of adapter
366  *	hw_alpha2		country code from HW (efuse/eeprom/mapfile)
367  *	hw_chplan		channel plan from HW (efuse/eeprom/mapfile)
368  *						BIT[7] software configure mode; 0:Enable, 1:disable
369  *						BIT[6:0] Channel Plan
370  *	sw_alpha2		country code from HW (registry/module param)
371  *	sw_chplan		channel plan from SW (registry/module param)
372  *	AutoLoadFail		efuse autoload fail or not
373  *
374  */
hal_com_config_channel_plan(PADAPTER padapter,char * hw_alpha2,u8 hw_chplan,char * sw_alpha2,u8 sw_chplan,BOOLEAN AutoLoadFail)375 void hal_com_config_channel_plan(
376 		PADAPTER padapter,
377 		char *hw_alpha2,
378 		u8 hw_chplan,
379 		char *sw_alpha2,
380 		u8 sw_chplan,
381 		BOOLEAN AutoLoadFail
382 )
383 {
384 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
385 	PHAL_DATA_TYPE	pHalData;
386 	u8 force_hw_chplan = _FALSE;
387 	int chplan = -1;
388 	const struct country_chplan *country_ent = NULL, *ent;
389 	u8 def_chplan = 0x7F; /* Realtek define,  used when HW, SW both invalid */
390 
391 	pHalData = GET_HAL_DATA(padapter);
392 
393 	/* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
394 	if (hw_chplan == 0xFF)
395 		goto chk_hw_country_code;
396 
397 	if (AutoLoadFail == _TRUE)
398 		goto chk_sw_config;
399 
400 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
401 	if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
402 		force_hw_chplan = _TRUE;
403 #endif
404 
405 	hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
406 
407 chk_hw_country_code:
408 	if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
409 		ent = rtw_get_chplan_from_country(hw_alpha2);
410 		if (ent) {
411 			/* get chplan from hw country code, by pass hw chplan setting */
412 			country_ent = ent;
413 			chplan = ent->chplan;
414 			goto chk_sw_config;
415 		} else
416 			RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
417 	}
418 
419 	if (rtw_is_channel_plan_valid(hw_chplan))
420 		chplan = hw_chplan;
421 	else if (force_hw_chplan == _TRUE) {
422 		RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
423 		/* hw infomaton invalid, refer to sw information */
424 		force_hw_chplan = _FALSE;
425 	}
426 
427 chk_sw_config:
428 	if (force_hw_chplan == _TRUE)
429 		goto done;
430 
431 	if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
432 		ent = rtw_get_chplan_from_country(sw_alpha2);
433 		if (ent) {
434 			/* get chplan from sw country code, by pass sw chplan setting */
435 			country_ent = ent;
436 			chplan = ent->chplan;
437 			goto done;
438 		} else
439 			RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
440 	}
441 
442 	if (rtw_is_channel_plan_valid(sw_chplan)) {
443 		/* cancel hw_alpha2 because chplan is specified by sw_chplan*/
444 		country_ent = NULL;
445 		chplan = sw_chplan;
446 	} else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
447 		RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
448 
449 done:
450 	if (chplan == -1) {
451 		RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
452 		chplan = def_chplan;
453 	} else if (country_ent) {
454 		RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
455 			, country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
456 	} else
457 		RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
458 
459 	rfctl->country_ent = country_ent;
460 	rfctl->ChannelPlan = chplan;
461 	pHalData->bDisableSWChannelPlan = force_hw_chplan;
462 }
463 
464 BOOLEAN
HAL_IsLegalChannel(PADAPTER Adapter,u32 Channel)465 HAL_IsLegalChannel(
466 		PADAPTER	Adapter,
467 		u32			Channel
468 )
469 {
470 	BOOLEAN bLegalChannel = _TRUE;
471 
472 	if (Channel > 14) {
473 		if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
474 			bLegalChannel = _FALSE;
475 			RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
476 		}
477 	} else if ((Channel <= 14) && (Channel >= 1)) {
478 		if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
479 			bLegalChannel = _FALSE;
480 			RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
481 		}
482 	} else {
483 		bLegalChannel = _FALSE;
484 		RTW_INFO("Channel is Invalid !!!\n");
485 	}
486 
487 	return bLegalChannel;
488 }
489 
MRateToHwRate(u8 rate)490 u8	MRateToHwRate(u8 rate)
491 {
492 	u8	ret = DESC_RATE1M;
493 
494 	switch (rate) {
495 	case MGN_1M:
496 		ret = DESC_RATE1M;
497 		break;
498 	case MGN_2M:
499 		ret = DESC_RATE2M;
500 		break;
501 	case MGN_5_5M:
502 		ret = DESC_RATE5_5M;
503 		break;
504 	case MGN_11M:
505 		ret = DESC_RATE11M;
506 		break;
507 	case MGN_6M:
508 		ret = DESC_RATE6M;
509 		break;
510 	case MGN_9M:
511 		ret = DESC_RATE9M;
512 		break;
513 	case MGN_12M:
514 		ret = DESC_RATE12M;
515 		break;
516 	case MGN_18M:
517 		ret = DESC_RATE18M;
518 		break;
519 	case MGN_24M:
520 		ret = DESC_RATE24M;
521 		break;
522 	case MGN_36M:
523 		ret = DESC_RATE36M;
524 		break;
525 	case MGN_48M:
526 		ret = DESC_RATE48M;
527 		break;
528 	case MGN_54M:
529 		ret = DESC_RATE54M;
530 		break;
531 
532 	case MGN_MCS0:
533 		ret = DESC_RATEMCS0;
534 		break;
535 	case MGN_MCS1:
536 		ret = DESC_RATEMCS1;
537 		break;
538 	case MGN_MCS2:
539 		ret = DESC_RATEMCS2;
540 		break;
541 	case MGN_MCS3:
542 		ret = DESC_RATEMCS3;
543 		break;
544 	case MGN_MCS4:
545 		ret = DESC_RATEMCS4;
546 		break;
547 	case MGN_MCS5:
548 		ret = DESC_RATEMCS5;
549 		break;
550 	case MGN_MCS6:
551 		ret = DESC_RATEMCS6;
552 		break;
553 	case MGN_MCS7:
554 		ret = DESC_RATEMCS7;
555 		break;
556 	case MGN_MCS8:
557 		ret = DESC_RATEMCS8;
558 		break;
559 	case MGN_MCS9:
560 		ret = DESC_RATEMCS9;
561 		break;
562 	case MGN_MCS10:
563 		ret = DESC_RATEMCS10;
564 		break;
565 	case MGN_MCS11:
566 		ret = DESC_RATEMCS11;
567 		break;
568 	case MGN_MCS12:
569 		ret = DESC_RATEMCS12;
570 		break;
571 	case MGN_MCS13:
572 		ret = DESC_RATEMCS13;
573 		break;
574 	case MGN_MCS14:
575 		ret = DESC_RATEMCS14;
576 		break;
577 	case MGN_MCS15:
578 		ret = DESC_RATEMCS15;
579 		break;
580 	case MGN_MCS16:
581 		ret = DESC_RATEMCS16;
582 		break;
583 	case MGN_MCS17:
584 		ret = DESC_RATEMCS17;
585 		break;
586 	case MGN_MCS18:
587 		ret = DESC_RATEMCS18;
588 		break;
589 	case MGN_MCS19:
590 		ret = DESC_RATEMCS19;
591 		break;
592 	case MGN_MCS20:
593 		ret = DESC_RATEMCS20;
594 		break;
595 	case MGN_MCS21:
596 		ret = DESC_RATEMCS21;
597 		break;
598 	case MGN_MCS22:
599 		ret = DESC_RATEMCS22;
600 		break;
601 	case MGN_MCS23:
602 		ret = DESC_RATEMCS23;
603 		break;
604 	case MGN_MCS24:
605 		ret = DESC_RATEMCS24;
606 		break;
607 	case MGN_MCS25:
608 		ret = DESC_RATEMCS25;
609 		break;
610 	case MGN_MCS26:
611 		ret = DESC_RATEMCS26;
612 		break;
613 	case MGN_MCS27:
614 		ret = DESC_RATEMCS27;
615 		break;
616 	case MGN_MCS28:
617 		ret = DESC_RATEMCS28;
618 		break;
619 	case MGN_MCS29:
620 		ret = DESC_RATEMCS29;
621 		break;
622 	case MGN_MCS30:
623 		ret = DESC_RATEMCS30;
624 		break;
625 	case MGN_MCS31:
626 		ret = DESC_RATEMCS31;
627 		break;
628 
629 	case MGN_VHT1SS_MCS0:
630 		ret = DESC_RATEVHTSS1MCS0;
631 		break;
632 	case MGN_VHT1SS_MCS1:
633 		ret = DESC_RATEVHTSS1MCS1;
634 		break;
635 	case MGN_VHT1SS_MCS2:
636 		ret = DESC_RATEVHTSS1MCS2;
637 		break;
638 	case MGN_VHT1SS_MCS3:
639 		ret = DESC_RATEVHTSS1MCS3;
640 		break;
641 	case MGN_VHT1SS_MCS4:
642 		ret = DESC_RATEVHTSS1MCS4;
643 		break;
644 	case MGN_VHT1SS_MCS5:
645 		ret = DESC_RATEVHTSS1MCS5;
646 		break;
647 	case MGN_VHT1SS_MCS6:
648 		ret = DESC_RATEVHTSS1MCS6;
649 		break;
650 	case MGN_VHT1SS_MCS7:
651 		ret = DESC_RATEVHTSS1MCS7;
652 		break;
653 	case MGN_VHT1SS_MCS8:
654 		ret = DESC_RATEVHTSS1MCS8;
655 		break;
656 	case MGN_VHT1SS_MCS9:
657 		ret = DESC_RATEVHTSS1MCS9;
658 		break;
659 	case MGN_VHT2SS_MCS0:
660 		ret = DESC_RATEVHTSS2MCS0;
661 		break;
662 	case MGN_VHT2SS_MCS1:
663 		ret = DESC_RATEVHTSS2MCS1;
664 		break;
665 	case MGN_VHT2SS_MCS2:
666 		ret = DESC_RATEVHTSS2MCS2;
667 		break;
668 	case MGN_VHT2SS_MCS3:
669 		ret = DESC_RATEVHTSS2MCS3;
670 		break;
671 	case MGN_VHT2SS_MCS4:
672 		ret = DESC_RATEVHTSS2MCS4;
673 		break;
674 	case MGN_VHT2SS_MCS5:
675 		ret = DESC_RATEVHTSS2MCS5;
676 		break;
677 	case MGN_VHT2SS_MCS6:
678 		ret = DESC_RATEVHTSS2MCS6;
679 		break;
680 	case MGN_VHT2SS_MCS7:
681 		ret = DESC_RATEVHTSS2MCS7;
682 		break;
683 	case MGN_VHT2SS_MCS8:
684 		ret = DESC_RATEVHTSS2MCS8;
685 		break;
686 	case MGN_VHT2SS_MCS9:
687 		ret = DESC_RATEVHTSS2MCS9;
688 		break;
689 	case MGN_VHT3SS_MCS0:
690 		ret = DESC_RATEVHTSS3MCS0;
691 		break;
692 	case MGN_VHT3SS_MCS1:
693 		ret = DESC_RATEVHTSS3MCS1;
694 		break;
695 	case MGN_VHT3SS_MCS2:
696 		ret = DESC_RATEVHTSS3MCS2;
697 		break;
698 	case MGN_VHT3SS_MCS3:
699 		ret = DESC_RATEVHTSS3MCS3;
700 		break;
701 	case MGN_VHT3SS_MCS4:
702 		ret = DESC_RATEVHTSS3MCS4;
703 		break;
704 	case MGN_VHT3SS_MCS5:
705 		ret = DESC_RATEVHTSS3MCS5;
706 		break;
707 	case MGN_VHT3SS_MCS6:
708 		ret = DESC_RATEVHTSS3MCS6;
709 		break;
710 	case MGN_VHT3SS_MCS7:
711 		ret = DESC_RATEVHTSS3MCS7;
712 		break;
713 	case MGN_VHT3SS_MCS8:
714 		ret = DESC_RATEVHTSS3MCS8;
715 		break;
716 	case MGN_VHT3SS_MCS9:
717 		ret = DESC_RATEVHTSS3MCS9;
718 		break;
719 	case MGN_VHT4SS_MCS0:
720 		ret = DESC_RATEVHTSS4MCS0;
721 		break;
722 	case MGN_VHT4SS_MCS1:
723 		ret = DESC_RATEVHTSS4MCS1;
724 		break;
725 	case MGN_VHT4SS_MCS2:
726 		ret = DESC_RATEVHTSS4MCS2;
727 		break;
728 	case MGN_VHT4SS_MCS3:
729 		ret = DESC_RATEVHTSS4MCS3;
730 		break;
731 	case MGN_VHT4SS_MCS4:
732 		ret = DESC_RATEVHTSS4MCS4;
733 		break;
734 	case MGN_VHT4SS_MCS5:
735 		ret = DESC_RATEVHTSS4MCS5;
736 		break;
737 	case MGN_VHT4SS_MCS6:
738 		ret = DESC_RATEVHTSS4MCS6;
739 		break;
740 	case MGN_VHT4SS_MCS7:
741 		ret = DESC_RATEVHTSS4MCS7;
742 		break;
743 	case MGN_VHT4SS_MCS8:
744 		ret = DESC_RATEVHTSS4MCS8;
745 		break;
746 	case MGN_VHT4SS_MCS9:
747 		ret = DESC_RATEVHTSS4MCS9;
748 		break;
749 	default:
750 		break;
751 	}
752 
753 	return ret;
754 }
755 
hw_rate_to_m_rate(u8 rate)756 u8	hw_rate_to_m_rate(u8 rate)
757 {
758 	u8	ret_rate = MGN_1M;
759 
760 	switch (rate) {
761 
762 	case DESC_RATE1M:
763 		ret_rate = MGN_1M;
764 		break;
765 	case DESC_RATE2M:
766 		ret_rate = MGN_2M;
767 		break;
768 	case DESC_RATE5_5M:
769 		ret_rate = MGN_5_5M;
770 		break;
771 	case DESC_RATE11M:
772 		ret_rate = MGN_11M;
773 		break;
774 	case DESC_RATE6M:
775 		ret_rate = MGN_6M;
776 		break;
777 	case DESC_RATE9M:
778 		ret_rate = MGN_9M;
779 		break;
780 	case DESC_RATE12M:
781 		ret_rate = MGN_12M;
782 		break;
783 	case DESC_RATE18M:
784 		ret_rate = MGN_18M;
785 		break;
786 	case DESC_RATE24M:
787 		ret_rate = MGN_24M;
788 		break;
789 	case DESC_RATE36M:
790 		ret_rate = MGN_36M;
791 		break;
792 	case DESC_RATE48M:
793 		ret_rate = MGN_48M;
794 		break;
795 	case DESC_RATE54M:
796 		ret_rate = MGN_54M;
797 		break;
798 	case DESC_RATEMCS0:
799 		ret_rate = MGN_MCS0;
800 		break;
801 	case DESC_RATEMCS1:
802 		ret_rate = MGN_MCS1;
803 		break;
804 	case DESC_RATEMCS2:
805 		ret_rate = MGN_MCS2;
806 		break;
807 	case DESC_RATEMCS3:
808 		ret_rate = MGN_MCS3;
809 		break;
810 	case DESC_RATEMCS4:
811 		ret_rate = MGN_MCS4;
812 		break;
813 	case DESC_RATEMCS5:
814 		ret_rate = MGN_MCS5;
815 		break;
816 	case DESC_RATEMCS6:
817 		ret_rate = MGN_MCS6;
818 		break;
819 	case DESC_RATEMCS7:
820 		ret_rate = MGN_MCS7;
821 		break;
822 	case DESC_RATEMCS8:
823 		ret_rate = MGN_MCS8;
824 		break;
825 	case DESC_RATEMCS9:
826 		ret_rate = MGN_MCS9;
827 		break;
828 	case DESC_RATEMCS10:
829 		ret_rate = MGN_MCS10;
830 		break;
831 	case DESC_RATEMCS11:
832 		ret_rate = MGN_MCS11;
833 		break;
834 	case DESC_RATEMCS12:
835 		ret_rate = MGN_MCS12;
836 		break;
837 	case DESC_RATEMCS13:
838 		ret_rate = MGN_MCS13;
839 		break;
840 	case DESC_RATEMCS14:
841 		ret_rate = MGN_MCS14;
842 		break;
843 	case DESC_RATEMCS15:
844 		ret_rate = MGN_MCS15;
845 		break;
846 	case DESC_RATEMCS16:
847 		ret_rate = MGN_MCS16;
848 		break;
849 	case DESC_RATEMCS17:
850 		ret_rate = MGN_MCS17;
851 		break;
852 	case DESC_RATEMCS18:
853 		ret_rate = MGN_MCS18;
854 		break;
855 	case DESC_RATEMCS19:
856 		ret_rate = MGN_MCS19;
857 		break;
858 	case DESC_RATEMCS20:
859 		ret_rate = MGN_MCS20;
860 		break;
861 	case DESC_RATEMCS21:
862 		ret_rate = MGN_MCS21;
863 		break;
864 	case DESC_RATEMCS22:
865 		ret_rate = MGN_MCS22;
866 		break;
867 	case DESC_RATEMCS23:
868 		ret_rate = MGN_MCS23;
869 		break;
870 	case DESC_RATEMCS24:
871 		ret_rate = MGN_MCS24;
872 		break;
873 	case DESC_RATEMCS25:
874 		ret_rate = MGN_MCS25;
875 		break;
876 	case DESC_RATEMCS26:
877 		ret_rate = MGN_MCS26;
878 		break;
879 	case DESC_RATEMCS27:
880 		ret_rate = MGN_MCS27;
881 		break;
882 	case DESC_RATEMCS28:
883 		ret_rate = MGN_MCS28;
884 		break;
885 	case DESC_RATEMCS29:
886 		ret_rate = MGN_MCS29;
887 		break;
888 	case DESC_RATEMCS30:
889 		ret_rate = MGN_MCS30;
890 		break;
891 	case DESC_RATEMCS31:
892 		ret_rate = MGN_MCS31;
893 		break;
894 	case DESC_RATEVHTSS1MCS0:
895 		ret_rate = MGN_VHT1SS_MCS0;
896 		break;
897 	case DESC_RATEVHTSS1MCS1:
898 		ret_rate = MGN_VHT1SS_MCS1;
899 		break;
900 	case DESC_RATEVHTSS1MCS2:
901 		ret_rate = MGN_VHT1SS_MCS2;
902 		break;
903 	case DESC_RATEVHTSS1MCS3:
904 		ret_rate = MGN_VHT1SS_MCS3;
905 		break;
906 	case DESC_RATEVHTSS1MCS4:
907 		ret_rate = MGN_VHT1SS_MCS4;
908 		break;
909 	case DESC_RATEVHTSS1MCS5:
910 		ret_rate = MGN_VHT1SS_MCS5;
911 		break;
912 	case DESC_RATEVHTSS1MCS6:
913 		ret_rate = MGN_VHT1SS_MCS6;
914 		break;
915 	case DESC_RATEVHTSS1MCS7:
916 		ret_rate = MGN_VHT1SS_MCS7;
917 		break;
918 	case DESC_RATEVHTSS1MCS8:
919 		ret_rate = MGN_VHT1SS_MCS8;
920 		break;
921 	case DESC_RATEVHTSS1MCS9:
922 		ret_rate = MGN_VHT1SS_MCS9;
923 		break;
924 	case DESC_RATEVHTSS2MCS0:
925 		ret_rate = MGN_VHT2SS_MCS0;
926 		break;
927 	case DESC_RATEVHTSS2MCS1:
928 		ret_rate = MGN_VHT2SS_MCS1;
929 		break;
930 	case DESC_RATEVHTSS2MCS2:
931 		ret_rate = MGN_VHT2SS_MCS2;
932 		break;
933 	case DESC_RATEVHTSS2MCS3:
934 		ret_rate = MGN_VHT2SS_MCS3;
935 		break;
936 	case DESC_RATEVHTSS2MCS4:
937 		ret_rate = MGN_VHT2SS_MCS4;
938 		break;
939 	case DESC_RATEVHTSS2MCS5:
940 		ret_rate = MGN_VHT2SS_MCS5;
941 		break;
942 	case DESC_RATEVHTSS2MCS6:
943 		ret_rate = MGN_VHT2SS_MCS6;
944 		break;
945 	case DESC_RATEVHTSS2MCS7:
946 		ret_rate = MGN_VHT2SS_MCS7;
947 		break;
948 	case DESC_RATEVHTSS2MCS8:
949 		ret_rate = MGN_VHT2SS_MCS8;
950 		break;
951 	case DESC_RATEVHTSS2MCS9:
952 		ret_rate = MGN_VHT2SS_MCS9;
953 		break;
954 	case DESC_RATEVHTSS3MCS0:
955 		ret_rate = MGN_VHT3SS_MCS0;
956 		break;
957 	case DESC_RATEVHTSS3MCS1:
958 		ret_rate = MGN_VHT3SS_MCS1;
959 		break;
960 	case DESC_RATEVHTSS3MCS2:
961 		ret_rate = MGN_VHT3SS_MCS2;
962 		break;
963 	case DESC_RATEVHTSS3MCS3:
964 		ret_rate = MGN_VHT3SS_MCS3;
965 		break;
966 	case DESC_RATEVHTSS3MCS4:
967 		ret_rate = MGN_VHT3SS_MCS4;
968 		break;
969 	case DESC_RATEVHTSS3MCS5:
970 		ret_rate = MGN_VHT3SS_MCS5;
971 		break;
972 	case DESC_RATEVHTSS3MCS6:
973 		ret_rate = MGN_VHT3SS_MCS6;
974 		break;
975 	case DESC_RATEVHTSS3MCS7:
976 		ret_rate = MGN_VHT3SS_MCS7;
977 		break;
978 	case DESC_RATEVHTSS3MCS8:
979 		ret_rate = MGN_VHT3SS_MCS8;
980 		break;
981 	case DESC_RATEVHTSS3MCS9:
982 		ret_rate = MGN_VHT3SS_MCS9;
983 		break;
984 	case DESC_RATEVHTSS4MCS0:
985 		ret_rate = MGN_VHT4SS_MCS0;
986 		break;
987 	case DESC_RATEVHTSS4MCS1:
988 		ret_rate = MGN_VHT4SS_MCS1;
989 		break;
990 	case DESC_RATEVHTSS4MCS2:
991 		ret_rate = MGN_VHT4SS_MCS2;
992 		break;
993 	case DESC_RATEVHTSS4MCS3:
994 		ret_rate = MGN_VHT4SS_MCS3;
995 		break;
996 	case DESC_RATEVHTSS4MCS4:
997 		ret_rate = MGN_VHT4SS_MCS4;
998 		break;
999 	case DESC_RATEVHTSS4MCS5:
1000 		ret_rate = MGN_VHT4SS_MCS5;
1001 		break;
1002 	case DESC_RATEVHTSS4MCS6:
1003 		ret_rate = MGN_VHT4SS_MCS6;
1004 		break;
1005 	case DESC_RATEVHTSS4MCS7:
1006 		ret_rate = MGN_VHT4SS_MCS7;
1007 		break;
1008 	case DESC_RATEVHTSS4MCS8:
1009 		ret_rate = MGN_VHT4SS_MCS8;
1010 		break;
1011 	case DESC_RATEVHTSS4MCS9:
1012 		ret_rate = MGN_VHT4SS_MCS9;
1013 		break;
1014 
1015 	default:
1016 		RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate);
1017 		break;
1018 	}
1019 
1020 	return ret_rate;
1021 }
1022 
HalSetBrateCfg(PADAPTER Adapter,u8 * mBratesOS,u16 * pBrateCfg)1023 void	HalSetBrateCfg(
1024 	PADAPTER		Adapter,
1025 	u8			*mBratesOS,
1026 	u16			*pBrateCfg)
1027 {
1028 	u8	i, is_brate, brate;
1029 
1030 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
1031 		is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
1032 		brate = mBratesOS[i] & 0x7f;
1033 
1034 		if (is_brate) {
1035 			switch (brate) {
1036 			case IEEE80211_CCK_RATE_1MB:
1037 				*pBrateCfg |= RATE_1M;
1038 				break;
1039 			case IEEE80211_CCK_RATE_2MB:
1040 				*pBrateCfg |= RATE_2M;
1041 				break;
1042 			case IEEE80211_CCK_RATE_5MB:
1043 				*pBrateCfg |= RATE_5_5M;
1044 				break;
1045 			case IEEE80211_CCK_RATE_11MB:
1046 				*pBrateCfg |= RATE_11M;
1047 				break;
1048 			case IEEE80211_OFDM_RATE_6MB:
1049 				*pBrateCfg |= RATE_6M;
1050 				break;
1051 			case IEEE80211_OFDM_RATE_9MB:
1052 				*pBrateCfg |= RATE_9M;
1053 				break;
1054 			case IEEE80211_OFDM_RATE_12MB:
1055 				*pBrateCfg |= RATE_12M;
1056 				break;
1057 			case IEEE80211_OFDM_RATE_18MB:
1058 				*pBrateCfg |= RATE_18M;
1059 				break;
1060 			case IEEE80211_OFDM_RATE_24MB:
1061 				*pBrateCfg |= RATE_24M;
1062 				break;
1063 			case IEEE80211_OFDM_RATE_36MB:
1064 				*pBrateCfg |= RATE_36M;
1065 				break;
1066 			case IEEE80211_OFDM_RATE_48MB:
1067 				*pBrateCfg |= RATE_48M;
1068 				break;
1069 			case IEEE80211_OFDM_RATE_54MB:
1070 				*pBrateCfg |= RATE_54M;
1071 				break;
1072 			}
1073 		}
1074 	}
1075 }
1076 
1077 static void
_OneOutPipeMapping(PADAPTER pAdapter)1078 _OneOutPipeMapping(
1079 		PADAPTER	pAdapter
1080 )
1081 {
1082 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
1083 
1084 	pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1085 	pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1086 	pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
1087 	pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
1088 
1089 	pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1090 	pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1091 	pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1092 	pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1093 }
1094 
1095 static void
_TwoOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)1096 _TwoOutPipeMapping(
1097 		PADAPTER	pAdapter,
1098 		BOOLEAN		bWIFICfg
1099 )
1100 {
1101 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
1102 
1103 	if (bWIFICfg) { /* WMM */
1104 
1105 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1106 		/* {  0, 	1, 	0, 	1, 	0, 	0, 	0, 	0, 		0	}; */
1107 		/* 0:ep_0 num, 1:ep_1 num */
1108 
1109 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
1110 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1111 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
1112 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
1113 
1114 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1115 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1116 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1117 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1118 
1119 	} else { /* typical setting */
1120 
1121 
1122 		/* BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA */
1123 		/* {  1, 	1, 	0, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
1124 		/* 0:ep_0 num, 1:ep_1 num */
1125 
1126 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1127 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1128 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
1129 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1130 
1131 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1132 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1133 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1134 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
1135 
1136 	}
1137 
1138 }
1139 
_ThreeOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)1140 static void _ThreeOutPipeMapping(
1141 		PADAPTER	pAdapter,
1142 		BOOLEAN		bWIFICfg
1143 )
1144 {
1145 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
1146 
1147 	if (bWIFICfg) { /* for WMM */
1148 
1149 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1150 		/* {  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	}; */
1151 		/* 0:H, 1:N, 2:L */
1152 
1153 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1154 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1155 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1156 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1157 
1158 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1159 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1160 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1161 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1162 
1163 	} else { /* typical setting */
1164 
1165 
1166 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1167 		/* {  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
1168 		/* 0:H, 1:N, 2:L */
1169 
1170 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1171 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1172 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1173 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1174 
1175 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1176 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1177 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1178 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
1179 	}
1180 
1181 }
1182 #if 0
1183 static void _FourOutPipeMapping(
1184 		PADAPTER	pAdapter,
1185 		BOOLEAN		bWIFICfg
1186 )
1187 {
1188 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
1189 
1190 	if (bWIFICfg) { /* for WMM */
1191 
1192 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1193 		/* {  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	}; */
1194 		/* 0:H, 1:N, 2:L ,3:E */
1195 
1196 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1197 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1198 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1199 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1200 
1201 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1202 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1203 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1204 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1205 
1206 	} else { /* typical setting */
1207 
1208 
1209 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1210 		/* {  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
1211 		/* 0:H, 1:N, 2:L */
1212 
1213 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1214 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1215 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1216 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1217 
1218 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1219 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1220 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1221 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
1222 	}
1223 
1224 }
1225 #endif
1226 BOOLEAN
Hal_MappingOutPipe(PADAPTER pAdapter,u8 NumOutPipe)1227 Hal_MappingOutPipe(
1228 		PADAPTER	pAdapter,
1229 		u8		NumOutPipe
1230 )
1231 {
1232 	struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1233 
1234 	BOOLEAN	 bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1235 
1236 	BOOLEAN result = _TRUE;
1237 
1238 	switch (NumOutPipe) {
1239 	case 2:
1240 		_TwoOutPipeMapping(pAdapter, bWIFICfg);
1241 		break;
1242 	case 3:
1243 	case 4:
1244 	case 5:
1245 	case 6:
1246 		_ThreeOutPipeMapping(pAdapter, bWIFICfg);
1247 		break;
1248 	case 1:
1249 		_OneOutPipeMapping(pAdapter);
1250 		break;
1251 	default:
1252 		result = _FALSE;
1253 		break;
1254 	}
1255 
1256 	return result;
1257 
1258 }
1259 
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1260 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1261 {
1262 	if (padapter->hal_func.reqtxrpt)
1263 		padapter->hal_func.reqtxrpt(padapter, macid);
1264 }
1265 
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1266 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1267 {
1268 	int i;
1269 	_adapter *iface;
1270 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1271 	u8 mac_addr[ETH_ALEN];
1272 
1273 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1274 	rtw_mbid_cam_dump(sel, __func__, adapter);
1275 #else
1276 	rtw_mi_hal_dump_macaddr(sel, adapter);
1277 #endif
1278 }
1279 
1280 #ifdef RTW_HALMAC
rtw_hal_hw_port_enable(_adapter * adapter)1281 void rtw_hal_hw_port_enable(_adapter *adapter)
1282 {
1283 #if 1
1284 	u8 port_enable = _TRUE;
1285 
1286 	rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1287 #else
1288 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1289 	struct rtw_halmac_bcn_ctrl bcn_ctrl;
1290 
1291 	_rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
1292 	bcn_ctrl.enable_bcn = 1;
1293 	bcn_ctrl.rx_bssid_fit = 1;
1294 	bcn_ctrl.rxbcn_rpt = 1;
1295 
1296 	/*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1297 				struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
1298 	if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
1299 		RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
1300 		rtw_warn_on(1);
1301 	}
1302 #endif
1303 }
rtw_hal_hw_port_disable(_adapter * adapter)1304 void rtw_hal_hw_port_disable(_adapter *adapter)
1305 {
1306 	u8 port_enable = _FALSE;
1307 
1308 	rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1309 }
1310 
rtw_restore_hw_port_cfg(_adapter * adapter)1311 void rtw_restore_hw_port_cfg(_adapter *adapter)
1312 {
1313 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1314 
1315 #else
1316 	int i;
1317 	_adapter *iface;
1318 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1319 
1320 	for (i = 0; i < dvobj->iface_nums; i++) {
1321 		iface = dvobj->padapters[i];
1322 		if (iface)
1323 			rtw_hal_hw_port_enable(iface);
1324 	}
1325 #endif
1326 }
1327 #endif
1328 
rtw_mi_set_mac_addr(_adapter * adapter)1329 void rtw_mi_set_mac_addr(_adapter *adapter)
1330 {
1331 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1332 	rtw_mi_set_mbid_cam(adapter);
1333 #else
1334 	int i;
1335 	_adapter *iface;
1336 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1337 
1338 	for (i = 0; i < dvobj->iface_nums; i++) {
1339 		iface = dvobj->padapters[i];
1340 		if (iface)
1341 			rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
1342 	}
1343 #endif
1344 	if (0)
1345 		rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1346 }
1347 
rtw_init_hal_com_default_value(PADAPTER Adapter)1348 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1349 {
1350 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
1351 	struct registry_priv *regsty = adapter_to_regsty(Adapter);
1352 
1353 	pHalData->AntDetection = 1;
1354 	pHalData->antenna_test = _FALSE;
1355 	pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
1356 	pHalData->ch_switch_offload = regsty->ch_switch_offload;
1357 	pHalData->multi_ch_switch_mode = 0;
1358 #ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
1359 	if (pHalData->ch_switch_offload == 0)
1360 		pHalData->ch_switch_offload = 1;
1361 #endif
1362 }
1363 
1364 #ifdef CONFIG_FW_C2H_REG
c2h_evt_clear(_adapter * adapter)1365 void c2h_evt_clear(_adapter *adapter)
1366 {
1367 	rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1368 }
1369 
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1370 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1371 {
1372 	s32 ret = _FAIL;
1373 	int i;
1374 	u8 trigger;
1375 
1376 	if (buf == NULL)
1377 		goto exit;
1378 
1379 	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1380 
1381 	if (trigger == C2H_EVT_HOST_CLOSE) {
1382 		goto exit; /* Not ready */
1383 	} else if (trigger != C2H_EVT_FW_CLOSE) {
1384 		goto clear_evt; /* Not a valid value */
1385 	}
1386 
1387 	_rtw_memset(buf, 0, C2H_REG_LEN);
1388 
1389 	/* Read ID, LEN, SEQ */
1390 	SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1391 	SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1392 	SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1393 
1394 	if (0) {
1395 		RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1396 			, C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1397 	}
1398 
1399 	/* Read the content */
1400 	for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1401 		*(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1402 
1403 	RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1404 
1405 	ret = _SUCCESS;
1406 
1407 clear_evt:
1408 	/*
1409 	* Clear event to notify FW we have read the command.
1410 	* If this field isn't clear, the FW won't update the next command message.
1411 	*/
1412 	c2h_evt_clear(adapter);
1413 
1414 exit:
1415 	return ret;
1416 }
1417 #endif /* CONFIG_FW_C2H_REG */
1418 
1419 #ifdef CONFIG_FW_C2H_PKT
1420 #ifndef DBG_C2H_PKT_PRE_HDL
1421 #define DBG_C2H_PKT_PRE_HDL 0
1422 #endif
1423 #ifndef DBG_C2H_PKT_HDL
1424 #define DBG_C2H_PKT_HDL 0
1425 #endif
rtw_hal_c2h_pkt_pre_hdl(_adapter * adapter,u8 * buf,u16 len)1426 void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1427 {
1428 #ifdef RTW_HALMAC
1429 	/* TODO: extract hal_mac IC's code here*/
1430 #else
1431 	u8 parse_fail = 0;
1432 	u8 hdl_here = 0;
1433 	s32 ret = _FAIL;
1434 	u8 id, seq, plen;
1435 	u8 *payload;
1436 
1437 	if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1438 		parse_fail = 1;
1439 		goto exit;
1440 	}
1441 
1442 	hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1443 	if (hdl_here)
1444 		ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1445 	else
1446 		ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1447 
1448 exit:
1449 	if (parse_fail)
1450 		RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1451 	else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1452 		RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1453 			, hdl_here ? "handle" : "enqueue"
1454 			, ret == _SUCCESS ? "ok" : "fail"
1455 		);
1456 		if (DBG_C2H_PKT_PRE_HDL >= 2)
1457 			RTW_PRINT_DUMP("dump: ", buf, len);
1458 	}
1459 #endif
1460 }
1461 
rtw_hal_c2h_pkt_hdl(_adapter * adapter,u8 * buf,u16 len)1462 void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1463 {
1464 #ifdef RTW_HALMAC
1465 	adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1466 #else
1467 	u8 parse_fail = 0;
1468 	u8 bypass = 0;
1469 	s32 ret = _FAIL;
1470 	u8 id, seq, plen;
1471 	u8 *payload;
1472 
1473 	if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1474 		parse_fail = 1;
1475 		goto exit;
1476 	}
1477 
1478 #ifdef CONFIG_WOWLAN
1479 	if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1480 		bypass = 1;
1481 		ret = _SUCCESS;
1482 		goto exit;
1483 	}
1484 #endif
1485 
1486 	ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1487 
1488 exit:
1489 	if (parse_fail)
1490 		RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1491 	else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1492 		RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1493 			, !bypass ? "handle" : "bypass"
1494 			, ret == _SUCCESS ? "ok" : "fail"
1495 		);
1496 		if (DBG_C2H_PKT_HDL >= 2)
1497 			RTW_PRINT_DUMP("dump: ", buf, len);
1498 	}
1499 #endif
1500 }
1501 #endif /* CONFIG_FW_C2H_PKT */
1502 
c2h_iqk_offload(_adapter * adapter,u8 * data,u8 len)1503 void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1504 {
1505 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1506 	struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1507 
1508 	RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1509 	if (0)
1510 		RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1511 
1512 	rtw_sctx_done(&iqk_sctx);
1513 }
1514 
c2h_iqk_offload_wait(_adapter * adapter,u32 timeout_ms)1515 int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1516 {
1517 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1518 	struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1519 
1520 	iqk_sctx->submit_time = rtw_get_current_time();
1521 	iqk_sctx->timeout_ms = timeout_ms;
1522 	iqk_sctx->status = RTW_SCTX_SUBMITTED;
1523 
1524 	return rtw_sctx_wait(iqk_sctx, __func__);
1525 }
1526 
1527 #ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX
c2h_txpwr_idx_offload_done(_adapter * adapter,u8 * data,u8 len)1528 void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len)
1529 {
1530 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1531 	struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1532 
1533 	if (0)
1534 		RTW_INFO("txpwr_idx offload finish in %dms\n", rtw_get_passing_time_ms(sctx->submit_time));
1535 	rtw_sctx_done(&sctx);
1536 }
1537 
c2h_txpwr_idx_offload_wait(_adapter * adapter)1538 int c2h_txpwr_idx_offload_wait(_adapter *adapter)
1539 {
1540 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1541 	struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1542 
1543 	return rtw_sctx_wait(sctx, __func__);
1544 }
1545 #endif
1546 
1547 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1548 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1549 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1550 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data)			LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1551 #define	GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1552 #define	GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1553 #define	GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1554 #define	GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1555 #define	GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1556 #define	GET_C2H_MAC_HIDDEN_RPT_BW(_data)				LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1557 #define	GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1558 #define	GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1559 #define	GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1560 
1561 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1562 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1563 #endif
1564 
1565 #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1566 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1567 {
1568 	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
1569 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1570 	enum rf_type rf_type;
1571 	u8 tx_path_num, rx_path_num;
1572 	int ret = _FAIL;
1573 
1574 	u8 uuid_x;
1575 	u8 uuid_y;
1576 	u8 uuid_z;
1577 	u16 uuid_crc;
1578 
1579 	u8 hci_type;
1580 	u8 package_type;
1581 	u8 tr_switch;
1582 	u8 wl_func;
1583 	u8 hw_stype;
1584 	u8 bw;
1585 	u8 ss_num = 4;
1586 	u8 ant_num;
1587 	u8 protocol;
1588 	u8 nic;
1589 
1590 	int i;
1591 
1592 	if (len < MAC_HIDDEN_RPT_LEN) {
1593 		RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1594 		goto exit;
1595 	}
1596 
1597 	uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1598 	uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1599 	uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1600 	uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1601 
1602 	hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1603 	package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1604 
1605 	tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1606 
1607 	wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1608 	hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1609 
1610 	bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1611 	ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1612 
1613 	protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1614 	nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1615 
1616 	if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1617 		for (i = 0; i < len; i++)
1618 			RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1619 
1620 		RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1621 		RTW_PRINT("hci_type:0x%x\n", hci_type);
1622 		RTW_PRINT("package_type:0x%x\n", package_type);
1623 		RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1624 		RTW_PRINT("wl_func:0x%x\n", wl_func);
1625 		RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1626 		RTW_PRINT("bw:0x%x\n", bw);
1627 		RTW_PRINT("ant_num:0x%x\n", ant_num);
1628 		RTW_PRINT("protocol:0x%x\n", protocol);
1629 		RTW_PRINT("nic:0x%x\n", nic);
1630 	}
1631 
1632 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
1633 	if (IS_8822C_SERIES(hal_data->version_id) || IS_8814B_SERIES(hal_data->version_id)) {
1634 		#define GET_C2H_MAC_HIDDEN_RPT_SS_NUM(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
1635 		ss_num = GET_C2H_MAC_HIDDEN_RPT_SS_NUM(data);
1636 
1637 		if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1638 			RTW_PRINT("ss_num:0x%x\n", ss_num);
1639 
1640 		if (ss_num == 0x03)
1641 			ss_num = 4;
1642 	}
1643 #endif
1644 
1645 #if defined(CONFIG_RTL8822C)
1646 	if (IS_8822C_SERIES(hal_data->version_id)) {
1647 		if (ant_num == 1)
1648 			hal_spec->rf_reg_trx_path_bmp = 0x22; /* 1T1R pathB */
1649 		if (hw_stype == 0xE)
1650 			hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */
1651 	}
1652 #endif
1653 	hal_data->PackageType = package_type;
1654 	hal_spec->hci_type = hci_type;
1655 	hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1656 	hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1657 	hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1658 
1659 	rf_type = rtw_chip_rftype_to_hal_rftype(adapter, 0);
1660 	if (!RF_TYPE_VALID(rf_type)) {
1661 		RTW_ERR("%s rtw_chip_rftype_to_hal_rftype failed\n", __func__);
1662 		goto exit;
1663 	}
1664 	hal_spec->rf_reg_path_avail_num = rtw_min(hal_spec->rf_reg_path_num, ant_num);
1665 	tx_path_num = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1666 	rx_path_num = rtw_min(rf_type_to_rf_rx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1667 	hal_spec->rf_reg_trx_path_bmp = rtw_restrict_trx_path_bmp_by_trx_num_lmt(
1668 		hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num, &tx_path_num, &rx_path_num);
1669 	if (!hal_spec->rf_reg_trx_path_bmp) {
1670 		RTW_ERR("%s rtw_restrict_trx_path_bmp_by_trx_num_lmt(0x%x, %u, %u) failed\n"
1671 			, __func__, hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num);
1672 		goto exit;
1673 	}
1674 	hal_spec->rf_reg_path_avail_num = rtw_max(tx_path_num, rx_path_num);
1675 
1676 	/*
1677 	* RF TX path num >= max_tx_cnt >= tx_nss_num
1678 	* ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1)
1679 	* Select at most 2 out of 4 TX RF path to do 1SS 2TX
1680 	*/
1681 	hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, tx_path_num);
1682 	hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt);
1683 	hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num);
1684 
1685 	hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rx_path_num);
1686 	hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num);
1687 
1688 	ret = _SUCCESS;
1689 
1690 exit:
1691 	return ret;
1692 }
1693 
c2h_mac_hidden_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1694 int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1695 {
1696 	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
1697 	int ret = _FAIL;
1698 
1699 	int i;
1700 
1701 	if (len < MAC_HIDDEN_RPT_2_LEN) {
1702 		RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1703 		goto exit;
1704 	}
1705 
1706 	if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1707 		for (i = 0; i < len; i++)
1708 			RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1709 	}
1710 
1711 	#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
1712 	if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {
1713 		#define GET_C2H_MAC_HIDDEN_RPT_IRV(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
1714 		u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
1715 
1716 		if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1717 			RTW_PRINT("irv:0x%x\n", irv);
1718 
1719 		if(irv != 0xf)
1720 			hal_data->version_id.CUTVersion = irv;
1721 	}
1722 	#endif
1723 
1724 	ret = _SUCCESS;
1725 
1726 exit:
1727 	return ret;
1728 }
1729 
hal_read_mac_hidden_rpt(_adapter * adapter)1730 int hal_read_mac_hidden_rpt(_adapter *adapter)
1731 {
1732 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(adapter);
1733 	int ret = _FAIL;
1734 	int ret_fwdl;
1735 	u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1736 	systime start = rtw_get_current_time();
1737 	u32 cnt = 0;
1738 	u32 timeout_ms = 800;
1739 	u32 min_cnt = 10;
1740 	u8 id = C2H_DEFEATURE_RSVD;
1741 	int i;
1742 
1743 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1744 	u8 hci_type = rtw_get_intf_type(adapter);
1745 
1746 	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1747 		&& !rtw_is_hw_init_completed(adapter))
1748 		rtw_hal_power_on(adapter);
1749 #endif
1750 
1751 	/* inform FW mac hidden rpt from reg is needed */
1752 	rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1753 
1754 	/* download FW */
1755 	pHalData->not_xmitframe_fw_dl = 1;
1756 	ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1757 	pHalData->not_xmitframe_fw_dl = 0;
1758 	if (ret_fwdl != _SUCCESS)
1759 		goto mac_hidden_rpt_hdl;
1760 
1761 	/* polling for data ready */
1762 	start = rtw_get_current_time();
1763 	do {
1764 		cnt++;
1765 		id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1766 		if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1767 			break;
1768 		rtw_msleep_os(10);
1769 	} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1770 
1771 	if (id == C2H_MAC_HIDDEN_RPT) {
1772 		/* read data */
1773 		for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1774 			mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1775 	}
1776 
1777 	/* inform FW mac hidden rpt has read */
1778 	rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1779 
1780 mac_hidden_rpt_hdl:
1781 	c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1782 	c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1783 
1784 	if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1785 		ret = _SUCCESS;
1786 
1787 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1788 	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1789 		&& !rtw_is_hw_init_completed(adapter))
1790 		rtw_hal_power_off(adapter);
1791 #endif
1792 
1793 	RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1794 		, (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1795 
1796 	return ret;
1797 }
1798 #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1799 
c2h_defeature_dbg_hdl(_adapter * adapter,u8 * data,u8 len)1800 int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1801 {
1802 	int ret = _FAIL;
1803 
1804 	int i;
1805 
1806 	if (len < DEFEATURE_DBG_LEN) {
1807 		RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1808 		goto exit;
1809 	}
1810 
1811 	for (i = 0; i < len; i++)
1812 		RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1813 
1814 	ret = _SUCCESS;
1815 
1816 exit:
1817 	return ret;
1818 }
1819 
1820 #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1821 #define DBG_CUSTOMER_STR_RPT_HANDLE 0
1822 #endif
1823 
1824 #ifdef CONFIG_RTW_CUSTOMER_STR
rtw_hal_h2c_customer_str_req(_adapter * adapter)1825 s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1826 {
1827 	u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1828 
1829 	SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1830 	return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1831 }
1832 
1833 #define	C2H_CUSTOMER_STR_RPT_BYTE0(_data)		((u8 *)(_data))
1834 #define	C2H_CUSTOMER_STR_RPT_2_BYTE8(_data)		((u8 *)(_data))
1835 
c2h_customer_str_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1836 int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1837 {
1838 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1839 	int ret = _FAIL;
1840 	int i;
1841 
1842 	if (len < CUSTOMER_STR_RPT_LEN) {
1843 		RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1844 		goto exit;
1845 	}
1846 
1847 	if (DBG_CUSTOMER_STR_RPT_HANDLE)
1848 		RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1849 
1850 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1851 
1852 	if (dvobj->customer_str_sctx != NULL) {
1853 		if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1854 			RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1855 		_rtw_memcpy(dvobj->customer_str,  C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1856 		dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1857 	} else
1858 		RTW_WARN("%s sctx not set\n", __func__);
1859 
1860 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1861 
1862 	ret = _SUCCESS;
1863 
1864 exit:
1865 	return ret;
1866 }
1867 
c2h_customer_str_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1868 int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1869 {
1870 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1871 	int ret = _FAIL;
1872 	int i;
1873 
1874 	if (len < CUSTOMER_STR_RPT_2_LEN) {
1875 		RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1876 		goto exit;
1877 	}
1878 
1879 	if (DBG_CUSTOMER_STR_RPT_HANDLE)
1880 		RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1881 
1882 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1883 
1884 	if (dvobj->customer_str_sctx != NULL) {
1885 		if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1886 			RTW_WARN("%s rpt not ready\n", __func__);
1887 		_rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN,  C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1888 		rtw_sctx_done(&dvobj->customer_str_sctx);
1889 	} else
1890 		RTW_WARN("%s sctx not set\n", __func__);
1891 
1892 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1893 
1894 	ret = _SUCCESS;
1895 
1896 exit:
1897 	return ret;
1898 }
1899 
1900 /* read customer str */
rtw_hal_customer_str_read(_adapter * adapter,u8 * cs)1901 s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1902 {
1903 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1904 	struct submit_ctx sctx;
1905 	s32 ret = _SUCCESS;
1906 
1907 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1908 	if (dvobj->customer_str_sctx != NULL)
1909 		ret = _FAIL;
1910 	else {
1911 		rtw_sctx_init(&sctx, 2 * 1000);
1912 		dvobj->customer_str_sctx = &sctx;
1913 	}
1914 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1915 
1916 	if (ret == _FAIL) {
1917 		RTW_WARN("%s another handle ongoing\n", __func__);
1918 		goto exit;
1919 	}
1920 
1921 	ret = rtw_customer_str_req_cmd(adapter);
1922 	if (ret != _SUCCESS) {
1923 		RTW_WARN("%s read cmd fail\n", __func__);
1924 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1925 		dvobj->customer_str_sctx = NULL;
1926 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1927 		goto exit;
1928 	}
1929 
1930 	/* wait till rpt done or timeout */
1931 	rtw_sctx_wait(&sctx, __func__);
1932 
1933 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1934 	dvobj->customer_str_sctx = NULL;
1935 	if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1936 		_rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1937 	else
1938 		ret = _FAIL;
1939 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1940 
1941 exit:
1942 	return ret;
1943 }
1944 
rtw_hal_h2c_customer_str_write(_adapter * adapter,const u8 * cs)1945 s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1946 {
1947 	u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1948 	u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1949 	u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1950 	s32 ret;
1951 
1952 	SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1953 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1954 
1955 	SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1956 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1957 
1958 	SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1959 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1960 
1961 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1962 	if (ret != _SUCCESS) {
1963 		RTW_WARN("%s w1 fail\n", __func__);
1964 		goto exit;
1965 	}
1966 
1967 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1968 	if (ret != _SUCCESS) {
1969 		RTW_WARN("%s w2 fail\n", __func__);
1970 		goto exit;
1971 	}
1972 
1973 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1974 	if (ret != _SUCCESS) {
1975 		RTW_WARN("%s w3 fail\n", __func__);
1976 		goto exit;
1977 	}
1978 
1979 exit:
1980 	return ret;
1981 }
1982 
1983 /* write customer str and check if value reported is the same as requested */
rtw_hal_customer_str_write(_adapter * adapter,const u8 * cs)1984 s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1985 {
1986 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1987 	struct submit_ctx sctx;
1988 	s32 ret = _SUCCESS;
1989 
1990 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1991 	if (dvobj->customer_str_sctx != NULL)
1992 		ret = _FAIL;
1993 	else {
1994 		rtw_sctx_init(&sctx, 2 * 1000);
1995 		dvobj->customer_str_sctx = &sctx;
1996 	}
1997 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1998 
1999 	if (ret == _FAIL) {
2000 		RTW_WARN("%s another handle ongoing\n", __func__);
2001 		goto exit;
2002 	}
2003 
2004 	ret = rtw_customer_str_write_cmd(adapter, cs);
2005 	if (ret != _SUCCESS) {
2006 		RTW_WARN("%s write cmd fail\n", __func__);
2007 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2008 		dvobj->customer_str_sctx = NULL;
2009 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2010 		goto exit;
2011 	}
2012 
2013 	ret = rtw_customer_str_req_cmd(adapter);
2014 	if (ret != _SUCCESS) {
2015 		RTW_WARN("%s read cmd fail\n", __func__);
2016 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2017 		dvobj->customer_str_sctx = NULL;
2018 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2019 		goto exit;
2020 	}
2021 
2022 	/* wait till rpt done or timeout */
2023 	rtw_sctx_wait(&sctx, __func__);
2024 
2025 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2026 	dvobj->customer_str_sctx = NULL;
2027 	if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
2028 		if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
2029 			RTW_WARN("%s read back check fail\n", __func__);
2030 			RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
2031 			RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
2032 			ret = _FAIL;
2033 		}
2034 	} else
2035 		ret = _FAIL;
2036 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2037 
2038 exit:
2039 	return ret;
2040 }
2041 #endif /* CONFIG_RTW_CUSTOMER_STR */
2042 
2043 #ifdef RTW_PER_CMD_SUPPORT_FW
2044 #define H2C_REQ_PER_RPT_LEN 5
2045 #define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)
2046 #define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)
2047 #define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value)	SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)
2048 
rtw_hal_set_req_per_rpt_cmd(_adapter * adapter,u8 group_macid,u8 rpt_type,u32 macid_bitmap)2049 u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,
2050 				      u8 rpt_type, u32 macid_bitmap)
2051 {
2052 	u8 ret = _FAIL;
2053 	u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};
2054 
2055 	SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);
2056 	SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);
2057 	SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);
2058 
2059 	ret = rtw_hal_fill_h2c_cmd(adapter,
2060 				   H2C_REQ_PER_RPT,
2061 				   H2C_REQ_PER_RPT_LEN,
2062 				   cmd_buf);
2063 	return ret;
2064 }
2065 
2066 #define	GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2067 #define	GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2068 #define	GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
2069 #define	GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
2070 #define	GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data)	LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)
2071 #define	GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
2072 #define	GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)
2073 #define	GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
2074 #define	GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)
2075 #define	GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data)	LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)
2076 
2077 #define	GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2078 #define	GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2079 #define	GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
2080 #define	GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
2081 #define	GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)
2082 #define	GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)
2083 #define	GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
2084 #define	GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)
2085 #define	GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
2086 #define	GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)
2087 #define	GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)
2088 #define	GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)
2089 
per_rate_rpt_update(_adapter * adapter,u8 mac_id,u8 per,u8 rate,u8 bw,u8 total_pkt)2090 static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,
2091 				u8 per, u8 rate,
2092 				u8 bw, u8 total_pkt)
2093 {
2094 #ifdef CONFIG_RTW_MESH
2095 	rtw_ieee80211s_update_metric(adapter, mac_id,
2096 				     per, rate,
2097 				     bw, total_pkt);
2098 #endif
2099 }
2100 
c2h_per_rate_rpt_hdl(_adapter * adapter,u8 * data,u8 len)2101 int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
2102 {
2103 	/* Now only consider type0, since it covers all params in type1
2104 	 * type0: mac_id, per, rate, bw, total_pkt
2105 	 * type1: mac_id, per, rate, bw
2106 	 */
2107 	u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};
2108 	u16 total_pkt[2] = {0};
2109 	int ret = _FAIL, i, macid_cnt = 0;
2110 
2111 	/* type0:
2112 	 * 1 macid includes   6 bytes info + 1 byte 0xff
2113 	 * 2 macid includes 2*6 bytes info
2114 	 */
2115 	if (!(len == 7 || len == 12)) {
2116 		RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);
2117 		goto exit;
2118 	}
2119 
2120 	macid_cnt++;
2121 	mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);
2122 	per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);
2123 	rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);
2124 	bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);
2125 	total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);
2126 
2127 	mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);
2128 	/* 0xff means no report anymore */
2129 	if (mac_id[1] == 0xff)
2130 		goto update_per;
2131 	if (len != 12) {
2132 		RTW_WARN("%s incorrect format\n", __FUNCTION__);
2133 		goto exit;
2134 	}
2135 	macid_cnt++;
2136 	per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);
2137 	rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);
2138 	bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);
2139 	total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);
2140 
2141 update_per:
2142 	for (i = 0; i < macid_cnt; i++) {
2143 		RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "
2144 			"rate = %u, bw = %u, total_pkt = %u\n",
2145 			__FUNCTION__, i, mac_id[i], per[i],
2146 			rate[i], bw[i], total_pkt[i]);
2147 		per_rate_rpt_update(adapter, mac_id[i],
2148 				    per[i], rate[i],
2149 				    bw[i], total_pkt[i]);
2150 	}
2151 	ret = _SUCCESS;
2152 exit:
2153 	return ret;
2154 }
2155 #endif /* RTW_PER_CMD_SUPPORT_FW */
2156 
2157 #ifdef CONFIG_LPS_ACK
2158 #define	GET_C2H_LPS_STATUS_RPT_GET_ACTION(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2159 #define	GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2160 #define DBG_LPS_STATUS_RPT 0
2161 
c2h_lps_status_rpt(PADAPTER adapter,u8 * data,u8 len)2162 int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len)
2163 {
2164 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
2165 	struct submit_ctx *lps_sctx = &pwrpriv->lps_ack_sctx;
2166 	u8 action = 0;
2167 	s8 status_code = 0;
2168 	int ret = _FAIL;
2169 
2170 	if (len < LPS_STATUS_RPT_LEN) {
2171 		RTW_WARN("%s len(%u) < %d\n", __func__, len, LPS_STATUS_RPT_LEN);
2172 		goto exit;
2173 	}
2174 
2175 	action = GET_C2H_LPS_STATUS_RPT_GET_ACTION(data);
2176 	status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data);
2177 
2178 	/* action=0: report force leave null data status */
2179 	/* action=1: report Rf on status when receiving a SetPwrMode H2C with PwrState = RFON */
2180 	switch (action) {
2181 		case 0:
2182 			/* status code 0: success, 1: no ack, 2: timeout, 3: cancel */
2183 		case 1:
2184 			/* status code 0: FW has already turn to RFON */
2185 			pwrpriv->lps_ack_status = status_code;
2186 
2187 			if (DBG_LPS_STATUS_RPT)
2188 				RTW_INFO("=== [C2H LPS Action(%d)] LPS Status Code:%d ===\n", action, status_code);
2189 
2190 			break;
2191 		default:
2192 			RTW_INFO("UnKnown Action(%d) for C2H LPS RPT\n", action);
2193 			break;
2194 	}
2195 
2196 	rtw_sctx_done(&lps_sctx);
2197 	ret = _SUCCESS;
2198 
2199 exit:
2200 	return ret;
2201 }
2202 #endif /* CONFIG_LPS_ACK */
2203 
rtw_hal_update_sta_wset(_adapter * adapter,struct sta_info * psta)2204 void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
2205 {
2206 	u8 w_set = 0;
2207 
2208 	if (psta->wireless_mode & WIRELESS_11B)
2209 		w_set |= WIRELESS_CCK;
2210 
2211 	if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
2212 		w_set |= WIRELESS_OFDM;
2213 
2214 	if (psta->wireless_mode & WIRELESS_11_24N)
2215 		w_set |= WIRELESS_HT;
2216 
2217 	if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))
2218 		w_set |= WIRELESS_VHT;
2219 
2220 	psta->cmn.support_wireless_set = w_set;
2221 }
2222 
rtw_hal_update_sta_mimo_type(_adapter * adapter,struct sta_info * psta)2223 void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
2224 {
2225 	s8 tx_nss, rx_nss;
2226 
2227 	tx_nss = rtw_get_sta_tx_nss(adapter, psta);
2228 	rx_nss =  rtw_get_sta_rx_nss(adapter, psta);
2229 	if ((tx_nss == 1) && (rx_nss == 1))
2230 		psta->cmn.mimo_type = RF_1T1R;
2231 	else if ((tx_nss == 1) && (rx_nss == 2))
2232 		psta->cmn.mimo_type = RF_1T2R;
2233 	else if ((tx_nss == 2) && (rx_nss == 2))
2234 		psta->cmn.mimo_type = RF_2T2R;
2235 	else if ((tx_nss == 2) && (rx_nss == 3))
2236 		psta->cmn.mimo_type = RF_2T3R;
2237 	else if ((tx_nss == 2) && (rx_nss == 4))
2238 		psta->cmn.mimo_type = RF_2T4R;
2239 	else if ((tx_nss == 3) && (rx_nss == 3))
2240 		psta->cmn.mimo_type = RF_3T3R;
2241 	else if ((tx_nss == 3) && (rx_nss == 4))
2242 		psta->cmn.mimo_type = RF_3T4R;
2243 	else if ((tx_nss == 4) && (rx_nss == 4))
2244 		psta->cmn.mimo_type = RF_4T4R;
2245 	else
2246 		rtw_warn_on(1);
2247 
2248 #ifdef CONFIG_CTRL_TXSS_BY_TP
2249 	rtw_ctrl_txss_update_mimo_type(adapter, psta);
2250 #endif
2251 
2252 	RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
2253 			psta->cmn.mac_id, tx_nss, rx_nss);
2254 }
2255 
rtw_hal_update_sta_smps_cap(_adapter * adapter,struct sta_info * psta)2256 void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
2257 {
2258 	/*Spatial Multiplexing Power Save*/
2259 #if 0
2260 	if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2261 		#ifdef CONFIG_80211N_HT
2262 		if (psta->htpriv.ht_option) {
2263 			if (psta->htpriv.smps_cap == 0)
2264 				psta->cmn.sm_ps = SM_PS_STATIC;
2265 			else if (psta->htpriv.smps_cap == 1)
2266 				psta->cmn.sm_ps = SM_PS_DYNAMIC;
2267 			else
2268 				psta->cmn.sm_ps = SM_PS_DISABLE;
2269 		}
2270 		#endif /* CONFIG_80211N_HT */
2271 	} else
2272 #endif
2273 		psta->cmn.sm_ps = SM_PS_DISABLE;
2274 
2275 	RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
2276 			psta->cmn.mac_id, psta->cmn.sm_ps);
2277 }
2278 
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)2279 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
2280 {
2281 
2282 	u8 raid;
2283 	if (IS_NEW_GENERATION_IC(adapter)) {
2284 
2285 		raid = (network_type & WIRELESS_11B)	? RATEID_IDX_B
2286 		       : RATEID_IDX_G;
2287 	} else {
2288 		raid = (network_type & WIRELESS_11B)	? RATR_INX_WIRELESS_B
2289 		       : RATR_INX_WIRELESS_G;
2290 	}
2291 	return raid;
2292 }
2293 
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)2294 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
2295 {
2296 	u8 i, tx_nss;
2297 	u64 tx_ra_bitmap = 0, tmp64=0;
2298 
2299 	if (psta == NULL)
2300 		return;
2301 
2302 	/* b/g mode ra_bitmap  */
2303 	for (i = 0; i < sizeof(psta->bssrateset); i++) {
2304 		if (psta->bssrateset[i])
2305 			tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
2306 	}
2307 
2308 #ifdef CONFIG_80211N_HT
2309 if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
2310 	tx_nss = GET_HAL_TX_NSS(padapter);
2311 #ifdef CONFIG_80211AC_VHT
2312 	if (psta->vhtpriv.vht_option) {
2313 		/* AC mode ra_bitmap */
2314 		tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
2315 	} else
2316 #endif /* CONFIG_80211AC_VHT */
2317 	if (psta->htpriv.ht_option) {
2318 		/* n mode ra_bitmap */
2319 
2320 		/* Handling SMPS mode for AP MODE only*/
2321 		if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2322 			/*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
2323 			if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
2324 				/*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
2325 				tx_nss = rtw_min(tx_nss, 1);
2326 			}
2327 		}
2328 
2329 		tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);
2330 		tx_ra_bitmap |= (tmp64 << 12);
2331 	}
2332 }
2333 #endif /* CONFIG_80211N_HT */
2334 	psta->cmn.ra_info.ramask = tx_ra_bitmap;
2335 	psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
2336 }
2337 
rtw_hal_update_sta_ra_info(PADAPTER padapter,struct sta_info * psta)2338 void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
2339 {
2340 	rtw_hal_update_sta_mimo_type(padapter, psta);
2341 	rtw_hal_update_sta_smps_cap(padapter, psta);
2342 	rtw_hal_update_sta_rate_mask(padapter, psta);
2343 }
2344 
2345 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
hw_bcn_ctrl_addr(_adapter * adapter,u8 hw_port)2346 static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)
2347 {
2348 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2349 
2350 	if (hw_port >= hal_spec->port_num) {
2351 		RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);
2352 		rtw_warn_on(1);
2353 		return 0;
2354 	}
2355 
2356 	switch (hw_port) {
2357 	case HW_PORT0:
2358 		return REG_BCN_CTRL;
2359 	case HW_PORT1:
2360 		return REG_BCN_CTRL_1;
2361 	}
2362 
2363 	return 0;
2364 }
2365 #endif
2366 
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2367 static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2368 {
2369 #ifdef RTW_HALMAC
2370 	rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
2371 				adapter->hw_port, net_type);
2372 #else /* !RTW_HALMAC */
2373 	switch (adapter->hw_port) {
2374 	case HW_PORT0:
2375 		/*REG_CR - BIT[17:16]-Network Type for port 1*/
2376 		*net_type = rtw_read8(adapter, MSR) & 0x03;
2377 		break;
2378 	case HW_PORT1:
2379 		/*REG_CR - BIT[19:18]-Network Type for port 1*/
2380 		*net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2381 		break;
2382 #if defined(CONFIG_RTL8814A)
2383 	case HW_PORT2:
2384 		/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2385 		*net_type = rtw_read8(adapter, MSR1) & 0x03;
2386 		break;
2387 	case HW_PORT3:
2388 		/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2389 		*net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2390 		break;
2391 	case HW_PORT4:
2392 		/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2393 		*net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2394 		break;
2395 #endif /*#if defined(CONFIG_RTL8814A)*/
2396 	default:
2397 		RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2398 			 ADPT_ARG(adapter), adapter->hw_port);
2399 		rtw_warn_on(1);
2400 		break;
2401 	}
2402 #endif /* !RTW_HALMAC */
2403 }
2404 
2405 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
rtw_hal_net_type_decision(_adapter * adapter,u8 net_type)2406 static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
2407 {
2408 	if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
2409 		if (net_type != _HW_STATE_NOLINK_)
2410 			return _HW_STATE_AP_;
2411 	}
2412 	return net_type;
2413 }
2414 #endif
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2415 static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2416 {
2417 #ifdef RTW_HALMAC
2418 	#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2419 	net_type = rtw_hal_net_type_decision(adapter, net_type);
2420 	#endif
2421 	rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
2422 				adapter->hw_port, net_type);
2423 #else /* !RTW_HALMAC */
2424 	u8 val8 = 0;
2425 
2426 	switch (adapter->hw_port) {
2427 	case HW_PORT0:
2428 		#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2429 		net_type = rtw_hal_net_type_decision(adapter, net_type);
2430 		#endif
2431 		/*REG_CR - BIT[17:16]-Network Type for port 0*/
2432 		val8 = rtw_read8(adapter, MSR) & 0x0C;
2433 		val8 |= net_type;
2434 		rtw_write8(adapter, MSR, val8);
2435 		break;
2436 	case HW_PORT1:
2437 		/*REG_CR - BIT[19:18]-Network Type for port 1*/
2438 		val8 = rtw_read8(adapter, MSR) & 0x03;
2439 		val8 |= net_type << 2;
2440 		rtw_write8(adapter, MSR, val8);
2441 		break;
2442 #if defined(CONFIG_RTL8814A)
2443 	case HW_PORT2:
2444 		/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2445 		val8 = rtw_read8(adapter, MSR1) & 0xFC;
2446 		val8 |= net_type;
2447 		rtw_write8(adapter, MSR1, val8);
2448 		break;
2449 	case HW_PORT3:
2450 		/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2451 		val8 = rtw_read8(adapter, MSR1) & 0xF3;
2452 		val8 |= net_type << 2;
2453 		rtw_write8(adapter, MSR1, val8);
2454 		break;
2455 	case HW_PORT4:
2456 		/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2457 		val8 = rtw_read8(adapter, MSR1) & 0xCF;
2458 		val8 |= net_type << 4;
2459 		rtw_write8(adapter, MSR1, val8);
2460 		break;
2461 #endif /* CONFIG_RTL8814A */
2462 	default:
2463 		RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2464 			 ADPT_ARG(adapter), adapter->hw_port);
2465 		rtw_warn_on(1);
2466 		break;
2467 	}
2468 #endif /* !RTW_HALMAC */
2469 }
2470 
2471 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
2472 	#define SEC_CAM_ACCESS_TIMEOUT_MS 200
2473 #endif
2474 
2475 #ifndef DBG_SEC_CAM_ACCESS
2476 	#define DBG_SEC_CAM_ACCESS 0
2477 #endif
2478 
rtw_sec_read_cam(_adapter * adapter,u8 addr)2479 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
2480 {
2481 	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2482 	u32 rdata;
2483 	u32 cnt = 0;
2484 	systime start = 0, end = 0;
2485 	u8 timeout = 0;
2486 	u8 sr = 0;
2487 
2488 	_enter_critical_mutex(mutex, NULL);
2489 
2490 	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
2491 
2492 	start = rtw_get_current_time();
2493 	while (1) {
2494 		if (rtw_is_surprise_removed(adapter)) {
2495 			sr = 1;
2496 			break;
2497 		}
2498 
2499 		cnt++;
2500 		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2501 			break;
2502 
2503 		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2504 			timeout = 1;
2505 			break;
2506 		}
2507 	}
2508 	end = rtw_get_current_time();
2509 
2510 	rdata = rtw_read32(adapter, REG_CAMREAD);
2511 
2512 	_exit_critical_mutex(mutex, NULL);
2513 
2514 	if (DBG_SEC_CAM_ACCESS || timeout) {
2515 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
2516 			, FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2517 	}
2518 
2519 	return rdata;
2520 }
2521 
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)2522 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
2523 {
2524 	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2525 	u32 cnt = 0;
2526 	systime start = 0, end = 0;
2527 	u8 timeout = 0;
2528 	u8 sr = 0;
2529 
2530 	_enter_critical_mutex(mutex, NULL);
2531 
2532 	rtw_write32(adapter, REG_CAMWRITE, wdata);
2533 	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
2534 
2535 	start = rtw_get_current_time();
2536 	while (1) {
2537 		if (rtw_is_surprise_removed(adapter)) {
2538 			sr = 1;
2539 			break;
2540 		}
2541 
2542 		cnt++;
2543 		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2544 			break;
2545 
2546 		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2547 			timeout = 1;
2548 			break;
2549 		}
2550 	}
2551 	end = rtw_get_current_time();
2552 
2553 	_exit_critical_mutex(mutex, NULL);
2554 
2555 	if (DBG_SEC_CAM_ACCESS || timeout) {
2556 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
2557 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2558 	}
2559 }
2560 
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)2561 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
2562 {
2563 	u8 i;
2564 	u32 rdata;
2565 	u8 begin = 0;
2566 	u8 end = 5; /* TODO: consider other key length accordingly */
2567 
2568 	if (!ctrl && !mac && !key) {
2569 		rtw_warn_on(1);
2570 		goto exit;
2571 	}
2572 
2573 	/* TODO: check id range */
2574 
2575 	if (!ctrl && !mac)
2576 		begin = 2; /* read from key */
2577 
2578 	if (!key && !mac)
2579 		end = 0; /* read to ctrl */
2580 	else if (!key)
2581 		end = 2; /* read to mac */
2582 
2583 	for (i = begin; i <= end; i++) {
2584 		rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
2585 
2586 		switch (i) {
2587 		case 0:
2588 			if (ctrl)
2589 				_rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
2590 			if (mac)
2591 				_rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
2592 			break;
2593 		case 1:
2594 			if (mac)
2595 				_rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
2596 			break;
2597 		default:
2598 			if (key)
2599 				_rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2600 			break;
2601 		}
2602 	}
2603 
2604 exit:
2605 	return;
2606 }
2607 
2608 
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)2609 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2610 {
2611 	unsigned int i;
2612 	int j;
2613 	u8 addr, addr1 = 0;
2614 	u32 wdata, wdata1 = 0;
2615 
2616 	/* TODO: consider other key length accordingly */
2617 #if 0
2618 	switch ((ctrl & 0x1c) >> 2) {
2619 	case _WEP40_:
2620 	case _TKIP_:
2621 	case _AES_:
2622 	case _WEP104_:
2623 
2624 	}
2625 #else
2626 	j = 7;
2627 #endif
2628 
2629 	for (; j >= 0; j--) {
2630 		switch (j) {
2631 		case 0:
2632 			wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2633 			break;
2634 		case 1:
2635 			wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2636 			break;
2637 		case 6:
2638 		case 7:
2639 			wdata = 0;
2640 			break;
2641 		default:
2642 			i = (j - 2) << 2;
2643 			wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2644 			break;
2645 		}
2646 
2647 		addr = (id << 3) + j;
2648 
2649 #if defined(CONFIG_RTL8192F)
2650 		if(j == 1) {
2651 			wdata1 = wdata;
2652 			addr1 = addr;
2653 			continue;
2654 		}
2655 #endif
2656 
2657 		rtw_sec_write_cam(adapter, addr, wdata);
2658 	}
2659 
2660 #if defined(CONFIG_RTL8192F)
2661 	rtw_sec_write_cam(adapter, addr1, wdata1);
2662 #endif
2663 }
2664 
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)2665 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2666 {
2667 	u8 addr;
2668 
2669 	addr = (id << 3);
2670 	rtw_sec_write_cam(adapter, addr, 0);
2671 }
2672 
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)2673 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2674 {
2675 	bool res;
2676 	u16 ctrl;
2677 
2678 	rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2679 
2680 	res = (ctrl & BIT6) ? _TRUE : _FALSE;
2681 	return res;
2682 }
2683 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)2684 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2685 {
2686 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2687 
2688 	_rtw_spinlock_init(&mbid_cam_ctl->lock);
2689 	mbid_cam_ctl->bitmap = 0;
2690 	ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2691 	_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2692 }
2693 
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)2694 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2695 {
2696 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2697 
2698 	_rtw_spinlock_free(&mbid_cam_ctl->lock);
2699 }
2700 
rtw_mbid_cam_reset(_adapter * adapter)2701 void rtw_mbid_cam_reset(_adapter *adapter)
2702 {
2703 	_irqL irqL;
2704 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2705 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2706 
2707 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2708 	mbid_cam_ctl->bitmap = 0;
2709 	_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2710 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2711 
2712 	ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2713 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2714 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2715 {
2716 	u8 i;
2717 	u8 cam_id = INVALID_CAM_ID;
2718 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2719 
2720 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2721 		if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2722 			cam_id = i;
2723 			break;
2724 		}
2725 	}
2726 
2727 	RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2728 	return cam_id;
2729 }
2730 
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2731 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2732 {
2733 	_irqL irqL;
2734 
2735 	u8 cam_id = INVALID_CAM_ID;
2736 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2737 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2738 
2739 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2740 	cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2741 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2742 
2743 	return cam_id;
2744 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2745 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2746 {
2747 	u8 i;
2748 	u8 cam_id = INVALID_CAM_ID;
2749 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2750 
2751 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2752 		if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2753 			cam_id = i;
2754 			break;
2755 		}
2756 	}
2757 	if (cam_id != INVALID_CAM_ID)
2758 		RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2759 			__func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2760 
2761 	return cam_id;
2762 }
2763 
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2764 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2765 {
2766 	_irqL irqL;
2767 	u8 cam_id = INVALID_CAM_ID;
2768 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2769 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2770 
2771 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2772 	cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2773 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2774 
2775 	return cam_id;
2776 }
rtw_get_max_mbid_cam_id(_adapter * adapter)2777 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2778 {
2779 	_irqL irqL;
2780 	s8 i;
2781 	u8 cam_id = INVALID_CAM_ID;
2782 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2783 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2784 
2785 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2786 	for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2787 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2788 			cam_id = i;
2789 			break;
2790 		}
2791 	}
2792 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2793 	/*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2794 	return cam_id;
2795 }
2796 
rtw_get_mbid_cam_entry_num(_adapter * adapter)2797 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2798 {
2799 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2800 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2801 
2802 	return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2803 }
2804 
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)2805 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2806 {
2807 	if (adapter && pmbid_cam && mac_addr) {
2808 		_rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2809 		pmbid_cam->iface_id = adapter->iface_id;
2810 	}
2811 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)2812 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2813 {
2814 	if (pmbid_cam) {
2815 		_rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2816 		pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2817 	}
2818 }
2819 
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)2820 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2821 {
2822 	_irqL irqL;
2823 	u8 cam_id = INVALID_CAM_ID, i;
2824 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2825 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2826 	u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2827 
2828 	if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2829 		goto exit;
2830 
2831 	if (entry_num >= TOTAL_MBID_CAM_NUM) {
2832 		RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2833 		rtw_warn_on(1);
2834 	}
2835 
2836 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2837 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2838 		if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2839 			mbid_cam_ctl->bitmap |= BIT(i);
2840 			cam_id = i;
2841 			break;
2842 		}
2843 	}
2844 	if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2845 		mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2846 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2847 
2848 	if (cam_id != INVALID_CAM_ID) {
2849 		ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2850 		RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2851 #ifdef DBG_MBID_CAM_DUMP
2852 		rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2853 #endif
2854 	} else
2855 		RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2856 exit:
2857 	return cam_id;
2858 }
2859 
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)2860 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2861 {
2862 	_irqL irqL;
2863 	u8 entry_id = INVALID_CAM_ID;
2864 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2865 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2866 
2867 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2868 	entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2869 	if (entry_id != INVALID_CAM_ID)
2870 		mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2871 
2872 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2873 
2874 	return entry_id;
2875 }
2876 
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)2877 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2878 {
2879 	_irqL irqL;
2880 	u8 ret = _FALSE;
2881 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2882 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2883 
2884 	if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2885 		RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2886 		rtw_warn_on(1);
2887 	}
2888 	if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2889 		goto exit;
2890 
2891 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2892 	if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2893 		if (mac_addr) {
2894 			mbid_cam_ctl->bitmap |= BIT(camid);
2895 			mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2896 			ret = _TRUE;
2897 		}
2898 	}
2899 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2900 
2901 	if (ret == _TRUE) {
2902 		ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2903 		RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2904 #ifdef DBG_MBID_CAM_DUMP
2905 		rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2906 #endif
2907 	} else
2908 		RTW_INFO("%s  [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2909 
2910 exit:
2911 	return ret;
2912 }
2913 
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)2914 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2915 {
2916 	_irqL irqL;
2917 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2918 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2919 
2920 	if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2921 		RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2922 		rtw_warn_on(1);
2923 	}
2924 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2925 	mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2926 	mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2927 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2928 	ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2929 	RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2930 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)2931 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2932 {
2933 	_irqL irqL;
2934 	u8 i;
2935 	_adapter *iface;
2936 	u8 iface_id;
2937 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2938 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2939 	u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2940 	u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2941 
2942 	RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2943 
2944 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2945 	RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2946 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2947 		RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2948 
2949 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2950 			iface_id = dvobj->mbid_cam_cache[i].iface_id;
2951 			_RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2952 			_RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2953 
2954 			iface = dvobj->padapters[iface_id];
2955 			if (iface) {
2956 				if (MLME_IS_STA(iface))
2957 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2958 				else if (MLME_IS_AP(iface))
2959 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2960 				else if (MLME_IS_MESH(iface))
2961 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
2962 				else
2963 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2964 			}
2965 
2966 		} else
2967 			_RTW_PRINT_SEL(sel, "N/A\n");
2968 	}
2969 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2970 	return 0;
2971 }
2972 
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2973 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2974 {
2975 	u8 poll = 1;
2976 	u8 cam_ready = _FALSE;
2977 	u32 cam_data1 = 0;
2978 	u16 cam_data2 = 0;
2979 
2980 	if (RTW_CANNOT_RUN(padapter))
2981 		return;
2982 
2983 	rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2984 
2985 	do {
2986 		if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2987 			cam_ready = _TRUE;
2988 			break;
2989 		}
2990 		poll++;
2991 	} while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2992 
2993 	if (cam_ready) {
2994 		cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2995 		mac[0] = cam_data1 & 0xFF;
2996 		mac[1] = (cam_data1 >> 8) & 0xFF;
2997 		mac[2] = (cam_data1 >> 16) & 0xFF;
2998 		mac[3] = (cam_data1 >> 24) & 0xFF;
2999 
3000 		cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
3001 		mac[4] = cam_data2 & 0xFF;
3002 		mac[5] = (cam_data2 >> 8) & 0xFF;
3003 	}
3004 
3005 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)3006 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
3007 {
3008 	/*_irqL irqL;*/
3009 	u8 i;
3010 	u8 mac_addr[ETH_ALEN];
3011 
3012 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3013 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
3014 
3015 	RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
3016 
3017 	/*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
3018 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
3019 		RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
3020 		_rtw_memset(mac_addr, 0, ETH_ALEN);
3021 		read_mbssid_cam(adapter, i, mac_addr);
3022 		_RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
3023 	}
3024 	/*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
3025 	return 0;
3026 }
3027 
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)3028 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
3029 {
3030 	u32	cam_val[2] = {0};
3031 
3032 	cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
3033 	cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT)  | (mac[5] << 8) | mac[4];
3034 
3035 	rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
3036 }
3037 
3038 /*
3039 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
3040 {
3041 	rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
3042 }
3043 */
3044 
rtw_ap_set_mbid_num(_adapter * adapter,u8 ap_num)3045 void rtw_ap_set_mbid_num(_adapter *adapter, u8 ap_num)
3046 {
3047 	rtw_write8(adapter, REG_MBID_NUM,
3048 		((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | ((ap_num -1) & 0x07)));
3049 
3050 }
rtw_mbid_cam_enable(_adapter * adapter)3051 void rtw_mbid_cam_enable(_adapter *adapter)
3052 {
3053 	/*enable MBSSID*/
3054 	rtw_hal_rcr_add(adapter, RCR_ENMBID);
3055 }
rtw_mi_set_mbid_cam(_adapter * adapter)3056 void rtw_mi_set_mbid_cam(_adapter *adapter)
3057 {
3058 	u8 i;
3059 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3060 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
3061 
3062 #ifdef DBG_MBID_CAM_DUMP
3063 	rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
3064 #endif
3065 
3066 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
3067 		if (mbid_cam_ctl->bitmap & BIT(i)) {
3068 			write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
3069 			RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
3070 		}
3071 	}
3072 	rtw_mbid_cam_enable(adapter);
3073 }
3074 #endif /*CONFIG_MBSSID_CAM*/
3075 
3076 #ifdef CONFIG_FW_HANDLE_TXBCN
3077 #define H2C_BCN_OFFLOAD_LEN	1
3078 
3079 #define SET_H2CCMD_BCN_OFFLOAD_EN(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
3080 #define SET_H2CCMD_BCN_ROOT_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
3081 #define SET_H2CCMD_BCN_VAP1_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
3082 #define SET_H2CCMD_BCN_VAP2_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
3083 #define SET_H2CCMD_BCN_VAP3_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)
3084 #define SET_H2CCMD_BCN_VAP4_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)
3085 
rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter * adapter,bool fw_bcn_en,u8 tbtt_rpt_map)3086 void rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter *adapter, bool fw_bcn_en, u8 tbtt_rpt_map)
3087 {
3088 	u8 fw_bcn_offload[1] = {0};
3089 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3090 
3091 	if (fw_bcn_en)
3092 		SET_H2CCMD_BCN_OFFLOAD_EN(fw_bcn_offload, 1);
3093 
3094 	if (tbtt_rpt_map & BIT(0))
3095 		SET_H2CCMD_BCN_ROOT_TBTT_RPT(fw_bcn_offload, 1);
3096 	if (tbtt_rpt_map & BIT(1))
3097 		SET_H2CCMD_BCN_VAP1_TBTT_RPT(fw_bcn_offload, 1);
3098 	if (tbtt_rpt_map & BIT(2))
3099 		SET_H2CCMD_BCN_VAP2_TBTT_RPT(fw_bcn_offload, 1);
3100 	if (tbtt_rpt_map & BIT(3))
3101 			SET_H2CCMD_BCN_VAP3_TBTT_RPT(fw_bcn_offload, 1);
3102 
3103 	dvobj->vap_tbtt_rpt_map = tbtt_rpt_map;
3104 	dvobj->fw_bcn_offload = fw_bcn_en;
3105 	RTW_INFO("[FW BCN] Offload : %s\n", (dvobj->fw_bcn_offload) ? "EN" : "DIS");
3106 	RTW_INFO("[FW BCN] TBTT RPT map : 0x%02x\n", dvobj->vap_tbtt_rpt_map);
3107 
3108 	rtw_hal_fill_h2c_cmd(adapter, H2C_FW_BCN_OFFLOAD,
3109 					H2C_BCN_OFFLOAD_LEN, fw_bcn_offload);
3110 }
3111 
rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter * adapter)3112 void rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter *adapter)
3113 {
3114 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3115 	u8 ret, vap_id;
3116 	u32 page_size = 0;
3117 	u8 bcn_rsvdpage[H2C_BCN_RSVDPAGE_LEN] = {0};
3118 
3119 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
3120 	#if 1
3121 	for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {
3122 		if (dvobj->vap_map & BIT(vap_id))
3123 			bcn_rsvdpage[vap_id] = vap_id * (MAX_BEACON_LEN / page_size);
3124 	}
3125 	#else
3126 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
3127 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 8, __Value)
3128 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 8, __Value)
3129 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 8, __Value)
3130 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 8, __Value)
3131 
3132 	if (dvobj->vap_map & BIT(0))
3133  		SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(bcn_rsvdpage, 0);
3134 	if (dvobj->vap_map & BIT(1))
3135 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(bcn_rsvdpage,
3136 					1 * (MAX_BEACON_LEN / page_size));
3137 	if (dvobj->vap_map & BIT(2))
3138 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(bcn_rsvdpage,
3139 					2 * (MAX_BEACON_LEN / page_size));
3140 	if (dvobj->vap_map & BIT(3))
3141 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(bcn_rsvdpage,
3142 					3 * (MAX_BEACON_LEN / page_size));
3143 	if (dvobj->vap_map & BIT(4))
3144 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(bcn_rsvdpage,
3145 					4 * (MAX_BEACON_LEN / page_size));
3146 	#endif
3147 	if (1) {
3148 		RTW_INFO("[BCN_LOC] vap_map : 0x%02x\n", dvobj->vap_map);
3149 		RTW_INFO("[BCN_LOC] page_size :%d, @bcn_page_num :%d\n"
3150 			, page_size, (MAX_BEACON_LEN / page_size));
3151 		RTW_INFO("[BCN_LOC] root ap : 0x%02x\n", *bcn_rsvdpage);
3152 		RTW_INFO("[BCN_LOC] vap_1 : 0x%02x\n", *(bcn_rsvdpage + 1));
3153 		RTW_INFO("[BCN_LOC] vap_2 : 0x%02x\n", *(bcn_rsvdpage + 2));
3154 		RTW_INFO("[BCN_LOC] vap_3 : 0x%02x\n", *(bcn_rsvdpage + 3));
3155 		RTW_INFO("[BCN_LOC] vap_4 : 0x%02x\n", *(bcn_rsvdpage + 4));
3156 	}
3157 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,
3158 					H2C_BCN_RSVDPAGE_LEN, bcn_rsvdpage);
3159 }
3160 
rtw_ap_multi_bcn_cfg(_adapter * adapter)3161 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3162 {
3163 	u8 dft_bcn_space = DEFAULT_BCN_INTERVAL;
3164 	u8 sub_bcn_space = (DEFAULT_BCN_INTERVAL / CONFIG_LIMITED_AP_NUM);
3165 
3166 	/*enable to rx data frame*/
3167 	rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3168 
3169 	/*Disable Port0's beacon function*/
3170 	rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
3171 	/*Reset Port0's TSF*/
3172 	rtw_write8(adapter, REG_DUAL_TSF_RST, BIT_TSFTR_RST);
3173 
3174 	rtw_ap_set_mbid_num(adapter, CONFIG_LIMITED_AP_NUM);
3175 
3176 	/*BCN space & BCN sub-space 0x554[15:0] = 0x64,0x5BC[23:16] = 0x21*/
3177 	rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), HW_PORT0, dft_bcn_space);
3178 	rtw_write8(adapter, REG_MBSSID_BCN_SPACE3 + 2, sub_bcn_space);
3179 
3180 	#if 0 /*setting in hw_var_set_opmode_mbid - ResumeTxBeacon*/
3181 	/*BCN hold time  0x540[19:8] = 0x80*/
3182 	rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
3183 	rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,
3184 		(rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
3185 	#endif
3186 
3187 	/*ATIM window -0x55A = 0x32, reg 0x570 = 0x32, reg 0x5A0 = 0x32 */
3188 	rtw_write8(adapter, REG_ATIMWND, 0x32);
3189 	rtw_write8(adapter, REG_ATIMWND1_V1, 0x32);
3190 	rtw_write8(adapter, REG_ATIMWND2, 0x32);
3191 	rtw_write8(adapter, REG_ATIMWND3, 0x32);
3192 	/*
3193 	rtw_write8(adapter, REG_ATIMWND4, 0x32);
3194 	rtw_write8(adapter, REG_ATIMWND5, 0x32);
3195 	rtw_write8(adapter, REG_ATIMWND6, 0x32);
3196 	rtw_write8(adapter, REG_ATIMWND7, 0x32);*/
3197 
3198 	/*no limit setting - 0x5A7 = 0xFF - Packet in Hi Queue Tx immediately*/
3199 	rtw_write8(adapter, REG_HIQ_NO_LMT_EN, 0xFF);
3200 
3201 	/*Mask all beacon*/
3202 	rtw_write8(adapter, REG_MBSSID_CTRL, 0);
3203 
3204 	/*BCN invalid bit setting 0x454[6] = 1*/
3205 	/*rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);*/
3206 
3207 	/*Enable Port0's beacon function*/
3208 	rtw_write8(adapter, REG_BCN_CTRL,
3209 	rtw_read8(adapter, REG_BCN_CTRL) | BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT  | BIT_EN_BCN_FUNCTION);
3210 
3211 	/* Enable HW seq for BCN
3212 	* 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT  */
3213 	 #ifdef CONFIG_RTL8822B
3214 	if (IS_HARDWARE_TYPE_8822B(adapter))
3215 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3216 	#endif
3217 
3218 	 #ifdef CONFIG_RTL8822C
3219 	if (IS_HARDWARE_TYPE_8822C(adapter))
3220 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3221 	#endif
3222 }
_rtw_mbid_bcn_cfg(_adapter * adapter,bool mbcnq_en,u8 mbcnq_id)3223 static void _rtw_mbid_bcn_cfg(_adapter *adapter, bool mbcnq_en, u8 mbcnq_id)
3224 {
3225 	if (mbcnq_id >= CONFIG_LIMITED_AP_NUM) {
3226 		RTW_ERR(FUNC_ADPT_FMT"- mbid bcnq_id(%d) invalid\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3227 		rtw_warn_on(1);
3228 	}
3229 
3230 	if (mbcnq_en) {
3231 		rtw_write8(adapter, REG_MBSSID_CTRL,
3232 			rtw_read8(adapter, REG_MBSSID_CTRL) | BIT(mbcnq_id));
3233 		RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) enabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3234 	} else {
3235 		rtw_write8(adapter, REG_MBSSID_CTRL,
3236 			rtw_read8(adapter, REG_MBSSID_CTRL) & (~BIT(mbcnq_id)));
3237 		RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) disabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3238 	}
3239 }
3240 /*#define CONFIG_FW_TBTT_RPT*/
rtw_ap_mbid_bcn_en(_adapter * adapter,u8 ap_id)3241 void rtw_ap_mbid_bcn_en(_adapter *adapter, u8 ap_id)
3242 {
3243 	RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3244 
3245 	#ifdef CONFIG_FW_TBTT_RPT
3246 	if (rtw_ap_get_nums(adapter) >= 1) {
3247 		u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3248 
3249 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3250 			tbtt_rpt_map | BIT(ap_id));/*H2C-0xBA*/
3251 	}
3252 	#else
3253 	if (rtw_ap_get_nums(adapter) == 1)
3254 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE, 0);/*H2C-0xBA*/
3255 	#endif
3256 
3257 	rtw_hal_set_bcn_rsvdpage_loc_cmd(adapter);/*H2C-0x09*/
3258 
3259 	_rtw_mbid_bcn_cfg(adapter, _TRUE, ap_id);
3260 }
rtw_ap_mbid_bcn_dis(_adapter * adapter,u8 ap_id)3261 void rtw_ap_mbid_bcn_dis(_adapter *adapter, u8 ap_id)
3262 {
3263 	RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3264 	_rtw_mbid_bcn_cfg(adapter, _FALSE, ap_id);
3265 
3266 	if (rtw_ap_get_nums(adapter) == 0)
3267 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _FALSE, 0);
3268 	#ifdef CONFIG_FW_TBTT_RPT
3269 	else if (rtw_ap_get_nums(adapter) >= 1) {
3270 		u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3271 
3272 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3273 			tbtt_rpt_map & ~BIT(ap_id));/*H2C-0xBA*/
3274 	}
3275 	#endif
3276 }
3277 #endif
3278 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_ap_multi_bcn_cfg(_adapter * adapter)3279 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3280 {
3281 	#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3282 	rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT);
3283 	#else
3284 	rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
3285 	#endif
3286 	/*enable to rx data frame*/
3287 	rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3288 
3289 	/*Beacon Control related register for first time*/
3290 	rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */
3291 
3292 	/*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
3293 	rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */
3294 
3295 	#ifndef CONFIG_HW_P0_TSF_SYNC
3296 	rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3297 	#endif
3298 
3299 	/*reset TSF*/
3300 	rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
3301 
3302 	/*enable BCN0 Function for if1*/
3303 	/*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
3304 	#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3305 	rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
3306 	#else
3307 	rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3308 	#endif
3309 	#ifdef CONFIG_BCN_XMIT_PROTECT
3310 	rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
3311 	#endif
3312 
3313 	if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
3314 		rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
3315 
3316 	/* Enable HW seq for BCN
3317 	 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT  */
3318 	#ifdef CONFIG_RTL8822B
3319 	if (IS_HARDWARE_TYPE_8822B(adapter))
3320 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3321 	#endif
3322 
3323 	#ifdef CONFIG_RTL8822C
3324 	if (IS_HARDWARE_TYPE_8822C(adapter))
3325 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3326 	#endif
3327 }
3328 #endif
3329 
3330 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3331 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3332 {
3333 
3334 #if 0 /*TODO - modify for more flexible*/
3335 	u8 idx = 0;
3336 
3337 	if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
3338 	    (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
3339 		for (idx = 0; idx < 6; idx++)
3340 			rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
3341 	}  else {
3342 		/*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
3343 		u8 entry_id;
3344 
3345 		if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
3346 		    (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
3347 			entry_id = 0;
3348 			if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
3349 				RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
3350 				write_mbssid_cam(adapter, entry_id, val);
3351 			}
3352 		} else {
3353 			entry_id = rtw_mbid_camid_alloc(adapter, val);
3354 			if (entry_id != INVALID_CAM_ID)
3355 				write_mbssid_cam(adapter, entry_id, val);
3356 		}
3357 	}
3358 #else
3359 	{
3360 		/*
3361 			MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
3362 		*/
3363 		u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
3364 
3365 
3366 		if (entry_id != INVALID_CAM_ID) {
3367 			write_mbssid_cam(adapter, entry_id, mac_addr);
3368 			RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
3369 				ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
3370 		}
3371 	}
3372 #endif
3373 }
3374 
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3375 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3376 {
3377 	u8 idx = 0;
3378 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3379 	u8 entry_id;
3380 
3381 	if (!mac_addr) {
3382 		rtw_warn_on(1);
3383 		return;
3384 	}
3385 
3386 
3387 	entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
3388 
3389 	if (entry_id != INVALID_CAM_ID)
3390 		write_mbssid_cam(adapter, entry_id, mac_addr);
3391 }
3392 
3393 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)3394 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
3395 {
3396 	if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
3397 		return adapter_to_dvobj(adapter)->inter_bcn_space;
3398 	else
3399 		return bcn_interval;
3400 }
3401 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
3402 
3403 #else
3404 
3405 #ifndef RTW_HALMAC
_get_macaddr_reg(enum _hw_port hwport)3406 static u32 _get_macaddr_reg(enum _hw_port hwport)
3407 {
3408 	u32 reg_macaddr = REG_MACID;
3409 
3410 	#ifdef CONFIG_CONCURRENT_MODE
3411 	if (hwport == HW_PORT1)
3412 		reg_macaddr = REG_MACID1;
3413 	#if defined(CONFIG_RTL8814A)
3414 	else if (hwport == HW_PORT2)
3415 		reg_macaddr = REG_MACID2;
3416 	else if (hwport == HW_PORT3)
3417 		reg_macaddr = REG_MACID3;
3418 	else if (hwport == HW_PORT4)
3419 		reg_macaddr = REG_MACID4;
3420 	#endif /*CONFIG_RTL8814A*/
3421 	#endif /*CONFIG_CONCURRENT_MODE*/
3422 
3423 	return reg_macaddr;
3424 }
3425 #endif /*!RTW_HALMAC*/
3426 
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * mac_addr)3427 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)
3428 {
3429 	enum _hw_port hwport;
3430 
3431 	if (mac_addr == NULL)
3432 		return;
3433 	hwport = get_hw_port(adapter);
3434 
3435 	RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
3436 		 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3437 
3438 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3439 	rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3440 #else /* !RTW_HALMAC */
3441 	{
3442 		u8 idx = 0;
3443 		u32 reg_macaddr = _get_macaddr_reg(hwport);
3444 
3445 		for (idx = 0; idx < ETH_ALEN; idx++)
3446 			rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);
3447 	}
3448 #endif /* !RTW_HALMAC */
3449 }
3450 
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)3451 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
3452 {
3453 	enum _hw_port hwport;
3454 
3455 	if (mac_addr == NULL)
3456 		return;
3457 	hwport = get_hw_port(adapter);
3458 
3459 	_rtw_memset(mac_addr, 0, ETH_ALEN);
3460 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3461 	rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3462 #else /* !RTW_HALMAC */
3463 	{
3464 		u8 idx = 0;
3465 		u32 reg_macaddr = _get_macaddr_reg(hwport);
3466 
3467 		for (idx = 0; idx < ETH_ALEN; idx++)
3468 			mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));
3469 	}
3470 #endif /* !RTW_HALMAC */
3471 
3472 	RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
3473 		 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3474 }
3475 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
3476 
3477 #ifndef RTW_HALMAC
_get_bssid_reg(enum _hw_port hw_port)3478 static u32 _get_bssid_reg(enum _hw_port hw_port)
3479 {
3480 	u32 reg_bssid = REG_BSSID;
3481 
3482 	#ifdef CONFIG_CONCURRENT_MODE
3483 	if (hw_port == HW_PORT1)
3484 		reg_bssid = REG_BSSID1;
3485 	#if defined(CONFIG_RTL8814A)
3486 	else if (hw_port == HW_PORT2)
3487 		reg_bssid = REG_BSSID2;
3488 	else if (hw_port == HW_PORT3)
3489 		reg_bssid = REG_BSSID3;
3490 	else if (hw_port == HW_PORT4)
3491 		reg_bssid = REG_BSSID4;
3492 	#endif /*CONFIG_RTL8814A*/
3493 	#endif /*CONFIG_CONCURRENT_MODE*/
3494 
3495 	return reg_bssid;
3496 }
3497 #endif /*!RTW_HALMAC*/
rtw_hal_set_bssid(_adapter * adapter,u8 * val)3498 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
3499 {
3500 	enum _hw_port hw_port = rtw_hal_get_port(adapter);
3501 #ifdef RTW_HALMAC
3502 
3503 	rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
3504 #else /* !RTW_HALMAC */
3505 	u8 idx = 0;
3506 	u32 reg_bssid = _get_bssid_reg(hw_port);
3507 
3508 	for (idx = 0 ; idx < ETH_ALEN; idx++)
3509 		rtw_write8(adapter, (reg_bssid + idx), val[idx]);
3510 #endif /* !RTW_HALMAC */
3511 
3512 	RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
3513 		__func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
3514 }
3515 
3516 #ifndef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_tsf_update(_adapter * adapter,u8 en)3517 static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
3518 {
3519 	u32 addr = 0;
3520 	u8 val8;
3521 
3522 	rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
3523 	if (addr) {
3524 		rtw_enter_protsel_port(adapter, get_hw_port(adapter));
3525 		val8 = rtw_read8(adapter, addr);
3526 		if (en && (val8 & DIS_TSF_UDT)) {
3527 			rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
3528 			#ifdef DBG_TSF_UPDATE
3529 			RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3530 			#endif
3531 		}
3532 		if (!en && !(val8 & DIS_TSF_UDT)) {
3533 			rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
3534 			#ifdef DBG_TSF_UPDATE
3535 			RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3536 			#endif
3537 		}
3538 		rtw_leave_protsel_port(adapter);
3539 	} else {
3540 		RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
3541 			, adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
3542 		rtw_warn_on(1);
3543 	}
3544 }
3545 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_set_hw_update_tsf(PADAPTER padapter)3546 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
3547 {
3548 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3549 
3550 #else
3551 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3552 
3553 	if (!pmlmeext->en_hw_update_tsf)
3554 		return;
3555 
3556 	/* check RCR */
3557 	if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
3558 		return;
3559 
3560 	if (pmlmeext->tsf_update_required) {
3561 		pmlmeext->tsf_update_pause_stime = 0;
3562 		rtw_hal_set_tsf_update(padapter, 1);
3563 	}
3564 
3565 	pmlmeext->en_hw_update_tsf = 0;
3566 #endif
3567 }
3568 
rtw_iface_enable_tsf_update(_adapter * adapter)3569 void rtw_iface_enable_tsf_update(_adapter *adapter)
3570 {
3571 	adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3572 	adapter->mlmeextpriv.tsf_update_required = 1;
3573 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3574 
3575 #else
3576 	rtw_hal_set_tsf_update(adapter, 1);
3577 #endif
3578 }
3579 
rtw_iface_disable_tsf_update(_adapter * adapter)3580 void rtw_iface_disable_tsf_update(_adapter *adapter)
3581 {
3582 	adapter->mlmeextpriv.tsf_update_required = 0;
3583 	adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3584 	adapter->mlmeextpriv.en_hw_update_tsf = 0;
3585 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3586 
3587 #else
3588 	rtw_hal_set_tsf_update(adapter, 0);
3589 #endif
3590 }
3591 
rtw_hal_tsf_update_pause(_adapter * adapter)3592 static void rtw_hal_tsf_update_pause(_adapter *adapter)
3593 {
3594 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3595 
3596 #else
3597 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3598 	_adapter *iface;
3599 	int i;
3600 
3601 	for (i = 0; i < dvobj->iface_nums; i++) {
3602 		iface = dvobj->padapters[i];
3603 		if (!iface)
3604 			continue;
3605 
3606 		rtw_hal_set_tsf_update(iface, 0);
3607 		if (iface->mlmeextpriv.tsf_update_required) {
3608 			iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
3609 			if (!iface->mlmeextpriv.tsf_update_pause_stime)
3610 				iface->mlmeextpriv.tsf_update_pause_stime++;
3611 		}
3612 		iface->mlmeextpriv.en_hw_update_tsf = 0;
3613 	}
3614 #endif
3615 }
3616 
rtw_hal_tsf_update_restore(_adapter * adapter)3617 static void rtw_hal_tsf_update_restore(_adapter *adapter)
3618 {
3619 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3620 
3621 #else
3622 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3623 	_adapter *iface;
3624 	int i;
3625 
3626 	for (i = 0; i < dvobj->iface_nums; i++) {
3627 		iface = dvobj->padapters[i];
3628 		if (!iface)
3629 			continue;
3630 
3631 		if (iface->mlmeextpriv.tsf_update_required) {
3632 			/* enable HW TSF update when recive beacon*/
3633 			iface->mlmeextpriv.en_hw_update_tsf = 1;
3634 			#ifdef DBG_TSF_UPDATE
3635 			RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
3636 				, iface->hw_port, ADPT_ARG(iface));
3637 			#endif
3638 		}
3639 	}
3640 #endif
3641 }
3642 
rtw_hal_periodic_tsf_update_chk(_adapter * adapter)3643 void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
3644 {
3645 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3646 
3647 #else
3648 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3649 	_adapter *iface;
3650 	struct mlme_ext_priv *mlmeext;
3651 	int i;
3652 	u32 restore_ms = 0;
3653 
3654 	if (dvobj->periodic_tsf_update_etime) {
3655 		if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
3656 			/* end for restore status */
3657 			dvobj->periodic_tsf_update_etime = 0;
3658 			rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3659 		}
3660 		return;
3661 	}
3662 
3663 	if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
3664 		return;
3665 
3666 	/*
3667 	* all required ifaces can switch to restore status together
3668 	* loop all pause iface to get largest restore time required
3669 	*/
3670 	for (i = 0; i < dvobj->iface_nums; i++) {
3671 		iface = dvobj->padapters[i];
3672 		if (!iface)
3673 			continue;
3674 
3675 		mlmeext = &iface->mlmeextpriv;
3676 
3677 		if (mlmeext->tsf_update_required
3678 			&& mlmeext->tsf_update_pause_stime
3679 			&& rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
3680 				> mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
3681 		) {
3682 			if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
3683 				restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
3684 		}
3685 	}
3686 
3687 	if (!restore_ms)
3688 		return;
3689 
3690 	dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
3691 	if (!dvobj->periodic_tsf_update_etime)
3692 		dvobj->periodic_tsf_update_etime++;
3693 
3694 	rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3695 
3696 	/* set timer to end restore status */
3697 	_set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
3698 #endif
3699 }
3700 
rtw_hal_periodic_tsf_update_end_timer_hdl(void * ctx)3701 void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
3702 {
3703 	struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
3704 
3705 	if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
3706 		return;
3707 
3708 	rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
3709 }
3710 
hw_var_rcr_config(_adapter * adapter,u32 rcr)3711 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
3712 {
3713 	int err;
3714 
3715 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3716 	rcr = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_AMF | RCR_APP_PHYST_RXFF | RCR_APP_MIC | RCR_APP_ICV;
3717 #endif
3718 	err = rtw_write32(adapter, REG_RCR, rcr);
3719 	if (err == _SUCCESS)
3720 		GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
3721 	return err;
3722 }
3723 
hw_var_rcr_get(_adapter * adapter,u32 * rcr)3724 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
3725 {
3726 	u32 v32;
3727 
3728 	v32 = rtw_read32(adapter, REG_RCR);
3729 	if (rcr)
3730 		*rcr = v32;
3731 	GET_HAL_DATA(adapter)->ReceiveConfig = v32;
3732 	return _SUCCESS;
3733 }
3734 
3735 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)3736 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
3737 {
3738 	PHAL_DATA_TYPE hal;
3739 	u32 rcr;
3740 
3741 	hal = GET_HAL_DATA(adapter);
3742 
3743 	rcr = hal->ReceiveConfig;
3744 	if ((rcr & check_bit) == check_bit)
3745 		return 1;
3746 
3747 	return 0;
3748 }
3749 
rtw_hal_rcr_add(_adapter * adapter,u32 add)3750 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
3751 {
3752 	PHAL_DATA_TYPE hal;
3753 	u32 rcr;
3754 	u8 ret = _SUCCESS;
3755 
3756 	hal = GET_HAL_DATA(adapter);
3757 
3758 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3759 	rcr |= add;
3760 	if (rcr != hal->ReceiveConfig)
3761 		ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3762 
3763 	return ret;
3764 }
3765 
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)3766 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
3767 {
3768 	PHAL_DATA_TYPE hal;
3769 	u32 rcr;
3770 	u8 ret = _SUCCESS;
3771 
3772 	hal = GET_HAL_DATA(adapter);
3773 
3774 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3775 	rcr &= ~clear;
3776 	if (rcr != hal->ReceiveConfig)
3777 		ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3778 
3779 	return ret;
3780 }
3781 
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)3782 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
3783 {
3784 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3785 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3786 	u32 rcr, rcr_new;
3787 	struct mi_state mstate, mstate_s;
3788 
3789 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3790 	rcr_new = rcr;
3791 
3792 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
3793 	rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
3794 #else
3795 	rtw_mi_status_no_self(adapter, &mstate);
3796 	rtw_mi_status_no_others(adapter, &mstate_s);
3797 
3798 	/* only adjust parameters interested */
3799 	switch (self_action) {
3800 	case MLME_SCAN_ENTER:
3801 		mstate_s.scan_num = 1;
3802 		mstate_s.scan_enter_num = 1;
3803 		break;
3804 	case MLME_SCAN_DONE:
3805 		mstate_s.scan_enter_num = 0;
3806 		break;
3807 	case MLME_STA_CONNECTING:
3808 		mstate_s.lg_sta_num = 1;
3809 		mstate_s.ld_sta_num = 0;
3810 		break;
3811 	case MLME_STA_CONNECTED:
3812 		mstate_s.lg_sta_num = 0;
3813 		mstate_s.ld_sta_num = 1;
3814 		break;
3815 	case MLME_STA_DISCONNECTED:
3816 		mstate_s.lg_sta_num = 0;
3817 		mstate_s.ld_sta_num = 0;
3818 		break;
3819 #ifdef CONFIG_TDLS
3820 	case MLME_TDLS_LINKED:
3821 		mstate_s.ld_tdls_num = 1;
3822 		break;
3823 	case MLME_TDLS_NOLINK:
3824 		mstate_s.ld_tdls_num = 0;
3825 		break;
3826 #endif
3827 #ifdef CONFIG_AP_MODE
3828 	case MLME_AP_STARTED:
3829 		mstate_s.ap_num = 1;
3830 		break;
3831 	case MLME_AP_STOPPED:
3832 		mstate_s.ap_num = 0;
3833 		mstate_s.ld_ap_num = 0;
3834 		break;
3835 #endif
3836 #ifdef CONFIG_RTW_MESH
3837 	case MLME_MESH_STARTED:
3838 		mstate_s.mesh_num = 1;
3839 		break;
3840 	case MLME_MESH_STOPPED:
3841 		mstate_s.mesh_num = 0;
3842 		mstate_s.ld_mesh_num = 0;
3843 		break;
3844 #endif
3845 	case MLME_ACTION_NONE:
3846 	case MLME_ADHOC_STARTED:
3847 		/* caller without effect of decision */
3848 		break;
3849 	default:
3850 		rtw_warn_on(1);
3851 	};
3852 
3853 	rtw_mi_status_merge(&mstate, &mstate_s);
3854 
3855 	if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
3856 		#ifdef CONFIG_FIND_BEST_CHANNEL
3857 		|| MSTATE_SCAN_ENTER_NUM(&mstate)
3858 		#endif
3859 		|| hal_data->in_cta_test
3860 	)
3861 		rcr_new &= ~RCR_CBSSID_DATA;
3862 	else
3863 		rcr_new |= RCR_CBSSID_DATA;
3864 
3865 	if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
3866 		rcr_new &= ~RCR_CBSSID_BCN;
3867 	else if (MSTATE_STA_LG_NUM(&mstate)
3868 		|| adapter_to_dvobj(adapter)->periodic_tsf_update_etime
3869 	)
3870 		rcr_new |= RCR_CBSSID_BCN;
3871 	else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
3872 		|| MSTATE_MESH_NUM(&mstate)
3873 	)
3874 		rcr_new &= ~RCR_CBSSID_BCN;
3875 	else
3876 		rcr_new |= RCR_CBSSID_BCN;
3877 
3878 	#ifdef CONFIG_CLIENT_PORT_CFG
3879 	if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
3880 		rcr_new &= ~RCR_CBSSID_BCN;
3881 	#endif
3882 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
3883 
3884 	if (rcr == rcr_new)
3885 		return;
3886 
3887 	if (!hal_spec->rx_tsf_filter
3888 		&& (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
3889 		rtw_hal_tsf_update_pause(adapter);
3890 
3891 	rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
3892 
3893 	if (!hal_spec->rx_tsf_filter
3894 		&& !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
3895 		&& self_action != MLME_STA_CONNECTING)
3896 		rtw_hal_tsf_update_restore(adapter);
3897 }
3898 
hw_var_set_rcr_am(_adapter * adapter,u8 enable)3899 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
3900 {
3901 	u32 rcr = RCR_AM;
3902 
3903 	if (enable)
3904 		rtw_hal_rcr_add(adapter, rcr);
3905 	else
3906 		rtw_hal_rcr_clear(adapter, rcr);
3907 }
3908 
hw_var_set_bcn_interval(_adapter * adapter,u16 interval)3909 static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
3910 {
3911 #ifdef CONFIG_SWTIMER_BASED_TXBCN
3912 	interval = rtw_hal_bcn_interval_adjust(adapter, interval);
3913 #endif
3914 
3915 #ifdef RTW_HALMAC
3916 	rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
3917 #else
3918 	rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
3919 #endif
3920 
3921 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3922 	{
3923 		struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
3924 		struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3925 
3926 		if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3927 			RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
3928 			rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
3929 		}
3930 	}
3931 #endif
3932 }
3933 
3934 #if CONFIG_TX_AC_LIFETIME
3935 const char *const _tx_aclt_conf_str[] = {
3936 	"DEFAULT",
3937 	"AP_M2U",
3938 	"MESH",
3939 	"INVALID",
3940 };
3941 
dump_tx_aclt_force_val(void * sel,struct dvobj_priv * dvobj)3942 void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)
3943 {
3944 #define TX_ACLT_FORCE_MSG_LEN 64
3945 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3946 	struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3947 	char buf[TX_ACLT_FORCE_MSG_LEN];
3948 	int cnt = 0;
3949 
3950 	RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3951 		, hal_spec->tx_aclt_unit_factor * 32
3952 		, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3953 
3954 	RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");
3955 	RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"
3956 		, conf->en
3957 		, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3958 		, conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3959 	);
3960 
3961 	cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");
3962 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3963 		goto exit;
3964 
3965 	if (conf->vo_vi)
3966 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);
3967 	else
3968 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "         AUTO");
3969 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3970 		goto exit;
3971 
3972 
3973 	if (conf->be_bk)
3974 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);
3975 	else
3976 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "         AUTO");
3977 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3978 		goto exit;
3979 
3980 	RTW_PRINT_SEL(sel, "%s\n", buf);
3981 
3982 exit:
3983 	return;
3984 }
3985 
rtw_hal_set_tx_aclt_force_val(_adapter * adapter,struct tx_aclt_conf_t * input,u8 arg_num)3986 void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)
3987 {
3988 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3989 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3990 	struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3991 
3992 	if (arg_num >= 1) {
3993 		if (input->en == 0xFF)
3994 			conf->en = input->en;
3995 		else
3996 			conf->en = input->en & 0xF;
3997 	}
3998 	if (arg_num >= 2) {
3999 		conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
4000 		if (conf->vo_vi > 0xFFFF)
4001 			conf->vo_vi = 0xFFFF;
4002 	}
4003 	if (arg_num >= 3) {
4004 		conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
4005 		if (conf->be_bk > 0xFFFF)
4006 			conf->be_bk = 0xFFFF;
4007 	}
4008 }
4009 
dump_tx_aclt_confs(void * sel,struct dvobj_priv * dvobj)4010 void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)
4011 {
4012 #define TX_ACLT_CONF_MSG_LEN 32
4013 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
4014 	struct tx_aclt_conf_t *conf;
4015 	char buf[TX_ACLT_CONF_MSG_LEN];
4016 	int cnt;
4017 	int i;
4018 
4019 	RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
4020 		, hal_spec->tx_aclt_unit_factor * 32
4021 		, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
4022 
4023 	RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"
4024 		, "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");
4025 
4026 	for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
4027 		conf = &dvobj->tx_aclt_confs[i];
4028 		cnt = 0;
4029 
4030 		if (conf->vo_vi)
4031 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "     0x%04x", conf->vo_vi);
4032 		else
4033 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "        N/A");
4034 		if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
4035 			continue;
4036 
4037 		if (conf->be_bk)
4038 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "     0x%04x", conf->be_bk);
4039 		else
4040 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "        N/A");
4041 		if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
4042 			continue;
4043 
4044 		RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"
4045 			, tx_aclt_conf_str(i), i
4046 			, conf->en
4047 			, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
4048 			, conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
4049 			, buf
4050 		);
4051 	}
4052 }
4053 
rtw_hal_set_tx_aclt_conf(_adapter * adapter,u8 conf_idx,struct tx_aclt_conf_t * input,u8 arg_num)4054 void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)
4055 {
4056 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4057 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4058 	struct tx_aclt_conf_t *conf;
4059 
4060 	if (conf_idx >= TX_ACLT_CONF_NUM)
4061 		return;
4062 
4063 	conf = &dvobj->tx_aclt_confs[conf_idx];
4064 
4065 	if (arg_num >= 1) {
4066 		if (input->en != 0xFF)
4067 			conf->en = input->en & 0xF;
4068 	}
4069 	if (arg_num >= 2) {
4070 		conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
4071 		if (conf->vo_vi > 0xFFFF)
4072 			conf->vo_vi = 0xFFFF;
4073 	}
4074 	if (arg_num >= 3) {
4075 		conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
4076 		if (conf->be_bk > 0xFFFF)
4077 			conf->be_bk = 0xFFFF;
4078 	}
4079 }
4080 
rtw_hal_update_tx_aclt(_adapter * adapter)4081 void rtw_hal_update_tx_aclt(_adapter *adapter)
4082 {
4083 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4084 	struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);
4085 	u8 lt_en = 0, lt_en_ori;
4086 	u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;
4087 	u32 lt, lt_ori;
4088 	struct tx_aclt_conf_t *conf;
4089 	int i;
4090 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
4091 	_adapter *iface;
4092 	u8 ap_m2u_num = 0;
4093 
4094 	for (i = 0; i < dvobj->iface_nums; i++) {
4095 		iface = dvobj->padapters[i];
4096 		if (!iface)
4097 			continue;
4098 
4099 		if (MLME_IS_AP(iface)
4100 			&& ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST)
4101 				|| (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST))
4102 		)
4103 			ap_m2u_num++;
4104 	}
4105 #endif
4106 
4107 	lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);
4108 	lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);
4109 
4110 	for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
4111 		if (!(dvobj->tx_aclt_flags & BIT(i)))
4112 			continue;
4113 
4114 		conf = &dvobj->tx_aclt_confs[i];
4115 
4116 		if (i == TX_ACLT_CONF_DEFAULT) {
4117 			/* first and default status, assign directly */
4118 			lt_en = conf->en;
4119 			if (conf->vo_vi)
4120 				lt_vo_vi = conf->vo_vi;
4121 			if (conf->be_bk)
4122 				lt_be_bk = conf->be_bk;
4123 		}
4124 		#if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH)
4125 		else if (0
4126 			#if CONFIG_RTW_AP_DATA_BMC_TO_UC
4127 			|| (i == TX_ACLT_CONF_AP_M2U
4128 				&& ap_m2u_num
4129 				&& macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)
4130 			#endif
4131 			#ifdef CONFIG_RTW_MESH
4132 			|| (i == TX_ACLT_CONF_MESH
4133 				&& macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)
4134 			#endif
4135 		) {
4136 			/* long term status, OR en and MIN lifetime */
4137 			lt_en |= conf->en;
4138 			if (conf->vo_vi && lt_vo_vi > conf->vo_vi)
4139 				lt_vo_vi = conf->vo_vi;
4140 			if (conf->be_bk && lt_be_bk > conf->be_bk)
4141 				lt_be_bk = conf->be_bk;
4142 		}
4143 		#endif
4144 	}
4145 
4146 	if (dvobj->tx_aclt_force_val.en != 0xFF)
4147 		lt_en = dvobj->tx_aclt_force_val.en;
4148 	if (dvobj->tx_aclt_force_val.vo_vi)
4149 		lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;
4150 	if (dvobj->tx_aclt_force_val.be_bk)
4151 		lt_be_bk = dvobj->tx_aclt_force_val.be_bk;
4152 
4153 	lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);
4154 	lt = (lt_be_bk << 16) | lt_vo_vi;
4155 
4156 	if (0)
4157 		RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);
4158 
4159 	if (lt_en != lt_en_ori)
4160 		rtw_write8(adapter, REG_LIFETIME_EN, lt_en);
4161 	if (lt != lt_ori)
4162 		rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);
4163 }
4164 #endif /* CONFIG_TX_AC_LIFETIME */
4165 
hw_var_port_switch(_adapter * adapter)4166 void hw_var_port_switch(_adapter *adapter)
4167 {
4168 #ifdef CONFIG_CONCURRENT_MODE
4169 #ifdef CONFIG_RUNTIME_PORT_SWITCH
4170 	/*
4171 	0x102: MSR
4172 	0x550: REG_BCN_CTRL
4173 	0x551: REG_BCN_CTRL_1
4174 	0x55A: REG_ATIMWND
4175 	0x560: REG_TSFTR
4176 	0x568: REG_TSFTR1
4177 	0x570: REG_ATIMWND_1
4178 	0x610: REG_MACID
4179 	0x618: REG_BSSID
4180 	0x700: REG_MACID1
4181 	0x708: REG_BSSID1
4182 	*/
4183 
4184 	int i;
4185 	u8 msr;
4186 	u8 bcn_ctrl;
4187 	u8 bcn_ctrl_1;
4188 	u8 atimwnd[2];
4189 	u8 atimwnd_1[2];
4190 	u8 tsftr[8];
4191 	u8 tsftr_1[8];
4192 	u8 macid[6];
4193 	u8 bssid[6];
4194 	u8 macid_1[6];
4195 	u8 bssid_1[6];
4196 #if defined(CONFIG_RTL8192F)
4197 	u16 wlan_act_mask_ctrl = 0;
4198 	u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
4199 #endif
4200 
4201 	u8 hw_port;
4202 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4203 	_adapter *iface = NULL;
4204 
4205 	msr = rtw_read8(adapter, MSR);
4206 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4207 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4208 #if defined(CONFIG_RTL8192F)
4209 	wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4210 #endif
4211 
4212 	for (i = 0; i < 2; i++)
4213 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4214 	for (i = 0; i < 2; i++)
4215 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4216 
4217 	for (i = 0; i < 8; i++)
4218 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4219 	for (i = 0; i < 8; i++)
4220 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4221 
4222 	for (i = 0; i < 6; i++)
4223 		macid[i] = rtw_read8(adapter, REG_MACID + i);
4224 
4225 	for (i = 0; i < 6; i++)
4226 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4227 
4228 	for (i = 0; i < 6; i++)
4229 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4230 
4231 	for (i = 0; i < 6; i++)
4232 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4233 
4234 #ifdef DBG_RUNTIME_PORT_SWITCH
4235 	RTW_INFO(FUNC_ADPT_FMT" before switch\n"
4236 		 "msr:0x%02x\n"
4237 		 "bcn_ctrl:0x%02x\n"
4238 		 "bcn_ctrl_1:0x%02x\n"
4239 #if defined(CONFIG_RTL8192F)
4240 		 "wlan_act_mask_ctrl:0x%02x\n"
4241 #endif
4242 		 "atimwnd:0x%04x\n"
4243 		 "atimwnd_1:0x%04x\n"
4244 		 "tsftr:%llu\n"
4245 		 "tsftr1:%llu\n"
4246 		 "macid:"MAC_FMT"\n"
4247 		 "bssid:"MAC_FMT"\n"
4248 		 "macid_1:"MAC_FMT"\n"
4249 		 "bssid_1:"MAC_FMT"\n"
4250 		 , FUNC_ADPT_ARG(adapter)
4251 		 , msr
4252 		 , bcn_ctrl
4253 		 , bcn_ctrl_1
4254 #if defined(CONFIG_RTL8192F)
4255 		 , wlan_act_mask_ctrl
4256 #endif
4257 		 , *((u16 *)atimwnd)
4258 		 , *((u16 *)atimwnd_1)
4259 		 , *((u64 *)tsftr)
4260 		 , *((u64 *)tsftr_1)
4261 		 , MAC_ARG(macid)
4262 		 , MAC_ARG(bssid)
4263 		 , MAC_ARG(macid_1)
4264 		 , MAC_ARG(bssid_1)
4265 		);
4266 #endif /* DBG_RUNTIME_PORT_SWITCH */
4267 
4268 	/* disable bcn function, disable update TSF */
4269 	rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4270 	rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4271 
4272 #if defined(CONFIG_RTL8192F)
4273 	rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
4274 #endif
4275 
4276 	/* switch msr */
4277 	msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
4278 	rtw_write8(adapter, MSR, msr);
4279 
4280 	/* write port0 */
4281 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
4282 	for (i = 0; i < 2; i++)
4283 		rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
4284 	for (i = 0; i < 8; i++)
4285 		rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
4286 	for (i = 0; i < 6; i++)
4287 		rtw_write8(adapter, REG_MACID + i, macid_1[i]);
4288 	for (i = 0; i < 6; i++)
4289 		rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
4290 
4291 	/* write port1 */
4292 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
4293 	for (i = 0; i < 2; i++)
4294 		rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
4295 	for (i = 0; i < 8; i++)
4296 		rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
4297 	for (i = 0; i < 6; i++)
4298 		rtw_write8(adapter, REG_MACID1 + i, macid[i]);
4299 	for (i = 0; i < 6; i++)
4300 		rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
4301 
4302 	/* write bcn ctl */
4303 #ifdef CONFIG_BT_COEXIST
4304 	/* always enable port0 beacon function for PSTDMA */
4305 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
4306 	    || IS_HARDWARE_TYPE_8723D(adapter))
4307 		bcn_ctrl_1 |= EN_BCN_FUNCTION;
4308 	/* always disable port1 beacon function for PSTDMA */
4309 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
4310 		bcn_ctrl &= ~EN_BCN_FUNCTION;
4311 #endif
4312 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
4313 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
4314 
4315 #if defined(CONFIG_RTL8192F)
4316 	/* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
4317 	if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
4318 		!= (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
4319 		wlan_act_mask_ctrl ^= en_port_mask;
4320 	rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
4321 #endif
4322 
4323 	if (adapter->iface_id == IFACE_ID0)
4324 		iface = dvobj->padapters[IFACE_ID1];
4325 	else if (adapter->iface_id == IFACE_ID1)
4326 		iface = dvobj->padapters[IFACE_ID0];
4327 
4328 
4329 	if (adapter->hw_port == HW_PORT0) {
4330 		adapter->hw_port = HW_PORT1;
4331 		iface->hw_port = HW_PORT0;
4332 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4333 			  ADPT_ARG(iface), ADPT_ARG(adapter));
4334 	} else {
4335 		adapter->hw_port = HW_PORT0;
4336 		iface->hw_port = HW_PORT1;
4337 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4338 			  ADPT_ARG(adapter), ADPT_ARG(iface));
4339 	}
4340 
4341 #ifdef DBG_RUNTIME_PORT_SWITCH
4342 	msr = rtw_read8(adapter, MSR);
4343 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4344 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4345 #if defined(CONFIG_RTL8192F)
4346 	wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4347 #endif
4348 
4349 	for (i = 0; i < 2; i++)
4350 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4351 	for (i = 0; i < 2; i++)
4352 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4353 
4354 	for (i = 0; i < 8; i++)
4355 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4356 	for (i = 0; i < 8; i++)
4357 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4358 
4359 	for (i = 0; i < 6; i++)
4360 		macid[i] = rtw_read8(adapter, REG_MACID + i);
4361 
4362 	for (i = 0; i < 6; i++)
4363 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4364 
4365 	for (i = 0; i < 6; i++)
4366 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4367 
4368 	for (i = 0; i < 6; i++)
4369 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4370 
4371 	RTW_INFO(FUNC_ADPT_FMT" after switch\n"
4372 		 "msr:0x%02x\n"
4373 		 "bcn_ctrl:0x%02x\n"
4374 		 "bcn_ctrl_1:0x%02x\n"
4375 #if defined(CONFIG_RTL8192F)
4376 		 "wlan_act_mask_ctrl:0x%02x\n"
4377 #endif
4378 		 "atimwnd:%u\n"
4379 		 "atimwnd_1:%u\n"
4380 		 "tsftr:%llu\n"
4381 		 "tsftr1:%llu\n"
4382 		 "macid:"MAC_FMT"\n"
4383 		 "bssid:"MAC_FMT"\n"
4384 		 "macid_1:"MAC_FMT"\n"
4385 		 "bssid_1:"MAC_FMT"\n"
4386 		 , FUNC_ADPT_ARG(adapter)
4387 		 , msr
4388 		 , bcn_ctrl
4389 		 , bcn_ctrl_1
4390 #if defined(CONFIG_RTL8192F)
4391 		 , wlan_act_mask_ctrl
4392 #endif
4393 		 , *((u16 *)atimwnd)
4394 		 , *((u16 *)atimwnd_1)
4395 		 , *((u64 *)tsftr)
4396 		 , *((u64 *)tsftr_1)
4397 		 , MAC_ARG(macid)
4398 		 , MAC_ARG(bssid)
4399 		 , MAC_ARG(macid_1)
4400 		 , MAC_ARG(bssid_1)
4401 		);
4402 #endif /* DBG_RUNTIME_PORT_SWITCH */
4403 
4404 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
4405 #endif /* CONFIG_CONCURRENT_MODE */
4406 }
4407 
4408 const char *const _h2c_msr_role_str[] = {
4409 	"RSVD",
4410 	"STA",
4411 	"AP",
4412 	"GC",
4413 	"GO",
4414 	"TDLS",
4415 	"ADHOC",
4416 	"MESH",
4417 	"INVALID",
4418 };
4419 
4420 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)4421 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
4422 {
4423 	s32 ret = _SUCCESS;
4424 	u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
4425 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4426 	u8 port_id = rtw_hal_get_port(adapter);
4427 
4428 	if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
4429 		return ret;
4430 
4431 	SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
4432 	SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
4433 
4434 	RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
4435 	RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
4436 		__func__, ADPT_ARG(adapter), port_id, mac_id);
4437 
4438 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
4439 	dvobj->dft.port_id = port_id;
4440 	dvobj->dft.mac_id = mac_id;
4441 
4442 	return ret;
4443 }
rtw_set_default_port_id(_adapter * adapter)4444 s32 rtw_set_default_port_id(_adapter *adapter)
4445 {
4446 	s32 ret = _SUCCESS;
4447 	struct sta_info		*psta;
4448 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4449 
4450 	if (is_client_associated_to_ap(adapter)) {
4451 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
4452 		if (psta)
4453 			ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
4454 	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
4455 
4456 	} else {
4457 	}
4458 
4459 	return ret;
4460 }
rtw_set_ps_rsvd_page(_adapter * adapter)4461 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
4462 {
4463 	s32 ret = _SUCCESS;
4464 	u16 media_status_rpt = RT_MEDIA_CONNECT;
4465 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4466 
4467 	if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
4468 		return ret;
4469 
4470 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
4471 			  (u8 *)&media_status_rpt);
4472 
4473 	return ret;
4474 }
4475 
4476 #if 0
4477 _adapter * _rtw_search_dp_iface(_adapter *adapter)
4478 {
4479 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4480 	_adapter *iface;
4481 	_adapter *target_iface = NULL;
4482 	int i;
4483 	u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
4484 	u8 p2p_go_num = 0, p2p_gc_num = 0;
4485 	_adapter *sta_ifs[8];
4486 	_adapter *ap_ifs[8];
4487 	_adapter *mesh_ifs[8];
4488 	_adapter *gc_ifs[8];
4489 	_adapter *go_ifs[8];
4490 
4491 	for (i = 0; i < dvobj->iface_nums; i++) {
4492 		iface = dvobj->padapters[i];
4493 
4494 		if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
4495 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4496 				sta_ifs[sta_num++] = iface;
4497 
4498 				#ifdef CONFIG_TDLS
4499 				if (iface->tdlsinfo.link_established == _TRUE)
4500 					tdls_num++;
4501 				#endif
4502 				#ifdef CONFIG_P2P
4503 				if (MLME_IS_GC(iface))
4504 					gc_ifs[p2p_gc_num++] = iface;
4505 				#endif
4506 			}
4507 #ifdef CONFIG_AP_MODE
4508 		} else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
4509 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4510 				ap_ifs[ap_num++] = iface;
4511 				#ifdef CONFIG_P2P
4512 				if (MLME_IS_GO(iface))
4513 					go_ifs[p2p_go_num++] = iface;
4514 				#endif
4515 			}
4516 #endif
4517 		} else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
4518 			&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4519 		) {
4520 			adhoc_num++;
4521 
4522 #ifdef CONFIG_RTW_MESH
4523 		} else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
4524 			&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4525 		) {
4526 			mesh_ifs[mesh_num++] = iface;
4527 #endif
4528 		}
4529 	}
4530 
4531 	if (p2p_gc_num) {
4532 		target_iface = gc_ifs[0];
4533 	}
4534 	else if (sta_num) {
4535 		if(sta_num == 1) {
4536 			target_iface = sta_ifs[0];
4537 		} else if (sta_num >= 2) {
4538 			/*TODO get target_iface by timestamp*/
4539 			target_iface = sta_ifs[0];
4540 		}
4541 	} else if (ap_num) {
4542 		target_iface = ap_ifs[0];
4543 	}
4544 
4545 	RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
4546 	RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
4547 	RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
4548 	RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
4549 	RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
4550 	RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
4551 	RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
4552 
4553 	if (target_iface)
4554 		RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
4555 			__func__, ADPT_ARG(target_iface));
4556 	else
4557 		RTW_INFO("%s => target_iface NULL\n", __func__);
4558 
4559 	return target_iface;
4560 }
4561 
4562 void rtw_search_default_port(_adapter *adapter)
4563 {
4564 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4565 	_adapter *adp_iface = NULL;
4566 #ifdef CONFIG_WOWLAN
4567 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
4568 
4569 	if (pwrpriv->wowlan_mode == _TRUE) {
4570 		adp_iface = adapter;
4571 		goto exit;
4572 	}
4573 #endif
4574 	adp_iface = _rtw_search_dp_iface(adapter);
4575 
4576 exit :
4577 	if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
4578 		rtw_set_default_port_id(adp_iface);
4579 	else
4580 		rtw_hal_set_default_port_id_cmd(adapter, 0);
4581 
4582 	if (1) {
4583 		_adapter *tmp_adp;
4584 
4585 		tmp_adp = (adp_iface) ? adp_iface : adapter;
4586 
4587 		RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
4588 			__func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
4589 	}
4590 }
4591 #endif
4592 #endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
4593 
4594 #ifdef CONFIG_P2P_PS
4595 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)4596 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
4597 {
4598 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4599 	struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4600 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
4601 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4602 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
4603 	struct sta_priv		*pstapriv = &adapter->stapriv;
4604 	struct sta_info		*psta;
4605 	HAL_P2P_PS_PARA p2p_ps_para;
4606 	int status = -1;
4607 	u8 i;
4608 	u8 hw_port = rtw_hal_get_port(adapter);
4609 
4610 	_rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
4611 	_rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
4612 
4613 	(&p2p_ps_para)->p2p_port_id = hw_port;
4614 	(&p2p_ps_para)->p2p_group = 0;
4615 	psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4616 	if (psta) {
4617 		(&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
4618 	} else {
4619 		if (p2p_ps_state != P2P_PS_DISABLE) {
4620 			RTW_ERR("%s , psta was NULL\n", __func__);
4621 			return;
4622 		}
4623 	}
4624 
4625 
4626 	switch (p2p_ps_state) {
4627 	case P2P_PS_DISABLE:
4628 		RTW_INFO("P2P_PS_DISABLE\n");
4629 		_rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
4630 		break;
4631 
4632 	case P2P_PS_ENABLE:
4633 		RTW_INFO("P2P_PS_ENABLE\n");
4634 		/* update CTWindow value. */
4635 		if (pwdinfo->ctwindow > 0) {
4636 			(&p2p_ps_para)->ctwindow_en = 1;
4637 			(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4638 			/*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
4639 		}
4640 
4641 
4642 		if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
4643 			(&p2p_ps_para)->offload_en = 1;
4644 			if (pwdinfo->role == P2P_ROLE_GO) {
4645 				(&p2p_ps_para)->role = 1;
4646 				(&p2p_ps_para)->all_sta_sleep = 0;
4647 			} else
4648 				(&p2p_ps_para)->role = 0;
4649 
4650 			(&p2p_ps_para)->discovery = 0;
4651 		}
4652 		/* hw only support 2 set of NoA */
4653 		for (i = 0; i < pwdinfo->noa_num; i++) {
4654 			/* To control the register setting for which NOA */
4655 			(&p2p_ps_para)->noa_sel = i;
4656 			(&p2p_ps_para)->noa_en = 1;
4657 			(&p2p_ps_para)->disable_close_rf = 0;
4658 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
4659 #ifdef CONFIG_CONCURRENT_MODE
4660 			if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))
4661 #endif /* CONFIG_CONCURRENT_MODE */
4662 				(&p2p_ps_para)->disable_close_rf = 1;
4663 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
4664 			/* config P2P NoA Descriptor Register */
4665 			/* config NOA duration */
4666 			(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
4667 			/* config NOA interval */
4668 			(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
4669 			/* config NOA start time */
4670 			(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
4671 			/* config NOA count */
4672 			(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
4673 			/*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
4674 				(&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
4675 				(&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
4676 			status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4677 			if (status == -1)
4678 				RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4679 		}
4680 
4681 		break;
4682 
4683 	case P2P_PS_SCAN:
4684 		/*This feature FW not ready 20161116 YiWei*/
4685 		return;
4686 		/*
4687 		RTW_INFO("P2P_PS_SCAN\n");
4688 		(&p2p_ps_para)->discovery = 1;
4689 		(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4690 		(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4691 		(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4692 		(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4693 		(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4694 		*/
4695 		break;
4696 
4697 	case P2P_PS_SCAN_DONE:
4698 		/*This feature FW not ready 20161116 YiWei*/
4699 		return;
4700 		/*
4701 		RTW_INFO("P2P_PS_SCAN_DONE\n");
4702 		(&p2p_ps_para)->discovery = 0;
4703 		pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
4704 		(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4705 		(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4706 		(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4707 		(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4708 		(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4709 		*/
4710 		break;
4711 
4712 	default:
4713 		break;
4714 	}
4715 
4716 	if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
4717 		status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4718 		if (status == -1)
4719 			RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4720 	}
4721 	_rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
4722 
4723 }
4724 #endif /* RTW_HALMAC */
4725 #endif /* CONFIG_P2P */
4726 
4727 /*
4728 * rtw_hal_set_FwMediaStatusRpt_cmd -
4729 *
4730 * @adapter:
4731 * @opmode:  0:disconnect, 1:connect
4732 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
4733 * @miracast_sink: 0:source. 1:sink
4734 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
4735 * @macid:
4736 * @macid_ind:  0:update Media Status to macid.  1:update Media Status from macid to macid_end
4737 * @macid_end:
4738 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)4739 s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, bool macid_ind, u8 macid_end)
4740 {
4741 	struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4742 	u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
4743 	int i;
4744 	s32 ret;
4745 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4746 	u8 hw_port = rtw_hal_get_port(adapter);
4747 #endif
4748 	u8 op_num_change_bmp = 0;
4749 
4750 	SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
4751 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
4752 	SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
4753 	SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
4754 	SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
4755 	SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
4756 	SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
4757 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4758 	SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
4759 #endif
4760 	RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
4761 
4762 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
4763 	if (ret != _SUCCESS)
4764 		goto exit;
4765 
4766 #if defined(CONFIG_RTL8188E)
4767 	if (rtw_get_chip_type(adapter) == RTL8188E) {
4768 		HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4769 
4770 		/* 8188E FW doesn't set macid no link, driver does it by self */
4771 		if (opmode)
4772 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
4773 		else
4774 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
4775 
4776 		/* for 8188E RA */
4777 #if (RATE_ADAPTIVE_SUPPORT == 1)
4778 		if (hal_data->fw_ractrl == _FALSE) {
4779 			u8 max_macid;
4780 
4781 			max_macid = rtw_search_max_mac_id(adapter);
4782 			rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
4783 		}
4784 #endif
4785 	}
4786 #endif
4787 
4788 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
4789 	/* TODO: this should move to IOT issue area */
4790 	if (rtw_get_chip_type(adapter) == RTL8812
4791 		|| rtw_get_chip_type(adapter) == RTL8821
4792 	) {
4793 		if (MLME_IS_STA(adapter))
4794 			Hal_PatchwithJaguar_8812(adapter, opmode);
4795 	}
4796 #endif
4797 
4798 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
4799 	if (macid_ind == 0)
4800 		macid_end = macid;
4801 
4802 	for (i = macid; macid <= macid_end; macid++) {
4803 		op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
4804 		if (!opmode) {
4805 			rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
4806 			rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
4807 			rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
4808 			rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
4809 		}
4810 	}
4811 
4812 #if CONFIG_TX_AC_LIFETIME
4813 	if (op_num_change_bmp)
4814 		rtw_hal_update_tx_aclt(adapter);
4815 #endif
4816 
4817 	if (!opmode)
4818 		rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
4819 
4820 exit:
4821 	return ret;
4822 }
4823 
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)4824 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
4825 {
4826 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
4827 }
4828 
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)4829 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
4830 {
4831 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
4832 }
4833 
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4834 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4835 {
4836 	u8	u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
4837 	u8	ret = 0;
4838 
4839 	RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
4840 		 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
4841 		 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
4842 		 rsvdpageloc->LocBTQosNull);
4843 
4844 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
4845 	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
4846 	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
4847 	SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
4848 	SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
4849 
4850 	ret = rtw_hal_fill_h2c_cmd(padapter,
4851 				   H2C_RSVD_PAGE,
4852 				   H2C_RSVDPAGE_LOC_LEN,
4853 				   u1H2CRsvdPageParm);
4854 
4855 }
4856 
4857 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)4858 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
4859 {
4860 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4861 
4862 	if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)
4863 		|| IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)
4864 		|| IS_8822C_SERIES(pHalData->version_id))
4865 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4866 	/*
4867 	* Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
4868 	* It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
4869 	* and implement HAL function.
4870 	* TODO: GPIO_8 multi function?
4871 	*/
4872 
4873 	if ((index == 13 || index == 14)
4874 		#if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
4875 		/* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
4876 		&& (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
4877 		#endif
4878 	)
4879 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4880 }
4881 
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)4882 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
4883 {
4884 #if defined(CONFIG_RTL8192F)
4885 	rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval));
4886 #else
4887 	if (index <= 7) {
4888 		/* config GPIO mode */
4889 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4890 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4891 
4892 		/* config GPIO Sel */
4893 		/* 0: input */
4894 		/* 1: output */
4895 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4896 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
4897 
4898 		/* set output value */
4899 		if (outputval) {
4900 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4901 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
4902 		} else {
4903 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4904 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
4905 		}
4906 	} else if (index <= 15) {
4907 		/* 88C Series: */
4908 		/* index: 11~8 transform to 3~0 */
4909 		/* 8723 Series: */
4910 		/* index: 12~8 transform to 4~0 */
4911 
4912 		index -= 8;
4913 
4914 		/* config GPIO mode */
4915 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4916 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4917 
4918 		/* config GPIO Sel */
4919 		/* 0: input */
4920 		/* 1: output */
4921 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4922 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
4923 
4924 		/* set output value */
4925 		if (outputval) {
4926 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4927 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
4928 		} else {
4929 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4930 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
4931 		}
4932 	} else {
4933 		RTW_INFO("%s: invalid GPIO%d=%d\n",
4934 			 __FUNCTION__, index, outputval);
4935 	}
4936 #endif
4937 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)4938 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
4939 {
4940 #if defined(CONFIG_RTL8192F)
4941 	rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));
4942 #else
4943 	if (index <= 7) {
4944 		/* config GPIO mode */
4945 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4946 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4947 
4948 		/* config GPIO Sel */
4949 		/* 0: input */
4950 		/* 1: output */
4951 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4952 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
4953 
4954 	} else if (index <= 15) {
4955 		/* 88C Series: */
4956 		/* index: 11~8 transform to 3~0 */
4957 		/* 8723 Series: */
4958 		/* index: 12~8 transform to 4~0 */
4959 
4960 		index -= 8;
4961 
4962 		/* config GPIO mode */
4963 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4964 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4965 
4966 		/* config GPIO Sel */
4967 		/* 0: input */
4968 		/* 1: output */
4969 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4970 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
4971 	} else
4972 		RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
4973 #endif
4974 }
4975 
4976 #endif
4977 
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4978 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4979 {
4980 	struct	pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
4981 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
4982 	u8 ret = 0;
4983 #ifdef CONFIG_WOWLAN
4984 	u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
4985 
4986 	RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
4987 		 __func__, rsvdpageloc->LocRemoteCtrlInfo,
4988 		 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
4989 		 rsvdpageloc->LocNDPInfo);
4990 	RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
4991 		 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
4992 		 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
4993 
4994 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
4995 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
4996 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
4997 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
4998 							rsvdpageloc->LocNbrAdv);
4999 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
5000 						      rsvdpageloc->LocNDPInfo);
5001 #ifdef CONFIG_GTK_OL
5002 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
5003 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
5004 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
5005 #endif /* CONFIG_GTK_OL */
5006 		ret = rtw_hal_fill_h2c_cmd(padapter,
5007 					   H2C_AOAC_RSVD_PAGE,
5008 					   H2C_AOAC_RSVDPAGE_LOC_LEN,
5009 					   u1H2CAoacRsvdPageParm);
5010 
5011 		RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
5012 		_rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
5013 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
5014 					 rsvdpageloc->LocAOACReport);
5015 		ret = rtw_hal_fill_h2c_cmd(padapter,
5016 				   H2C_AOAC_RSVDPAGE3,
5017 				   H2C_AOAC_RSVDPAGE_LOC_LEN,
5018 				   u1H2CAoacRsvdPageParm);
5019 		pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
5020 	}
5021 #ifdef CONFIG_PNO_SUPPORT
5022 	else {
5023 
5024 		if (!pwrpriv->wowlan_in_resume) {
5025 			RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
5026 			_rtw_memset(&u1H2CAoacRsvdPageParm, 0,
5027 				    sizeof(u1H2CAoacRsvdPageParm));
5028 			SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
5029 						      rsvdpageloc->LocPNOInfo);
5030 			ret = rtw_hal_fill_h2c_cmd(padapter,
5031 						   H2C_AOAC_RSVDPAGE3,
5032 						   H2C_AOAC_RSVDPAGE_LOC_LEN,
5033 						   u1H2CAoacRsvdPageParm);
5034 		}
5035 	}
5036 #endif /* CONFIG_PNO_SUPPORT */
5037 #endif /* CONFIG_WOWLAN */
5038 }
5039 
5040 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)5041 void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
5042 {
5043 	struct	hal_ops *pHalFunc = &padapter->hal_func;
5044 	u8	u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
5045 	u8	ret = 0;
5046 
5047 
5048 	RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
5049 
5050 	SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
5051 	SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
5052 	ret = rtw_hal_fill_h2c_cmd(padapter,
5053 				   H2C_FW_DBG_MSG_PKT,
5054 				   H2C_FW_DBG_MSG_PKT_LEN,
5055 				   u1H2C_fw_dbg_msg_pkt_parm);
5056 
5057 }
5058 #endif /*DBG_FW_DEBUG_MSG_PKT*/
5059 
5060 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)5061 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
5062 	u32 page_num, u8 *buffer, u32 buffer_size)
5063 {
5064 	u32 addr = 0, size = 0, count = 0;
5065 	u32 page_size = 0, data_low = 0, data_high = 0;
5066 	u16 txbndy = 0, offset = 0;
5067 	u8 i = 0;
5068 	bool rst = _FALSE;
5069 
5070 #ifdef DBG_LA_MODE
5071 	struct registry_priv *registry_par = &adapter->registrypriv;
5072 
5073 	if(registry_par->la_mode_en == 1) {
5074 		RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
5075 		return rst;
5076 	}
5077 #endif
5078 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5079 
5080 	addr = page_offset * page_size;
5081 	size = page_num * page_size;
5082 
5083 	if (buffer_size < size) {
5084 		RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
5085 			__func__, buffer_size, size);
5086 		return rst;
5087 	}
5088 #ifdef RTW_HALMAC
5089 	if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
5090 		rst = _FALSE;
5091 	else
5092 		rst = _TRUE;
5093 #else
5094 	txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
5095 
5096 	offset = (txbndy + page_offset) * page_size / 8;
5097 	count = (buffer_size / 8) + 1;
5098 
5099 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
5100 
5101 	for (i = 0 ; i < count ; i++) {
5102 		rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
5103 		data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
5104 		data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
5105 		_rtw_memcpy(buffer + (i * 8),
5106 			&data_low, sizeof(data_low));
5107 		_rtw_memcpy(buffer + ((i * 8) + 4),
5108 			&data_high, sizeof(data_high));
5109 	}
5110 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
5111 	rst = _TRUE;
5112 #endif /*RTW_HALMAC*/
5113 
5114 #ifdef DBG_GET_RSVD_PAGE
5115 	RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
5116 		 __func__, page_offset, page_num, addr, size);
5117 	RTW_INFO_DUMP("\n", buffer, size);
5118 	RTW_INFO(" ==================================================\n");
5119 #endif
5120 	return rst;
5121 }
5122 
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)5123 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
5124 {
5125 	u32 page_size = 0;
5126 	u8 *buffer = NULL;
5127 	u32 buf_size = 0;
5128 
5129 	if (page_num == 0)
5130 		return;
5131 
5132 	RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
5133 	RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
5134 
5135 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5136 	if (page_size) {
5137 		buf_size = page_size * page_num;
5138 		buffer = rtw_zvmalloc(buf_size);
5139 
5140 		if (buffer) {
5141 			rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
5142 			RTW_DUMP_SEL(sel, buffer, buf_size);
5143 			rtw_vmfree(buffer, buf_size);
5144 		} else
5145 			RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
5146 	} else
5147 			RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
5148 
5149 	RTW_PRINT_SEL(sel, "==========================\n");
5150 }
5151 
5152 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)5153 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
5154 {
5155 	u8 *buffer = NULL;
5156 	u32 buff_size = 0;
5157 	static const char * const fifo_sel_str[] = {
5158 		"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
5159 	};
5160 
5161 	if (fifo_sel > 5) {
5162 		RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
5163 		return;
5164 	}
5165 
5166 	RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
5167 	RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
5168 
5169 	if (fifo_size) {
5170 		buff_size = RND4(fifo_size);
5171 		buffer = rtw_zvmalloc(buff_size);
5172 		if (buffer == NULL)
5173 			buff_size = 0;
5174 	}
5175 
5176 	rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
5177 
5178 	if (buffer) {
5179 		RTW_DUMP_SEL(sel, buffer, fifo_size);
5180 		rtw_vmfree(buffer, buff_size);
5181 	}
5182 
5183 	RTW_PRINT_SEL(sel, "==========================\n");
5184 }
5185 #endif
5186 
5187 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)5188 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
5189 {
5190 	RTW_INFO("%s: Set 0x690=0x00\n", __func__);
5191 	rtw_write8(adapter, REG_WOW_CTRL,
5192 		   (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
5193 	RTW_PRINT("%s: Release RXDMA\n", __func__);
5194 	rtw_write32(adapter, REG_RXPKT_NUM,
5195 		    (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
5196 }
5197 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)5198 static void rtw_hal_disable_tx_report(_adapter *adapter)
5199 {
5200 	rtw_write8(adapter, REG_TX_RPT_CTRL,
5201 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
5202 	RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5203 }
5204 
rtw_hal_enable_tx_report(_adapter * adapter)5205 static void rtw_hal_enable_tx_report(_adapter *adapter)
5206 {
5207 	rtw_write8(adapter, REG_TX_RPT_CTRL,
5208 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
5209 	RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5210 }
5211 #endif
rtw_hal_release_rx_dma(_adapter * adapter)5212 static void rtw_hal_release_rx_dma(_adapter *adapter)
5213 {
5214 	u32 val32 = 0;
5215 
5216 	val32 = rtw_read32(adapter, REG_RXPKT_NUM);
5217 
5218 	rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
5219 
5220 	RTW_INFO("%s, [0x%04x]: 0x%08x\n",
5221 		 __func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));
5222 }
5223 
rtw_hal_pause_rx_dma(_adapter * adapter)5224 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
5225 {
5226 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
5227 	u8 ret = 0;
5228 	s8 trycnt = 100;
5229 	u32 tmp = 0;
5230 	int res = 0;
5231 	/* RX DMA stop */
5232 	RTW_PRINT("Pause DMA\n");
5233 	rtw_write32(adapter, REG_RXPKT_NUM,
5234 		    (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
5235 	do {
5236 		if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
5237 #ifdef CONFIG_USB_HCI
5238 			/* stop interface before leave */
5239 			if (_TRUE == hal->usb_intf_start) {
5240 				rtw_intf_stop(adapter);
5241 				RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
5242 				RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
5243 			}
5244 #endif /* CONFIG_USB_HCI */
5245 
5246 			RTW_PRINT("RX_DMA_IDLE is true\n");
5247 			ret = _SUCCESS;
5248 			break;
5249 		}
5250 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5251 		else {
5252 			res = RecvOnePkt(adapter);
5253 			RTW_PRINT("RecvOnePkt Result: %d\n", res);
5254 		}
5255 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
5256 
5257 #ifdef CONFIG_USB_HCI
5258 		else {
5259 			/* to avoid interface start repeatedly  */
5260 			if (_FALSE == hal->usb_intf_start)
5261 				rtw_intf_start(adapter);
5262 		}
5263 #endif /* CONFIG_USB_HCI */
5264 	} while (trycnt--);
5265 
5266 	if (trycnt < 0) {
5267 		tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
5268 
5269 		RTW_PRINT("Stop RX DMA failed......\n");
5270 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
5271 		RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
5272 			  __func__, rtw_read16(adapter, REG_RXPKTNUM));
5273 #else
5274 		RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
5275 			  __func__, ((tmp & 0xFF00) >> 8));
5276 #endif
5277 		if (tmp & BIT(3))
5278 			RTW_PRINT("%s, RX DMA has req\n",
5279 				  __func__);
5280 		else
5281 			RTW_PRINT("%s, RX DMA no req\n",
5282 				  __func__);
5283 		ret = _FAIL;
5284 	}
5285 
5286 	return ret;
5287 }
5288 
5289 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5290 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)5291 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
5292 {
5293 	u8 ret = 0;
5294 	int res = 0;
5295 	u32 tmp = 0;
5296 #ifdef CONFIG_GPIO_WAKEUP
5297 	return _SUCCESS;
5298 #else
5299 	RTW_PRINT("%s\n", __func__);
5300 
5301 	res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5302 	if (!res)
5303 		RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
5304 	else
5305 		RTW_INFO("sdio_local_read fail\n");
5306 
5307 	tmp = SDIO_HIMR_CPWM2_MSK;
5308 
5309 	res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5310 
5311 	if (!res) {
5312 		res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5313 		RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
5314 		ret = _SUCCESS;
5315 	} else {
5316 		RTW_INFO("sdio_local_write fail\n");
5317 		ret = _FAIL;
5318 	}
5319 	return ret;
5320 #endif /* CONFIG_CPIO_WAKEUP */
5321 }
5322 #endif
5323 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
5324 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
5325 
5326 #ifdef CONFIG_WOWLAN
5327 /*
5328  * rtw_hal_check_wow_ctrl
5329  * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
5330  *									If 0x1C7 == 0 (for 3081), WOW enable successful.
5331  *		     _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
5332  *									If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
5333  */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)5334 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
5335 {
5336 	u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
5337 	u8 mstatus = 0;
5338 	u8 reason = 0xFF;
5339 	u8 trycnt = 25;
5340 	u8 res = _FALSE;
5341 
5342 	if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
5343 		if (chk_type) {
5344 			reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5345 			RTW_INFO("%s reason:0x%02x\n", __func__, reason);
5346 
5347 			while (reason && trycnt > 1) {
5348 				reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5349 				RTW_PRINT("Loop index: %d :0x%02x\n",
5350 					  trycnt, reason);
5351 				trycnt--;
5352 				rtw_msleep_os(20);
5353 			}
5354 			if (!reason)
5355 				res = _TRUE;
5356 			else
5357 				res = _FALSE;
5358 		} else {
5359 			/* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
5360 			fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
5361 			rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
5362 			RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
5363 
5364 			while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
5365 				rtw_msleep_os(20);
5366 				fe1_imr = rtw_read32(adapter, REG_FE1IMR);
5367 				rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
5368 				RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
5369 					  trycnt, fe1_imr, rxpkt_num);
5370 				trycnt--;
5371 			}
5372 
5373 			if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
5374 				res = _FALSE;
5375 			else
5376 				res = _TRUE;
5377 		}
5378 	} else {
5379 		mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5380 		RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
5381 
5382 
5383 		if (chk_type) {
5384 			while (!(mstatus & BIT1) && trycnt > 1) {
5385 				mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5386 				RTW_PRINT("Loop index: %d :0x%02x\n",
5387 					  trycnt, mstatus);
5388 				trycnt--;
5389 				rtw_msleep_os(20);
5390 			}
5391 			if (mstatus & BIT1)
5392 				res = _TRUE;
5393 			else
5394 				res = _FALSE;
5395 		} else {
5396 			while (mstatus & BIT1 && trycnt > 1) {
5397 				mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5398 				RTW_PRINT("Loop index: %d :0x%02x\n",
5399 					  trycnt, mstatus);
5400 				trycnt--;
5401 				rtw_msleep_os(20);
5402 			}
5403 
5404 			if (mstatus & BIT1)
5405 				res = _FALSE;
5406 			else
5407 				res = _TRUE;
5408 		}
5409 	}
5410 
5411 	RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
5412 		  __func__, chk_type, res, (25 - trycnt));
5413 	return res;
5414 }
5415 
5416 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)5417 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
5418 {
5419 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5420 	u8 res = 0, count = 0;
5421 	u8 ret = _FALSE;
5422 
5423 	if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
5424 		res = rtw_read8(adapter, REG_PNO_STATUS);
5425 		while (!(res & BIT(7)) && count < 25) {
5426 			RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
5427 				 count, res);
5428 			res = rtw_read8(adapter, REG_PNO_STATUS);
5429 			count++;
5430 			rtw_msleep_os(2);
5431 		}
5432 		if (res & BIT(7))
5433 			ret = _TRUE;
5434 		else
5435 			ret = _FALSE;
5436 		RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
5437 	}
5438 	return ret;
5439 }
5440 #endif
5441 
rtw_hal_backup_rate(_adapter * adapter)5442 static void rtw_hal_backup_rate(_adapter *adapter)
5443 {
5444 	RTW_INFO("%s\n", __func__);
5445 	/* backup data rate to register 0x8b for wowlan FW */
5446 	rtw_write8(adapter, 0x8d, 1);
5447 	rtw_write8(adapter, 0x8c, 0);
5448 	rtw_write8(adapter, 0x8f, 0x40);
5449 	rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
5450 }
5451 
5452 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)5453 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
5454 {
5455 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5456 	int cam_id, index = 0;
5457 	u8 *addr = NULL;
5458 
5459 	if (!MLME_IS_STA(adapter))
5460 		return;
5461 
5462 	addr = get_bssid(pmlmepriv);
5463 
5464 	if (addr == NULL) {
5465 		RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
5466 		return;
5467 	}
5468 
5469 	rtw_clean_dk_section(adapter);
5470 
5471 	do {
5472 		cam_id = rtw_camid_search(adapter, addr, index, 1);
5473 
5474 		if (cam_id == -1)
5475 			RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
5476 		else
5477 			rtw_sec_cam_swap(adapter, cam_id, index);
5478 
5479 		index++;
5480 	} while (index < 4);
5481 
5482 	rtw_write8(adapter, REG_SECCFG, 0xcc);
5483 }
5484 
rtw_hal_update_gtk_offload_info(_adapter * adapter)5485 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
5486 {
5487 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5488 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5489 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5490 	struct security_priv *psecuritypriv = &adapter->securitypriv;
5491 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5492 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
5493 	_irqL irqL;
5494 	u8 get_key[16];
5495 	u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
5496 	u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
5497 
5498 	if (!MLME_IS_STA(adapter))
5499 		return;
5500 
5501 	_rtw_memset(get_key, 0, sizeof(get_key));
5502 	_rtw_memcpy(&replay_count,
5503 		paoac_rpt->replay_counter_eapol_key, 8);
5504 
5505 	/*read gtk key index*/
5506 	gtk_id = paoac_rpt->key_index;
5507 	aoac_rpt_ver = paoac_rpt->version_info;
5508 
5509 	if (aoac_rpt_ver == 0) {
5510 		/* initial verison */
5511 		if (gtk_id == 5)
5512 			has_rekey = _FALSE;
5513 		else
5514 			has_rekey = _TRUE;
5515 	} else if (aoac_rpt_ver >= 1) {
5516 		/* Add krack patch */
5517 		if (gtk_id == 5)
5518 			RTW_WARN("%s FW check iv fail\n", __func__);
5519 
5520 		if (aoac_rpt_ver == 1)
5521 			RTW_WARN("%s aoac report version should be update to v2\n", __func__);
5522 
5523 		/* Fix key id mismatch */
5524 		if (aoac_rpt_ver == 2)
5525 			has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
5526 	}
5527 
5528 	if (has_rekey == _FALSE) {
5529 		RTW_INFO("%s no rekey event happened.\n", __func__);
5530 	} else if (has_rekey == _TRUE) {
5531 		RTW_INFO("%s update security key.\n", __func__);
5532 		/*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
5533 		rtw_sec_read_cam_ent(adapter, gtk_id,
5534 				     NULL, NULL, get_key);
5535 		rtw_clean_hw_dk_cam(adapter);
5536 
5537 		if (_rtw_camid_is_gk(adapter, gtk_id)) {
5538 			_enter_critical_bh(&cam_ctl->lock, &irqL);
5539 			_rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
5540 				    get_key, 16);
5541 			_exit_critical_bh(&cam_ctl->lock, &irqL);
5542 		} else {
5543 			struct setkey_parm parm_gtk;
5544 
5545 			parm_gtk.algorithm = paoac_rpt->security_type;
5546 			parm_gtk.keyid = gtk_id;
5547 			_rtw_memcpy(parm_gtk.key, get_key, 16);
5548 			setkey_hdl(adapter, (u8 *)&parm_gtk);
5549 		}
5550 
5551 		/*update key into related sw variable and sec-cam cache*/
5552 		psecuritypriv->dot118021XGrpKeyid = gtk_id;
5553 		_rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
5554 				get_key, 16);
5555 		/* update SW TKIP TX/RX MIC value */
5556 		if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
5557 			offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
5558 			_rtw_memcpy(
5559 				&psecuritypriv->dot118021XGrptxmickey[gtk_id],
5560 				&(paoac_rpt->group_key[offset]),
5561 				RTW_TKIP_MIC_LEN);
5562 
5563 			offset = RTW_KEK_LEN;
5564 			_rtw_memcpy(
5565 				&psecuritypriv->dot118021XGrprxmickey[gtk_id],
5566 				&(paoac_rpt->group_key[offset]),
5567 				RTW_TKIP_MIC_LEN);
5568 		}
5569 		RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
5570 			KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
5571 	}
5572 
5573 	/* Update broadcast RX IV */
5574 	if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
5575 		sz = sizeof(psecuritypriv->iv_seq[0]);
5576 		for (i = 0 ; i < 4 ; i++) {
5577 			_rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
5578 			tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
5579 			pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
5580 			_rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
5581 		}
5582 	}
5583 
5584 	rtw_clean_dk_section(adapter);
5585 
5586 	rtw_write8(adapter, REG_SECCFG, 0x0c);
5587 
5588 	#ifdef CONFIG_GTK_OL_DBG
5589 	/* if (gtk_keyindex != 5) */
5590 	dump_sec_cam(RTW_DBGDUMP, adapter);
5591 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
5592 	#endif
5593 }
5594 #endif /*CONFIG_GTK_OL*/
5595 
rtw_dump_aoac_rpt(_adapter * adapter)5596 static void rtw_dump_aoac_rpt(_adapter *adapter)
5597 {
5598 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5599 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5600 	int i = 0;
5601 
5602 	RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
5603 	RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
5604 		paoac_rpt->replay_counter_eapol_key, 8);
5605 	RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
5606 	RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
5607 	RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
5608 	RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
5609 		 paoac_rpt->wow_pattern_idx);
5610 	RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
5611 	RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
5612 	RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
5613 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
5614 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
5615 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
5616 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
5617 }
5618 
rtw_hal_get_aoac_rpt(_adapter * adapter)5619 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
5620 {
5621 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5622 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5623 	u32 page_offset = 0, page_number = 0;
5624 	u32 page_size = 0, buf_size = 0;
5625 	u8 *buffer = NULL;
5626 	u8 i = 0, tmp = 0;
5627 	int ret = -1;
5628 
5629 	/* read aoac report from rsvd page */
5630 	page_offset = pwrctl->wowlan_aoac_rpt_loc;
5631 	page_number = 1;
5632 
5633 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5634 	buf_size = page_size * page_number;
5635 
5636 	buffer = rtw_zvmalloc(buf_size);
5637 
5638 	if (buffer == NULL) {
5639 		RTW_ERR("%s buffer allocate failed size(%d)\n",
5640 			__func__, buf_size);
5641 		return;
5642 	}
5643 
5644 	RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
5645 
5646 	ret = rtw_hal_get_rsvd_page(adapter, page_offset,
5647 		page_number, buffer, buf_size);
5648 
5649 	if (ret == _FALSE) {
5650 		RTW_ERR("%s get aoac report failed\n", __func__);
5651 		rtw_warn_on(1);
5652 		goto _exit;
5653 	}
5654 
5655 	_rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
5656 	_rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
5657 
5658 	for (i = 0 ; i < 4 ; i++) {
5659 		tmp = paoac_rpt->replay_counter_eapol_key[i];
5660 		paoac_rpt->replay_counter_eapol_key[i] =
5661 			paoac_rpt->replay_counter_eapol_key[7 - i];
5662 		paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
5663 	}
5664 
5665 	rtw_dump_aoac_rpt(adapter);
5666 
5667 _exit:
5668 	if (buffer)
5669 		rtw_vmfree(buffer, buf_size);
5670 }
5671 
rtw_hal_update_tx_iv(_adapter * adapter)5672 static void rtw_hal_update_tx_iv(_adapter *adapter)
5673 {
5674 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5675 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5676 	struct sta_info	*psta;
5677 	struct mlme_ext_priv	*pmlmeext = &(adapter->mlmeextpriv);
5678 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5679 	struct security_priv	*psecpriv = &adapter->securitypriv;
5680 
5681 	u16 val16 = 0;
5682 	u32 val32 = 0;
5683 	u64 txiv = 0;
5684 	u8 *pval = NULL;
5685 
5686 	psta = rtw_get_stainfo(&adapter->stapriv,
5687 			       get_my_bssid(&pmlmeinfo->network));
5688 
5689 	/* Update TX iv data. */
5690 	pval = (u8 *)&paoac_rpt->iv;
5691 
5692 	if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
5693 		val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
5694 			((u16)(paoac_rpt->iv[0]) << 8);
5695 		val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5696 			((u32)(paoac_rpt->iv[5]) << 8) +
5697 			((u32)(paoac_rpt->iv[6]) << 16) +
5698 			((u32)(paoac_rpt->iv[7]) << 24);
5699 	} else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
5700 		val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
5701 			((u16)(paoac_rpt->iv[1]) << 8);
5702 		val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5703 			((u32)(paoac_rpt->iv[5]) << 8) +
5704 			((u32)(paoac_rpt->iv[6]) << 16) +
5705 			((u32)(paoac_rpt->iv[7]) << 24);
5706 	}
5707 
5708 	if (psta) {
5709 		txiv = val16 + ((u64)val32 << 16);
5710 		if (txiv != 0)
5711 			psta->dot11txpn.val = txiv;
5712 	}
5713 }
5714 
rtw_hal_update_sw_security_info(_adapter * adapter)5715 static void rtw_hal_update_sw_security_info(_adapter *adapter)
5716 {
5717 	struct security_priv *psecpriv = &adapter->securitypriv;
5718 	u8 sz = sizeof (psecpriv->iv_seq);
5719 
5720 	rtw_hal_update_tx_iv(adapter);
5721 #ifdef CONFIG_GTK_OL
5722 	if (psecpriv->binstallKCK_KEK == _TRUE &&
5723 		(psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5724 		rtw_hal_update_gtk_offload_info(adapter);
5725 #else
5726 	_rtw_memset(psecpriv->iv_seq, 0, sz);
5727 #endif
5728 }
5729 
5730 #if 0 //define but not use
5731 static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable)
5732 {
5733 	u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0};
5734 	u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1;
5735 	u8 ret = _FAIL;
5736 
5737 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5738 
5739 	if(enable) {
5740 		SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid);
5741 		SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason);
5742 		SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason);
5743 
5744 		ret = rtw_hal_fill_h2c_cmd(adapter,
5745 						H2C_GPIO_CUSTOM,
5746 						H2C_GPIO_CUSTOM_LEN,
5747 						H2CGpioCustomParm);
5748 		RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM,
5749 		H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]);
5750 	}
5751 
5752 	return ret;
5753 }
5754 #endif
5755 
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)5756 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
5757 {
5758 	u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
5759 	u8 adopt = 1, check_period = 5;
5760 	u8 ret = _FAIL;
5761 	u8 hw_port = rtw_hal_get_port(adapter);
5762 
5763 	SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
5764 	SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
5765 	SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
5766 	SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
5767 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5768 	SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
5769 	RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5770 #else
5771 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5772 #endif
5773 	ret = rtw_hal_fill_h2c_cmd(adapter,
5774 				   H2C_KEEP_ALIVE,
5775 				   H2C_KEEP_ALIVE_CTRL_LEN,
5776 				   u1H2CKeepAliveParm);
5777 
5778 	return ret;
5779 }
5780 
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)5781 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
5782 {
5783 	u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
5784 	u8 adopt = 1, check_period = 100, trypkt_num = 5;
5785 	u8 ret = _FAIL;
5786 	struct registry_priv *pregistry = &adapter->registrypriv;
5787 	u8 hw_port = rtw_hal_get_port(adapter);
5788 
5789 	SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
5790 	SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
5791 	if (!(pregistry->wakeup_event & BIT(2)))
5792 		SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt);
5793 	SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
5794 	SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
5795 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5796 	SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
5797 	RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5798 #else
5799 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5800 #endif
5801 
5802 	ret = rtw_hal_fill_h2c_cmd(adapter,
5803 				   H2C_DISCON_DECISION,
5804 				   H2C_DISCON_DECISION_LEN,
5805 				   u1H2CDisconDecisionParm);
5806 	return ret;
5807 }
5808 
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)5809 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
5810 {
5811 	struct registry_priv  *registry_par = &adapter->registrypriv;
5812 	struct security_priv *psecpriv = &adapter->securitypriv;
5813 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5814 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
5815 
5816 	u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
5817 	u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;
5818 	u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
5819 	u8 sdio_wakeup_enable = 1;
5820 	u8 gpio_high_active = 0;
5821 	u8 magic_pkt = 0;
5822 	u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
5823 	u8 ret = _FAIL;
5824 #ifdef CONFIG_DIS_UPHY
5825 	u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
5826 #endif /* CONFIG_DIS_UPHY */
5827 
5828 #ifdef CONFIG_GPIO_WAKEUP
5829 	gpio_high_active = ppwrpriv->is_high_active;
5830 	gpionum = ppwrpriv->wowlan_gpio_index;
5831 	sdio_wakeup_enable = 0;
5832 #endif /* CONFIG_GPIO_WAKEUP */
5833 
5834 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
5835 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5836 		no_wake = 1;
5837 
5838 	if (!ppwrpriv->wowlan_pno_enable &&
5839 		registry_par->wakeup_event & BIT(0) && !no_wake)
5840 		magic_pkt = enable;
5841 
5842 	if ((registry_par->wakeup_event & BIT(1)) &&
5843 		(psecpriv->dot11PrivacyAlgrthm == _WEP40_ ||
5844 		psecpriv->dot11PrivacyAlgrthm == _WEP104_) && !no_wake)
5845 			hw_unicast = 1;
5846 
5847 	if (registry_par->wakeup_event & BIT(2) && !no_wake)
5848 		discont_wake = enable;
5849 
5850 	RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5851 		 enable, change_unit);
5852 
5853 	/* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5854 	if (enable && change_unit) {
5855 		gpio_dur = 0x40;
5856 		gpio_unit = 1;
5857 		gpio_pulse_en = 1;
5858 	}
5859 
5860 #ifdef CONFIG_PLATFORM_ARM_RK3188
5861 	if (enable) {
5862 		gpio_pulse_en = 1;
5863 		gpio_pulse_cnt = 0x04;
5864 	}
5865 #endif
5866 
5867 	SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5868 	if(!no_wake)
5869 		SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5870 	SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5871 	SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5872 	SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5873 	SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5874 
5875 #ifdef CONFIG_GTK_OL
5876 	if (psecpriv->binstallKCK_KEK == _TRUE &&
5877 		(psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5878 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5879 	else
5880 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5881 #else
5882 	SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5883 #endif
5884 	SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5885 	SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5886 	SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5887 
5888 	SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5889 	SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5890 
5891 	SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5892 	SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5893 
5894 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5895 	if (enable)
5896 		SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5897 #endif
5898 
5899 #ifdef CONFIG_DIS_UPHY
5900 	if (enable) {
5901 		dis_uphy = 1;
5902 		/* time unit: 0 -> ms, 1 -> 256 ms*/
5903 		dis_uphy_unit = 1;
5904 		dis_uphy_time = 0x4;
5905 	}
5906 
5907 	SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5908 	SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5909 	SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5910 	if (ppwrpriv->hst2dev_high_active == 1)
5911 		SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5912 #ifdef CONFIG_RTW_ONE_PIN_GPIO
5913 	SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5914 	SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5915 	SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5916 #else
5917 	SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5918 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
5919 #endif /* CONFIG_DIS_UPHY */
5920 
5921 
5922 	ret = rtw_hal_fill_h2c_cmd(adapter,
5923 				   H2C_WOWLAN,
5924 				   H2C_WOWLAN_LEN,
5925 				   u1H2CWoWlanCtrlParm);
5926 	return ret;
5927 }
5928 
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)5929 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5930 {
5931 	struct security_priv *psecuritypriv = &(adapter->securitypriv);
5932 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5933 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
5934 	u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5935 	u8 ret = _FAIL, count = 0, no_wake = 0;
5936 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
5937 
5938 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
5939 
5940 	if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5941 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5942 		no_wake = 1;
5943 	if(no_wake) {
5944 		SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5945 			u1H2CRemoteWakeCtrlParm, enable);
5946 	} else {
5947 		if (!ppwrpriv->wowlan_pno_enable) {
5948 			SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5949 				u1H2CRemoteWakeCtrlParm, enable);
5950 			SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5951 				u1H2CRemoteWakeCtrlParm, 1);
5952 	#ifdef CONFIG_GTK_OL
5953 			if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5954 				(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) {
5955 				SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5956 					u1H2CRemoteWakeCtrlParm, 1);
5957 			} else {
5958 				RTW_INFO("no kck kek\n");
5959 				SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5960 					u1H2CRemoteWakeCtrlParm, 0);
5961 			}
5962 	#endif /* CONFIG_GTK_OL */
5963 
5964 	#ifdef CONFIG_IPV6
5965 			if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5966 				RTW_INFO("enable NS offload\n");
5967 				SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5968 					u1H2CRemoteWakeCtrlParm, enable);
5969 			}
5970 
5971 			/*
5972 			 * filter NetBios name service pkt to avoid being waked-up
5973 			 * by this kind of unicast pkt this exceptional modification
5974 			 * is used for match competitor's behavior
5975 			 */
5976 
5977 			SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5978 				u1H2CRemoteWakeCtrlParm, enable);
5979 	#endif /*CONFIG_IPV6*/
5980 #if 0 /* replaced by WOWLAN pattern match */
5981 	#ifdef CONFIG_RTL8192F
5982 			if (IS_HARDWARE_TYPE_8192F(adapter)){
5983 				SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
5984 					u1H2CRemoteWakeCtrlParm, enable);
5985 			}
5986 	#endif /* CONFIG_RTL8192F */
5987 #endif
5988 			if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
5989 				(psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
5990 				(psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
5991 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5992 					u1H2CRemoteWakeCtrlParm, 0);
5993 			} else {
5994 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5995 					u1H2CRemoteWakeCtrlParm, 1);
5996 			}
5997 
5998 			if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
5999 #ifdef CONFIG_GTK_OL
6000 				if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))
6001 					SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
6002 						u1H2CRemoteWakeCtrlParm, enable);
6003 #endif /* CONFIG_GTK_OL */
6004 				if (IS_HARDWARE_TYPE_8188E(adapter) ||
6005 				    IS_HARDWARE_TYPE_8812(adapter)) {
6006 					SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
6007 						u1H2CRemoteWakeCtrlParm, 0);
6008 					SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6009 						u1H2CRemoteWakeCtrlParm, 1);
6010 				}
6011 			}
6012 
6013 			SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
6014 				u1H2CRemoteWakeCtrlParm, 1);
6015 		}
6016 	#ifdef CONFIG_PNO_SUPPORT
6017 		else {
6018 			SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
6019 				u1H2CRemoteWakeCtrlParm, enable);
6020 			SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
6021 				u1H2CRemoteWakeCtrlParm, enable);
6022 		}
6023 	#endif
6024 
6025 	#ifdef CONFIG_P2P_WOWLAN
6026 		if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
6027 			RTW_INFO("P2P OFFLOAD ENABLE\n");
6028 			SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
6029 		} else {
6030 			RTW_INFO("P2P OFFLOAD DISABLE\n");
6031 			SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
6032 		}
6033 	#endif /* CONFIG_P2P_WOWLAN */
6034 	}
6035 
6036 
6037 	ret = rtw_hal_fill_h2c_cmd(adapter,
6038 				   H2C_REMOTE_WAKE_CTRL,
6039 				   H2C_REMOTE_WAKE_CTRL_LEN,
6040 				   u1H2CRemoteWakeCtrlParm);
6041 	return ret;
6042 }
6043 
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)6044 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
6045 {
6046 	u8 ret = _FAIL;
6047 	u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
6048 
6049 	RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
6050 		 __func__, group_alg, pairwise_alg);
6051 	SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
6052 			pairwise_alg);
6053 	SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
6054 			group_alg);
6055 
6056 	ret = rtw_hal_fill_h2c_cmd(adapter,
6057 				   H2C_AOAC_GLOBAL_INFO,
6058 				   H2C_AOAC_GLOBAL_INFO_LEN,
6059 				   u1H2CAOACGlobalInfoParm);
6060 
6061 	return ret;
6062 }
6063 
6064 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)6065 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
6066 		PRSVDPAGE_LOC rsvdpageloc, u8 enable)
6067 {
6068 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6069 	u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
6070 	u8 res = 0, count = 0, ret = _FAIL;
6071 
6072 	RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
6073 		 __func__, rsvdpageloc->LocProbePacket,
6074 		 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
6075 
6076 	SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6077 	SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6078 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6079 					       rsvdpageloc->LocScanInfo);
6080 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6081 			rsvdpageloc->LocProbePacket);
6082 	/*
6083 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6084 				rsvdpageloc->LocSSIDInfo);
6085 	*/
6086 	ret = rtw_hal_fill_h2c_cmd(adapter,
6087 				   H2C_D0_SCAN_OFFLOAD_INFO,
6088 				   H2C_SCAN_OFFLOAD_CTRL_LEN,
6089 				   u1H2CScanOffloadInfoParm);
6090 	return ret;
6091 }
6092 #endif /* CONFIG_PNO_SUPPORT */
6093 
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)6094 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6095 {
6096 	struct security_priv *psecpriv = &padapter->securitypriv;
6097 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6098 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
6099 	struct registry_priv *pregistry = &padapter->registrypriv;
6100 	u8	pkt_type = 0, no_wake = 0;
6101 
6102 	if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6103 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
6104 		no_wake = 1;
6105 
6106 	RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6107 
6108 	rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6109 
6110 	if (enable) {
6111 		if(!no_wake)
6112 			rtw_hal_set_global_info_cmd(padapter,
6113 					    psecpriv->dot118021XGrpPrivacy,
6114 					    psecpriv->dot11PrivacyAlgrthm);
6115 
6116 		if (!(ppwrpriv->wowlan_pno_enable)) {
6117 			if (!no_wake)
6118 				rtw_hal_set_disconnect_decision_cmd(padapter,
6119 								    enable);
6120 #ifdef CONFIG_ARP_KEEP_ALIVE
6121 			if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6122 			    (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6123 				pkt_type = 0;
6124 			else
6125 				pkt_type = 1;
6126 #else
6127 			pkt_type = 0;
6128 #endif /* CONFIG_ARP_KEEP_ALIVE */
6129 			if(!no_wake)
6130 				rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6131 		}
6132 #ifdef CONFIG_PNO_SUPPORT
6133 		rtw_hal_check_pno_enabled(padapter);
6134 #endif /* CONFIG_PNO_SUPPORT */
6135 	} else {
6136 #if 0
6137 		{
6138 			u32 PageSize = 0;
6139 			rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
6140 			dump_TX_FIFO(padapter, 4, PageSize);
6141 		}
6142 #endif
6143 	}
6144 #ifdef CONFIG_CUSTOM_PULSE
6145 	rtw_hal_set_gpio_custom_cmd(padapter, enable);
6146 #endif /* CONFIG_CUSTOM_PULSE */
6147 	rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6148 	RTW_PRINT("-%s()-\n", __func__);
6149 }
6150 #endif /* CONFIG_WOWLAN */
6151 
6152 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)6153 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
6154 {
6155 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6156 
6157 	u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
6158 	u8 gpionum = 0, gpio_dur = 0;
6159 	u8 gpio_pulse = enable;
6160 	u8 sdio_wakeup_enable = 1;
6161 	u8 gpio_high_active = 0;
6162 	u8 ret = _FAIL;
6163 
6164 #ifdef CONFIG_GPIO_WAKEUP
6165 	gpio_high_active = ppwrpriv->is_high_active;
6166 	gpionum = ppwrpriv->wowlan_gpio_index;
6167 	sdio_wakeup_enable = 0;
6168 #endif /*CONFIG_GPIO_WAKEUP*/
6169 
6170 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
6171 
6172 	SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
6173 					  gpionum);
6174 	SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
6175 					 gpio_pulse);
6176 	SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
6177 						gpio_high_active);
6178 	SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
6179 				       enable);
6180 	SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
6181 					     gpio_dur);
6182 
6183 	ret = rtw_hal_fill_h2c_cmd(adapter,
6184 				   H2C_AP_WOW_GPIO_CTRL,
6185 				   H2C_AP_WOW_GPIO_CTRL_LEN,
6186 				   u1H2CAPWoWlanCtrlParm);
6187 
6188 	return ret;
6189 }
6190 
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)6191 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6192 {
6193 	u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
6194 	u8 ret = _FAIL;
6195 
6196 	RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
6197 
6198 	SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
6199 
6200 	ret = rtw_hal_fill_h2c_cmd(adapter,
6201 				   H2C_AP_OFFLOAD,
6202 				   H2C_AP_OFFLOAD_LEN,
6203 				   u1H2CAPOffloadCtrlParm);
6204 
6205 	return ret;
6206 }
6207 
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)6208 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
6209 {
6210 	u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
6211 	u8 ret = _FAIL;
6212 
6213 	RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
6214 
6215 	SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
6216 #ifndef CONFIG_USB_HCI
6217 	SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
6218 #endif /*CONFIG_USB_HCI*/
6219 	SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
6220 
6221 	if (enable)
6222 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
6223 	else
6224 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
6225 
6226 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
6227 				   H2C_AP_PS_LEN, ap_ps_parm);
6228 
6229 	return ret;
6230 }
6231 
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)6232 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
6233 		PRSVDPAGE_LOC rsvdpageloc)
6234 {
6235 	struct hal_ops *pHalFunc = &padapter->hal_func;
6236 	u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
6237 	u8 ret = _FAIL, header = 0;
6238 
6239 	if (pHalFunc->fill_h2c_cmd == NULL) {
6240 		RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
6241 		return;
6242 	}
6243 
6244 	header = rtw_read8(padapter, REG_BCNQ_BDNY);
6245 
6246 	RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
6247 		 rsvdpageloc->LocApOffloadBCN,
6248 		 rsvdpageloc->LocProbeRsp,
6249 		 header);
6250 
6251 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
6252 				      rsvdpageloc->LocApOffloadBCN + header);
6253 
6254 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
6255 				   H2C_BCN_RSVDPAGE_LEN, rsvdparm);
6256 
6257 	if (ret == _FAIL)
6258 		RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
6259 
6260 	rtw_msleep_os(10);
6261 
6262 	_rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
6263 
6264 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
6265 			rsvdpageloc->LocProbeRsp + header);
6266 
6267 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
6268 				   H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
6269 
6270 	if (ret == _FAIL)
6271 		RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
6272 
6273 	rtw_msleep_os(10);
6274 }
6275 
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)6276 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
6277 {
6278 	rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
6279 	rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
6280 	rtw_hal_set_ap_ps_cmd(padapter, enable);
6281 }
6282 
rtw_hal_ap_wow_enable(_adapter * padapter)6283 static void rtw_hal_ap_wow_enable(_adapter *padapter)
6284 {
6285 	struct security_priv *psecuritypriv = &padapter->securitypriv;
6286 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6287 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6288 	struct sta_info *psta = NULL;
6289 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6290 #ifdef DBG_CHECK_FW_PS_STATE
6291 	struct dvobj_priv *psdpriv = padapter->dvobj;
6292 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6293 #endif /*DBG_CHECK_FW_PS_STATE*/
6294 	int res;
6295 	u16 media_status_rpt;
6296 #ifdef CONFIG_GPIO_WAKEUP
6297 	u8 val8 = 0;
6298 #endif
6299 
6300 	RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
6301 #ifdef DBG_CHECK_FW_PS_STATE
6302 	if (rtw_fw_ps_state(padapter) == _FAIL) {
6303 		pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
6304 		RTW_PRINT("wowlan enable no leave 32k\n");
6305 	}
6306 #endif /*DBG_CHECK_FW_PS_STATE*/
6307 
6308 	/* 1. Download WOWLAN FW*/
6309 	rtw_hal_fw_dl(padapter, _TRUE);
6310 
6311 	media_status_rpt = RT_MEDIA_CONNECT;
6312 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6313 			  (u8 *)&media_status_rpt);
6314 
6315 	issue_beacon(padapter, 0);
6316 
6317 	rtw_msleep_os(2);
6318 	#if defined(CONFIG_RTL8188E)
6319 	if (IS_HARDWARE_TYPE_8188E(padapter))
6320 		rtw_hal_disable_tx_report(padapter);
6321 	#endif
6322 	/* RX DMA stop */
6323 	res = rtw_hal_pause_rx_dma(padapter);
6324 	if (res == _FAIL)
6325 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
6326 
6327 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6328 	/* Enable CPWM2 only. */
6329 	res = rtw_hal_enable_cpwm2(padapter);
6330 	if (res == _FAIL)
6331 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6332 #endif
6333 
6334 #ifdef CONFIG_GPIO_WAKEUP
6335 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6336 	rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6337 	rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6338 #else
6339 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6340 	if (pwrctrlpriv->is_high_active == 0)
6341 		rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6342 	else
6343 		rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index,
6344 			GPIO_OUTPUT_LOW);
6345 #else
6346 	val8 = (pwrpriv->is_high_active == 0) ? 1 : 0;
6347 	rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8);
6348 	rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6349 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n",
6350 		 __func__, pwrpriv->wowlan_gpio_index,
6351 		 pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW",
6352 		 pwrpriv->is_high_active ? "HIGI" : "LOW");
6353 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
6354 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6355 #endif /* CONFIG_GPIO_WAKEUP */
6356 
6357 	/* 5. Set Enable WOWLAN H2C command. */
6358 	RTW_PRINT("Set Enable AP WOWLan cmd\n");
6359 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
6360 
6361 	rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
6362 #ifdef CONFIG_USB_HCI
6363 	rtw_mi_intf_stop(padapter);
6364 #endif
6365 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
6366 	/* Invoid SE0 reset signal during suspending*/
6367 	rtw_write8(padapter, REG_RSV_CTRL, 0x20);
6368 	if (IS_8188F(pHalData->version_id) == FALSE
6369 		&& IS_8188GTV(pHalData->version_id) == FALSE)
6370 		rtw_write8(padapter, REG_RSV_CTRL, 0x60);
6371 #endif
6372 }
6373 
rtw_hal_ap_wow_disable(_adapter * padapter)6374 static void rtw_hal_ap_wow_disable(_adapter *padapter)
6375 {
6376 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6377 #ifdef DBG_CHECK_FW_PS_STATE
6378 	struct dvobj_priv *psdpriv = padapter->dvobj;
6379 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6380 #endif /*DBG_CHECK_FW_PS_STATE*/
6381 	u16 media_status_rpt;
6382 
6383 	RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
6384 	/* 1. Read wakeup reason*/
6385 	pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
6386 
6387 	RTW_PRINT("wakeup_reason: 0x%02x\n",
6388 		  pwrctl->wowlan_wake_reason);
6389 
6390 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
6391 
6392 	rtw_msleep_os(2);
6393 #ifdef DBG_CHECK_FW_PS_STATE
6394 	if (rtw_fw_ps_state(padapter) == _FAIL) {
6395 		pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
6396 		RTW_PRINT("wowlan enable no leave 32k\n");
6397 	}
6398 #endif /*DBG_CHECK_FW_PS_STATE*/
6399 
6400 	#if defined(CONFIG_RTL8188E)
6401 	if (IS_HARDWARE_TYPE_8188E(padapter))
6402 		rtw_hal_enable_tx_report(padapter);
6403 	#endif
6404 
6405 	rtw_hal_force_enable_rxdma(padapter);
6406 
6407 	rtw_hal_fw_dl(padapter, _FALSE);
6408 
6409 #ifdef CONFIG_GPIO_WAKEUP
6410 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6411 	rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6412 #else
6413 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6414 	if (pwrctl->is_high_active == 0)
6415 		rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6416 	else
6417 		rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index
6418 			, GPIO_OUTPUT_LOW);
6419 #else
6420 	rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index,
6421 		pwrctl->wowlan_gpio_output_state);
6422 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n",
6423 		 __func__, pwrctl->wowlan_gpio_index,
6424 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
6425 		 pwrctl->is_high_active ? "HIGI" : "LOW");
6426 #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
6427 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6428 #endif /* CONFIG_GPIO_WAKEUP */
6429 	media_status_rpt = RT_MEDIA_CONNECT;
6430 
6431 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6432 			  (u8 *)&media_status_rpt);
6433 
6434 	issue_beacon(padapter, 0);
6435 }
6436 #endif /*CONFIG_AP_WOWLAN*/
6437 
6438 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)6439 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6440 {
6441 	u8 *ssid_ie;
6442 	sint ssid_len_ori;
6443 	int len_diff = 0;
6444 
6445 	ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
6446 
6447 	/* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
6448 
6449 	if (ssid_ie && ssid_len_ori > 0) {
6450 		switch (hidden_ssid_mode) {
6451 		case 1: {
6452 			u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6453 			u32 remain_len = 0;
6454 
6455 			remain_len = ies_len - (next_ie - ies);
6456 
6457 			ssid_ie[1] = 0;
6458 			_rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
6459 			len_diff -= ssid_len_ori;
6460 
6461 			break;
6462 		}
6463 		case 2:
6464 			_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6465 			break;
6466 		default:
6467 			break;
6468 		}
6469 	}
6470 
6471 	return len_diff;
6472 }
6473 
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)6474 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
6475 {
6476 	/* struct xmit_frame	*pmgntframe; */
6477 	/* struct pkt_attrib	*pattrib; */
6478 	/* unsigned char	*pframe; */
6479 	struct rtw_ieee80211_hdr *pwlanhdr;
6480 	unsigned short *fctrl;
6481 	unsigned int	rate_len;
6482 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
6483 	u32	pktlen;
6484 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6485 	/*	_irqL irqL;
6486 	 *	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6487 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6488 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6489 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6490 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6491 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
6492 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6493 #ifdef CONFIG_P2P
6494 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6495 #endif /* CONFIG_P2P */
6496 
6497 	/* for debug */
6498 	u8 *dbgbuf = pframe;
6499 	u8 dbgbufLen = 0, index = 0;
6500 
6501 	RTW_INFO("%s\n", __FUNCTION__);
6502 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6503 	/*	_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6504 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6505 
6506 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6507 
6508 
6509 	fctrl = &(pwlanhdr->frame_ctl);
6510 	*(fctrl) = 0;
6511 
6512 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6513 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6514 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6515 
6516 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6517 	/* pmlmeext->mgnt_seq++; */
6518 	set_frame_sub_type(pframe, WIFI_BEACON);
6519 
6520 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6521 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6522 
6523 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6524 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6525 #ifdef CONFIG_P2P
6526 		/* for P2P : Primary Device Type & Device Name */
6527 		u32 wpsielen = 0, insert_len = 0;
6528 		u8 *wpsie = NULL;
6529 		wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
6530 
6531 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
6532 			uint wps_offset, remainder_ielen;
6533 			u8 *premainder_ie, *pframe_wscie;
6534 
6535 			wps_offset = (uint)(wpsie - cur_network->IEs);
6536 
6537 			premainder_ie = wpsie + wpsielen;
6538 
6539 			remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6540 
6541 #ifdef CONFIG_IOCTL_CFG80211
6542 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6543 				if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
6544 					_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
6545 					pframe += wps_offset;
6546 					pktlen += wps_offset;
6547 
6548 					_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6549 					pframe += pmlmepriv->wps_beacon_ie_len;
6550 					pktlen += pmlmepriv->wps_beacon_ie_len;
6551 
6552 					/* copy remainder_ie to pframe */
6553 					_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6554 					pframe += remainder_ielen;
6555 					pktlen += remainder_ielen;
6556 				} else {
6557 					_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6558 					pframe += cur_network->IELength;
6559 					pktlen += cur_network->IELength;
6560 				}
6561 			} else
6562 #endif /* CONFIG_IOCTL_CFG80211 */
6563 			{
6564 				pframe_wscie = pframe + wps_offset;
6565 				_rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
6566 				pframe += (wps_offset + wpsielen);
6567 				pktlen += (wps_offset + wpsielen);
6568 
6569 				/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6570 				/*	Primary Device Type */
6571 				/*	Type: */
6572 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6573 				insert_len += 2;
6574 
6575 				/*	Length: */
6576 				*(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
6577 				insert_len += 2;
6578 
6579 				/*	Value: */
6580 				/*	Category ID */
6581 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6582 				insert_len += 2;
6583 
6584 				/*	OUI */
6585 				*(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
6586 				insert_len += 4;
6587 
6588 				/*	Sub Category ID */
6589 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6590 				insert_len += 2;
6591 
6592 
6593 				/*	Device Name */
6594 				/*	Type: */
6595 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6596 				insert_len += 2;
6597 
6598 				/*	Length: */
6599 				*(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
6600 				insert_len += 2;
6601 
6602 				/*	Value: */
6603 				_rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
6604 				insert_len += pwdinfo->device_name_len;
6605 
6606 
6607 				/* update wsc ie length */
6608 				*(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
6609 
6610 				/* pframe move to end */
6611 				pframe += insert_len;
6612 				pktlen += insert_len;
6613 
6614 				/* copy remainder_ie to pframe */
6615 				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6616 				pframe += remainder_ielen;
6617 				pktlen += remainder_ielen;
6618 			}
6619 		} else
6620 #endif /* CONFIG_P2P */
6621 		{
6622 			int len_diff;
6623 			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6624 			len_diff = update_hidden_ssid(
6625 					   pframe + _BEACON_IE_OFFSET_
6626 				   , cur_network->IELength - _BEACON_IE_OFFSET_
6627 					   , pmlmeinfo->hidden_ssid_mode
6628 				   );
6629 			pframe += (cur_network->IELength + len_diff);
6630 			pktlen += (cur_network->IELength + len_diff);
6631 		}
6632 #if 0
6633 		{
6634 			u8 *wps_ie;
6635 			uint wps_ielen;
6636 			u8 sr = 0;
6637 			wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
6638 				pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
6639 			if (wps_ie && wps_ielen > 0)
6640 				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6641 			if (sr != 0)
6642 				set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6643 			else
6644 				_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6645 		}
6646 #endif
6647 #ifdef CONFIG_P2P
6648 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6649 			u32 len;
6650 #ifdef CONFIG_IOCTL_CFG80211
6651 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6652 				len = pmlmepriv->p2p_beacon_ie_len;
6653 				if (pmlmepriv->p2p_beacon_ie && len > 0)
6654 					_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6655 			} else
6656 #endif /* CONFIG_IOCTL_CFG80211 */
6657 			{
6658 				len = build_beacon_p2p_ie(pwdinfo, pframe);
6659 			}
6660 
6661 			pframe += len;
6662 			pktlen += len;
6663 
6664 			#ifdef CONFIG_WFD
6665 			len = rtw_append_beacon_wfd_ie(padapter, pframe);
6666 			pframe += len;
6667 			pktlen += len;
6668 			#endif
6669 
6670 		}
6671 #endif /* CONFIG_P2P */
6672 
6673 		goto _issue_bcn;
6674 
6675 	}
6676 
6677 	/* below for ad-hoc mode */
6678 
6679 	/* timestamp will be inserted by hardware */
6680 	pframe += 8;
6681 	pktlen += 8;
6682 
6683 	/* beacon interval: 2 bytes */
6684 
6685 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6686 
6687 	pframe += 2;
6688 	pktlen += 2;
6689 
6690 	/* capability info: 2 bytes */
6691 
6692 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6693 
6694 	pframe += 2;
6695 	pktlen += 2;
6696 
6697 	/* SSID */
6698 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6699 
6700 	/* supported rates... */
6701 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6702 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6703 
6704 	/* DS parameter set */
6705 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6706 
6707 	/* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6708 	{
6709 		u8 erpinfo = 0;
6710 		u32 ATIMWindow;
6711 		/* IBSS Parameter Set... */
6712 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
6713 		ATIMWindow = 0;
6714 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6715 
6716 		/* ERP IE */
6717 		pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
6718 	}
6719 
6720 
6721 	/* EXTERNDED SUPPORTED RATE */
6722 	if (rate_len > 8)
6723 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6724 
6725 
6726 	/* todo:HT for adhoc */
6727 
6728 _issue_bcn:
6729 
6730 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6731 	/*	pmlmepriv->update_bcn = _FALSE;
6732 	 *
6733 	 *	_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6734 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6735 
6736 	*pLength = pktlen;
6737 #if 0
6738 	/* printf dbg msg */
6739 	dbgbufLen = pktlen;
6740 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6741 
6742 	for (index = 0; index < dbgbufLen; index++)
6743 		printk("%x ", *(dbgbuf + index));
6744 
6745 	printk("\n");
6746 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6747 
6748 #endif
6749 }
6750 
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6751 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6752 {
6753 	/* struct xmit_frame			*pmgntframe; */
6754 	/* struct pkt_attrib			*pattrib; */
6755 	/* unsigned char					*pframe; */
6756 	struct rtw_ieee80211_hdr	*pwlanhdr;
6757 	unsigned short				*fctrl;
6758 	unsigned char					*mac;
6759 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
6760 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6761 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6762 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6763 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
6764 	u16					beacon_interval = 100;
6765 	u16					capInfo = 0;
6766 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6767 	u8					wpsie[255] = { 0x00 };
6768 	u32					wpsielen = 0, p2pielen = 0;
6769 	u32					pktlen;
6770 #ifdef CONFIG_WFD
6771 	u32					wfdielen = 0;
6772 #endif
6773 
6774 	/* for debug */
6775 	u8 *dbgbuf = pframe;
6776 	u8 dbgbufLen = 0, index = 0;
6777 
6778 	RTW_INFO("%s\n", __FUNCTION__);
6779 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6780 
6781 	mac = adapter_mac_addr(padapter);
6782 
6783 	fctrl = &(pwlanhdr->frame_ctl);
6784 	*(fctrl) = 0;
6785 
6786 	/* DA filled by FW */
6787 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6788 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6789 
6790 	/*	Use the device address for BSSID field.	 */
6791 	_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6792 
6793 	SetSeqNum(pwlanhdr, 0);
6794 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
6795 
6796 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6797 	pframe += pktlen;
6798 
6799 
6800 	/* timestamp will be inserted by hardware */
6801 	pframe += 8;
6802 	pktlen += 8;
6803 
6804 	/* beacon interval: 2 bytes */
6805 	_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6806 	pframe += 2;
6807 	pktlen += 2;
6808 
6809 	/*	capability info: 2 bytes */
6810 	/*	ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6811 	capInfo |= cap_ShortPremble;
6812 	capInfo |= cap_ShortSlot;
6813 
6814 	_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6815 	pframe += 2;
6816 	pktlen += 2;
6817 
6818 
6819 	/* SSID */
6820 	pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
6821 
6822 	/* supported rates... */
6823 	/*	Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6824 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
6825 
6826 	/* DS parameter set */
6827 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
6828 
6829 #ifdef CONFIG_IOCTL_CFG80211
6830 	if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6831 		if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6832 			/* WPS IE */
6833 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6834 			pktlen += pmlmepriv->wps_probe_resp_ie_len;
6835 			pframe += pmlmepriv->wps_probe_resp_ie_len;
6836 
6837 			/* P2P IE */
6838 			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6839 			pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6840 			pframe += pmlmepriv->p2p_probe_resp_ie_len;
6841 		}
6842 	} else
6843 #endif /* CONFIG_IOCTL_CFG80211		 */
6844 	{
6845 
6846 		/*	Todo: WPS IE */
6847 		/*	Noted by Albert 20100907 */
6848 		/*	According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6849 
6850 		wpsielen = 0;
6851 		/*	WPS OUI */
6852 		*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6853 		wpsielen += 4;
6854 
6855 		/*	WPS version */
6856 		/*	Type: */
6857 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6858 		wpsielen += 2;
6859 
6860 		/*	Length: */
6861 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6862 		wpsielen += 2;
6863 
6864 		/*	Value: */
6865 		wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
6866 
6867 		/*	WiFi Simple Config State */
6868 		/*	Type: */
6869 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6870 		wpsielen += 2;
6871 
6872 		/*	Length: */
6873 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6874 		wpsielen += 2;
6875 
6876 		/*	Value: */
6877 		wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;	/*	Not Configured. */
6878 
6879 		/*	Response Type */
6880 		/*	Type: */
6881 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6882 		wpsielen += 2;
6883 
6884 		/*	Length: */
6885 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6886 		wpsielen += 2;
6887 
6888 		/*	Value: */
6889 		wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6890 
6891 		/*	UUID-E */
6892 		/*	Type: */
6893 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6894 		wpsielen += 2;
6895 
6896 		/*	Length: */
6897 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6898 		wpsielen += 2;
6899 
6900 		/*	Value: */
6901 		if (pwdinfo->external_uuid == 0) {
6902 			_rtw_memset(wpsie + wpsielen, 0x0, 16);
6903 			_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6904 		} else
6905 			_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6906 		wpsielen += 0x10;
6907 
6908 		/*	Manufacturer */
6909 		/*	Type: */
6910 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6911 		wpsielen += 2;
6912 
6913 		/*	Length: */
6914 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6915 		wpsielen += 2;
6916 
6917 		/*	Value: */
6918 		_rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6919 		wpsielen += 7;
6920 
6921 		/*	Model Name */
6922 		/*	Type: */
6923 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
6924 		wpsielen += 2;
6925 
6926 		/*	Length: */
6927 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
6928 		wpsielen += 2;
6929 
6930 		/*	Value: */
6931 		_rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6932 		wpsielen += 6;
6933 
6934 		/*	Model Number */
6935 		/*	Type: */
6936 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6937 		wpsielen += 2;
6938 
6939 		/*	Length: */
6940 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6941 		wpsielen += 2;
6942 
6943 		/*	Value: */
6944 		wpsie[wpsielen++] = 0x31;		/*	character 1 */
6945 
6946 		/*	Serial Number */
6947 		/*	Type: */
6948 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6949 		wpsielen += 2;
6950 
6951 		/*	Length: */
6952 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6953 		wpsielen += 2;
6954 
6955 		/*	Value: */
6956 		_rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6957 		wpsielen += ETH_ALEN;
6958 
6959 		/*	Primary Device Type */
6960 		/*	Type: */
6961 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6962 		wpsielen += 2;
6963 
6964 		/*	Length: */
6965 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6966 		wpsielen += 2;
6967 
6968 		/*	Value: */
6969 		/*	Category ID */
6970 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6971 		wpsielen += 2;
6972 
6973 		/*	OUI */
6974 		*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6975 		wpsielen += 4;
6976 
6977 		/*	Sub Category ID */
6978 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6979 		wpsielen += 2;
6980 
6981 		/*	Device Name */
6982 		/*	Type: */
6983 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6984 		wpsielen += 2;
6985 
6986 		/*	Length: */
6987 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
6988 		wpsielen += 2;
6989 
6990 		/*	Value: */
6991 		_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
6992 		wpsielen += pwdinfo->device_name_len;
6993 
6994 		/*	Config Method */
6995 		/*	Type: */
6996 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6997 		wpsielen += 2;
6998 
6999 		/*	Length: */
7000 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7001 		wpsielen += 2;
7002 
7003 		/*	Value: */
7004 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7005 		wpsielen += 2;
7006 
7007 
7008 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7009 
7010 
7011 		p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
7012 		pframe += p2pielen;
7013 		pktlen += p2pielen;
7014 	}
7015 
7016 #ifdef CONFIG_WFD
7017 	wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
7018 	pframe += wfdielen;
7019 	pktlen += wfdielen;
7020 #endif
7021 
7022 	*pLength = pktlen;
7023 
7024 #if 0
7025 	/* printf dbg msg */
7026 	dbgbufLen = pktlen;
7027 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7028 
7029 	for (index = 0; index < dbgbufLen; index++)
7030 		printk("%x ", *(dbgbuf + index));
7031 
7032 	printk("\n");
7033 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7034 #endif
7035 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7036 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7037 {
7038 	struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7039 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7040 	u8			action = P2P_PUB_ACTION_ACTION;
7041 	u32			p2poui = cpu_to_be32(P2POUI);
7042 	u8			oui_subtype = P2P_GO_NEGO_RESP;
7043 	u8			wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
7044 	u8			p2pielen = 0, i;
7045 	uint			wpsielen = 0;
7046 	u16			wps_devicepassword_id = 0x0000;
7047 	uint			wps_devicepassword_id_len = 0;
7048 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
7049 	u16			len_channellist_attr = 0;
7050 	u32			pktlen;
7051 	u8			dialogToken = 0;
7052 
7053 	/* struct xmit_frame			*pmgntframe; */
7054 	/* struct pkt_attrib			*pattrib; */
7055 	/* unsigned char					*pframe; */
7056 	struct rtw_ieee80211_hdr	*pwlanhdr;
7057 	unsigned short				*fctrl;
7058 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7059 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7060 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7061 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7062 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
7063 
7064 #ifdef CONFIG_WFD
7065 	u32					wfdielen = 0;
7066 #endif
7067 
7068 	/* for debug */
7069 	u8 *dbgbuf = pframe;
7070 	u8 dbgbufLen = 0, index = 0;
7071 
7072 	RTW_INFO("%s\n", __FUNCTION__);
7073 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7074 
7075 	fctrl = &(pwlanhdr->frame_ctl);
7076 	*(fctrl) = 0;
7077 
7078 	/* RA, filled by FW */
7079 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7080 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7081 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7082 
7083 	SetSeqNum(pwlanhdr, 0);
7084 	set_frame_sub_type(pframe, WIFI_ACTION);
7085 
7086 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7087 	pframe += pktlen;
7088 
7089 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7090 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7091 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7092 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7093 
7094 	/* dialog token, filled by FW */
7095 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7096 
7097 	_rtw_memset(wpsie, 0x00, 255);
7098 	wpsielen = 0;
7099 
7100 	/*	WPS Section */
7101 	wpsielen = 0;
7102 	/*	WPS OUI */
7103 	*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7104 	wpsielen += 4;
7105 
7106 	/*	WPS version */
7107 	/*	Type: */
7108 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7109 	wpsielen += 2;
7110 
7111 	/*	Length: */
7112 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7113 	wpsielen += 2;
7114 
7115 	/*	Value: */
7116 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
7117 
7118 	/*	Device Password ID */
7119 	/*	Type: */
7120 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
7121 	wpsielen += 2;
7122 
7123 	/*	Length: */
7124 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7125 	wpsielen += 2;
7126 
7127 	/*	Value: */
7128 	if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
7129 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
7130 	else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
7131 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
7132 	else
7133 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
7134 	wpsielen += 2;
7135 
7136 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7137 
7138 
7139 	/*	P2P IE Section. */
7140 
7141 	/*	P2P OUI */
7142 	p2pielen = 0;
7143 	p2pie[p2pielen++] = 0x50;
7144 	p2pie[p2pielen++] = 0x6F;
7145 	p2pie[p2pielen++] = 0x9A;
7146 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
7147 
7148 	/*	Commented by Albert 20100908 */
7149 	/*	According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
7150 	/*	1. Status */
7151 	/*	2. P2P Capability */
7152 	/*	3. Group Owner Intent */
7153 	/*	4. Configuration Timeout */
7154 	/*	5. Operating Channel */
7155 	/*	6. Intended P2P Interface Address */
7156 	/*	7. Channel List */
7157 	/*	8. Device Info */
7158 	/*	9. Group ID	( Only GO ) */
7159 
7160 
7161 	/*	ToDo: */
7162 
7163 	/*	P2P Status */
7164 	/*	Type: */
7165 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
7166 
7167 	/*	Length: */
7168 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7169 	p2pielen += 2;
7170 
7171 	/*	Value, filled by FW */
7172 	p2pie[p2pielen++] = 1;
7173 
7174 	/*	P2P Capability */
7175 	/*	Type: */
7176 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
7177 
7178 	/*	Length: */
7179 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7180 	p2pielen += 2;
7181 
7182 	/*	Value: */
7183 	/*	Device Capability Bitmap, 1 byte */
7184 
7185 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
7186 		/*	Commented by Albert 2011/03/08 */
7187 		/*	According to the P2P specification */
7188 		/*	if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
7189 		p2pie[p2pielen++] = 0;
7190 	} else {
7191 		/*	Be group owner or meet the error case */
7192 		p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
7193 	}
7194 
7195 	/*	Group Capability Bitmap, 1 byte */
7196 	if (pwdinfo->persistent_supported)
7197 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
7198 	else
7199 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
7200 
7201 	/*	Group Owner Intent */
7202 	/*	Type: */
7203 	p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
7204 
7205 	/*	Length: */
7206 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7207 	p2pielen += 2;
7208 
7209 	/*	Value: */
7210 	if (pwdinfo->peer_intent & 0x01) {
7211 		/*	Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
7212 		p2pie[p2pielen++] = (pwdinfo->intent << 1);
7213 	} else {
7214 		/*	Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
7215 		p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
7216 	}
7217 
7218 
7219 	/*	Configuration Timeout */
7220 	/*	Type: */
7221 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7222 
7223 	/*	Length: */
7224 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7225 	p2pielen += 2;
7226 
7227 	/*	Value: */
7228 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
7229 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
7230 
7231 	/*	Operating Channel */
7232 	/*	Type: */
7233 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7234 
7235 	/*	Length: */
7236 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7237 	p2pielen += 2;
7238 
7239 	/*	Value: */
7240 	/*	Country String */
7241 	p2pie[p2pielen++] = 'X';
7242 	p2pie[p2pielen++] = 'X';
7243 
7244 	/*	The third byte should be set to 0x04. */
7245 	/*	Described in the "Operating Channel Attribute" section. */
7246 	p2pie[p2pielen++] = 0x04;
7247 
7248 	/*	Operating Class */
7249 	if (pwdinfo->operating_channel <= 14) {
7250 		/*	Operating Class */
7251 		p2pie[p2pielen++] = 0x51;
7252 	} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
7253 		/*	Operating Class */
7254 		p2pie[p2pielen++] = 0x73;
7255 	} else {
7256 		/*	Operating Class */
7257 		p2pie[p2pielen++] = 0x7c;
7258 	}
7259 
7260 	/*	Channel Number */
7261 	p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
7262 
7263 	/*	Intended P2P Interface Address	 */
7264 	/*	Type: */
7265 	p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
7266 
7267 	/*	Length: */
7268 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7269 	p2pielen += 2;
7270 
7271 	/*	Value: */
7272 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7273 	p2pielen += ETH_ALEN;
7274 
7275 	/*	Channel List */
7276 	/*	Type: */
7277 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7278 
7279 	/* Country String(3) */
7280 	/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7281 	/* + number of channels in all classes */
7282 	len_channellist_attr = 3
7283 		       + (1 + 1) * (u16)ch_list->reg_classes
7284 		       + get_reg_classes_full_count(ch_list);
7285 
7286 #ifdef CONFIG_CONCURRENT_MODE
7287 	if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7288 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7289 	else
7290 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7291 
7292 #else
7293 
7294 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7295 
7296 #endif
7297 	p2pielen += 2;
7298 
7299 	/*	Value: */
7300 	/*	Country String */
7301 	p2pie[p2pielen++] = 'X';
7302 	p2pie[p2pielen++] = 'X';
7303 
7304 	/*	The third byte should be set to 0x04. */
7305 	/*	Described in the "Operating Channel Attribute" section. */
7306 	p2pie[p2pielen++] = 0x04;
7307 
7308 	/*	Channel Entry List */
7309 
7310 #ifdef CONFIG_CONCURRENT_MODE
7311 	if (rtw_mi_check_status(padapter, MI_LINKED)) {
7312 		u8 union_ch = rtw_mi_get_union_chan(padapter);
7313 
7314 		/*	Operating Class */
7315 		if (union_ch > 14) {
7316 			if (union_ch >= 149)
7317 				p2pie[p2pielen++] = 0x7c;
7318 			else
7319 				p2pie[p2pielen++] = 0x73;
7320 		} else
7321 			p2pie[p2pielen++] = 0x51;
7322 
7323 
7324 		/*	Number of Channels */
7325 		/*	Just support 1 channel and this channel is AP's channel */
7326 		p2pie[p2pielen++] = 1;
7327 
7328 		/*	Channel List */
7329 		p2pie[p2pielen++] = union_ch;
7330 	} else
7331 #endif /* CONFIG_CONCURRENT_MODE */
7332 	{
7333 		int i, j;
7334 		for (j = 0; j < ch_list->reg_classes; j++) {
7335 			/*	Operating Class */
7336 			p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7337 
7338 			/*	Number of Channels */
7339 			p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7340 
7341 			/*	Channel List */
7342 			for (i = 0; i < ch_list->reg_class[j].channels; i++)
7343 				p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7344 		}
7345 	}
7346 
7347 	/*	Device Info */
7348 	/*	Type: */
7349 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7350 
7351 	/*	Length: */
7352 	/*	21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
7353 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7354 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
7355 	p2pielen += 2;
7356 
7357 	/*	Value: */
7358 	/*	P2P Device Address */
7359 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7360 	p2pielen += ETH_ALEN;
7361 
7362 	/*	Config Method */
7363 	/*	This field should be big endian. Noted by P2P specification. */
7364 
7365 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7366 
7367 	p2pielen += 2;
7368 
7369 	/*	Primary Device Type */
7370 	/*	Category ID */
7371 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7372 	p2pielen += 2;
7373 
7374 	/*	OUI */
7375 	*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
7376 	p2pielen += 4;
7377 
7378 	/*	Sub Category ID */
7379 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7380 	p2pielen += 2;
7381 
7382 	/*	Number of Secondary Device Types */
7383 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
7384 
7385 	/*	Device Name */
7386 	/*	Type: */
7387 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7388 	p2pielen += 2;
7389 
7390 	/*	Length: */
7391 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
7392 	p2pielen += 2;
7393 
7394 	/*	Value: */
7395 	_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
7396 	p2pielen += pwdinfo->device_name_len;
7397 
7398 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7399 		/*	Group ID Attribute */
7400 		/*	Type: */
7401 		p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
7402 
7403 		/*	Length: */
7404 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
7405 		p2pielen += 2;
7406 
7407 		/*	Value: */
7408 		/*	p2P Device Address */
7409 		_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
7410 		p2pielen += ETH_ALEN;
7411 
7412 		/*	SSID */
7413 		_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
7414 		p2pielen += pwdinfo->nego_ssidlen;
7415 
7416 	}
7417 
7418 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7419 
7420 #ifdef CONFIG_WFD
7421 	wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
7422 	pframe += wfdielen;
7423 	pktlen += wfdielen;
7424 #endif
7425 
7426 	*pLength = pktlen;
7427 #if 0
7428 	/* printf dbg msg */
7429 	dbgbufLen = pktlen;
7430 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7431 
7432 	for (index = 0; index < dbgbufLen; index++)
7433 		printk("%x ", *(dbgbuf + index));
7434 
7435 	printk("\n");
7436 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7437 #endif
7438 }
7439 
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7440 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7441 {
7442 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7443 	u8			action = P2P_PUB_ACTION_ACTION;
7444 	u32			p2poui = cpu_to_be32(P2POUI);
7445 	u8			oui_subtype = P2P_INVIT_RESP;
7446 	u8			p2pie[255] = { 0x00 };
7447 	u8			p2pielen = 0, i;
7448 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
7449 	u16			len_channellist_attr = 0;
7450 	u32			pktlen;
7451 	u8			dialogToken = 0;
7452 #ifdef CONFIG_WFD
7453 	u32					wfdielen = 0;
7454 #endif
7455 
7456 	/* struct xmit_frame			*pmgntframe; */
7457 	/* struct pkt_attrib			*pattrib; */
7458 	/* unsigned char					*pframe; */
7459 	struct rtw_ieee80211_hdr	*pwlanhdr;
7460 	unsigned short				*fctrl;
7461 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7462 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7463 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7464 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7465 
7466 	/* for debug */
7467 	u8 *dbgbuf = pframe;
7468 	u8 dbgbufLen = 0, index = 0;
7469 
7470 
7471 	RTW_INFO("%s\n", __FUNCTION__);
7472 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7473 
7474 	fctrl = &(pwlanhdr->frame_ctl);
7475 	*(fctrl) = 0;
7476 
7477 	/* RA fill by FW */
7478 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7479 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7480 
7481 	/* BSSID fill by FW */
7482 	_rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
7483 
7484 	SetSeqNum(pwlanhdr, 0);
7485 	set_frame_sub_type(pframe, WIFI_ACTION);
7486 
7487 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7488 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7489 
7490 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7491 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7492 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7493 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7494 
7495 	/* dialog token, filled by FW */
7496 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7497 
7498 	/*	P2P IE Section. */
7499 
7500 	/*	P2P OUI */
7501 	p2pielen = 0;
7502 	p2pie[p2pielen++] = 0x50;
7503 	p2pie[p2pielen++] = 0x6F;
7504 	p2pie[p2pielen++] = 0x9A;
7505 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
7506 
7507 	/*	Commented by Albert 20101005 */
7508 	/*	According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
7509 	/*	1. Status */
7510 	/*	2. Configuration Timeout */
7511 	/*	3. Operating Channel	( Only GO ) */
7512 	/*	4. P2P Group BSSID	( Only GO ) */
7513 	/*	5. Channel List */
7514 
7515 	/*	P2P Status */
7516 	/*	Type: */
7517 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
7518 
7519 	/*	Length: */
7520 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7521 	p2pielen += 2;
7522 
7523 	/*	Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
7524 	p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7525 
7526 	/*	Configuration Timeout */
7527 	/*	Type: */
7528 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7529 
7530 	/*	Length: */
7531 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7532 	p2pielen += 2;
7533 
7534 	/*	Value: */
7535 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
7536 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
7537 
7538 	/* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
7539 #if 0
7540 	if (status_code == P2P_STATUS_SUCCESS) {
7541 		struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7542 
7543 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7544 			/*	The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
7545 			/*	In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
7546 			/*	First one is operating channel attribute. */
7547 			/*	Second one is P2P Group BSSID attribute. */
7548 
7549 			/*	Operating Channel */
7550 			/*	Type: */
7551 			p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7552 
7553 			/*	Length: */
7554 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7555 			p2pielen += 2;
7556 
7557 			/*	Value: */
7558 			/*	Country String */
7559 			p2pie[p2pielen++] = 'X';
7560 			p2pie[p2pielen++] = 'X';
7561 
7562 			/*	The third byte should be set to 0x04. */
7563 			/*	Described in the "Operating Channel Attribute" section. */
7564 			p2pie[p2pielen++] = 0x04;
7565 
7566 			/*	Operating Class */
7567 			p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
7568 
7569 			/*	Channel Number */
7570 			p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
7571 
7572 
7573 			/*	P2P Group BSSID */
7574 			/*	Type: */
7575 			p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
7576 
7577 			/*	Length: */
7578 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7579 			p2pielen += 2;
7580 
7581 			/*	Value: */
7582 			/*	P2P Device Address for GO */
7583 			_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7584 			p2pielen += ETH_ALEN;
7585 
7586 		}
7587 
7588 		/*	Channel List */
7589 		/*	Type: */
7590 		p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7591 
7592 		/*	Length: */
7593 		/* Country String(3) */
7594 		/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7595 		/* + number of channels in all classes */
7596 		len_channellist_attr = 3
7597 			+ (1 + 1) * (u16)ch_list->reg_classes
7598 			+ get_reg_classes_full_count(ch_list);
7599 
7600 #ifdef CONFIG_CONCURRENT_MODE
7601 		if (rtw_mi_check_status(padapter, MI_LINKED))
7602 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7603 		else
7604 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7605 
7606 #else
7607 
7608 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7609 
7610 #endif
7611 		p2pielen += 2;
7612 
7613 		/*	Value: */
7614 		/*	Country String */
7615 		p2pie[p2pielen++] = 'X';
7616 		p2pie[p2pielen++] = 'X';
7617 
7618 		/*	The third byte should be set to 0x04. */
7619 		/*	Described in the "Operating Channel Attribute" section. */
7620 		p2pie[p2pielen++] = 0x04;
7621 
7622 		/*	Channel Entry List */
7623 #ifdef CONFIG_CONCURRENT_MODE
7624 		if (rtw_mi_check_status(padapter, MI_LINKED)) {
7625 			u8 union_ch = rtw_mi_get_union_chan(padapter);
7626 
7627 			/*	Operating Class */
7628 			if (union_ch > 14) {
7629 				if (union_ch >= 149)
7630 					p2pie[p2pielen++] = 0x7c;
7631 				else
7632 					p2pie[p2pielen++] = 0x73;
7633 
7634 			} else
7635 				p2pie[p2pielen++] = 0x51;
7636 
7637 
7638 			/*	Number of Channels */
7639 			/*	Just support 1 channel and this channel is AP's channel */
7640 			p2pie[p2pielen++] = 1;
7641 
7642 			/*	Channel List */
7643 			p2pie[p2pielen++] = union_ch;
7644 		} else
7645 #endif /* CONFIG_CONCURRENT_MODE */
7646 		{
7647 			int i, j;
7648 			for (j = 0; j < ch_list->reg_classes; j++) {
7649 				/*	Operating Class */
7650 				p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7651 
7652 				/*	Number of Channels */
7653 				p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7654 
7655 				/*	Channel List */
7656 				for (i = 0; i < ch_list->reg_class[j].channels; i++)
7657 					p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7658 			}
7659 		}
7660 	}
7661 #endif
7662 
7663 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7664 
7665 #ifdef CONFIG_WFD
7666 	wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
7667 	pframe += wfdielen;
7668 	pktlen += wfdielen;
7669 #endif
7670 
7671 	*pLength = pktlen;
7672 
7673 #if 0
7674 	/* printf dbg msg */
7675 	dbgbufLen = pktlen;
7676 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7677 
7678 	for (index = 0; index < dbgbufLen; index++)
7679 		printk("%x ", *(dbgbuf + index));
7680 
7681 	printk("\n");
7682 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7683 #endif
7684 }
7685 
7686 
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7687 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7688 {
7689 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7690 	u8			action = P2P_PUB_ACTION_ACTION;
7691 	u8			dialogToken = 0;
7692 	u32			p2poui = cpu_to_be32(P2POUI);
7693 	u8			oui_subtype = P2P_PROVISION_DISC_RESP;
7694 	u8			wpsie[100] = { 0x00 };
7695 	u8			wpsielen = 0;
7696 	u32			pktlen;
7697 #ifdef CONFIG_WFD
7698 	u32					wfdielen = 0;
7699 #endif
7700 
7701 	/* struct xmit_frame			*pmgntframe; */
7702 	/* struct pkt_attrib			*pattrib; */
7703 	/* unsigned char					*pframe; */
7704 	struct rtw_ieee80211_hdr	*pwlanhdr;
7705 	unsigned short				*fctrl;
7706 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7707 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7708 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7709 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7710 
7711 	/* for debug */
7712 	u8 *dbgbuf = pframe;
7713 	u8 dbgbufLen = 0, index = 0;
7714 
7715 	RTW_INFO("%s\n", __FUNCTION__);
7716 
7717 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7718 
7719 	fctrl = &(pwlanhdr->frame_ctl);
7720 	*(fctrl) = 0;
7721 
7722 	/* RA filled by FW */
7723 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7724 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7725 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7726 
7727 	SetSeqNum(pwlanhdr, 0);
7728 	set_frame_sub_type(pframe, WIFI_ACTION);
7729 
7730 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7731 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7732 
7733 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7734 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7735 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7736 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7737 	/* dialog token, filled by FW */
7738 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7739 
7740 	wpsielen = 0;
7741 	/*	WPS OUI */
7742 	/* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
7743 	RTW_PUT_BE32(wpsie, WPSOUI);
7744 	wpsielen += 4;
7745 
7746 #if 0
7747 	/*	WPS version */
7748 	/*	Type: */
7749 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7750 	wpsielen += 2;
7751 
7752 	/*	Length: */
7753 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7754 	wpsielen += 2;
7755 
7756 	/*	Value: */
7757 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
7758 #endif
7759 
7760 	/*	Config Method */
7761 	/*	Type: */
7762 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
7763 	RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
7764 	wpsielen += 2;
7765 
7766 	/*	Length: */
7767 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
7768 	RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
7769 	wpsielen += 2;
7770 
7771 	/*	Value: filled by FW, default value is PBC */
7772 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
7773 	RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
7774 	wpsielen += 2;
7775 
7776 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7777 
7778 #ifdef CONFIG_WFD
7779 	wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
7780 	pframe += wfdielen;
7781 	pktlen += wfdielen;
7782 #endif
7783 
7784 	*pLength = pktlen;
7785 
7786 	/* printf dbg msg */
7787 #if 0
7788 	dbgbufLen = pktlen;
7789 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT  ProvisionDis Rsp\n");
7790 
7791 	for (index = 0; index < dbgbufLen; index++)
7792 		printk("%x ", *(dbgbuf + index));
7793 
7794 	printk("\n");
7795 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7796 #endif
7797 }
7798 
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)7799 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
7800 {
7801 	u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
7802 	struct hal_ops *pHalFunc = &adapter->hal_func;
7803 	u8 ret = _FAIL;
7804 
7805 	RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
7806 		 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
7807 		 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
7808 		 rsvdpageloc->LocPDRsp);
7809 
7810 	SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
7811 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
7812 	SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
7813 	SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
7814 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
7815 
7816 	/* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
7817 	ret = rtw_hal_fill_h2c_cmd(adapter,
7818 				   H2C_P2P_OFFLOAD_RSVD_PAGE,
7819 				   H2C_P2PRSVDPAGE_LOC_LEN,
7820 				   u1H2CP2PRsvdPageParm);
7821 
7822 	return ret;
7823 }
7824 
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)7825 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
7826 {
7827 
7828 	u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
7829 	struct wifidirect_info	*pwdinfo = &(adapter->wdinfo);
7830 	struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
7831 	struct hal_ops *pHalFunc = &adapter->hal_func;
7832 	u8 ret = _FAIL;
7833 
7834 	_rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
7835 	RTW_INFO("%s\n", __func__);
7836 	switch (pwdinfo->role) {
7837 	case P2P_ROLE_DEVICE:
7838 		RTW_INFO("P2P_ROLE_DEVICE\n");
7839 		p2p_wowlan_offload->role = 0;
7840 		break;
7841 	case P2P_ROLE_CLIENT:
7842 		RTW_INFO("P2P_ROLE_CLIENT\n");
7843 		p2p_wowlan_offload->role = 1;
7844 		break;
7845 	case P2P_ROLE_GO:
7846 		RTW_INFO("P2P_ROLE_GO\n");
7847 		p2p_wowlan_offload->role = 2;
7848 		break;
7849 	default:
7850 		RTW_INFO("P2P_ROLE_DISABLE\n");
7851 		break;
7852 	}
7853 	p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
7854 	p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
7855 	offload_cmd = (u8 *)p2p_wowlan_offload;
7856 	RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
7857 
7858 	ret = rtw_hal_fill_h2c_cmd(adapter,
7859 				   H2C_P2P_OFFLOAD,
7860 				   H2C_P2P_OFFLOAD_LEN,
7861 				   offload_cmd);
7862 	return ret;
7863 
7864 	/* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
7865 }
7866 #endif /* CONFIG_P2P_WOWLAN */
7867 
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)7868 void rtw_hal_construct_beacon(_adapter *padapter,
7869 				     u8 *pframe, u32 *pLength)
7870 {
7871 	struct rtw_ieee80211_hdr	*pwlanhdr;
7872 	u16					*fctrl;
7873 	u32					pktlen;
7874 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7875 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7876 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
7877 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7878 
7879 
7880 	/* RTW_INFO("%s\n", __FUNCTION__); */
7881 
7882 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7883 
7884 	fctrl = &(pwlanhdr->frame_ctl);
7885 	*(fctrl) = 0;
7886 
7887 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7888 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7889 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7890 
7891 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7892 	/* pmlmeext->mgnt_seq++; */
7893 	set_frame_sub_type(pframe, WIFI_BEACON);
7894 
7895 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7896 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7897 
7898 	/* timestamp will be inserted by hardware */
7899 	pframe += 8;
7900 	pktlen += 8;
7901 
7902 	/* beacon interval: 2 bytes */
7903 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7904 
7905 	pframe += 2;
7906 	pktlen += 2;
7907 
7908 #if 0
7909 	/* capability info: 2 bytes */
7910 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7911 
7912 	pframe += 2;
7913 	pktlen += 2;
7914 
7915 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7916 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7917 		pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
7918 		_rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
7919 
7920 		goto _ConstructBeacon;
7921 	}
7922 
7923 	/* below for ad-hoc mode */
7924 
7925 	/* SSID */
7926 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
7927 
7928 	/* supported rates... */
7929 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7930 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
7931 
7932 	/* DS parameter set */
7933 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
7934 
7935 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
7936 		u32 ATIMWindow;
7937 		/* IBSS Parameter Set... */
7938 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
7939 		ATIMWindow = 0;
7940 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
7941 	}
7942 
7943 
7944 	/* todo: ERP IE */
7945 
7946 
7947 	/* EXTERNDED SUPPORTED RATE */
7948 	if (rate_len > 8)
7949 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
7950 
7951 	/* todo:HT for adhoc */
7952 
7953 _ConstructBeacon:
7954 #endif
7955 
7956 	if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
7957 		RTW_ERR("beacon frame too large ,len(%d,%d)\n",
7958 			(pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
7959 		rtw_warn_on(1);
7960 		return;
7961 	}
7962 
7963 	*pLength = pktlen;
7964 
7965 	/* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
7966 
7967 }
7968 
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)7969 static void rtw_hal_construct_PSPoll(_adapter *padapter,
7970 				     u8 *pframe, u32 *pLength)
7971 {
7972 	struct rtw_ieee80211_hdr	*pwlanhdr;
7973 	u16					*fctrl;
7974 	u32					pktlen;
7975 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7976 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7977 
7978 	/* RTW_INFO("%s\n", __FUNCTION__); */
7979 
7980 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7981 
7982 	/* Frame control. */
7983 	fctrl = &(pwlanhdr->frame_ctl);
7984 	*(fctrl) = 0;
7985 	SetPwrMgt(fctrl);
7986 	set_frame_sub_type(pframe, WIFI_PSPOLL);
7987 
7988 	/* AID. */
7989 	set_duration(pframe, (pmlmeinfo->aid | 0xc000));
7990 
7991 	/* BSSID. */
7992 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7993 
7994 	/* TA. */
7995 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7996 
7997 	*pLength = 16;
7998 }
7999 
8000 
8001 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_construct_fw_dbg_msg_pkt(PADAPTER padapter,u8 * pframe,u32 * plength)8002 void rtw_hal_construct_fw_dbg_msg_pkt(
8003 	PADAPTER padapter,
8004 	u8		*pframe,
8005 	u32		*plength)
8006 {
8007 	struct rtw_ieee80211_hdr	*pwlanhdr;
8008 	u16						*fctrl;
8009 	u32						pktlen;
8010 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
8011 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
8012 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8013 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8014 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8015 
8016 
8017 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8018 
8019 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8020 
8021 	fctrl = &pwlanhdr->frame_ctl;
8022 	*(fctrl) = 0;
8023 
8024 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8025 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8026 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8027 
8028 	SetSeqNum(pwlanhdr, 0);
8029 
8030 	set_frame_sub_type(pframe, WIFI_DATA);
8031 
8032 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8033 
8034 	*plength = pktlen;
8035 }
8036 #endif /*DBG_FW_DEBUG_MSG_PKT*/
8037 
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)8038 void rtw_hal_construct_NullFunctionData(
8039 	PADAPTER padapter,
8040 	u8		*pframe,
8041 	u32		*pLength,
8042 	u8		bQoS,
8043 	u8		AC,
8044 	u8		bEosp,
8045 	u8		bForcePowerSave)
8046 {
8047 	struct rtw_ieee80211_hdr	*pwlanhdr;
8048 	u16						*fctrl;
8049 	u32						pktlen;
8050 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
8051 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
8052 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8053 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8054 	u8 *sta_addr = NULL;
8055 	u8 bssid[ETH_ALEN] = {0};
8056 
8057 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8058 
8059 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8060 
8061 	fctrl = &pwlanhdr->frame_ctl;
8062 	*(fctrl) = 0;
8063 	if (bForcePowerSave)
8064 		SetPwrMgt(fctrl);
8065 
8066 	sta_addr = get_my_bssid(&pmlmeinfo->network);
8067 	if (NULL == sta_addr) {
8068 		_rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
8069 		sta_addr = bssid;
8070 	}
8071 
8072 	switch (cur_network->network.InfrastructureMode) {
8073 	case Ndis802_11Infrastructure:
8074 		SetToDs(fctrl);
8075 		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8076 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8077 		_rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
8078 		break;
8079 	case Ndis802_11APMode:
8080 		SetFrDs(fctrl);
8081 		_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8082 		_rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8083 		_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8084 		break;
8085 	case Ndis802_11IBSS:
8086 	default:
8087 		_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8088 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8089 		_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8090 		break;
8091 	}
8092 
8093 	SetSeqNum(pwlanhdr, 0);
8094 	set_duration(pwlanhdr, 0);
8095 
8096 	if (bQoS == _TRUE) {
8097 		struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
8098 
8099 		set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
8100 
8101 		pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
8102 		SetPriority(&pwlanqoshdr->qc, AC);
8103 		SetEOSP(&pwlanqoshdr->qc, bEosp);
8104 
8105 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8106 	} else {
8107 		set_frame_sub_type(pframe, WIFI_DATA_NULL);
8108 
8109 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8110 	}
8111 
8112 	*pLength = pktlen;
8113 }
8114 
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,BOOLEAN bHideSSID)8115 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
8116 				BOOLEAN bHideSSID)
8117 {
8118 	struct rtw_ieee80211_hdr	*pwlanhdr;
8119 	u16					*fctrl;
8120 	u8					*mac, *bssid, *sta_addr;
8121 	u32					pktlen;
8122 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8123 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8124 	WLAN_BSSID_EX  *cur_network = &(pmlmeinfo->network);
8125 
8126 	/*RTW_INFO("%s\n", __FUNCTION__);*/
8127 
8128 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8129 
8130 	mac = adapter_mac_addr(padapter);
8131 	bssid = cur_network->MacAddress;
8132 	sta_addr = get_my_bssid(&pmlmeinfo->network);
8133 
8134 	fctrl = &(pwlanhdr->frame_ctl);
8135 	*(fctrl) = 0;
8136 	_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8137 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8138 	_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8139 
8140 	SetSeqNum(pwlanhdr, 0);
8141 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
8142 
8143 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8144 	pframe += pktlen;
8145 
8146 	if (cur_network->IELength > MAX_IE_SZ)
8147 		return;
8148 
8149 	_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8150 	pframe += cur_network->IELength;
8151 	pktlen += cur_network->IELength;
8152 
8153 	*pLength = pktlen;
8154 }
8155 
8156 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)8157 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
8158 				    u8 *pframe, u32 offset)
8159 {
8160 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8161 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8162 	struct rtw_ieee80211_hdr	*pwlanhdr;
8163 	struct mic_data	micdata;
8164 	struct sta_info	*psta = NULL;
8165 	int res = 0;
8166 
8167 	u8	*payload = (u8 *)(pframe + offset);
8168 
8169 	u8	mic[8];
8170 	u8	priority[4] = {0x0};
8171 	u8	null_key[16] = {0x0};
8172 
8173 	RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
8174 
8175 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8176 
8177 	psta = rtw_get_stainfo(&padapter->stapriv,
8178 			get_my_bssid(&(pmlmeinfo->network)));
8179 	if (psta != NULL) {
8180 		res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
8181 				  null_key, 16);
8182 		if (res == _TRUE)
8183 			RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
8184 		rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
8185 	}
8186 
8187 	rtw_secmicappend(&micdata, pwlanhdr->addr3, 6);  /* DA */
8188 
8189 	rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
8190 
8191 	priority[0] = 0;
8192 
8193 	rtw_secmicappend(&micdata, &priority[0], 4);
8194 
8195 	rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
8196 
8197 	rtw_secgetmic(&micdata, &(mic[0]));
8198 
8199 	payload += 36;
8200 
8201 	_rtw_memcpy(payload, &(mic[0]), 8);
8202 }
8203 /*
8204  * Description:
8205  *	Construct the ARP response packet to support ARP offload.
8206  *   */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8207 static void rtw_hal_construct_ARPRsp(
8208 	PADAPTER padapter,
8209 	u8			*pframe,
8210 	u32			*pLength,
8211 	u8			*pIPAddress
8212 )
8213 {
8214 	struct rtw_ieee80211_hdr	*pwlanhdr;
8215 	u16	*fctrl;
8216 	u32	pktlen;
8217 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8218 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8219 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8220 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8221 	static u8	ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
8222 	u8	*pARPRspPkt = pframe;
8223 	/* for TKIP Cal MIC */
8224 	u8	*payload = pframe;
8225 	u8	EncryptionHeadOverhead = 0, arp_offset = 0;
8226 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8227 
8228 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8229 
8230 	fctrl = &pwlanhdr->frame_ctl;
8231 	*(fctrl) = 0;
8232 
8233 	/* ------------------------------------------------------------------------- */
8234 	/* MAC Header. */
8235 	/* ------------------------------------------------------------------------- */
8236 	SetFrameType(fctrl, WIFI_DATA);
8237 	/* set_frame_sub_type(fctrl, 0); */
8238 	SetToDs(fctrl);
8239 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8240 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8241 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8242 
8243 	SetSeqNum(pwlanhdr, 0);
8244 	set_duration(pwlanhdr, 0);
8245 	/* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
8246 	/* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
8247 	/* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
8248 	/* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
8249 	/* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
8250 	/* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
8251 
8252 	/* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
8253 	/* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
8254 #ifdef CONFIG_WAPI_SUPPORT
8255 	*pLength = sMacHdrLng;
8256 #else
8257 	*pLength = 24;
8258 #endif
8259 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8260 	case _WEP40_:
8261 	case _WEP104_:
8262 		EncryptionHeadOverhead = 4;
8263 		break;
8264 	case _TKIP_:
8265 		EncryptionHeadOverhead = 8;
8266 		break;
8267 	case _AES_:
8268 		EncryptionHeadOverhead = 8;
8269 		break;
8270 #ifdef CONFIG_WAPI_SUPPORT
8271 	case _SMS4_:
8272 		EncryptionHeadOverhead = 18;
8273 		break;
8274 #endif
8275 	default:
8276 		EncryptionHeadOverhead = 0;
8277 	}
8278 
8279 	if (EncryptionHeadOverhead > 0) {
8280 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8281 		*pLength += EncryptionHeadOverhead;
8282 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8283 		SetPrivacy(fctrl);
8284 	}
8285 
8286 	/* ------------------------------------------------------------------------- */
8287 	/* Frame Body. */
8288 	/* ------------------------------------------------------------------------- */
8289 	arp_offset = *pLength;
8290 	pARPRspPkt = (u8 *)(pframe + arp_offset);
8291 	payload = pARPRspPkt; /* Get Payload pointer */
8292 	/* LLC header */
8293 	_rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
8294 	*pLength += 8;
8295 
8296 	/* ARP element */
8297 	pARPRspPkt += 8;
8298 	SET_ARP_HTYPE(pARPRspPkt, 1);
8299 	SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP);	/* IP protocol */
8300 	SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
8301 	SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
8302 	SET_ARP_OPER(pARPRspPkt, 2);	/* ARP response */
8303 	SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
8304 	SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
8305 #ifdef CONFIG_ARP_KEEP_ALIVE
8306 	if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
8307 		SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
8308 		SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
8309 	} else
8310 #endif
8311 	{
8312 		SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
8313 				    get_my_bssid(&(pmlmeinfo->network)));
8314 		SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
8315 					   pIPAddress);
8316 		RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
8317 			 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
8318 		RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
8319 			 IP_ARG(pIPAddress));
8320 	}
8321 
8322 	*pLength += 28;
8323 
8324 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8325 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8326 		    IS_HARDWARE_TYPE_8812(padapter)) {
8327 			rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
8328 		}
8329 		*pLength += 8;
8330 	}
8331 }
8332 
8333 #ifdef CONFIG_IPV6
8334 /*
8335  * Description: Neighbor Discovery Offload.
8336  */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)8337 static void rtw_hal_construct_na_message(_adapter *padapter,
8338 				     u8 *pframe, u32 *pLength)
8339 {
8340 	struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8341 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8342 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8343 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
8344 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8345 
8346 	u32 pktlen = 0;
8347 	u16 *fctrl = NULL;
8348 
8349 	u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8350 	u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8351 	u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8352 	u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8353 	u8 val8 = 0;
8354 
8355 	u8 *p_na_msg = pframe;
8356 	/* for TKIP Cal MIC */
8357 	u8 *payload = pframe;
8358 	u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8359 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8360 
8361 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8362 
8363 	fctrl = &pwlanhdr->frame_ctl;
8364 	*(fctrl) = 0;
8365 
8366 	/* ------------------------------------------------------------------------- */
8367 	/* MAC Header. */
8368 	/* ------------------------------------------------------------------------- */
8369 	SetFrameType(fctrl, WIFI_DATA);
8370 	SetToDs(fctrl);
8371 	_rtw_memcpy(pwlanhdr->addr1,
8372 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8373 	_rtw_memcpy(pwlanhdr->addr2,
8374 		    adapter_mac_addr(padapter), ETH_ALEN);
8375 	_rtw_memcpy(pwlanhdr->addr3,
8376 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8377 
8378 	SetSeqNum(pwlanhdr, 0);
8379 	set_duration(pwlanhdr, 0);
8380 
8381 #ifdef CONFIG_WAPI_SUPPORT
8382 	*pLength = sMacHdrLng;
8383 #else
8384 	*pLength = 24;
8385 #endif
8386 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8387 	case _WEP40_:
8388 	case _WEP104_:
8389 		EncryptionHeadOverhead = 4;
8390 		break;
8391 	case _TKIP_:
8392 		EncryptionHeadOverhead = 8;
8393 		break;
8394 	case _AES_:
8395 		EncryptionHeadOverhead = 8;
8396 		break;
8397 #ifdef CONFIG_WAPI_SUPPORT
8398 	case _SMS4_:
8399 		EncryptionHeadOverhead = 18;
8400 		break;
8401 #endif
8402 	default:
8403 		EncryptionHeadOverhead = 0;
8404 	}
8405 
8406 	if (EncryptionHeadOverhead > 0) {
8407 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8408 		*pLength += EncryptionHeadOverhead;
8409 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8410 		SetPrivacy(fctrl);
8411 	}
8412 
8413 	/* ------------------------------------------------------------------------- */
8414 	/* Frame Body. */
8415 	/* ------------------------------------------------------------------------- */
8416 	na_msg_offset = *pLength;
8417 	p_na_msg = (u8 *)(pframe + na_msg_offset);
8418 	payload = p_na_msg; /* Get Payload pointer */
8419 
8420 	/* LLC header */
8421 	val8 = sizeof(ns_hdr);
8422 	_rtw_memcpy(p_na_msg, ns_hdr, val8);
8423 	*pLength += val8;
8424 	p_na_msg += val8;
8425 
8426 	/* IPv6 Header */
8427 	/* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8428 	val8 = sizeof(ipv6_info);
8429 	_rtw_memcpy(p_na_msg, ipv6_info, val8);
8430 	*pLength += val8;
8431 	p_na_msg += val8;
8432 
8433 	/* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8434 	val8 = sizeof(ipv6_contx);
8435 	_rtw_memcpy(p_na_msg, ipv6_contx, val8);
8436 	*pLength += val8;
8437 	p_na_msg += val8;
8438 
8439 	/* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8440 	_rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8441 	*pLength += 32;
8442 	p_na_msg += 32;
8443 
8444 	/* ICMPv6 */
8445 	/* 1. Type : 0x88 (NA)
8446 	 * 2. Code : 0x00
8447 	 * 3. ChechSum : 0x00 0x00 (RSvd)
8448 	 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8449 	 */
8450 	val8 = sizeof(icmpv6_hdr);
8451 	_rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8452 	*pLength += val8;
8453 	p_na_msg += val8;
8454 
8455 	/* TA: 16 bytes*/
8456 	_rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8457 	*pLength += 16;
8458 	p_na_msg += 16;
8459 
8460 	/* ICMPv6 Target Link Layer Address */
8461 	p_na_msg[0] = 0x02; /* type */
8462 	p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8463 	*pLength += 2;
8464 	p_na_msg += 2;
8465 
8466 	_rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8467 	*pLength += 6;
8468 	p_na_msg += 6;
8469 
8470 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8471 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8472 		    IS_HARDWARE_TYPE_8812(padapter)) {
8473 			rtw_hal_append_tkip_mic(padapter, pframe,
8474 						na_msg_offset);
8475 		}
8476 		*pLength += 8;
8477 	}
8478 }
8479 /*
8480  * Description: Neighbor Discovery Protocol Information.
8481  */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)8482 static void rtw_hal_construct_ndp_info(_adapter *padapter,
8483 				     u8 *pframe, u32 *pLength)
8484 {
8485 	struct mlme_ext_priv *pmlmeext = NULL;
8486 	struct mlme_ext_info *pmlmeinfo = NULL;
8487 	struct rtw_ndp_info ndp_info;
8488 	u8	*pndp_info = pframe;
8489 	u8	len = sizeof(struct rtw_ndp_info);
8490 
8491 	RTW_INFO("%s: len: %d\n", __func__, len);
8492 
8493 	pmlmeext =  &padapter->mlmeextpriv;
8494 	pmlmeinfo = &pmlmeext->mlmext_info;
8495 
8496 	_rtw_memset(pframe, 0, len);
8497 	_rtw_memset(&ndp_info, 0, len);
8498 
8499 	ndp_info.enable = 1;
8500 	ndp_info.check_remote_ip = 0;
8501 	ndp_info.num_of_target_ip = 1;
8502 
8503 	_rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8504 		    ETH_ALEN);
8505 	_rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8506 		    RTW_IPv6_ADDR_LEN);
8507 
8508 	_rtw_memcpy(pndp_info, &ndp_info, len);
8509 }
8510 #endif /* CONFIG_IPV6 */
8511 
8512 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)8513 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8514 				       u32 *pLength, pno_ssid_t *ssid)
8515 {
8516 	struct rtw_ieee80211_hdr	*pwlanhdr;
8517 	u16				*fctrl;
8518 	u32				pktlen;
8519 	unsigned char			*mac;
8520 	unsigned char			bssrate[NumRates];
8521 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
8522 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8523 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8524 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8525 	int	bssrate_len = 0;
8526 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8527 
8528 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8529 	mac = adapter_mac_addr(padapter);
8530 
8531 	fctrl = &(pwlanhdr->frame_ctl);
8532 	*(fctrl) = 0;
8533 
8534 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8535 	_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8536 
8537 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8538 
8539 	SetSeqNum(pwlanhdr, 0);
8540 	set_frame_sub_type(pframe, WIFI_PROBEREQ);
8541 
8542 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8543 	pframe += pktlen;
8544 
8545 	if (ssid == NULL)
8546 		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8547 	else {
8548 		/* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8549 		pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8550 	}
8551 
8552 	get_rate_set(padapter, bssrate, &bssrate_len);
8553 
8554 	if (bssrate_len > 8) {
8555 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8556 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8557 	} else
8558 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8559 
8560 	*pLength = pktlen;
8561 }
8562 
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)8563 static void rtw_hal_construct_PNO_info(_adapter *padapter,
8564 				       u8 *pframe, u32 *pLength)
8565 {
8566 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8567 	int i;
8568 
8569 	u8	*pPnoInfoPkt = pframe;
8570 	pPnoInfoPkt = (u8 *)(pframe + *pLength);
8571 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8572 
8573 	pPnoInfoPkt += 1;
8574 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8575 
8576 	pPnoInfoPkt += 3;
8577 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8578 
8579 	pPnoInfoPkt += 4;
8580 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8581 
8582 	pPnoInfoPkt += 4;
8583 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8584 
8585 	pPnoInfoPkt += 4;
8586 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8587 
8588 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8589 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8590 
8591 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8592 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8593 
8594 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8595 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8596 
8597 	pPnoInfoPkt += MAX_HIDDEN_AP;
8598 
8599 	/*
8600 	SSID is located at 128th Byte in NLO info Page
8601 	*/
8602 
8603 	*pLength += 128;
8604 	pPnoInfoPkt = pframe + 128;
8605 
8606 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8607 		_rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8608 			    pwrctl->pnlo_info->ssid_length[i]);
8609 		*pLength += WLAN_SSID_MAXLEN;
8610 		pPnoInfoPkt += WLAN_SSID_MAXLEN;
8611 	}
8612 }
8613 
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)8614 static void rtw_hal_construct_ssid_list(_adapter *padapter,
8615 					u8 *pframe, u32 *pLength)
8616 {
8617 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8618 	u8 *pSSIDListPkt = pframe;
8619 	int i;
8620 
8621 	pSSIDListPkt = (u8 *)(pframe + *pLength);
8622 
8623 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8624 		_rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8625 			    pwrctl->pnlo_info->ssid_length[i]);
8626 
8627 		*pLength += WLAN_SSID_MAXLEN;
8628 		pSSIDListPkt += WLAN_SSID_MAXLEN;
8629 	}
8630 }
8631 
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)8632 static void rtw_hal_construct_scan_info(_adapter *padapter,
8633 					u8 *pframe, u32 *pLength)
8634 {
8635 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8636 	u8 *pScanInfoPkt = pframe;
8637 	int i;
8638 
8639 	pScanInfoPkt = (u8 *)(pframe + *pLength);
8640 
8641 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8642 
8643 	*pLength += 1;
8644 	pScanInfoPkt += 1;
8645 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8646 
8647 
8648 	*pLength += 1;
8649 	pScanInfoPkt += 1;
8650 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8651 
8652 
8653 	*pLength += 1;
8654 	pScanInfoPkt += 1;
8655 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8656 
8657 	*pLength += 1;
8658 	pScanInfoPkt += 1;
8659 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8660 
8661 	*pLength += 1;
8662 	pScanInfoPkt += 1;
8663 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8664 
8665 	*pLength += 1;
8666 	pScanInfoPkt += 1;
8667 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8668 
8669 	*pLength += 1;
8670 	pScanInfoPkt += 1;
8671 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8672 
8673 	*pLength += 1;
8674 	pScanInfoPkt += 1;
8675 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8676 
8677 	*pLength += 8;
8678 	pScanInfoPkt += 8;
8679 
8680 	for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8681 		_rtw_memcpy(pScanInfoPkt,
8682 			    &pwrctl->pscan_info->ssid_channel_info[i], 4);
8683 		*pLength += 4;
8684 		pScanInfoPkt += 4;
8685 	}
8686 }
8687 #endif /* CONFIG_PNO_SUPPORT */
8688 
8689 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)8690 static void rtw_hal_construct_GTKRsp(
8691 	PADAPTER	padapter,
8692 	u8		*pframe,
8693 	u32		*pLength
8694 )
8695 {
8696 	struct rtw_ieee80211_hdr	*pwlanhdr;
8697 	u16	*fctrl;
8698 	u32	pktlen;
8699 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8700 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
8701 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8702 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8703 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8704 	static u8	LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
8705 	static u8	GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
8706 	u8	*pGTKRspPkt = pframe;
8707 	u8	EncryptionHeadOverhead = 0;
8708 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8709 
8710 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8711 
8712 	fctrl = &pwlanhdr->frame_ctl;
8713 	*(fctrl) = 0;
8714 
8715 	/* ------------------------------------------------------------------------- */
8716 	/* MAC Header. */
8717 	/* ------------------------------------------------------------------------- */
8718 	SetFrameType(fctrl, WIFI_DATA);
8719 	/* set_frame_sub_type(fctrl, 0); */
8720 	SetToDs(fctrl);
8721 
8722 	_rtw_memcpy(pwlanhdr->addr1,
8723 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8724 
8725 	_rtw_memcpy(pwlanhdr->addr2,
8726 		    adapter_mac_addr(padapter), ETH_ALEN);
8727 
8728 	_rtw_memcpy(pwlanhdr->addr3,
8729 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8730 
8731 	SetSeqNum(pwlanhdr, 0);
8732 	set_duration(pwlanhdr, 0);
8733 
8734 #ifdef CONFIG_WAPI_SUPPORT
8735 	*pLength = sMacHdrLng;
8736 #else
8737 	*pLength = 24;
8738 #endif /* CONFIG_WAPI_SUPPORT */
8739 
8740 	/* ------------------------------------------------------------------------- */
8741 	/* Security Header: leave space for it if necessary. */
8742 	/* ------------------------------------------------------------------------- */
8743 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8744 	case _WEP40_:
8745 	case _WEP104_:
8746 		EncryptionHeadOverhead = 4;
8747 		break;
8748 	case _TKIP_:
8749 		EncryptionHeadOverhead = 8;
8750 		break;
8751 	case _AES_:
8752 		EncryptionHeadOverhead = 8;
8753 		break;
8754 #ifdef CONFIG_WAPI_SUPPORT
8755 	case _SMS4_:
8756 		EncryptionHeadOverhead = 18;
8757 		break;
8758 #endif /* CONFIG_WAPI_SUPPORT */
8759 	default:
8760 		EncryptionHeadOverhead = 0;
8761 	}
8762 
8763 	if (EncryptionHeadOverhead > 0) {
8764 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8765 		*pLength += EncryptionHeadOverhead;
8766 		/* SET_80211_HDR_WEP(pGTKRspPkt, 1);  */ /* Suggested by CCW. */
8767 		/* GTK's privacy bit is done by FW */
8768 		/* SetPrivacy(fctrl); */
8769 	}
8770 	/* ------------------------------------------------------------------------- */
8771 	/* Frame Body. */
8772 	/* ------------------------------------------------------------------------- */
8773 	pGTKRspPkt = (u8 *)(pframe + *pLength);
8774 	/* LLC header */
8775 	_rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
8776 	*pLength += 8;
8777 
8778 	/* GTK element */
8779 	pGTKRspPkt += 8;
8780 
8781 	/* GTK frame body after LLC, part 1 */
8782 	/* TKIP key_length = 32, AES key_length = 16 */
8783 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8784 		GTKbody_a[8] = 0x20;
8785 
8786 	/* GTK frame body after LLC, part 1 */
8787 	_rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
8788 	*pLength += 11;
8789 	pGTKRspPkt += 11;
8790 	/* GTK frame body after LLC, part 2 */
8791 	_rtw_memset(&(pframe[*pLength]), 0, 88);
8792 	*pLength += 88;
8793 	pGTKRspPkt += 88;
8794 
8795 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8796 		*pLength += 8;
8797 }
8798 #endif /* CONFIG_GTK_OL */
8799 
8800 #define PN_2_CCMPH(ch,key_id)	((ch) & 0x000000000000ffff) \
8801 				| (((ch) & 0x0000ffffffff0000) << 16) \
8802 				| (((key_id) << 30)) \
8803 				| BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)8804 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
8805 						  u8 *pframe, u32 *pLength)
8806 {
8807 	struct mlme_priv   *pmlmepriv = &adapter->mlmepriv;
8808 	struct sta_priv *pstapriv = &adapter->stapriv;
8809 	struct security_priv *psecuritypriv = &adapter->securitypriv;
8810 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
8811 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8812 	struct sta_info *psta;
8813 	struct stainfo_rxcache *prxcache;
8814 	u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
8815 	size_t sz = 0, total = 0;
8816 	u64 ccmp_hdr = 0, tmp_key = 0;
8817 
8818 	psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8819 
8820 	if (psta == NULL) {
8821 		rtw_warn_on(1);
8822 		return;
8823 	}
8824 
8825 	prxcache = &psta->sta_recvpriv.rxcache;
8826 	sz = sizeof(cur_dot11rxiv);
8827 
8828 	/* 3 SEC IV * 1 page */
8829 	rtw_get_sec_iv(adapter, cur_dot11rxiv,
8830 		       get_my_bssid(&pmlmeinfo->network));
8831 
8832 	_rtw_memcpy(pframe, cur_dot11rxiv, sz);
8833 	*pLength += sz;
8834 	pframe += sz;
8835 
8836 	_rtw_memset(&cur_dot11rxiv, 0, sz);
8837 
8838 	if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
8839 		id = psecuritypriv->dot118021XGrpKeyid;
8840 		tid_id = prxcache->last_tid;
8841 		REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
8842 		REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
8843 		REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
8844 		REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
8845 		_rtw_memcpy(pframe, cur_dot11rxiv, sz);
8846 		*pLength += sz;
8847 		pframe += sz;
8848 
8849 		_rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
8850 		*pLength += sz;
8851 		pframe += sz;
8852 
8853 		total = sizeof(psecuritypriv->iv_seq);
8854 		total /= sizeof(psecuritypriv->iv_seq[0]);
8855 
8856 		for (i = 0 ; i < total ; i ++) {
8857 			ccmp_hdr =
8858 				le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
8859 			_rtw_memset(&cur_dot11rxiv, 0, sz);
8860 			if (ccmp_hdr != 0) {
8861 				tmp_key = i;
8862 				ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
8863 				*(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
8864 				_rtw_memcpy(pframe, cur_dot11rxiv, sz);
8865 			}
8866 			*pLength += sz;
8867 			pframe += sz;
8868 		}
8869 	}
8870 }
8871 
rtw_hal_set_wow_fw_rsvd_page(_adapter * adapter,u8 * pframe,u16 index,u8 tx_desc,u32 page_size,u8 * page_num,u32 * total_pkt_len,RSVDPAGE_LOC * rsvd_page_loc)8872 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
8873 		  u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
8874 				  RSVDPAGE_LOC *rsvd_page_loc)
8875 {
8876 	struct security_priv *psecuritypriv = &adapter->securitypriv;
8877 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8878 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8879 	struct mlme_ext_priv	*pmlmeext;
8880 	struct mlme_ext_info	*pmlmeinfo;
8881 	u32	ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
8882 	u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
8883 	u8 CurtPktPageNum = 0;
8884 
8885 #ifdef CONFIG_GTK_OL
8886 	struct sta_priv *pstapriv = &adapter->stapriv;
8887 	struct sta_info *psta;
8888 	struct security_priv *psecpriv = &adapter->securitypriv;
8889 	u8 kek[RTW_KEK_LEN];
8890 	u8 kck[RTW_KCK_LEN];
8891 #endif /* CONFIG_GTK_OL */
8892 #ifdef CONFIG_PNO_SUPPORT
8893 	int pno_index;
8894 	u8 ssid_num;
8895 #endif /* CONFIG_PNO_SUPPORT */
8896 
8897 	pmlmeext = &adapter->mlmeextpriv;
8898 	pmlmeinfo = &pmlmeext->mlmext_info;
8899 
8900 	if (pwrctl->wowlan_pno_enable == _FALSE) {
8901 		/* ARP RSP * 1 page */
8902 
8903 		rsvd_page_loc->LocArpRsp = *page_num;
8904 
8905 		RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
8906 
8907 		rtw_hal_construct_ARPRsp(adapter, &pframe[index],
8908 					 &ARPLength, pmlmeinfo->ip_addr);
8909 
8910 		rtw_hal_fill_fake_txdesc(adapter,
8911 					 &pframe[index - tx_desc],
8912 					 ARPLength, _FALSE, _FALSE, _TRUE);
8913 
8914 		CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
8915 
8916 		*page_num += CurtPktPageNum;
8917 
8918 		index += (CurtPktPageNum * page_size);
8919 		RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
8920 
8921 #ifdef CONFIG_IPV6
8922 		/* 2 NS offload and NDP Info*/
8923 		if (pwrctl->wowlan_ns_offload_en == _TRUE) {
8924 			rsvd_page_loc->LocNbrAdv = *page_num;
8925 			RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
8926 			rtw_hal_construct_na_message(adapter,
8927 						     &pframe[index], &ns_len);
8928 			rtw_hal_fill_fake_txdesc(adapter,
8929 						 &pframe[index - tx_desc],
8930 						 ns_len, _FALSE,
8931 						 _FALSE, _TRUE);
8932 			CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
8933 						      page_size);
8934 			*page_num += CurtPktPageNum;
8935 			index += (CurtPktPageNum * page_size);
8936 			RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
8937 
8938 			rsvd_page_loc->LocNDPInfo = *page_num;
8939 			RTW_INFO("LocNDPInfo: %d\n",
8940 				 rsvd_page_loc->LocNDPInfo);
8941 
8942 			rtw_hal_construct_ndp_info(adapter,
8943 						   &pframe[index - tx_desc],
8944 						   &ns_len);
8945 			CurtPktPageNum =
8946 				(u8)PageNum(tx_desc + ns_len, page_size);
8947 			*page_num += CurtPktPageNum;
8948 			index += (CurtPktPageNum * page_size);
8949 			RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
8950 
8951 		}
8952 #endif /*CONFIG_IPV6*/
8953 		/* 3 Remote Control Info. * 1 page */
8954 		rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
8955 		RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
8956 		rtw_hal_construct_remote_control_info(adapter,
8957 						      &pframe[index - tx_desc],
8958 						      &rc_len);
8959 		CurtPktPageNum = (u8)PageNum(rc_len, page_size);
8960 		*page_num += CurtPktPageNum;
8961 		*total_pkt_len = index + rc_len;
8962 		RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
8963 #ifdef CONFIG_GTK_OL
8964 		index += (CurtPktPageNum * page_size);
8965 
8966 		/* if the ap staion info. exists, get the kek, kck from staion info. */
8967 		psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8968 		if (psta == NULL) {
8969 			_rtw_memset(kek, 0, RTW_KEK_LEN);
8970 			_rtw_memset(kck, 0, RTW_KCK_LEN);
8971 			RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
8972 				 __func__);
8973 		} else {
8974 			_rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
8975 			_rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
8976 		}
8977 
8978 		/* 3 KEK, KCK */
8979 		rsvd_page_loc->LocGTKInfo = *page_num;
8980 		RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
8981 
8982 		if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
8983 			struct security_priv *psecpriv = NULL;
8984 
8985 			psecpriv = &adapter->securitypriv;
8986 			_rtw_memcpy(pframe + index - tx_desc,
8987 				    &psecpriv->dot11PrivacyAlgrthm, 1);
8988 			_rtw_memcpy(pframe + index - tx_desc + 1,
8989 				    &psecpriv->dot118021XGrpPrivacy, 1);
8990 			_rtw_memcpy(pframe + index - tx_desc + 2,
8991 				    kck, RTW_KCK_LEN);
8992 			_rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
8993 				    kek, RTW_KEK_LEN);
8994 			CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
8995 		} else {
8996 
8997 			_rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
8998 			_rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
8999 				    kek, RTW_KEK_LEN);
9000 			GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
9001 
9002 			if (psta != NULL &&
9003 				psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
9004 				_rtw_memcpy(pframe + index - tx_desc + 56,
9005 					&psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
9006 				GTKLength += RTW_TKIP_MIC_LEN;
9007 			}
9008 			CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
9009 		}
9010 #if 0
9011 		{
9012 			int i;
9013 			printk("\ntoFW KCK: ");
9014 			for (i = 0; i < 16; i++)
9015 				printk(" %02x ", kck[i]);
9016 			printk("\ntoFW KEK: ");
9017 			for (i = 0; i < 16; i++)
9018 				printk(" %02x ", kek[i]);
9019 			printk("\n");
9020 		}
9021 
9022 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
9023 			 __FUNCTION__, &pframe[index - tx_desc],
9024 			 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
9025 #endif
9026 
9027 		*page_num += CurtPktPageNum;
9028 
9029 		index += (CurtPktPageNum * page_size);
9030 		RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
9031 
9032 		/* 3 GTK Response */
9033 		rsvd_page_loc->LocGTKRsp = *page_num;
9034 		RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
9035 		rtw_hal_construct_GTKRsp(adapter, &pframe[index], &GTKLength);
9036 
9037 		rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
9038 					 GTKLength, _FALSE, _FALSE, _TRUE);
9039 #if 0
9040 		{
9041 			int gj;
9042 			printk("123GTK pkt=>\n");
9043 			for (gj = 0; gj < GTKLength + tx_desc; gj++) {
9044 				printk(" %02x ", pframe[index - tx_desc + gj]);
9045 				if ((gj + 1) % 16 == 0)
9046 					printk("\n");
9047 			}
9048 			printk(" <=end\n");
9049 		}
9050 
9051 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
9052 			 __FUNCTION__, &pframe[index - tx_desc],
9053 			 (tx_desc + GTKLength));
9054 #endif
9055 
9056 		CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
9057 
9058 		*page_num += CurtPktPageNum;
9059 
9060 		index += (CurtPktPageNum * page_size);
9061 		RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
9062 
9063 		/* below page is empty for GTK extension memory */
9064 		/* 3(11) GTK EXT MEM */
9065 		rsvd_page_loc->LocGTKEXTMEM = *page_num;
9066 		RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
9067 		CurtPktPageNum = 2;
9068 
9069 		if (page_size >= 256)
9070 			CurtPktPageNum = 1;
9071 
9072 		*page_num += CurtPktPageNum;
9073 		/* extension memory for FW */
9074 		*total_pkt_len = index + (page_size * CurtPktPageNum);
9075 		RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
9076 #endif /* CONFIG_GTK_OL */
9077 
9078 		index += (CurtPktPageNum * page_size);
9079 
9080 		/*Reserve 1 page for AOAC report*/
9081 		rsvd_page_loc->LocAOACReport = *page_num;
9082 		RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
9083 		*page_num += 1;
9084 		*total_pkt_len = index + (page_size * 1);
9085 		RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
9086 	} else {
9087 #ifdef CONFIG_PNO_SUPPORT
9088 		if (pwrctl->wowlan_in_resume == _FALSE &&
9089 		    pwrctl->pno_inited == _TRUE) {
9090 
9091 			/* Broadcast Probe Request */
9092 			rsvd_page_loc->LocProbePacket = *page_num;
9093 
9094 			RTW_INFO("loc_probe_req: %d\n",
9095 				 rsvd_page_loc->LocProbePacket);
9096 
9097 			rtw_hal_construct_ProbeReq(
9098 				adapter,
9099 				&pframe[index],
9100 				&ProbeReqLength,
9101 				NULL);
9102 
9103 			rtw_hal_fill_fake_txdesc(adapter,
9104 						 &pframe[index - tx_desc],
9105 				 ProbeReqLength, _FALSE, _FALSE, _FALSE);
9106 
9107 			CurtPktPageNum =
9108 				(u8)PageNum(tx_desc + ProbeReqLength, page_size);
9109 
9110 			*page_num += CurtPktPageNum;
9111 
9112 			index += (CurtPktPageNum * page_size);
9113 			RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9114 
9115 			/* Hidden SSID Probe Request */
9116 			ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
9117 
9118 			for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
9119 				pwrctl->pnlo_info->loc_probe_req[pno_index] =
9120 					*page_num;
9121 
9122 				rtw_hal_construct_ProbeReq(
9123 					adapter,
9124 					&pframe[index],
9125 					&ProbeReqLength,
9126 					&pwrctl->pno_ssid_list->node[pno_index]);
9127 
9128 				rtw_hal_fill_fake_txdesc(adapter,
9129 						 &pframe[index - tx_desc],
9130 					ProbeReqLength, _FALSE, _FALSE, _FALSE);
9131 
9132 				CurtPktPageNum =
9133 					(u8)PageNum(tx_desc + ProbeReqLength, page_size);
9134 
9135 				*page_num += CurtPktPageNum;
9136 
9137 				index += (CurtPktPageNum * page_size);
9138 				RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9139 			}
9140 
9141 			/* PNO INFO Page */
9142 			rsvd_page_loc->LocPNOInfo = *page_num;
9143 			RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
9144 			rtw_hal_construct_PNO_info(adapter,
9145 						   &pframe[index - tx_desc],
9146 						   &PNOLength);
9147 
9148 			CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
9149 			*page_num += CurtPktPageNum;
9150 			index += (CurtPktPageNum * page_size);
9151 			RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
9152 
9153 			/* Scan Info Page */
9154 			rsvd_page_loc->LocScanInfo = *page_num;
9155 			RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
9156 			rtw_hal_construct_scan_info(adapter,
9157 						    &pframe[index - tx_desc],
9158 						    &ScanInfoLength);
9159 
9160 			CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
9161 			*page_num += CurtPktPageNum;
9162 			*total_pkt_len = index + ScanInfoLength;
9163 			index += (CurtPktPageNum * page_size);
9164 			RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
9165 		}
9166 #endif /* CONFIG_PNO_SUPPORT */
9167 	}
9168 }
9169 
rtw_hal_gate_bb(_adapter * adapter,bool stop)9170 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9171 {
9172 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9173 	u8 i = 0, val8 = 0, empty = _FAIL;
9174 
9175 	if (stop) {
9176 		/* checking TX queue status */
9177 		for (i = 0 ; i < 5 ; i++) {
9178 			rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9179 			if (empty) {
9180 				break;
9181 			} else {
9182 				RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9183 					 __func__, i);
9184 				rtw_mdelay_os(10);
9185 			}
9186 		}
9187 
9188 		if (val8 == 5)
9189 			RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9190 
9191 		/* Pause TX*/
9192 		pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9193 		rtw_write8(adapter, REG_TXPAUSE, 0xff);
9194 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9195 		val8 &= ~BIT(0);
9196 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9197 		RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9198 			 __func__,
9199 			 rtw_read8(adapter, REG_SYS_FUNC_EN),
9200 			 pwrpriv->wowlan_txpause_status);
9201 	} else {
9202 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9203 		val8 |= BIT(0);
9204 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9205 		RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9206 			 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9207 			 pwrpriv->wowlan_txpause_status);
9208 		/* release TX*/
9209 		rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9210 	}
9211 }
9212 
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)9213 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9214 {
9215 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9216 	 u8 *pattern;
9217 	 u8 len = 0;
9218 	 u8 *mask;
9219 
9220 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
9221 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9222 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9223 	u8 multicast_addr1[2] = {0x33, 0x33};
9224 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9225 	u8 mask_len = 0;
9226 	u8 mac_addr[ETH_ALEN] = {0};
9227 	u16 count = 0;
9228 	int i;
9229 
9230 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9231 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9232 			 __func__, MAX_WKFM_CAM_NUM);
9233 		return _FAIL;
9234 	}
9235 
9236 	pattern = pwrctl->patterns[idx].content;
9237 	len = pwrctl->patterns[idx].len;
9238 	mask = pwrctl->patterns[idx].mask;
9239 
9240 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9241 	_rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9242 
9243 	mask_len = DIV_ROUND_UP(len, 8);
9244 
9245 	/* 1. setup A1 table */
9246 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9247 		pwow_pattern->type = PATTERN_BROADCAST;
9248 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
9249 		pwow_pattern->type = PATTERN_MULTICAST;
9250 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
9251 		pwow_pattern->type = PATTERN_MULTICAST;
9252 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9253 		pwow_pattern->type = PATTERN_UNICAST;
9254 	else
9255 		pwow_pattern->type = PATTERN_INVALID;
9256 
9257 	/* translate mask from os to mask for hw */
9258 
9259 	/******************************************************************************
9260 	 * pattern from OS uses 'ethenet frame', like this:
9261 
9262 		|    6   |    6   |   2  |     20    |  Variable  |  4  |
9263 		|--------+--------+------+-----------+------------+-----|
9264 		|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
9265 		|   DA   |   SA   | Type |
9266 
9267 	 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9268 
9269 		|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
9270 		|-------------------+--------+------+-----------+------------+-----|
9271 		| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
9272 				    | Others | Tpye |
9273 
9274 	 * Therefore, we need translate mask_from_OS to mask_to_hw.
9275 	 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9276 	 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9277 	 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9278 	 ******************************************************************************/
9279 	/* Shift 6 bits */
9280 	for (i = 0; i < mask_len - 1; i++) {
9281 		mask_hw[i] = mask[i] >> 6;
9282 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9283 	}
9284 
9285 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
9286 	/* Set bit 0-5 to zero */
9287 	mask_hw[0] &= 0xC0;
9288 
9289 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9290 		pwow_pattern->mask[i] = mask_hw[i * 4];
9291 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9292 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9293 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9294 	}
9295 
9296 	/* To get the wake up pattern from the mask.
9297 	 * We do not count first 12 bits which means
9298 	 * DA[6] and SA[6] in the pattern to match HW design. */
9299 	count = 0;
9300 	for (i = 12; i < len; i++) {
9301 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
9302 			content[count] = pattern[i];
9303 			count++;
9304 		}
9305 	}
9306 
9307 	pwow_pattern->crc = rtw_calc_crc(content, count);
9308 
9309 	if (pwow_pattern->crc != 0) {
9310 		if (pwow_pattern->type == PATTERN_INVALID)
9311 			pwow_pattern->type = PATTERN_VALID;
9312 	}
9313 
9314 	return _SUCCESS;
9315 }
9316 
9317 #ifndef CONFIG_WOW_PATTERN_HW_CAM
rtw_hal_reset_mac_rx(_adapter * adapter)9318 static void rtw_hal_reset_mac_rx(_adapter *adapter)
9319 {
9320 	u8 val8 = 0;
9321 	/* Set REG_CR bit1, bit3, bit7 to 0*/
9322 	val8 = rtw_read8(adapter, REG_CR);
9323 	val8 &= 0x75;
9324 	rtw_write8(adapter, REG_CR, val8);
9325 	val8 = rtw_read8(adapter, REG_CR);
9326 	/* Set REG_CR bit1, bit3, bit7 to 1*/
9327 	val8 |= 0x8a;
9328 	rtw_write8(adapter, REG_CR, val8);
9329 	RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
9330 }
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)9331 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
9332 {
9333 	u8 val8 = 0;
9334 	u16 rxff_bndy = 0;
9335 	u32 rx_dma_buff_sz = 0;
9336 
9337 	val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
9338 	if (val8 != 0)
9339 		RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
9340 			 __func__, (REG_FIFOPAGE + 3));
9341 
9342 	rtw_hal_reset_mac_rx(adapter);
9343 
9344 	if (wow_mode) {
9345 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9346 				    (u8 *)&rx_dma_buff_sz);
9347 		rxff_bndy = rx_dma_buff_sz - 1;
9348 
9349 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9350 		RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
9351 			 REG_TRXFF_BNDY + 2,
9352 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9353 	} else {
9354 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
9355 				    (u8 *)&rx_dma_buff_sz);
9356 		rxff_bndy = rx_dma_buff_sz - 1;
9357 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9358 		RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
9359 			 REG_TRXFF_BNDY + 2,
9360 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9361 	}
9362 }
9363 
9364 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9365 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9366 {
9367 	u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9368 	u16 offset, rx_buf_ptr = 0;
9369 	u16 cam_start_offset = 0;
9370 	u16 ctrl_l = 0, ctrl_h = 0;
9371 	u8 count = 0, tmp = 0;
9372 	int i = 0;
9373 	bool res = _TRUE;
9374 
9375 	if (idx > MAX_WKFM_CAM_NUM) {
9376 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9377 			 __func__);
9378 		return _FALSE;
9379 	}
9380 
9381 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9382 			    (u8 *)&rx_dma_buff_sz);
9383 
9384 	if (rx_dma_buff_sz == 0) {
9385 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9386 		return _FALSE;
9387 	}
9388 
9389 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9390 
9391 	if (page_sz == 0) {
9392 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9393 		return _FALSE;
9394 	}
9395 
9396 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9397 	cam_start_offset = offset * page_sz;
9398 
9399 	ctrl_l = 0x0;
9400 	ctrl_h = 0x0;
9401 
9402 	/* Enable RX packet buffer access */
9403 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9404 
9405 	/* Read the WKFM CAM */
9406 	for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9407 		/*
9408 		 * Set Rx packet buffer offset.
9409 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9410 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9411 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9412 		 * * Index: The index of the wake up frame mask
9413 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9414 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9415 		 */
9416 		rx_buf_ptr =
9417 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9418 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9419 
9420 		rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9421 		data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9422 		data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9423 
9424 		RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9425 
9426 		count = 0;
9427 
9428 		do {
9429 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9430 			rtw_udelay_os(2);
9431 			count++;
9432 		} while (!tmp && count < 100);
9433 
9434 		if (count >= 100) {
9435 			RTW_INFO("%s count:%d\n", __func__, count);
9436 			res = _FALSE;
9437 		}
9438 	}
9439 
9440 	/* Disable RX packet buffer access */
9441 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9442 		   DISABLE_TRXPKT_BUF_ACCESS);
9443 	return res;
9444 }
9445 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9446 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9447 			     struct  rtl_wow_pattern *context)
9448 {
9449 	u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
9450 	u16 offset, rx_buf_ptr = 0;
9451 	u16 cam_start_offset = 0;
9452 	u16 ctrl_l = 0, ctrl_h = 0;
9453 	u8 count = 0, tmp = 0;
9454 	int res = 0, i = 0;
9455 
9456 	if (idx > MAX_WKFM_CAM_NUM) {
9457 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9458 			 __func__);
9459 		return _FALSE;
9460 	}
9461 
9462 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9463 			    (u8 *)&rx_dma_buff_sz);
9464 
9465 	if (rx_dma_buff_sz == 0) {
9466 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9467 		return _FALSE;
9468 	}
9469 
9470 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9471 
9472 	if (page_sz == 0) {
9473 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9474 		return _FALSE;
9475 	}
9476 
9477 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9478 
9479 	cam_start_offset = offset * page_sz;
9480 
9481 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
9482 		ctrl_l = 0x0001;
9483 		ctrl_h = 0x0001;
9484 	} else {
9485 		ctrl_l = 0x0f01;
9486 		ctrl_h = 0xf001;
9487 	}
9488 
9489 	/* Enable RX packet buffer access */
9490 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9491 
9492 	/* Write the WKFM CAM */
9493 	for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
9494 		/*
9495 		 * Set Rx packet buffer offset.
9496 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9497 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9498 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9499 		 * * Index: The index of the wake up frame mask
9500 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9501 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9502 		 */
9503 		rx_buf_ptr =
9504 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
9505 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9506 
9507 		if (i == 0) {
9508 			if (context->type == PATTERN_VALID)
9509 				data = BIT(31);
9510 			else if (context->type == PATTERN_BROADCAST)
9511 				data = BIT(31) | BIT(26);
9512 			else if (context->type == PATTERN_MULTICAST)
9513 				data = BIT(31) | BIT(25);
9514 			else if (context->type == PATTERN_UNICAST)
9515 				data = BIT(31) | BIT(24);
9516 
9517 			if (context->crc != 0)
9518 				data |= context->crc;
9519 
9520 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9521 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9522 		} else if (i == 1) {
9523 			data = 0;
9524 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9525 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9526 		} else if (i == 2 || i == 4) {
9527 			data = context->mask[i - 2];
9528 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9529 			/* write to RX packet buffer*/
9530 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9531 		} else if (i == 3 || i == 5) {
9532 			data = context->mask[i - 2];
9533 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9534 			/* write to RX packet buffer*/
9535 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9536 		}
9537 
9538 		count = 0;
9539 		do {
9540 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9541 			rtw_udelay_os(2);
9542 			count++;
9543 		} while (tmp && count < 100);
9544 
9545 		if (count >= 100)
9546 			res = _FALSE;
9547 		else
9548 			res = _TRUE;
9549 	}
9550 
9551 	/* Disable RX packet buffer access */
9552 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9553 		   DISABLE_TRXPKT_BUF_ACCESS);
9554 
9555 	return res;
9556 }
9557 #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9558 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9559 {
9560 	u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9561 	u16 tx_page_start, tx_buf_ptr = 0;
9562 	u16 cam_start_offset = 0;
9563 	u16 ctrl_l = 0, ctrl_h = 0;
9564 	u8 count = 0, tmp = 0, last_entry = 0;
9565 	int i = 0;
9566 	bool res = _TRUE;
9567 
9568 	if (idx > MAX_WKFM_CAM_NUM) {
9569 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9570 			 __func__);
9571 		return _FALSE;
9572 	}
9573 
9574 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9575 	if (page_sz == 0) {
9576 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9577 		return _FALSE;
9578 	}
9579 
9580 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9581 	if (last_entry == 0) {
9582 		RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9583 		return _FALSE;
9584 	}
9585 
9586 	/* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9587 	tx_page_start = last_entry - 1;
9588 	cam_start_offset = tx_page_start * page_sz / 8;
9589 	ctrl_l = 0x0;
9590 	ctrl_h = 0x0;
9591 
9592 	/* Enable TX packet buffer access */
9593 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9594 
9595 	/* Read the WKFM CAM */
9596 	for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9597 		/*
9598 		 * Set Tx packet buffer offset.
9599 		 * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer.
9600 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9601 		 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9602 		 * * Index: The index of the wake up frame mask
9603 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9604 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9605 		 */
9606 		tx_buf_ptr =
9607 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9608 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr);
9609 		rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9610 		data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9611 		data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9612 
9613 		RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9614 
9615 		count = 0;
9616 
9617 		do {
9618 			tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9619 			rtw_udelay_os(2);
9620 			count++;
9621 		} while (!tmp && count < 100);
9622 
9623 		if (count >= 100) {
9624 			RTW_INFO("%s count:%d\n", __func__, count);
9625 			res = _FALSE;
9626 		}
9627 	}
9628 
9629 	/* Disable RX packet buffer access */
9630 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9631 		   DISABLE_TRXPKT_BUF_ACCESS);
9632 	return res;
9633 }
9634 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9635 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9636 			     struct  rtl_wow_pattern *context)
9637 {
9638 	u32 tx_page_start = 0, page_sz = 0;
9639 	u16 tx_buf_ptr = 0;
9640 	u16 cam_start_offset = 0;
9641 	u32 data_l = 0, data_h = 0;
9642 	u8 count = 0, tmp = 0, last_entry = 0;
9643 	int res = 0, i = 0;
9644 
9645 	if (idx > MAX_WKFM_CAM_NUM) {
9646 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9647 			 __func__);
9648 		return _FALSE;
9649 	}
9650 
9651 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9652 	if (page_sz == 0) {
9653 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9654 		return _FALSE;
9655 	}
9656 
9657 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9658 	if (last_entry == 0) {
9659 		RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9660 		return _FALSE;
9661 	}
9662 
9663 	/* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9664 	tx_page_start = last_entry - 1;
9665 	cam_start_offset = tx_page_start * page_sz / 8;
9666 
9667 	/* Write the PATTERN location to BIT_TXBUF_WKCAM_OFFSET */
9668 	rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET, cam_start_offset & 0xFF);
9669 	rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET + 1, (cam_start_offset >> 8) & 0xFF);
9670 	/* Enable TX packet buffer access */
9671 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9672 
9673 	/* Write the WKFM CAM */
9674 	for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9675 		/*
9676 		 * Set Tx packet buffer offset.
9677 		 * TxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9678 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9679 		 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9680 		 * * Index: The index of the wake up frame mask
9681 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9682 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9683 		 */
9684 		tx_buf_ptr = cam_start_offset + ((idx * WKFMCAM_SIZE + i * 8) >> 3);
9685 
9686 		if (i == 0) {
9687 			if (context->type == PATTERN_VALID)
9688 				data_l = BIT(31);
9689 			else if (context->type == PATTERN_BROADCAST)
9690 				data_l = BIT(31) | BIT(26);
9691 			else if (context->type == PATTERN_MULTICAST)
9692 				data_l = BIT(31) | BIT(25);
9693 			else if (context->type == PATTERN_UNICAST)
9694 				data_l = BIT(31) | BIT(24);
9695 
9696 			if (context->crc != 0)
9697 				data_l |= context->crc;
9698 
9699 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9700 		} else {
9701 			data_l = context->mask[i * 2 - 2];
9702 			data_h = context->mask[i * 2 - 1];
9703 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9704 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h);
9705 		}
9706 
9707 		rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0xFFFF) | BIT23 | (0xff <<24));
9708 		count = 0;
9709 		do {
9710 			tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9711 			rtw_udelay_os(2);
9712 			count++;
9713 		} while (tmp && count < 100);
9714 
9715 		if (count >= 100) {
9716 			res = _FALSE;
9717 			RTW_INFO("%s write failed\n", __func__);
9718 		} else {
9719 			res = _TRUE;
9720 			RTW_INFO("%s write OK\n", __func__);
9721 		}
9722 	}
9723 
9724 	/* Disable TX packet buffer access */
9725 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
9726 	return res;
9727 }
9728 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
9729 
rtw_clean_pattern(_adapter * adapter)9730 void rtw_clean_pattern(_adapter *adapter)
9731 {
9732 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9733 	struct rtl_wow_pattern zero_pattern;
9734 	int i = 0;
9735 
9736 	_rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
9737 
9738 	zero_pattern.type = PATTERN_INVALID;
9739 
9740 	for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
9741 		rtw_write_to_frame_mask(adapter, i, &zero_pattern);
9742 
9743 	rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
9744 }
9745 #if 0
9746 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
9747 			       u8 len, u8 *mask, u8 idx)
9748 {
9749 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9750 	struct mlme_ext_priv *pmlmeext = NULL;
9751 	struct mlme_ext_info *pmlmeinfo = NULL;
9752 	struct rtl_wow_pattern wow_pattern;
9753 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
9754 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9755 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9756 	u8 multicast_addr1[2] = {0x33, 0x33};
9757 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9758 	u8 res = _FALSE, index = 0, mask_len = 0;
9759 	u8 mac_addr[ETH_ALEN] = {0};
9760 	u16 count = 0;
9761 	int i, j;
9762 
9763 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9764 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9765 			 __func__, MAX_WKFM_CAM_NUM);
9766 		return _FALSE;
9767 	}
9768 
9769 	pmlmeext = &adapter->mlmeextpriv;
9770 	pmlmeinfo = &pmlmeext->mlmext_info;
9771 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9772 	_rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
9773 
9774 	mask_len = DIV_ROUND_UP(len, 8);
9775 
9776 	/* 1. setup A1 table */
9777 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9778 		wow_pattern.type = PATTERN_BROADCAST;
9779 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
9780 		wow_pattern.type = PATTERN_MULTICAST;
9781 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
9782 		wow_pattern.type = PATTERN_MULTICAST;
9783 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9784 		wow_pattern.type = PATTERN_UNICAST;
9785 	else
9786 		wow_pattern.type = PATTERN_INVALID;
9787 
9788 	/* translate mask from os to mask for hw */
9789 
9790 /******************************************************************************
9791  * pattern from OS uses 'ethenet frame', like this:
9792 
9793 	|    6   |    6   |   2  |     20    |  Variable  |  4  |
9794 	|--------+--------+------+-----------+------------+-----|
9795 	|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
9796 	|   DA   |   SA   | Type |
9797 
9798  * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9799 
9800 	|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
9801 	|-------------------+--------+------+-----------+------------+-----|
9802 	| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
9803 			    | Others | Tpye |
9804 
9805  * Therefore, we need translate mask_from_OS to mask_to_hw.
9806  * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9807  * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9808  * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9809  ******************************************************************************/
9810 	/* Shift 6 bits */
9811 	for (i = 0; i < mask_len - 1; i++) {
9812 		mask_hw[i] = mask[i] >> 6;
9813 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9814 	}
9815 
9816 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
9817 	/* Set bit 0-5 to zero */
9818 	mask_hw[0] &= 0xC0;
9819 
9820 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9821 		wow_pattern.mask[i] = mask_hw[i * 4];
9822 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
9823 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
9824 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
9825 	}
9826 
9827 	/* To get the wake up pattern from the mask.
9828 	 * We do not count first 12 bits which means
9829 	 * DA[6] and SA[6] in the pattern to match HW design. */
9830 	count = 0;
9831 	for (i = 12; i < len; i++) {
9832 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
9833 			content[count] = pattern[i];
9834 			count++;
9835 		}
9836 	}
9837 
9838 	wow_pattern.crc = rtw_calc_crc(content, count);
9839 
9840 	if (wow_pattern.crc != 0) {
9841 		if (wow_pattern.type == PATTERN_INVALID)
9842 			wow_pattern.type = PATTERN_VALID;
9843 	}
9844 
9845 	index = idx;
9846 
9847 	if (!pwrctl->bInSuspend)
9848 		index += 2;
9849 
9850 	/* write pattern */
9851 	res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
9852 
9853 	if (res == _FALSE)
9854 		RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
9855 			 __func__, idx);
9856 
9857 	return res;
9858 }
9859 #endif
9860 
rtw_fill_pattern(_adapter * adapter)9861 void rtw_fill_pattern(_adapter *adapter)
9862 {
9863 	int i = 0, total = 0, index;
9864 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9865 	struct rtl_wow_pattern wow_pattern;
9866 
9867 	total = pwrpriv->wowlan_pattern_idx;
9868 
9869 	if (total > MAX_WKFM_CAM_NUM)
9870 		total = MAX_WKFM_CAM_NUM;
9871 
9872 	for (i = 0 ; i < total ; i++) {
9873 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
9874 
9875 			index = i;
9876 			if (!pwrpriv->bInSuspend)
9877 				index += 2;
9878 
9879 			if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
9880 				RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
9881 		}
9882 
9883 	}
9884 	rtw_write8(adapter, REG_WKFMCAM_NUM, total);
9885 
9886 }
9887 
9888 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
9889 
9890 #define WOW_CAM_ACCESS_TIMEOUT_MS	200
9891 #define WOW_VALID_BIT	BIT31
9892 #define WOW_BC_BIT		BIT26
9893 #define WOW_MC_BIT		BIT25
9894 #define WOW_UC_BIT		BIT24
9895 
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)9896 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
9897 {
9898 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9899 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
9900 
9901 	u32 rdata = 0;
9902 	u32 cnt = 0;
9903 	systime start = 0;
9904 	u8 timeout = 0;
9905 	u8 rst = _FALSE;
9906 
9907 	_enter_critical_mutex(mutex, NULL);
9908 
9909 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
9910 
9911 	start = rtw_get_current_time();
9912 	while (1) {
9913 		if (rtw_is_surprise_removed(adapter))
9914 			break;
9915 
9916 		cnt++;
9917 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
9918 			rst = _SUCCESS;
9919 			break;
9920 		}
9921 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
9922 			timeout = 1;
9923 			break;
9924 		}
9925 	}
9926 
9927 	rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
9928 
9929 	_exit_critical_mutex(mutex, NULL);
9930 
9931 	/*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
9932 
9933 	if (timeout)
9934 		RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
9935 
9936 	return rdata;
9937 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)9938 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
9939 {
9940 	int i;
9941 	u32 rdata;
9942 
9943 	_rtw_memset(context, 0, sizeof(struct  rtl_wow_pattern));
9944 
9945 	for (i = 4; i >= 0; i--) {
9946 		rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
9947 
9948 		switch (i) {
9949 		case 4:
9950 			if (rdata & WOW_BC_BIT)
9951 				context->type = PATTERN_BROADCAST;
9952 			else if (rdata & WOW_MC_BIT)
9953 				context->type = PATTERN_MULTICAST;
9954 			else if (rdata & WOW_UC_BIT)
9955 				context->type = PATTERN_UNICAST;
9956 			else
9957 				context->type = PATTERN_INVALID;
9958 
9959 			context->crc = rdata & 0xFFFF;
9960 			break;
9961 		default:
9962 			_rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
9963 			break;
9964 		}
9965 	}
9966 }
9967 
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)9968 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
9969 {
9970 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9971 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
9972 	u32 cnt = 0;
9973 	systime start = 0, end = 0;
9974 	u8 timeout = 0;
9975 
9976 	/*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
9977 	_enter_critical_mutex(mutex, NULL);
9978 
9979 	rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
9980 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
9981 
9982 	start = rtw_get_current_time();
9983 	while (1) {
9984 		if (rtw_is_surprise_removed(adapter))
9985 			break;
9986 
9987 		cnt++;
9988 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
9989 			break;
9990 
9991 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
9992 			timeout = 1;
9993 			break;
9994 		}
9995 	}
9996 	end = rtw_get_current_time();
9997 
9998 	_exit_critical_mutex(mutex, NULL);
9999 
10000 	if (timeout) {
10001 		RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
10002 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
10003 	}
10004 }
10005 
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10006 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
10007 {
10008 	int j;
10009 	u8 addr;
10010 	u32 wdata = 0;
10011 
10012 	for (j = 4; j >= 0; j--) {
10013 		switch (j) {
10014 		case 4:
10015 			wdata = context->crc;
10016 
10017 			if (PATTERN_BROADCAST == context->type)
10018 				wdata |= WOW_BC_BIT;
10019 			if (PATTERN_MULTICAST == context->type)
10020 				wdata |= WOW_MC_BIT;
10021 			if (PATTERN_UNICAST == context->type)
10022 				wdata |= WOW_UC_BIT;
10023 			if (PATTERN_INVALID != context->type)
10024 				wdata |= WOW_VALID_BIT;
10025 			break;
10026 		default:
10027 			wdata = context->mask[j];
10028 			break;
10029 		}
10030 
10031 		addr = (id << 3) + j;
10032 
10033 		_rtw_wow_pattern_write_cam(adapter, addr, wdata);
10034 	}
10035 }
10036 
_rtw_wow_pattern_clean_cam(_adapter * adapter)10037 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
10038 {
10039 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10040 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10041 	u32 cnt = 0;
10042 	systime start = 0;
10043 	u8 timeout = 0;
10044 	u8 rst = _FAIL;
10045 
10046 	_enter_critical_mutex(mutex, NULL);
10047 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
10048 
10049 	start = rtw_get_current_time();
10050 	while (1) {
10051 		if (rtw_is_surprise_removed(adapter))
10052 			break;
10053 
10054 		cnt++;
10055 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10056 			rst = _SUCCESS;
10057 			break;
10058 		}
10059 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10060 			timeout = 1;
10061 			break;
10062 		}
10063 	}
10064 	_exit_critical_mutex(mutex, NULL);
10065 
10066 	if (timeout)
10067 		RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
10068 
10069 	return rst;
10070 }
10071 
rtw_clean_pattern(_adapter * adapter)10072 void rtw_clean_pattern(_adapter *adapter)
10073 {
10074 	if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
10075 		RTW_ERR("rtw_clean_pattern failed\n");
10076 }
10077 
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)10078 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
10079 {
10080 	int j;
10081 
10082 	RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
10083 	RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
10084 	RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
10085 	for (j = 0; j < 4; j++)
10086 		RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
10087 }
10088 
rtw_fill_pattern(_adapter * adapter)10089 void rtw_fill_pattern(_adapter *adapter)
10090 {
10091 	int i = 0, total = 0;
10092 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10093 	struct rtl_wow_pattern wow_pattern;
10094 
10095 	total = pwrpriv->wowlan_pattern_idx;
10096 
10097 	if (total > MAX_WKFM_CAM_NUM)
10098 		total = MAX_WKFM_CAM_NUM;
10099 
10100 	for (i = 0 ; i < total ; i++) {
10101 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10102 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10103 			rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
10104 		}
10105 	}
10106 }
10107 
10108 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)10109 void rtw_wow_pattern_cam_dump(_adapter *adapter)
10110 {
10111 
10112 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10113 	int i;
10114 
10115 	for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10116 		RTW_INFO("=======[%d]=======\n", i);
10117 		rtw_read_from_frame_mask(adapter, i);
10118 	}
10119 #else
10120 	struct  rtl_wow_pattern context;
10121 	int i;
10122 
10123 	for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10124 		rtw_wow_pattern_read_cam_ent(adapter, i, &context);
10125 		rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
10126 	}
10127 
10128 #endif
10129 }
10130 
10131 
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)10132 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
10133 {
10134 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10135 
10136 	switch (mode) {
10137 	case 0:
10138 		rtw_clean_pattern(adapter);
10139 		RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
10140 		break;
10141 	case 1:
10142 		rtw_set_default_pattern(adapter);
10143 		rtw_fill_pattern(adapter);
10144 		RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
10145 		break;
10146 	case 2:
10147 		rtw_clean_pattern(adapter);
10148 		rtw_wow_pattern_sw_reset(adapter);
10149 		RTW_INFO("%s: clean patterns\n", __func__);
10150 		break;
10151 	default:
10152 		RTW_INFO("%s: unknown mode\n", __func__);
10153 		break;
10154 	}
10155 }
10156 
rtw_hal_wow_enable(_adapter * adapter)10157 static void rtw_hal_wow_enable(_adapter *adapter)
10158 {
10159 	struct registry_priv  *registry_par = &adapter->registrypriv;
10160 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10161 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10162 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10163 	struct sta_info *psta = NULL;
10164 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
10165 	int res;
10166 	u16 media_status_rpt;
10167 	u8 no_wake = 0, i;
10168 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10169 	_adapter *iface;
10170 #ifdef CONFIG_GPIO_WAKEUP
10171 	u8 val8 = 0;
10172 #endif
10173 
10174 #ifdef CONFIG_LPS_PG
10175 	u8 lps_pg_hdl_id = 0;
10176 #endif
10177 
10178 
10179 
10180 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
10181 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
10182 		no_wake = 1;
10183 
10184 	RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
10185 	rtw_hal_gate_bb(adapter, _TRUE);
10186 
10187 	for (i = 0; i < dvobj->iface_nums; i++) {
10188 		iface = dvobj->padapters[i];
10189 		/* Start Usb TxDMA */
10190 		if(iface) {
10191 			RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface));
10192 			RTW_ENABLE_FUNC(iface, DF_TX_BIT);
10193 		}
10194 	}
10195 
10196 #ifdef CONFIG_GTK_OL
10197 	if (psecuritypriv->binstallKCK_KEK == _TRUE)
10198 		rtw_hal_fw_sync_cam_id(adapter);
10199 #endif
10200 	if (IS_HARDWARE_TYPE_8723B(adapter))
10201 		rtw_hal_backup_rate(adapter);
10202 
10203 	rtw_hal_fw_dl(adapter, _TRUE);
10204 	if(no_wake)
10205 		media_status_rpt = RT_MEDIA_DISCONNECT;
10206 	else
10207 		media_status_rpt = RT_MEDIA_CONNECT;
10208 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10209 			  (u8 *)&media_status_rpt);
10210 
10211 	/* RX DMA stop */
10212 	#if defined(CONFIG_RTL8188E)
10213 	if (IS_HARDWARE_TYPE_8188E(adapter))
10214 		rtw_hal_disable_tx_report(adapter);
10215 	#endif
10216 
10217 	res = rtw_hal_pause_rx_dma(adapter);
10218 	if (res == _FAIL)
10219 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
10220 
10221 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
10222 	/* Reconfig RX_FF Boundary */
10223 	rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
10224 	#endif
10225 
10226 	/* redownload wow pattern */
10227 	if(!no_wake)
10228 		rtw_hal_dl_pattern(adapter, 1);
10229 
10230 	if (!pwrctl->wowlan_pno_enable) {
10231 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10232 
10233 		if (psta != NULL) {
10234 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10235 			adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10236 			adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10237 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10238 			#endif
10239 			if(!no_wake)
10240 				rtw_sta_media_status_rpt(adapter, psta, 1);
10241 		}
10242 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10243 		else {
10244 			if(registry_par->suspend_type == FW_IPS_WRC) {
10245 				adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10246 				adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10247 				rtw_hal_set_default_port_id_cmd(adapter, 0);
10248 			}
10249 		}
10250 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10251 	}
10252 
10253 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10254 	/* Enable CPWM2 only. */
10255 	res = rtw_hal_enable_cpwm2(adapter);
10256 	if (res == _FAIL)
10257 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
10258 #endif
10259 #ifdef CONFIG_GPIO_WAKEUP
10260 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10261 	rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10262 	rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10263 #else
10264 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10265 	if (pwrctl->is_high_active == 0)
10266 		rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10267 	else
10268 		rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10269 			GPIO_OUTPUT_LOW);
10270 #else
10271 	val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10272 	rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8);
10273 	rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10274 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n",
10275 		 __func__, pwrctl->wowlan_gpio_index,
10276 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10277 		 pwrctl->is_high_active ? "HIGI" : "LOW");
10278 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10279 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10280 #endif /* CONFIG_GPIO_WAKEUP */
10281 	/* Set WOWLAN H2C command. */
10282 	RTW_PRINT("Set WOWLan cmd\n");
10283 	rtw_hal_set_fw_wow_related_cmd(adapter, 1);
10284 
10285 	res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
10286 
10287 	if (res == _FALSE)
10288 		RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
10289 
10290 	pwrctl->wowlan_wake_reason =
10291 		rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10292 
10293 	RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
10294 		  pwrctl->wowlan_wake_reason);
10295 #ifdef CONFIG_GTK_OL_DBG
10296 	dump_sec_cam(RTW_DBGDUMP, adapter);
10297 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
10298 #endif
10299 
10300 #ifdef CONFIG_LPS_PG
10301 	if (pwrctl->lps_level == LPS_PG) {
10302 		lps_pg_hdl_id = LPS_PG_INFO_CFG;
10303 		rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
10304 	}
10305 #endif
10306 
10307 #ifdef CONFIG_USB_HCI
10308 	/* free adapter's resource */
10309 	rtw_mi_intf_stop(adapter);
10310 
10311 #endif
10312 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
10313 	/* Invoid SE0 reset signal during suspending*/
10314 	rtw_write8(adapter, REG_RSV_CTRL, 0x20);
10315 	if (IS_8188F(pHalData->version_id) == FALSE
10316 		&& IS_8188GTV(pHalData->version_id) == FALSE)
10317 		rtw_write8(adapter, REG_RSV_CTRL, 0x60);
10318 #endif
10319 
10320 	rtw_hal_gate_bb(adapter, _FALSE);
10321 }
10322 
10323 #define DBG_WAKEUP_REASON
10324 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)10325 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
10326 {
10327 	RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
10328 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)10329 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
10330 {
10331 	if (RX_PAIRWISEKEY == reason)
10332 		_dbg_wake_up_reason_string(adapter, "Rx pairwise key");
10333 	else if (RX_GTK == reason)
10334 		_dbg_wake_up_reason_string(adapter, "Rx GTK");
10335 	else if (RX_FOURWAY_HANDSHAKE == reason)
10336 		_dbg_wake_up_reason_string(adapter, "Rx four way handshake");
10337 	else if (RX_DISASSOC == reason)
10338 		_dbg_wake_up_reason_string(adapter, "Rx disassoc");
10339 	else if (RX_DEAUTH == reason)
10340 		_dbg_wake_up_reason_string(adapter, "Rx deauth");
10341 	else if (RX_ARP_REQUEST == reason)
10342 		_dbg_wake_up_reason_string(adapter, "Rx ARP request");
10343 	else if (FW_DECISION_DISCONNECT == reason)
10344 		_dbg_wake_up_reason_string(adapter, "FW detect disconnect");
10345 	else if (RX_MAGIC_PKT == reason)
10346 		_dbg_wake_up_reason_string(adapter, "Rx magic packet");
10347 	else if (RX_UNICAST_PKT == reason)
10348 		_dbg_wake_up_reason_string(adapter, "Rx unicast packet");
10349 	else if (RX_PATTERN_PKT == reason)
10350 		_dbg_wake_up_reason_string(adapter, "Rx pattern packet");
10351 	else if (RTD3_SSID_MATCH == reason)
10352 		_dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
10353 	else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
10354 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
10355 	else if (RX_REALWOW_V2_ACK_LOST == reason)
10356 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
10357 	else if (ENABLE_FAIL_DMA_IDLE == reason)
10358 		_dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
10359 	else if (ENABLE_FAIL_DMA_PAUSE == reason)
10360 		_dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
10361 	else if (AP_OFFLOAD_WAKEUP == reason)
10362 		_dbg_wake_up_reason_string(adapter, "AP offload wakeup");
10363 	else if (CLK_32K_UNLOCK == reason)
10364 		_dbg_wake_up_reason_string(adapter, "clk 32k unlock");
10365 	else if (RTIME_FAIL_DMA_IDLE == reason)
10366 		_dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
10367 	else if (CLK_32K_LOCK == reason)
10368 		_dbg_wake_up_reason_string(adapter, "clk 32k lock");
10369 	else
10370 		_dbg_wake_up_reason_string(adapter, "unknown reasoen");
10371 }
10372 #endif
10373 
rtw_hal_wow_disable(_adapter * adapter)10374 static void rtw_hal_wow_disable(_adapter *adapter)
10375 {
10376 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10377 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10378 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10379 	struct sta_info *psta = NULL;
10380 	struct registry_priv  *registry_par = &adapter->registrypriv;
10381 	int res;
10382 	u16 media_status_rpt;
10383 
10384 	RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
10385 
10386 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
10387 		RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
10388 		return;
10389 	}
10390 
10391 	if (!pwrctl->wowlan_pno_enable) {
10392 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10393 		if (psta != NULL)
10394 			rtw_sta_media_status_rpt(adapter, psta, 0);
10395 		else
10396 			RTW_INFO("%s: psta is null\n", __func__);
10397 	}
10398 
10399 	if (0) {
10400 		RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
10401 		RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
10402 		RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
10403 		RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
10404 	}
10405 
10406 	pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10407 
10408 	RTW_PRINT("wakeup_reason: 0x%02x\n",
10409 		  pwrctl->wowlan_wake_reason);
10410 	#ifdef DBG_WAKEUP_REASON
10411 	_dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
10412 	#endif
10413 
10414 	rtw_hal_set_fw_wow_related_cmd(adapter, 0);
10415 
10416 	res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
10417 
10418 	if (res == _FALSE) {
10419 		RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
10420 		rtw_hal_force_enable_rxdma(adapter);
10421 	}
10422 
10423 	rtw_hal_gate_bb(adapter, _TRUE);
10424 
10425 	res = rtw_hal_pause_rx_dma(adapter);
10426 	if (res == _FAIL)
10427 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
10428 
10429 	/* clean HW pattern match */
10430 	rtw_hal_dl_pattern(adapter, 0);
10431 
10432 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
10433 	/* config RXFF boundary to original */
10434 	rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
10435 	#endif
10436 	rtw_hal_release_rx_dma(adapter);
10437 
10438 	#if defined(CONFIG_RTL8188E)
10439 	if (IS_HARDWARE_TYPE_8188E(adapter))
10440 		rtw_hal_enable_tx_report(adapter);
10441 	#endif
10442 
10443 	if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10444 		(pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
10445 		(pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
10446 		rtw_hal_get_aoac_rpt(adapter);
10447 		rtw_hal_update_sw_security_info(adapter);
10448 	}
10449 
10450 	rtw_hal_fw_dl(adapter, _FALSE);
10451 
10452 #ifdef CONFIG_GPIO_WAKEUP
10453 
10454 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10455 	rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10456 #else
10457 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10458 	if (pwrctl->is_high_active == 0)
10459 		rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10460 	else
10461 		rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10462 			GPIO_OUTPUT_LOW);
10463 #else
10464 	rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index
10465 		, pwrctl->wowlan_gpio_output_state);
10466 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n",
10467 		 __func__, pwrctl->wowlan_gpio_index,
10468 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10469 		 pwrctl->is_high_active ? "HIGI" : "LOW");
10470 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10471 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10472 #endif /* CONFIG_GPIO_WAKEUP */
10473 	if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10474 	    (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
10475 	    (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10476 	    (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
10477 
10478 		media_status_rpt = RT_MEDIA_CONNECT;
10479 		rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10480 				  (u8 *)&media_status_rpt);
10481 
10482 		if (psta != NULL) {
10483 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10484 			adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10485 			adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10486 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10487 			#endif
10488 			rtw_sta_media_status_rpt(adapter, psta, 1);
10489 		}
10490 	}
10491 	rtw_hal_gate_bb(adapter, _FALSE);
10492 }
10493 #endif /*CONFIG_WOWLAN*/
10494 
10495 #ifdef CONFIG_P2P_WOWLAN
rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter * adapter,u8 * pframe,u16 index,u8 tx_desc,u32 page_size,u8 * page_num,u32 * total_pkt_len,RSVDPAGE_LOC * rsvd_page_loc)10496 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
10497 	      u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
10498 				      RSVDPAGE_LOC *rsvd_page_loc)
10499 {
10500 	u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
10501 	u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
10502 	u8 CurtPktPageNum = 0;
10503 
10504 	/* P2P Beacon */
10505 	rsvd_page_loc->LocP2PBeacon = *page_num;
10506 	rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
10507 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10508 				 P2PBCNLength, _FALSE, _FALSE, _FALSE);
10509 
10510 #if 0
10511 	RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
10512 		__FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
10513 #endif
10514 
10515 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
10516 
10517 	*page_num += CurtPktPageNum;
10518 
10519 	index += (CurtPktPageNum * page_size);
10520 	RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
10521 
10522 	/* P2P Probe rsp */
10523 	rsvd_page_loc->LocP2PProbeRsp = *page_num;
10524 	rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
10525 				      &P2PProbeRspLength);
10526 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10527 				 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
10528 
10529 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",  */
10530 	/*	__FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
10531 
10532 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
10533 
10534 	*page_num += CurtPktPageNum;
10535 
10536 	index += (CurtPktPageNum * page_size);
10537 	RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
10538 
10539 	/* P2P nego rsp */
10540 	rsvd_page_loc->LocNegoRsp = *page_num;
10541 	rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
10542 				     &P2PNegoRspLength);
10543 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10544 				 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
10545 
10546 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
10547 	/*	__FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
10548 
10549 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
10550 
10551 	*page_num += CurtPktPageNum;
10552 
10553 	index += (CurtPktPageNum * page_size);
10554 	RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
10555 
10556 	/* P2P invite rsp */
10557 	rsvd_page_loc->LocInviteRsp = *page_num;
10558 	rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
10559 				       &P2PInviteRspLength);
10560 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10561 				 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
10562 
10563 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
10564 	/* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
10565 
10566 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
10567 
10568 	*page_num += CurtPktPageNum;
10569 
10570 	index += (CurtPktPageNum * page_size);
10571 	RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
10572 
10573 	/* P2P provision discovery rsp */
10574 	rsvd_page_loc->LocPDRsp = *page_num;
10575 	rtw_hal_construct_P2PProvisionDisRsp(adapter,
10576 					     &pframe[index], &P2PPDRspLength);
10577 
10578 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10579 				 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
10580 
10581 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
10582 	/*	__FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
10583 
10584 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
10585 
10586 	*page_num += CurtPktPageNum;
10587 
10588 	*total_pkt_len = index + P2PPDRspLength;
10589 	RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
10590 
10591 	index += (CurtPktPageNum * page_size);
10592 
10593 
10594 }
10595 #endif /* CONFIG_P2P_WOWLAN */
10596 
10597 #ifdef CONFIG_LPS_PG
10598 #ifndef DBG_LPSPG_INFO_DUMP
10599 #define DBG_LPSPG_INFO_DUMP 1
10600 #endif
10601 
10602 #include "hal_halmac.h"
10603 
10604 #ifdef CONFIG_RTL8822C
rtw_lps_pg_set_dpk_info_rsvd_page(_adapter * adapter)10605 static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
10606 {
10607 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10608 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10609 	struct dm_struct *dm = adapter_to_phydm(adapter);
10610 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
10611 	u8 *info = NULL;
10612 	u32 info_len;
10613 	int ret = _FAIL;
10614 
10615 	/* get length */
10616 	halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
10617 	if (!info_len) {
10618 		RTW_ERR("get %s length fail\n", cache->name);
10619 		goto exit;
10620 	}
10621 
10622 	/* allocate buf */
10623 	info = rtw_zmalloc(info_len);
10624 	if (!info) {
10625 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10626 		goto exit;
10627 	}
10628 
10629 	/* get content */
10630 	halrf_dpk_info_rsvd_page(dm, info, NULL);
10631 
10632 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
10633 
10634 		#if (DBG_LPSPG_INFO_DUMP >= 1)
10635 		RTW_INFO_DUMP(cache->name, info, info_len);
10636 		#endif
10637 
10638 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10639 		ret = !ret ? _SUCCESS : _FAIL;
10640 		if (ret != _SUCCESS) {
10641 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10642 			goto free_mem;
10643 		}
10644 
10645 		#if (DBG_LPSPG_INFO_DUMP >= 2)
10646 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10647 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10648 		#endif
10649 	}
10650 
10651 free_mem:
10652 	rtw_mfree(info, info_len);
10653 
10654 exit:
10655 	return ret;
10656 }
10657 
rtw_lps_pg_set_iqk_info_rsvd_page(_adapter * adapter)10658 static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
10659 {
10660 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10661 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10662 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10663 	struct dm_struct *dm = adapter_to_phydm(adapter);
10664 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
10665 	u8 *info = NULL;
10666 	u32 info_len = 0;
10667 	int ret = _FAIL;
10668 
10669 	if (hal_data->RegIQKFWOffload) {
10670 		rsvd_page_cache_free_data(cache);
10671 		ret = _SUCCESS;
10672 		goto exit;
10673 	}
10674 
10675 	/* get length */
10676 	halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
10677 	if (!info_len) {
10678 		RTW_ERR("get %s length fail\n", cache->name);
10679 		goto exit;
10680 	}
10681 
10682 	/* allocate buf */
10683 	info = rtw_zmalloc(info_len);
10684 	if (!info) {
10685 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10686 		goto exit;
10687 	}
10688 
10689 	/* get content */
10690 	halrf_iqk_info_rsvd_page(dm, info, NULL);
10691 
10692 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
10693 
10694 		#if (DBG_LPSPG_INFO_DUMP >= 1)
10695 		RTW_INFO_DUMP(cache->name, info, info_len);
10696 		#endif
10697 
10698 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10699 		ret = !ret ? _SUCCESS : _FAIL;
10700 		if (ret != _SUCCESS) {
10701 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10702 			goto free_mem;
10703 		}
10704 
10705 		#if (DBG_LPSPG_INFO_DUMP >= 2)
10706 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10707 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10708 		#endif
10709 	}
10710 
10711 free_mem:
10712 	rtw_mfree(info, info_len);
10713 
10714 exit:
10715 	return ret;
10716 }
10717 #endif /* CONFIG_RTL8822C */
10718 
rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv * dvobj,_adapter * ld_sta_iface,u8 * buf,u32 * buf_size)10719 static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size)
10720 {
10721 #define LPS_PG_INFO_RSVD_LEN	16
10722 
10723 	if (buf) {
10724 		_adapter *adapter = dvobj_get_primary_adapter(dvobj);
10725 		struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10726 		struct sta_info *psta;
10727 #ifdef CONFIG_MBSSID_CAM
10728 		u8 cam_id = INVALID_CAM_ID;
10729 #endif
10730 		u8 *psec_cam_id = buf + 8;
10731 		u8 sec_cam_num = 0;
10732 		u8 drv_rsvdpage_num = 0;
10733 
10734 		if (ld_sta_iface) {
10735 			psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv));
10736 			if (!psta) {
10737 				RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
10738 				rtw_warn_on(1);
10739 				goto size_chk;
10740 			}
10741 			/*Byte 0 - used macid*/
10742 			LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
10743 			RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
10744 		}
10745 
10746 #ifdef CONFIG_MBSSID_CAM
10747 		/*Byte 1 - used BSSID CAM entry*/
10748 		cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
10749 		if (cam_id != INVALID_CAM_ID)
10750 			LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
10751 		RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
10752 #endif
10753 
10754 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
10755 		/*Btye 2 - Max used Pattern Match CAM entry*/
10756 		if (pwrpriv->wowlan_mode == _TRUE
10757 			&& ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
10758 			LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
10759 			RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
10760 		}
10761 #endif
10762 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
10763 		/*Btye 3 - Max MU rate table Group ID*/
10764 		LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
10765 		RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
10766 #endif
10767 
10768 		/*Btye 8 ~15 - used Security CAM entry */
10769 		sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
10770 
10771 		/*Btye 4 - used Security CAM entry number*/
10772 		if (sec_cam_num < 8)
10773 			LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
10774 		RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
10775 
10776 		/*Btye 5 - Txbuf used page number for fw offload*/
10777 		if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
10778 			drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
10779 		else
10780 			drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
10781 		LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
10782 		RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
10783 	}
10784 
10785 size_chk:
10786 	if (buf_size)
10787 		*buf_size = LPS_PG_INFO_RSVD_LEN;
10788 }
10789 
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)10790 static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
10791 {
10792 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10793 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10794 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
10795 	u8 *info = NULL;
10796 	u32 info_len = 0;
10797 	int ret = _FAIL;
10798 
10799 	/* get length */
10800 	rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len);
10801 	if (!info_len) {
10802 		RTW_ERR("get %s length fail\n", cache->name);
10803 		goto exit;
10804 	}
10805 
10806 	/* allocate buf */
10807 	info = rtw_zmalloc(info_len);
10808 	if (!info) {
10809 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10810 		goto exit;
10811 	}
10812 
10813 	/* get content */
10814 	rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL);
10815 
10816 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
10817 
10818 		#if (DBG_LPSPG_INFO_DUMP >= 1)
10819 		RTW_INFO_DUMP(cache->name, info, info_len);
10820 		#endif
10821 
10822 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10823 		ret = !ret ? _SUCCESS : _FAIL;
10824 		if (ret != _SUCCESS) {
10825 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10826 			goto free_mem;
10827 		}
10828 
10829 		#if (DBG_LPSPG_INFO_DUMP >= 2)
10830 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10831 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10832 		#endif
10833 	}
10834 
10835 free_mem:
10836 	rtw_mfree(info, info_len);
10837 
10838 exit:
10839 	return ret;
10840 }
10841 
rtw_lps_pg_set_rsvd_page(_adapter * adapter,u8 * frame,u16 * index,u8 txdesc_size,u32 page_size,u8 * total_page_num,bool is_wow_mode,_adapter * ld_sta_iface,bool only_get_page_num)10842 static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
10843 	, u8 txdesc_size, u32 page_size, u8 *total_page_num
10844 	, bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num)
10845 {
10846 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10847 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10848 	struct rsvd_page_cache_t *cache;
10849 	bool rsvd = 1;
10850 	u8 *pos;
10851 	u32 len;
10852 
10853 	if (is_wow_mode) {
10854 		/* lps_level will not change when enter wow_mode */
10855 		if (pwrctl->lps_level != LPS_PG)
10856 			rsvd = 0;
10857 	} else {
10858 		if (!only_get_page_num && !ld_sta_iface)
10859 			rsvd = 0;
10860 	}
10861 
10862 	pos = only_get_page_num ? NULL : frame + *index;
10863 
10864 #ifdef CONFIG_RTL8822C
10865 	if (IS_8822C_SERIES(hal_data->version_id)) {
10866 		/* LPSPG_DPK_INFO */
10867 		cache = &pwrctl->lpspg_dpk_info;
10868 		if (rsvd) {
10869 			if (pwrctl->lps_level != LPS_PG)
10870 				pos = NULL;
10871 			len = 0;
10872 			halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10873 			#if (DBG_LPSPG_INFO_DUMP >= 1)
10874 			if (pos)
10875 				RTW_INFO_DUMP(cache->name, pos, len);
10876 			#endif
10877 			rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10878 			*total_page_num += cache->page_num;
10879 			*index += page_size * cache->page_num;
10880 			pos = only_get_page_num ? NULL : frame + *index;
10881 			RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10882 		} else
10883 			rsvd_page_cache_free(cache);
10884 
10885 		/* LPSPG_IQK_INFO */
10886 		cache = &pwrctl->lpspg_iqk_info;
10887 		if (rsvd
10888 			/* RegIQKFWOffload will not change when enter wow_mode */
10889 			&& !(is_wow_mode && hal_data->RegIQKFWOffload)
10890 		) {
10891 			if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
10892 				pos = NULL;
10893 			len = 0;
10894 			halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10895 			#if (DBG_LPSPG_INFO_DUMP >= 1)
10896 			if (pos)
10897 				RTW_INFO_DUMP(cache->name, pos, len);
10898 			#endif
10899 			rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10900 			*total_page_num += cache->page_num;
10901 			*index += page_size * cache->page_num;
10902 			pos = only_get_page_num ? NULL : frame + *index;
10903 			RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10904 		} else
10905 			rsvd_page_cache_free(cache);
10906 	}
10907 #endif
10908 
10909 	/* LPSPG_INFO */
10910 	cache = &pwrctl->lpspg_info;
10911 	if (rsvd) {
10912 		if (pwrctl->lps_level != LPS_PG)
10913 			pos = NULL;
10914 		rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len);
10915 		#if (DBG_LPSPG_INFO_DUMP >= 1)
10916 		if (pos)
10917 			RTW_INFO_DUMP(cache->name, pos, len);
10918 		#endif
10919 		rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10920 		*total_page_num += cache->page_num;
10921 		*index += page_size * cache->page_num;
10922 		pos = only_get_page_num ? NULL : frame + *index;
10923 		RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10924 	} else
10925 		rsvd_page_cache_free(cache);
10926 }
10927 
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)10928 u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
10929 {
10930 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10931 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10932 
10933 	u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
10934 	u8 ret = _FAIL;
10935 
10936 	if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
10937 		SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1);	/*SecurityCAM_En*/
10938 
10939 #ifdef CONFIG_MBSSID_CAM
10940 	SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1);		/*BSSIDCAM_En*/
10941 #endif
10942 
10943 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
10944 	if (pwrpriv->wowlan_mode == _TRUE &&
10945 	    check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
10946 
10947 		SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1);	/*PatternMatchCAM_En*/
10948 	}
10949 #endif
10950 
10951 #ifdef CONFIG_MACID_SEARCH
10952 	SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1);	/*MACIDSearch_En*/
10953 #endif
10954 
10955 #ifdef CONFIG_TX_SC
10956 	SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1);	/*TXSC_En*/
10957 #endif
10958 
10959 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
10960 	SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1);	/*MURateTable_En*/
10961 #endif
10962 
10963 	SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
10964 
10965 #ifdef CONFIG_RTL8822C
10966 	if (pwrpriv->bFwCurrentInPSMode == _FALSE) {
10967 		SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
10968 		if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
10969 			SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
10970 	} else {
10971 		SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0);
10972 		if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
10973 			SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0);
10974 	}
10975 #endif
10976 
10977 #if (DBG_LPSPG_INFO_DUMP >= 1)
10978 	RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
10979 #endif
10980 
10981 	ret = rtw_hal_fill_h2c_cmd(adapter,
10982 				   H2C_LPS_PG_INFO,
10983 				   H2C_LPS_PG_INFO_LEN,
10984 				   lpspg_info);
10985 	return ret;
10986 }
rtw_hal_set_lps_pg_info(_adapter * adapter)10987 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
10988 {
10989 	u8 ret = _FAIL;
10990 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10991 
10992 	if (pwrpriv->lpspg_info.loc == 0) {
10993 		RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
10994 		rtw_warn_on(1);
10995 		return ret;
10996 	}
10997 	#ifdef CONFIG_RTL8822C
10998 	rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
10999 	rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
11000 	#endif
11001 	rtw_hal_set_lps_pg_info_rsvd_page(adapter);
11002 
11003 	ret = rtw_hal_set_lps_pg_info_cmd(adapter);
11004 
11005 	return ret;
11006 }
11007 
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)11008 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
11009 {
11010 #if 0
11011 	if (sta->cmn.ra_info.rssi_level >= 4)
11012 		sta->lps_pg_rssi_lv = 3;	/*RSSI High - 1SS_VHT_MCS7*/
11013 	else if (sta->cmn.ra_info.rssi_level >=  2)
11014 		sta->lps_pg_rssi_lv = 2;	/*RSSI Middle - 1SS_VHT_MCS3*/
11015 	else
11016 		sta->lps_pg_rssi_lv = 1;	/*RSSI Lower - Lowest_rate*/
11017 #else
11018 	sta->lps_pg_rssi_lv = 0;
11019 #endif
11020 	RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
11021 		__func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
11022 }
11023 
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)11024 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
11025 {
11026 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
11027 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11028 	struct sta_priv *pstapriv = &adapter->stapriv;
11029 	struct sta_info *sta;
11030 
11031 	sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
11032 
11033 	switch (hdl_id) {
11034 	case LPS_PG_INFO_CFG:
11035 		rtw_hal_set_lps_pg_info(adapter);
11036 		break;
11037 	case LPS_PG_REDLEMEM:
11038 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11039 			break;
11040 
11041 		/*set xmit_block*/
11042 		rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11043 		if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
11044 			rtw_warn_on(1);
11045 		/*clearn xmit_block*/
11046 		rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11047 		break;
11048 	case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
11049 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11050 			break;
11051 
11052 		if (sta)
11053 			rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
11054 		break;
11055 	case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
11056 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11057 			break;
11058 
11059 		if (sta) {
11060 			rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
11061 			rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
11062 			sta->lps_pg_rssi_lv = 0;
11063 		}
11064 		break;
11065 
11066 	default:
11067 		break;
11068 	}
11069 }
11070 
11071 #endif /*CONFIG_LPS_PG*/
11072 
_rtw_mi_assoc_if_num(_adapter * adapter)11073 static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
11074 {
11075 	u8 mi_iface_num = 0;
11076 
11077 	if (0) {
11078 		RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
11079 		RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
11080 		RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11081 		RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
11082 		RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
11083 		/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
11084 		/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
11085 	}
11086 
11087 	mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
11088 		DEV_AP_NUM(adapter_to_dvobj(adapter)) +
11089 		DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11090 	return mi_iface_num;
11091 }
11092 #ifdef CONFIG_CONCURRENT_MODE
_rtw_search_sta_iface(_adapter * adapter)11093 static _adapter *_rtw_search_sta_iface(_adapter *adapter)
11094 {
11095 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11096 	_adapter *iface = NULL;
11097 	_adapter *sta_iface = NULL;
11098 	int i;
11099 
11100 	for (i = 0; i < dvobj->iface_nums; i++) {
11101 		iface = dvobj->padapters[i];
11102 		if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
11103 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11104 				sta_iface = iface;
11105 				break;
11106 			}
11107 		}
11108 	}
11109 	return sta_iface;
11110 }
11111 #if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
_rtw_search_ap_iface(_adapter * adapter)11112 static _adapter *_rtw_search_ap_iface(_adapter *adapter)
11113 {
11114 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11115 	_adapter *iface = NULL;
11116 	_adapter *ap_iface = NULL;
11117 	int i;
11118 
11119 	for (i = 0; i < dvobj->iface_nums; i++) {
11120 		iface = dvobj->padapters[i];
11121 		if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
11122 			ap_iface = iface;
11123 			break;
11124 		}
11125 	}
11126 	return ap_iface;
11127 }
11128 #endif/*CONFIG_AP_MODE*/
11129 #endif/*CONFIG_CONCURRENT_MODE*/
11130 
11131 #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
rtw_hal_set_pathb_phase(_adapter * adapter,u8 phase_idx)11132 void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
11133 {
11134 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(adapter);
11135 	struct PHY_DM_STRUCT		*pDM_Odm = &pHalData->odmpriv;
11136 
11137 	return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
11138 }
11139 #endif
11140 
11141 /*
11142  * Description: Fill the reserved packets that FW will use to RSVD page.
11143  *			Now we just send 4 types packet to rsvd page.
11144  *			(1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
11145  * Input:
11146  * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
11147  *		    so we need to set the packet length to total lengh.
11148  *	      TRUE: At the second time, we should send the first packet (default:beacon)
11149  *		    to Hw again and set the lengh in descriptor to the real beacon lengh.
11150  * page_num - The amount of reserved page which driver need.
11151  *	      If this is not NULL, this function doesn't real download reserved
11152  *	      page, but just count the number of reserved page.
11153  *
11154  * 2009.10.15 by tynli.
11155  * 2017.06.20 modified by Lucas.
11156  *
11157  * Page Size = 128: 8188e, 8723a/b, 8192c/d,
11158  * Page Size = 256: 8192e, 8821a
11159  * Page Size = 512: 8812a
11160  */
11161 
11162 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)11163 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
11164 {
11165 	PHAL_DATA_TYPE pHalData;
11166 	struct xmit_frame	*pcmdframe = NULL;
11167 	struct pkt_attrib	*pattrib;
11168 	struct xmit_priv	*pxmitpriv;
11169 	struct pwrctrl_priv *pwrctl;
11170 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11171 	u32	BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
11172 	u32	NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
11173 	u32	ProbeReqLength = 0, NullFunctionDataLength = 0;
11174 	u8	TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
11175 	u8	TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
11176 	u8	*ReservedPagePacket;
11177 	u16	BufIndex = 0;
11178 	u32	TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
11179 	RSVDPAGE_LOC	RsvdPageLoc;
11180 	struct registry_priv  *registry_par = &adapter->registrypriv;
11181 
11182 #ifdef DBG_FW_DEBUG_MSG_PKT
11183 	u32	fw_dbg_msg_pkt_len = 0;
11184 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11185 
11186 #ifdef DBG_CONFIG_ERROR_DETECT
11187 	struct sreset_priv *psrtpriv;
11188 #endif /* DBG_CONFIG_ERROR_DETECT */
11189 
11190 #ifdef CONFIG_MCC_MODE
11191 	u8 dl_mcc_page = _FAIL;
11192 #endif /* CONFIG_MCC_MODE */
11193 	u8 nr_assoc_if;
11194 
11195 	_adapter *sta_iface = NULL;
11196 	_adapter *ap_iface = NULL;
11197 
11198 	bool is_wow_mode = _FALSE;
11199 
11200 	pHalData = GET_HAL_DATA(adapter);
11201 #ifdef DBG_CONFIG_ERROR_DETECT
11202 	psrtpriv = &pHalData->srestpriv;
11203 #endif
11204 	pxmitpriv = &adapter->xmitpriv;
11205 	pwrctl = adapter_to_pwrctl(adapter);
11206 
11207 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
11208 
11209 	if (PageSize == 0) {
11210 		RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
11211 		return;
11212 	}
11213 	nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
11214 
11215 	if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
11216 		pwrctl->wowlan_ap_mode == _TRUE ||
11217 		pwrctl->wowlan_p2p_mode == _TRUE)
11218 		is_wow_mode = _TRUE;
11219 
11220 	/*page_num for init time to get rsvd page number*/
11221 	/* Prepare ReservedPagePacket */
11222 	if (page_num) {
11223 		ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
11224 		if (!ReservedPagePacket) {
11225 			RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11226 			*page_num = 0xFF;
11227 			return;
11228 		}
11229 		RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm  ==>\n",
11230 			FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11231 
11232 	} else {
11233 		if (is_wow_mode)
11234 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11235 		else
11236 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11237 
11238 		RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
11239 			FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
11240 
11241 		MaxRsvdPageBufSize = RsvdPageNum * PageSize;
11242 		if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
11243 			RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
11244 				 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
11245 			rtw_warn_on(1);
11246 			return;
11247 		}
11248 
11249 		pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
11250 		if (pcmdframe == NULL) {
11251 			RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11252 			return;
11253 		}
11254 
11255 		ReservedPagePacket = pcmdframe->buf_addr;
11256 	}
11257 
11258 	_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
11259 
11260 	BufIndex = TxDescOffset;
11261 
11262 	/*======== beacon content =======*/
11263 	rtw_hal_construct_beacon(adapter,
11264 				 &ReservedPagePacket[BufIndex], &BeaconLength);
11265 
11266 	/*
11267 	* When we count the first page size, we need to reserve description size for the RSVD
11268 	* packet, it will be filled in front of the packet in TXPKTBUF.
11269 	*/
11270 	BeaconLength = MAX_BEACON_LEN - TxDescLen;
11271 	CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
11272 
11273 #ifdef CONFIG_FW_HANDLE_TXBCN
11274 	CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
11275 #endif
11276 	TotalPageNum += CurtPktPageNum;
11277 
11278 	BufIndex += (CurtPktPageNum * PageSize);
11279 
11280 	RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11281 
11282 	/*======== probe response content ========*/
11283 	if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
11284 		#ifdef CONFIG_CONCURRENT_MODE
11285 		if (nr_assoc_if >= 2)
11286 			RTW_ERR("Not support > 2 net-interface in WOW\n");
11287 		#endif
11288 		/* (4) probe response*/
11289 		RsvdPageLoc.LocProbeRsp = TotalPageNum;
11290 		rtw_hal_construct_ProbeRsp(
11291 			adapter, &ReservedPagePacket[BufIndex],
11292 			&ProbeRspLength,
11293 			_FALSE);
11294 		rtw_hal_fill_fake_txdesc(adapter,
11295 				 &ReservedPagePacket[BufIndex - TxDescLen],
11296 				 ProbeRspLength, _FALSE, _FALSE, _FALSE);
11297 
11298 		CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
11299 		TotalPageNum += CurtPktPageNum;
11300 		TotalPacketLen = BufIndex + ProbeRspLength;
11301 		BufIndex += (CurtPktPageNum * PageSize);
11302 		RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11303 		goto download_page;
11304 	}
11305 
11306 	/*======== ps-poll content * 1 page ========*/
11307 	sta_iface = adapter;
11308 	#ifdef CONFIG_CONCURRENT_MODE
11309 	if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
11310 		sta_iface = _rtw_search_sta_iface(adapter);
11311 		RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
11312 	}
11313 	#endif
11314 
11315 	if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11316 		RsvdPageLoc.LocPsPoll = TotalPageNum;
11317 		RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
11318 		rtw_hal_construct_PSPoll(sta_iface,
11319 					 &ReservedPagePacket[BufIndex], &PSPollLength);
11320 		rtw_hal_fill_fake_txdesc(sta_iface,
11321 					 &ReservedPagePacket[BufIndex - TxDescLen],
11322 					 PSPollLength, _TRUE, _FALSE, _FALSE);
11323 
11324 		CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
11325 
11326 		TotalPageNum += CurtPktPageNum;
11327 
11328 		BufIndex += (CurtPktPageNum * PageSize);
11329 		RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11330 	}
11331 
11332 #ifdef CONFIG_MCC_MODE
11333 	/*======== MCC * n page ======== */
11334 	if (MCC_EN(adapter)) {/*Normal mode*/
11335 		dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
11336 				&BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
11337 	} else {
11338 		dl_mcc_page = _FAIL;
11339 	}
11340 
11341 	if (dl_mcc_page == _FAIL)
11342 #endif /* CONFIG_MCC_MODE */
11343 	{	/*======== null data * 1 page ======== */
11344 		if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11345 			RsvdPageLoc.LocNullData = TotalPageNum;
11346 			RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
11347 			rtw_hal_construct_NullFunctionData(
11348 				sta_iface,
11349 				&ReservedPagePacket[BufIndex],
11350 				&NullDataLength,
11351 				_FALSE, 0, 0, _FALSE);
11352 			rtw_hal_fill_fake_txdesc(sta_iface,
11353 				 &ReservedPagePacket[BufIndex - TxDescLen],
11354 				 NullDataLength, _FALSE, _FALSE, _FALSE);
11355 
11356 			CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
11357 
11358 			TotalPageNum += CurtPktPageNum;
11359 
11360 			BufIndex += (CurtPktPageNum * PageSize);
11361 			RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11362 		}
11363 	}
11364 
11365 	/*======== Qos null data * 1 page ======== */
11366 	if (pwrctl->wowlan_mode == _FALSE ||
11367 		pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11368 		if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11369 			RsvdPageLoc.LocQosNull = TotalPageNum;
11370 			RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
11371 			rtw_hal_construct_NullFunctionData(sta_iface,
11372 						&ReservedPagePacket[BufIndex],
11373 						&QosNullLength,
11374 						_TRUE, 0, 0, _FALSE);
11375 			rtw_hal_fill_fake_txdesc(sta_iface,
11376 					 &ReservedPagePacket[BufIndex - TxDescLen],
11377 					 QosNullLength, _FALSE, _FALSE, _FALSE);
11378 
11379 			CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
11380 						     PageSize);
11381 
11382 			TotalPageNum += CurtPktPageNum;
11383 
11384 			BufIndex += (CurtPktPageNum * PageSize);
11385 			RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11386 		}
11387 	}
11388 
11389 #ifdef CONFIG_BT_COEXIST
11390 	/*======== BT Qos null data * 1 page ======== */
11391 	if (pwrctl->wowlan_mode == _FALSE ||
11392 		pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11393 
11394 		ap_iface = adapter;
11395 		#ifdef CONFIG_CONCURRENT_MODE
11396 		if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) {	/*DEV_AP_STARTING_NUM*/
11397 			ap_iface = _rtw_search_ap_iface(adapter);
11398 			RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
11399 		}
11400 		#endif
11401 
11402 		if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
11403 			RsvdPageLoc.LocBTQosNull = TotalPageNum;
11404 
11405 			RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
11406 
11407 			rtw_hal_construct_NullFunctionData(ap_iface,
11408 						&ReservedPagePacket[BufIndex],
11409 						&BTQosNullLength,
11410 						_TRUE, 0, 0, _FALSE);
11411 
11412 			rtw_hal_fill_fake_txdesc(ap_iface,
11413 					&ReservedPagePacket[BufIndex - TxDescLen],
11414 					BTQosNullLength, _FALSE, _TRUE, _FALSE);
11415 
11416 			CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
11417 							 PageSize);
11418 
11419 			TotalPageNum += CurtPktPageNum;
11420 			BufIndex += (CurtPktPageNum * PageSize);
11421 
11422 			RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11423 		}
11424 	}
11425 #endif /* CONFIG_BT_COEXIT */
11426 
11427 	TotalPacketLen = BufIndex;
11428 
11429 #ifdef DBG_FW_DEBUG_MSG_PKT
11430 		/*======== FW DEBUG MSG * n page ======== */
11431 		RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
11432 		RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
11433 		rtw_hal_construct_fw_dbg_msg_pkt(
11434 			adapter,
11435 			&ReservedPagePacket[BufIndex],
11436 			&fw_dbg_msg_pkt_len);
11437 
11438 		rtw_hal_fill_fake_txdesc(adapter,
11439 				 &ReservedPagePacket[BufIndex - TxDescLen],
11440 				 fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
11441 
11442 		CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
11443 
11444 		if (CurtPktPageNum < 2)
11445 			CurtPktPageNum = 2; /*Need at least 2 rsvd page*/
11446 		TotalPageNum += CurtPktPageNum;
11447 
11448 		TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
11449 		BufIndex += (CurtPktPageNum * PageSize);
11450 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11451 
11452 #ifdef CONFIG_LPS_PG
11453 	rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
11454 		, TxDescLen, PageSize, &TotalPageNum, is_wow_mode
11455 		, (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL
11456 		, page_num ? 1 : 0
11457 	);
11458 	TotalPacketLen = BufIndex;
11459 #endif
11460 
11461 #ifdef CONFIG_WOWLAN
11462 	/*======== WOW * n page ======== */
11463 	if (pwrctl->wowlan_mode == _TRUE &&
11464 		pwrctl->wowlan_in_resume == _FALSE &&
11465 		check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {/*WOW mode*/
11466 		rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11467 					     BufIndex, TxDescLen, PageSize,
11468 			     &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11469 	}
11470 #endif /* CONFIG_WOWLAN */
11471 
11472 #ifdef CONFIG_P2P_WOWLAN
11473 	/*======== P2P WOW * n page ======== */
11474 	if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
11475 		rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11476 						 BufIndex, TxDescLen, PageSize,
11477 				 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11478 	}
11479 #endif /* CONFIG_P2P_WOWLAN */
11480 
11481 	/*Note:  BufIndex already add a TxDescOffset offset in first Beacon page
11482 	* The "TotalPacketLen" is calculate by BufIndex.
11483 	* We need to decrease TxDescOffset before doing length check. by yiwei
11484 	*/
11485 	TotalPacketLen = TotalPacketLen - TxDescOffset;
11486 
11487 download_page:
11488 	if (page_num) {
11489 		*page_num = TotalPageNum;
11490 		rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
11491 		ReservedPagePacket = NULL;
11492 		RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
11493 			FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11494 		return;
11495 	}
11496 
11497 	/* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
11498 	RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
11499 		 __func__, TotalPageNum, TotalPacketLen);
11500 
11501 	if (TotalPacketLen > MaxRsvdPageBufSize) {
11502 		RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
11503 			 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
11504 		rtw_warn_on(1);
11505 		goto error;
11506 	} else {
11507 		/* update attribute */
11508 		pattrib = &pcmdframe->attrib;
11509 		update_mgntframe_attrib(adapter, pattrib);
11510 		pattrib->qsel = QSLT_BEACON;
11511 		pattrib->pktlen = TotalPacketLen;
11512 		pattrib->last_txcmdsz = TotalPacketLen;
11513 #ifdef CONFIG_PCI_HCI
11514 		dump_mgntframe(adapter, pcmdframe);
11515 #else
11516 		dump_mgntframe_and_wait(adapter, pcmdframe, 100);
11517 #endif
11518 	}
11519 
11520 	RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
11521 		 __func__, TotalPacketLen, TotalPageNum);
11522 #ifdef DBG_DUMP_SET_RSVD_PAGE
11523 	RTW_INFO(" ==================================================\n");
11524 	RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
11525 	RTW_INFO(" ==================================================\n");
11526 #endif
11527 
11528 
11529 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
11530 		|| MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
11531 		rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
11532 #ifdef DBG_FW_DEBUG_MSG_PKT
11533 		rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
11534 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11535 #ifdef CONFIG_WOWLAN
11536 		if (pwrctl->wowlan_mode == _TRUE &&
11537 			pwrctl->wowlan_in_resume == _FALSE)
11538 			rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11539 #endif /* CONFIG_WOWLAN */
11540 #ifdef CONFIG_AP_WOWLAN
11541 		if (pwrctl->wowlan_ap_mode == _TRUE)
11542 			rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
11543 #endif /* CONFIG_AP_WOWLAN */
11544 	} else if (pwrctl->wowlan_pno_enable) {
11545 #ifdef CONFIG_PNO_SUPPORT
11546 		rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11547 		if (pwrctl->wowlan_in_resume)
11548 			rtw_hal_set_scan_offload_info_cmd(adapter,
11549 							  &RsvdPageLoc, 0);
11550 		else
11551 			rtw_hal_set_scan_offload_info_cmd(adapter,
11552 							  &RsvdPageLoc, 1);
11553 #endif /* CONFIG_PNO_SUPPORT */
11554 	}
11555 
11556 #ifdef CONFIG_P2P_WOWLAN
11557 	if (_TRUE == pwrctl->wowlan_p2p_mode)
11558 		rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
11559 #endif /* CONFIG_P2P_WOWLAN */
11560 
11561 	return;
11562 error:
11563 	rtw_free_xmitframe(pxmitpriv, pcmdframe);
11564 }
11565 
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)11566 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
11567 {
11568 	if (finished)
11569 		rtw_mi_tx_beacon_hdl(adapter);
11570 	else
11571 		_rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
11572 }
11573 
11574 /**
11575  * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
11576  * @adapter:	struct _ADAPTER*
11577  *
11578  * Caculate needed reserved page number.
11579  * In different state would get different number, for example normal mode and
11580  * WOW mode would need different reserved page size.
11581  *
11582  * Return the number of reserved page which driver need.
11583  */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)11584 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
11585 {
11586 	u8 num = 0;
11587 
11588 
11589 	_rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
11590 
11591 	return num;
11592 }
11593 
11594 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
hw_var_set_bcn_func(_adapter * adapter,u8 enable)11595 static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
11596 {
11597 	u32 bcn_ctrl_reg;
11598 
11599 #ifdef CONFIG_CONCURRENT_MODE
11600 	if (adapter->hw_port == HW_PORT1)
11601 		bcn_ctrl_reg = REG_BCN_CTRL_1;
11602 	else
11603 #endif
11604 		bcn_ctrl_reg = REG_BCN_CTRL;
11605 
11606 	if (enable)
11607 		rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
11608 	else {
11609 		u8 val8;
11610 
11611 		val8 = rtw_read8(adapter, bcn_ctrl_reg);
11612 		val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
11613 
11614 #ifdef CONFIG_BT_COEXIST
11615 		if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
11616 			/* Always enable port0 beacon function for PSTDMA */
11617 			if (REG_BCN_CTRL == bcn_ctrl_reg)
11618 				val8 |= EN_BCN_FUNCTION;
11619 		}
11620 #endif
11621 
11622 		rtw_write8(adapter, bcn_ctrl_reg, val8);
11623 	}
11624 
11625 #ifdef CONFIG_RTL8192F
11626 	if (IS_HARDWARE_TYPE_8192F(adapter)) {
11627 		u16 val16, val16_ori;
11628 
11629 		val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
11630 
11631 		#ifdef CONFIG_CONCURRENT_MODE
11632 		if (adapter->hw_port == HW_PORT1) {
11633 			if (enable)
11634 				val16 |= EN_PORT_1_FUNCTION;
11635 			else
11636 				val16 &= ~EN_PORT_1_FUNCTION;
11637 		} else
11638 		#endif
11639 		{
11640 			if (enable)
11641 				val16 |= EN_PORT_0_FUNCTION;
11642 			else
11643 				val16 &= ~EN_PORT_0_FUNCTION;
11644 
11645 			#ifdef CONFIG_BT_COEXIST
11646 			if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
11647 				val16 |= EN_PORT_0_FUNCTION;
11648 			#endif
11649 		}
11650 
11651 		if (val16 != val16_ori)
11652 			rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1,  val16);
11653 	}
11654 #endif
11655 }
11656 #endif
11657 
11658 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
hw_var_set_mlme_disconnect(_adapter * adapter)11659 static void hw_var_set_mlme_disconnect(_adapter *adapter)
11660 {
11661 	u8 val8;
11662 
11663 	/* reject all data frames */
11664 #ifdef CONFIG_CONCURRENT_MODE
11665 	if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11666 #endif
11667 		rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
11668 
11669 #ifdef CONFIG_CONCURRENT_MODE
11670 	if (adapter->hw_port == HW_PORT1) {
11671 		/* reset TSF1 */
11672 		rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
11673 
11674 		/* disable update TSF1 */
11675 		rtw_iface_disable_tsf_update(adapter);
11676 
11677 		if (!IS_HARDWARE_TYPE_8723D(adapter)
11678 			&& !IS_HARDWARE_TYPE_8192F(adapter)
11679 			&& !IS_HARDWARE_TYPE_8710B(adapter)
11680 		) {
11681 			/* disable Port1's beacon function */
11682 			val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
11683 			val8 &= ~EN_BCN_FUNCTION;
11684 			rtw_write8(adapter, REG_BCN_CTRL_1, val8);
11685 		}
11686 	} else
11687 #endif
11688 	{
11689 		/* reset TSF */
11690 		rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
11691 
11692 		/* disable update TSF */
11693 		rtw_iface_disable_tsf_update(adapter);
11694 	}
11695 }
11696 #endif
11697 
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 enable)11698 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
11699 {
11700 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11701 	u16 value_rxfltmap2;
11702 
11703 #ifdef DBG_IFACE_STATUS
11704 	DBG_IFACE_STATUS_DUMP(adapter);
11705 #endif
11706 
11707 #ifdef CONFIG_FIND_BEST_CHANNEL
11708 	/* Receive all data frames */
11709 	value_rxfltmap2 = 0xFFFF;
11710 #else
11711 	/* not to receive data frame */
11712 	value_rxfltmap2 = 0;
11713 #endif
11714 
11715 	if (enable) { /* under sitesurvey */
11716 		/*
11717 		* 1. configure REG_RXFLTMAP2
11718 		* 2. disable TSF update &  buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
11719 		* 3. config RCR to receive different BSSID BCN or probe rsp
11720 		*/
11721 		rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
11722 
11723 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
11724 
11725 		/* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
11726 		#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11727 		hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
11728 		hal_data->RegRRSR &= 0x000FFFFF;
11729 		#endif
11730 
11731 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11732 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11733 			/* set 718[1:0]=2'b00 to avoid BF scan hang */
11734 			hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
11735 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
11736 		}
11737 		#endif
11738 
11739 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11740 			StopTxBeacon(adapter);
11741 	} else { /* sitesurvey done */
11742 		/*
11743 		* 1. enable rx data frame
11744 		* 2. config RCR not to receive different BSSID BCN or probe rsp
11745 		* 3. doesn't enable TSF update &  buddy TSF right now to avoid HW conflict
11746 		*	 so, we enable TSF update when rx first BCN after sitesurvey done
11747 		*/
11748 		if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) {
11749 			/* enable to rx data frame */
11750 			rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11751 		}
11752 
11753 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
11754 
11755 		/* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
11756 		#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11757 			rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
11758 		#endif
11759 
11760 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11761 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11762 			/* Restore orignal 0x718 setting*/
11763 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
11764 		}
11765 		#endif
11766 
11767 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11768 			ResumeTxBeacon(adapter);
11769 			rtw_mi_tx_beacon_hdl(adapter);
11770 		}
11771 	}
11772 }
11773 
11774 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
hw_var_set_mlme_join(_adapter * adapter,u8 type)11775 static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
11776 {
11777 	u8 val8;
11778 	u16 val16;
11779 	u32 val32;
11780 	u8 RetryLimit = RL_VAL_STA;
11781 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11782 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11783 
11784 #ifdef CONFIG_CONCURRENT_MODE
11785 	if (type == 0) {
11786 		/* prepare to join */
11787 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11788 			StopTxBeacon(adapter);
11789 
11790 		/* enable to rx data frame.Accept all data frame */
11791 		rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11792 
11793 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11794 			RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11795 		else /* Ad-hoc Mode */
11796 			RetryLimit = RL_VAL_AP;
11797 
11798 		rtw_iface_enable_tsf_update(adapter);
11799 
11800 	} else if (type == 1) {
11801 		/* joinbss_event call back when join res < 0 */
11802 		if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11803 			rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11804 
11805 		rtw_iface_disable_tsf_update(adapter);
11806 
11807 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11808 			ResumeTxBeacon(adapter);
11809 
11810 			/* reset TSF 1/2 after ResumeTxBeacon */
11811 			rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11812 		}
11813 
11814 	} else if (type == 2) {
11815 		/* sta add event call back */
11816 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
11817 			/* fixed beacon issue for 8191su........... */
11818 			rtw_write8(adapter, 0x542 , 0x02);
11819 			RetryLimit = RL_VAL_AP;
11820 		}
11821 
11822 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11823 			ResumeTxBeacon(adapter);
11824 
11825 			/* reset TSF 1/2 after ResumeTxBeacon */
11826 			rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11827 		}
11828 	}
11829 
11830 	val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11831 	rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11832 #else /* !CONFIG_CONCURRENT_MODE */
11833 	if (type == 0) { /* prepare to join */
11834 		/* enable to rx data frame.Accept all data frame */
11835 		rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11836 
11837 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11838 			RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11839 		else /* Ad-hoc Mode */
11840 			RetryLimit = RL_VAL_AP;
11841 
11842 		rtw_iface_enable_tsf_update(adapter);
11843 
11844 	} else if (type == 1) { /* joinbss_event call back when join res < 0 */
11845 		rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11846 
11847 		rtw_iface_disable_tsf_update(adapter);
11848 
11849 	} else if (type == 2) { /* sta add event call back */
11850 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
11851 			RetryLimit = RL_VAL_AP;
11852 	}
11853 
11854 	val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11855 	rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11856 #endif /* !CONFIG_CONCURRENT_MODE */
11857 }
11858 #endif
11859 
11860 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)11861 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
11862 {
11863 	u8 buf[2];
11864 	int ret;
11865 
11866 	if (reset_port == HW_PORT0) {
11867 		buf[0] = 0x1;
11868 		buf[1] = 0;
11869 	} else {
11870 		buf[0] = 0x0;
11871 		buf[1] = 0x1;
11872 	}
11873 
11874 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
11875 
11876 	return ret;
11877 }
11878 
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)11879 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
11880 {
11881 	u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
11882 	u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
11883 				REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
11884 	int ret;
11885 
11886 	/* site survey will cause reset tsf fail */
11887 	rtw_mi_buddy_scan_abort(adapter, _FALSE);
11888 	reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
11889 	ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
11890 	if (ret != _SUCCESS)
11891 		return ret;
11892 
11893 	while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
11894 		rtw_msleep_os(100);
11895 		loop_cnt++;
11896 		reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
11897 	}
11898 
11899 	return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
11900 }
11901 #endif /* CONFIG_TSF_RESET_OFFLOAD */
11902 
11903 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
11904 #ifdef CONFIG_HW_P0_TSF_SYNC
11905 #ifdef CONFIG_CONCURRENT_MODE
hw_port0_tsf_sync_sel(_adapter * adapter,u8 benable,u8 hw_port,u16 tr_offset)11906 static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
11907 {
11908 	u8 val8;
11909 	u8 client_id = 0;
11910 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11911 
11912 #ifdef CONFIG_MCC_MODE
11913 	if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
11914 		RTW_INFO("[MCC] do not set HW TSF sync\n");
11915 		return;
11916 	}
11917 #endif
11918 	/* check if port0 is already synced */
11919 	if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
11920 		RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
11921 			FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
11922 		return;
11923 	}
11924 
11925 	/* check if port0 already disable sync */
11926 	if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
11927 		RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
11928 		return;
11929 	}
11930 
11931 	/* check if port0 sync to port0 */
11932 	if (benable && hw_port == HW_PORT0) {
11933 		RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
11934 		rtw_warn_on(1);
11935 		return;
11936 	}
11937 
11938 	/*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
11939 	/*	Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
11940 		Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
11941 
11942 	val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
11943 
11944 	if (benable) {
11945 		/*Disable Port0's beacon function*/
11946 		rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
11947 
11948 		/*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
11949 		if (tr_offset)
11950 			rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
11951 
11952 		/*reg 0x577[6]=1*/	/*auto sync by tbtt*/
11953 		rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
11954 
11955 		if (HW_PORT1 == hw_port)
11956 			client_id = 0;
11957 		else if (HW_PORT2 == hw_port)
11958 			client_id = 1;
11959 		else if (HW_PORT3 == hw_port)
11960 			client_id = 2;
11961 		else if (HW_PORT4 == hw_port)
11962 			client_id = 3;
11963 
11964 		val8 &= 0x8F;
11965 		val8 |= (BIT(6) | (client_id << 4));
11966 
11967 		dvobj->p0_tsf.sync_port = hw_port;
11968 		dvobj->p0_tsf.offset = tr_offset;
11969 		rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
11970 
11971 		/*Enable Port0's beacon function*/
11972 		rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)  | BIT_EN_BCN_FUNCTION);
11973 		RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
11974 	} else {
11975 		val8 &= ~BIT(6);
11976 
11977 		dvobj->p0_tsf.sync_port = MAX_HW_PORT;
11978 		dvobj->p0_tsf.offset = 0;
11979 		rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
11980 		RTW_INFO("%s P0 TSF sync disable\n", __func__);
11981 	}
11982 }
_search_ld_sta(_adapter * adapter,u8 include_self)11983 static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
11984 {
11985 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11986 	u8 i;
11987 	_adapter *iface = NULL;
11988 
11989 	if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
11990 		RTW_ERR("STA_LD_NUM == 0\n");
11991 		rtw_warn_on(1);
11992 	}
11993 
11994 	for (i = 0; i < dvobj->iface_nums; i++) {
11995 		iface = dvobj->padapters[i];
11996 		if (!iface)
11997 			continue;
11998 		if (include_self == _FALSE && adapter == iface)
11999 			continue;
12000 		if (is_client_associated_to_ap(iface))
12001 			break;
12002 	}
12003 	if (iface)
12004 		RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
12005 	return iface;
12006 }
12007 #endif /*CONFIG_CONCURRENT_MODE*/
12008 /*Correct port0's TSF*/
12009 /*#define DBG_P0_TSF_SYNC*/
hw_var_set_correct_tsf(PADAPTER adapter,u8 mlme_state)12010 void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
12011 {
12012 #ifdef CONFIG_CONCURRENT_MODE
12013 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12014 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12015 	_adapter *sta_if = NULL;
12016 	u8 hw_port;
12017 
12018 	RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
12019 	#ifdef DBG_P0_TSF_SYNC
12020 	RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
12021 	RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
12022 	RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
12023 	if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12024 		RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
12025 	else
12026 		RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12027 	RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12028 	#endif
12029 	switch (mlme_state) {
12030 		case MLME_STA_CONNECTED :
12031 			{
12032 				hw_port = rtw_hal_get_port(adapter);
12033 
12034 				if (!MLME_IS_STA(adapter)) {
12035 					RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12036 					rtw_warn_on(1);
12037 				}
12038 
12039 				if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
12040 					RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
12041 					rtw_warn_on(1);
12042 					hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12043 				}
12044 
12045 				if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12046 					(rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
12047 					hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12048 					#ifdef DBG_P0_TSF_SYNC
12049 					RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
12050 					#endif
12051 				}
12052 			}
12053 			break;
12054 		case MLME_STA_DISCONNECTED :
12055 			{
12056 				hw_port = rtw_hal_get_port(adapter);
12057 
12058 				if (!MLME_IS_STA(adapter)) {
12059 					RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12060 					rtw_warn_on(1);
12061 				}
12062 
12063 				if (dvobj->p0_tsf.sync_port == hw_port) {
12064 					if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
12065 						/* search next appropriate sta*/
12066 						sta_if = _search_ld_sta(adapter, _FALSE);
12067 						if (sta_if) {
12068 							hw_port = rtw_hal_get_port(sta_if);
12069 							hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12070 							#ifdef DBG_P0_TSF_SYNC
12071 							RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
12072 							#endif
12073 						}
12074 					} else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
12075 						hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12076 						#ifdef DBG_P0_TSF_SYNC
12077 						RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
12078 						#endif
12079 					}
12080 				}
12081 			}
12082 			break;
12083 		case MLME_AP_STARTED :
12084 		case MLME_MESH_STARTED :
12085 			{
12086 				if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12087 					RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12088 					rtw_warn_on(1);
12089 				}
12090 
12091 				if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12092 					rtw_mi_get_assoced_sta_num(adapter)) {
12093 					/* get port of sta */
12094 					sta_if = _search_ld_sta(adapter, _FALSE);
12095 					if (sta_if) {
12096 						hw_port = rtw_hal_get_port(sta_if);
12097 						hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12098 						#ifdef DBG_P0_TSF_SYNC
12099 						RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
12100 						#endif
12101 					}
12102 				}
12103 			}
12104 			break;
12105 		case MLME_AP_STOPPED :
12106 		case MLME_MESH_STOPPED :
12107 			{
12108 				if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12109 					RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12110 					rtw_warn_on(1);
12111 				}
12112 				/*stop ap mode*/
12113 				if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
12114 					(dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
12115 					hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12116 					#ifdef DBG_P0_TSF_SYNC
12117 					RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
12118 					#endif
12119 				}
12120 			}
12121 			break;
12122 		default :
12123 			RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
12124 			break;
12125 	}
12126 
12127 	/*#ifdef DBG_P0_TSF_SYNC*/
12128 	#if 1
12129 	if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12130 		RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
12131 	else
12132 		RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12133 	RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12134 	#endif
12135 #endif /*CONFIG_CONCURRENT_MODE*/
12136 }
12137 
12138 #else /*! CONFIG_HW_P0_TSF_SYNC*/
12139 
12140 #ifdef CONFIG_MI_WITH_MBSSID_CAM
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12141 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12142 {
12143 	/*do nothing*/
12144 }
12145 #else /* !CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)12146 static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
12147 {
12148 	if (hw_port == HW_PORT0) {
12149 		/*disable related TSF function*/
12150 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
12151 #if defined(CONFIG_RTL8192F)
12152 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12153 					REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
12154 #endif
12155 
12156 		rtw_write32(padapter, REG_TSFTR, tsf);
12157 		rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
12158 
12159 		/*enable related TSF function*/
12160 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
12161 #if defined(CONFIG_RTL8192F)
12162 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12163 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
12164 #endif
12165 	} else if (hw_port == HW_PORT1) {
12166 		/*disable related TSF function*/
12167 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
12168 #if defined(CONFIG_RTL8192F)
12169 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12170 					REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
12171 #endif
12172 
12173 		rtw_write32(padapter, REG_TSFTR1, tsf);
12174 		rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
12175 
12176 		/*enable related TSF function*/
12177 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
12178 #if defined(CONFIG_RTL8192F)
12179 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12180 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
12181 #endif
12182 	} else
12183 		RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
12184 }
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12185 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12186 {
12187 	u64 tsf;
12188 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
12189 	struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
12190 
12191 	tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
12192 
12193 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12194 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12195 		StopTxBeacon(adapter);
12196 
12197 	rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
12198 
12199 #ifdef CONFIG_CONCURRENT_MODE
12200 	/* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
12201 	if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
12202 		&& (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12203 	) {
12204 		struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12205 		int i;
12206 		_adapter *iface;
12207 
12208 		for (i = 0; i < dvobj->iface_nums; i++) {
12209 			iface = dvobj->padapters[i];
12210 			if (!iface)
12211 				continue;
12212 			if (iface == adapter)
12213 				continue;
12214 
12215 			if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
12216 				&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
12217 			) {
12218 				rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
12219 				#ifdef CONFIG_TSF_RESET_OFFLOAD
12220 				if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
12221 					RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
12222 						, __func__, ADPT_ARG(iface), iface->hw_port);
12223 				#endif	/* CONFIG_TSF_RESET_OFFLOAD*/
12224 			}
12225 		}
12226 	}
12227 #endif /* CONFIG_CONCURRENT_MODE */
12228 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12229 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12230 		ResumeTxBeacon(adapter);
12231 }
12232 #endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
12233 #endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
12234 #endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
12235 
rtw_hal_get_tsftr_by_port(_adapter * adapter,u8 port)12236 u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
12237 {
12238 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
12239 	u64 tsftr = 0;
12240 
12241 	if (port >= hal_spec->port_num) {
12242 		RTW_ERR("%s invalid port(%d) \n", __func__, port);
12243 		goto exit;
12244 	}
12245 
12246 	switch (rtw_get_chip_type(adapter)) {
12247 #if defined(CONFIG_RTL8814B)
12248 	case RTL8814B:
12249 	{
12250 		u8 val8;
12251 
12252 		/* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
12253 		val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
12254 		val8 &= ~0x70;
12255 		val8 |= port << 4;
12256 		rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
12257 
12258 		tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
12259 		tsftr = tsftr << 32;
12260 		tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
12261 
12262 		break;
12263 	}
12264 #endif
12265 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
12266 	case RTL8814A:
12267 	case RTL8822B:
12268 	case RTL8821C:
12269 	case RTL8822C:
12270 	{
12271 		u8 val8;
12272 
12273 		/* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
12274 		val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
12275 		val8 &= 0x8F;
12276 		val8 |= port << 4;
12277 		rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
12278 
12279 		tsftr = rtw_read32(adapter, REG_TSFTR + 4);
12280 		tsftr = tsftr << 32;
12281 		tsftr |= rtw_read32(adapter, REG_TSFTR);
12282 
12283 		break;
12284 	}
12285 #endif
12286 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
12287 		|| defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
12288 		|| defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
12289 		|| defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
12290 		|| defined(CONFIG_RTL8710B)
12291 	case RTL8188E:
12292 	case RTL8188F:
12293 	case RTL8188GTV:
12294 	case RTL8192E:
12295 	case RTL8192F:
12296 	case RTL8723B:
12297 	case RTL8703B:
12298 	case RTL8723D:
12299 	case RTL8812:
12300 	case RTL8821:
12301 	case RTL8710B:
12302 	{
12303 		u32 addr;
12304 
12305 		if (port == HW_PORT0)
12306 			addr = REG_TSFTR;
12307 		else if (port == HW_PORT1)
12308 			addr = REG_TSFTR1;
12309 		else {
12310 			RTW_ERR("%s unknown port(%d) \n", __func__, port);
12311 			goto exit;
12312 		}
12313 
12314 		tsftr = rtw_read32(adapter, addr + 4);
12315 		tsftr = tsftr << 32;
12316 		tsftr |= rtw_read32(adapter, addr);
12317 
12318 		break;
12319 	}
12320 #endif
12321 	default:
12322 		RTW_ERR("%s unknow chip type\n", __func__);
12323 	}
12324 
12325 exit:
12326 	return tsftr;
12327 }
12328 
12329 #ifdef CONFIG_TDLS
12330 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)12331 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
12332 {
12333 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
12334 	u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
12335 
12336 
12337 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
12338 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
12339 	switch (bwmode) {
12340 	case CHANNEL_WIDTH_40:
12341 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
12342 		break;
12343 	case CHANNEL_WIDTH_80:
12344 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
12345 		break;
12346 	case CHANNEL_WIDTH_20:
12347 	default:
12348 		break;
12349 	}
12350 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
12351 
12352 	return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
12353 }
12354 #endif
12355 #endif
12356 
12357 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)12358 void rtw_hal_update_uapsd_tid(_adapter *adapter)
12359 {
12360 	struct mlme_priv		*pmlmepriv = &adapter->mlmepriv;
12361 	struct qos_priv		*pqospriv = &pmlmepriv->qospriv;
12362 
12363 	/* write complement of pqospriv->uapsd_tid to mac register 0x693 because
12364 	    it's designed  for "0" represents "enable" and "1" represents "disable" */
12365 	rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
12366 }
12367 #endif /* CONFIG_WMMPS_STA */
12368 
12369 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
12370 /* For multi-port support, driver needs to inform the port ID to FW for btc operations */
rtw_hal_set_wifi_btc_port_id_cmd(_adapter * adapter)12371 s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
12372 {
12373 	u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
12374 	u8 hw_port = rtw_hal_get_port(adapter);
12375 
12376 	SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
12377 	RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
12378 	return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
12379 }
12380 #endif
12381 
12382 #define LPS_ACTIVE_TIMEOUT	50 /*number of times*/
rtw_lps_state_chk(_adapter * adapter,u8 ps_mode)12383 void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
12384 {
12385 	struct pwrctrl_priv 		*pwrpriv = adapter_to_pwrctl(adapter);
12386 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
12387 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12388 	struct sta_priv		*pstapriv = &adapter->stapriv;
12389 	struct sta_info		*psta = NULL;
12390 	u8 ps_ready = _FALSE;
12391 	s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
12392 
12393 	if (ps_mode == PS_MODE_ACTIVE) {
12394 #ifdef CONFIG_LPS_ACK
12395 		if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
12396 			if (pwrpriv->lps_ack_status > 0) {
12397 				psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
12398 				if (psta != NULL) {
12399 					if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
12400 						RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
12401 				}
12402 			}
12403 		} else {
12404 			RTW_WARN("LPS sctx query timeout, operation abort!!\n");
12405 			return;
12406 		}
12407 		pwrpriv->lps_ack_status = -1;
12408 #else
12409 		do {
12410 			if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
12411 				ps_ready = _TRUE;
12412 				break;
12413 			}
12414 			rtw_msleep_os(1);
12415 		} while (leave_wait_count--);
12416 
12417 		if (ps_ready == _FALSE) {
12418 			RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
12419 			return;
12420 		}
12421 #endif /* CONFIG_LPS_ACK */
12422 		}
12423 	}
12424 
rtw_var_set_basic_rate(PADAPTER padapter,u8 * val)12425 void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
12426 
12427 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
12428 	struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
12429 	u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
12430 	u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
12431 	u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
12432 	#if CONFIG_IEEE80211_BAND_5GHZ
12433 	u16 rrsr_5g_force_mask = (RRSR_6M);
12434 	u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
12435 	#endif
12436 	u32 temp_RRSR;
12437 
12438 	HalSetBrateCfg(padapter, val, &BrateCfg);
12439 	input_b = BrateCfg;
12440 
12441 	/* apply force and allow mask */
12442 	#if CONFIG_IEEE80211_BAND_5GHZ
12443 	if (pHalData->current_band_type != BAND_ON_2_4G) {
12444 		BrateCfg |= rrsr_5g_force_mask;
12445 		BrateCfg &= rrsr_5g_allow_mask;
12446 	} else
12447 	#endif
12448 	{ /* 2.4G */
12449 		BrateCfg |= rrsr_2g_force_mask;
12450 		BrateCfg &= rrsr_2g_allow_mask;
12451 	}
12452 	masked = BrateCfg;
12453 
12454 #ifdef CONFIG_CMCC_TEST
12455 	BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
12456 	BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
12457 #endif
12458 
12459 	/* IOT consideration */
12460 	if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
12461 		/* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
12462 		if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
12463 			BrateCfg |= RRSR_6M;
12464 	}
12465 		ioted = BrateCfg;
12466 
12467 #ifdef CONFIG_NARROWBAND_SUPPORTING
12468 	if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
12469 		|| (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
12470 		BrateCfg &= ~RRSR_CCK_RATES;
12471 		BrateCfg |= RRSR_6M;
12472 	}
12473 #endif
12474 	pHalData->BasicRateSet = BrateCfg;
12475 
12476 	RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
12477 
12478 	/* Set RRSR rate table. */
12479 		temp_RRSR = rtw_read32(padapter, REG_RRSR);
12480 		temp_RRSR &=0xFFFF0000;
12481 		temp_RRSR |=BrateCfg;
12482 		rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
12483 
12484 	rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
12485 
12486 	#if defined(CONFIG_RTL8188E)
12487 	rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
12488 	#endif
12489 }
12490 
SetHwReg(_adapter * adapter,u8 variable,u8 * val)12491 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
12492 {
12493 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12494 	u8 ret = _SUCCESS;
12495 
12496 	switch (variable) {
12497 	case HW_VAR_MEDIA_STATUS: {
12498 		u8 net_type = *((u8 *)val);
12499 
12500 		rtw_hal_set_msr(adapter, net_type);
12501 	}
12502 	break;
12503 	case HW_VAR_DO_IQK:
12504 		if (*val)
12505 			hal_data->bNeedIQK = _TRUE;
12506 		else
12507 			hal_data->bNeedIQK = _FALSE;
12508 		break;
12509 	case HW_VAR_MAC_ADDR:
12510 #ifdef CONFIG_MI_WITH_MBSSID_CAM
12511 		rtw_hal_set_macaddr_mbid(adapter, val);
12512 #else
12513 		rtw_hal_set_macaddr_port(adapter, val);
12514 #endif
12515 		break;
12516 	case HW_VAR_BSSID:
12517 		rtw_hal_set_bssid(adapter, val);
12518 		break;
12519 	case HW_VAR_RCR:
12520 		ret = hw_var_rcr_config(adapter, *((u32 *)val));
12521 		break;
12522 	case HW_VAR_ON_RCR_AM:
12523 		hw_var_set_rcr_am(adapter, 1);
12524 		break;
12525 	case HW_VAR_OFF_RCR_AM:
12526 		hw_var_set_rcr_am(adapter, 0);
12527 		break;
12528 	case HW_VAR_BEACON_INTERVAL:
12529 		hw_var_set_bcn_interval(adapter, *(u16 *)val);
12530 		break;
12531 #ifdef CONFIG_MBSSID_CAM
12532 	case HW_VAR_MBSSID_CAM_WRITE: {
12533 		u32	cmd = 0;
12534 		u32	*cam_val = (u32 *)val;
12535 
12536 		rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
12537 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
12538 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12539 	}
12540 		break;
12541 	case HW_VAR_MBSSID_CAM_CLEAR: {
12542 		u32 cmd;
12543 		u8 entry_id = *(u8 *)val;
12544 
12545 		rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
12546 
12547 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
12548 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12549 	}
12550 		break;
12551 	case HW_VAR_RCR_MBSSID_EN:
12552 		if (*((u8 *)val))
12553 			rtw_hal_rcr_add(adapter, RCR_ENMBID);
12554 		else
12555 			rtw_hal_rcr_clear(adapter, RCR_ENMBID);
12556 		break;
12557 #endif
12558 	case HW_VAR_PORT_SWITCH:
12559 		hw_var_port_switch(adapter);
12560 		break;
12561 	case HW_VAR_INIT_RTS_RATE: {
12562 		u16 brate_cfg = *((u16 *)val);
12563 		u8 rate_index = 0;
12564 		HAL_VERSION *hal_ver = &hal_data->version_id;
12565 
12566 		if (IS_8188E(*hal_ver)) {
12567 
12568 			while (brate_cfg > 0x1) {
12569 				brate_cfg = (brate_cfg >> 1);
12570 				rate_index++;
12571 			}
12572 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
12573 		} else
12574 			rtw_warn_on(1);
12575 	}
12576 		break;
12577 	case HW_VAR_SEC_CFG: {
12578 		u16 reg_scr_ori;
12579 		u16 reg_scr;
12580 
12581 		reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
12582 		reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
12583 
12584 		if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
12585 			reg_scr |= SCR_CHK_BMC;
12586 
12587 		if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
12588 			reg_scr |= SCR_NoSKMC;
12589 
12590 		if (reg_scr != reg_scr_ori)
12591 			rtw_write16(adapter, REG_SECCFG, reg_scr);
12592 	}
12593 		break;
12594 	case HW_VAR_SEC_DK_CFG: {
12595 		struct security_priv *sec = &adapter->securitypriv;
12596 		u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
12597 
12598 		if (val) { /* Enable default key related setting */
12599 			reg_scr |= SCR_TXBCUSEDK;
12600 			if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
12601 				reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
12602 		} else /* Disable default key related setting */
12603 			reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
12604 
12605 		rtw_write8(adapter, REG_SECCFG, reg_scr);
12606 	}
12607 		break;
12608 
12609 	case HW_VAR_ASIX_IOT:
12610 		/* enable  ASIX IOT function */
12611 		if (*((u8 *)val) == _TRUE) {
12612 			/* 0xa2e[0]=0 (disable rake receiver) */
12613 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12614 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
12615 			/* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
12616 			rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
12617 		} else {
12618 			/* restore reg:0xa2e,   reg:0xa1c */
12619 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12620 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
12621 			rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
12622 		}
12623 		break;
12624 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
12625 	case HW_VAR_WOWLAN: {
12626 		struct wowlan_ioctl_param *poidparam;
12627 
12628 		poidparam = (struct wowlan_ioctl_param *)val;
12629 		switch (poidparam->subcode) {
12630 #ifdef CONFIG_WOWLAN
12631 		case WOWLAN_PATTERN_CLEAN:
12632 			rtw_hal_dl_pattern(adapter, 2);
12633 			break;
12634 		case WOWLAN_ENABLE:
12635 			rtw_hal_wow_enable(adapter);
12636 			break;
12637 		case WOWLAN_DISABLE:
12638 			rtw_hal_wow_disable(adapter);
12639 			break;
12640 #endif /*CONFIG_WOWLAN*/
12641 #ifdef CONFIG_AP_WOWLAN
12642 		case WOWLAN_AP_ENABLE:
12643 			rtw_hal_ap_wow_enable(adapter);
12644 			break;
12645 		case WOWLAN_AP_DISABLE:
12646 			rtw_hal_ap_wow_disable(adapter);
12647 			break;
12648 #endif /*CONFIG_AP_WOWLAN*/
12649 		default:
12650 			break;
12651 		}
12652 	}
12653 		break;
12654 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
12655 
12656 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
12657 	case HW_VAR_BCN_FUNC:
12658 		hw_var_set_bcn_func(adapter, *val);
12659 		break;
12660 #endif
12661 
12662 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
12663 	case HW_VAR_MLME_DISCONNECT:
12664 		hw_var_set_mlme_disconnect(adapter);
12665 		break;
12666 #endif
12667 
12668 	case HW_VAR_MLME_SITESURVEY:
12669 		hw_var_set_mlme_sitesurvey(adapter, *val);
12670 		#ifdef CONFIG_BT_COEXIST
12671 		if (hal_data->EEPROMBluetoothCoexist == 1)
12672 			rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
12673 		#endif
12674 		break;
12675 
12676 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
12677 	case HW_VAR_MLME_JOIN:
12678 		hw_var_set_mlme_join(adapter, *val);
12679 		break;
12680 #endif
12681 
12682 	case HW_VAR_EN_HW_UPDATE_TSF:
12683 		rtw_hal_set_hw_update_tsf(adapter);
12684 		break;
12685 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12686 	case HW_VAR_CORRECT_TSF:
12687 		hw_var_set_correct_tsf(adapter, *val);
12688 		break;
12689 #endif
12690 
12691 #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
12692 	case HW_VAR_TSF_AUTO_SYNC:
12693 		if (*val == _TRUE)
12694 			hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
12695 		else
12696 			hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
12697 		break;
12698 #endif
12699 	case HW_VAR_APFM_ON_MAC:
12700 		hal_data->bMacPwrCtrlOn = *val;
12701 		RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
12702 		break;
12703 #ifdef CONFIG_WMMPS_STA
12704 	case  HW_VAR_UAPSD_TID:
12705 		rtw_hal_update_uapsd_tid(adapter);
12706 		break;
12707 #endif /* CONFIG_WMMPS_STA */
12708 #ifdef CONFIG_LPS_PG
12709 	case HW_VAR_LPS_PG_HANDLE:
12710 		rtw_hal_lps_pg_handler(adapter, *val);
12711 		break;
12712 #endif
12713 #ifdef CONFIG_LPS_LCLK_WD_TIMER
12714 	case HW_VAR_DM_IN_LPS_LCLK:
12715 		rtw_phydm_wd_lps_lclk_hdl(adapter);
12716 		break;
12717 #endif
12718 	case HW_VAR_ENABLE_RX_BAR:
12719 		if (*val == _TRUE) {
12720 			/* enable RX BAR */
12721 			u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12722 
12723 			val16 |= BIT(8);
12724 			rtw_write16(adapter, REG_RXFLTMAP1, val16);
12725 		} else {
12726 			/* disable RX BAR */
12727 			u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12728 
12729 			val16 &= (~BIT(8));
12730 			rtw_write16(adapter, REG_RXFLTMAP1, val16);
12731 		}
12732 		RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
12733 			REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
12734 		break;
12735 	case HW_VAR_HCI_SUS_STATE:
12736 		hal_data->hci_sus_state = *(u8 *)val;
12737 		RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
12738 		break;
12739 #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
12740 		case HW_VAR_BCN_HEAD_SEL:
12741 		{
12742 			u8 vap_id = *(u8 *)val;
12743 
12744 			if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
12745 				RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
12746 				rtw_warn_on(1);
12747 			}
12748 			if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
12749 				u16 drv_pg_bndy = 0, bcn_addr = 0;
12750 				u32 page_size = 0;
12751 
12752 				/*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
12753 				rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
12754 				rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
12755 
12756 				if (vap_id != 0xFF)
12757 					bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
12758 				else
12759 					bcn_addr = drv_pg_bndy;
12760 				RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
12761 					ADPT_ARG(adapter), vap_id, bcn_addr);
12762 				rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
12763 					(bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
12764 			}
12765 		}
12766 		break;
12767 #endif
12768 	case HW_VAR_LPS_STATE_CHK :
12769 		rtw_lps_state_chk(adapter, *(u8 *)val);
12770 		break;
12771 
12772 #ifdef CONFIG_RTS_FULL_BW
12773 	case HW_VAR_SET_RTS_BW:
12774 	{
12775 		#ifdef RTW_HALMAC
12776 			rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
12777 		#else
12778 			u8 temp;
12779 			if(*val)
12780 				temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
12781 			else
12782 				temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
12783 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
12784 			/*RTW_INFO("HW_VAR_SET_RTS_BW	val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
12785 		#endif
12786 	}
12787 	break;
12788 #endif/*CONFIG_RTS_FULL_BW*/
12789 #if defined(CONFIG_PCI_HCI)
12790 	case HW_VAR_ENSWBCN:
12791 	if (*val == _TRUE) {
12792 		rtw_write8(adapter, REG_CR + 1,
12793 			   rtw_read8(adapter, REG_CR + 1) | BIT(0));
12794 	} else
12795 		rtw_write8(adapter, REG_CR + 1,
12796 			   rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
12797 	break;
12798 #endif
12799 	default:
12800 		if (0)
12801 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12802 				  FUNC_ADPT_ARG(adapter), variable);
12803 		ret = _FAIL;
12804 		break;
12805 	}
12806 
12807 	return ret;
12808 }
12809 
GetHwReg(_adapter * adapter,u8 variable,u8 * val)12810 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
12811 {
12812 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12813 	u64 val64;
12814 
12815 
12816 	switch (variable) {
12817 	case HW_VAR_MAC_ADDR:
12818 		#ifndef CONFIG_MI_WITH_MBSSID_CAM
12819 		rtw_hal_get_macaddr_port(adapter, val);
12820 		#endif
12821 		break;
12822 	case HW_VAR_BASIC_RATE:
12823 		*((u16 *)val) = hal_data->BasicRateSet;
12824 		break;
12825 	case HW_VAR_MEDIA_STATUS:
12826 		rtw_hal_get_msr(adapter, val);
12827 		break;
12828 	case HW_VAR_DO_IQK:
12829 		*val = hal_data->bNeedIQK;
12830 		break;
12831 	case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
12832 		if (hal_is_band_support(adapter, BAND_ON_5G))
12833 			*val = _TRUE;
12834 		else
12835 			*val = _FALSE;
12836 		break;
12837 	case HW_VAR_APFM_ON_MAC:
12838 		*val = hal_data->bMacPwrCtrlOn;
12839 		break;
12840 	case HW_VAR_RCR:
12841 		hw_var_rcr_get(adapter, (u32 *)val);
12842 		break;
12843 	case HW_VAR_FWLPS_RF_ON:
12844 		/* When we halt NIC, we should check if FW LPS is leave. */
12845 		if (rtw_is_surprise_removed(adapter)
12846 			|| (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
12847 		) {
12848 			/*
12849 			 * If it is in HW/SW Radio OFF or IPS state,
12850 			 * we do not check Fw LPS Leave,
12851 			 * because Fw is unload.
12852 			 */
12853 			*val = _TRUE;
12854 		} else {
12855 			u32 rcr = 0;
12856 
12857 			rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
12858 			if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
12859 				*val = _FALSE;
12860 			else
12861 				*val = _TRUE;
12862 		}
12863 		break;
12864 
12865 	case HW_VAR_HCI_SUS_STATE:
12866 		*((u8 *)val) = hal_data->hci_sus_state;
12867 		break;
12868 
12869 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
12870 	case HW_VAR_BCN_CTRL_ADDR:
12871 		*((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
12872 		break;
12873 #endif
12874 
12875 #ifdef CONFIG_WAPI_SUPPORT
12876 	case HW_VAR_CAM_EMPTY_ENTRY: {
12877 		u8	ucIndex = *((u8 *)val);
12878 		u8	i;
12879 		u32	ulCommand = 0;
12880 		u32	ulContent = 0;
12881 		u32	ulEncAlgo = CAM_AES;
12882 
12883 		for (i = 0; i < CAM_CONTENT_COUNT; i++) {
12884 			/* filled id in CAM config 2 byte */
12885 			if (i == 0)
12886 				ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
12887 			else
12888 				ulContent = 0;
12889 			/* polling bit, and No Write enable, and address */
12890 			ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
12891 			ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
12892 			/* write content 0 is equall to mark invalid */
12893 			rtw_write32(adapter, REG_CAMWRITE, ulContent);  /* delay_ms(40); */
12894 			rtw_write32(adapter, REG_CAMCMD, ulCommand);  /* delay_ms(40); */
12895 		}
12896 	}
12897 #endif
12898 
12899 	default:
12900 		if (0)
12901 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12902 				  FUNC_ADPT_ARG(adapter), variable);
12903 		break;
12904 	}
12905 
12906 }
12907 
_get_page_size(struct _ADAPTER * a)12908 static u32 _get_page_size(struct _ADAPTER *a)
12909 {
12910 #ifdef RTW_HALMAC
12911 	struct dvobj_priv *d;
12912 	u32 size = 0;
12913 	int err = 0;
12914 
12915 
12916 	d = adapter_to_dvobj(a);
12917 
12918 	err = rtw_halmac_get_page_size(d, &size);
12919 	if (!err)
12920 		return size;
12921 
12922 	RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
12923 		 FUNC_ADPT_ARG(a), err);
12924 #endif /* RTW_HALMAC */
12925 
12926 	return PAGE_SIZE_128;
12927 }
12928 
12929 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)12930 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
12931 {
12932 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12933 	u8 bResult = _SUCCESS;
12934 
12935 	switch (variable) {
12936 
12937 	case HAL_DEF_DBG_DUMP_RXPKT:
12938 		hal_data->bDumpRxPkt = *((u8 *)value);
12939 		break;
12940 	case HAL_DEF_DBG_DUMP_TXPKT:
12941 		hal_data->bDumpTxPkt = *((u8 *)value);
12942 		break;
12943 	case HAL_DEF_ANT_DETECT:
12944 		hal_data->AntDetection = *((u8 *)value);
12945 		break;
12946 	default:
12947 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
12948 		bResult = _FAIL;
12949 		break;
12950 	}
12951 
12952 	return bResult;
12953 }
12954 
12955 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)12956 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
12957 {
12958 	struct registry_priv	*pregistrypriv = &adapter->registrypriv;
12959 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12960 
12961 	if ((pregistrypriv->beamformer_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter) || IS_HARDWARE_TYPE_8821C(adapter)))
12962 		return pregistrypriv->beamformer_rf_num;
12963 	else if (IS_HARDWARE_TYPE_8814AE(adapter)
12964 #if 0
12965 #if defined(CONFIG_USB_HCI)
12966 		|| (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2))  /* for USB3.0 */
12967 #endif
12968 #endif
12969 		) {
12970 		/*BF cap provided by Yu Chen, Sean, 2015, 01 */
12971 		if (hal_data->rf_type == RF_3T3R)
12972 			return 2;
12973 		else if (hal_data->rf_type == RF_4T4R)
12974 			return 3;
12975 		else
12976 			return 1;
12977 	} else
12978 		return 1;
12979 
12980 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)12981 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
12982 {
12983 	struct registry_priv		*pregistrypriv = &adapter->registrypriv;
12984 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
12985 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12986 
12987 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12988 
12989 	if ((pregistrypriv->beamformee_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter) || IS_HARDWARE_TYPE_8821C(adapter)))
12990 		return pregistrypriv->beamformee_rf_num;
12991 	else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
12992 		if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
12993 			return 2;
12994 		else
12995 			return 2;/*TODO: May be 3 in the future, by ChenYu. */
12996 	} else
12997 		return 1;
12998 
12999 }
13000 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_hal_beamforming_config_csirate(PADAPTER adapter)13001 void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
13002 {
13003 	struct dm_struct *p_dm_odm;
13004 	struct beamforming_info *bf_info;
13005 	u8 fix_rate_enable = 0;
13006 	u8 new_csi_rate_idx;
13007 	u8 rrsr_54_en;
13008 	u32 temp_rrsr;
13009 
13010 	/* Acting as BFee */
13011 	if (IS_BEAMFORMEE(adapter)) {
13012 	#if 0
13013 		/* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
13014 		if (IS_HARDWARE_TYPE_8821C(Adapter))
13015 			FixRateEnable = 1;	/* Support after 8821C */
13016 	#endif
13017 
13018 		p_dm_odm = adapter_to_phydm(adapter);
13019 		bf_info = GET_BEAMFORM_INFO(adapter);
13020 
13021 		rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
13022 				p_dm_odm->rssi_min,
13023 				bf_info->cur_csi_rpt_rate,
13024 				fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
13025 
13026 		temp_rrsr = rtw_read32(adapter, REG_RRSR);
13027 		if (rrsr_54_en == 1)
13028 			temp_rrsr |= RRSR_54M;
13029 		else if (rrsr_54_en == 0)
13030 			temp_rrsr &= ~RRSR_54M;
13031 		rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
13032 
13033 		if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
13034 			bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
13035 	}
13036 }
13037 #endif
13038 #endif
13039 
13040 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13041 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13042 {
13043 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13044 	u8 bResult = _SUCCESS;
13045 
13046 	switch (variable) {
13047 	case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
13048 		struct mlme_priv *pmlmepriv;
13049 		struct sta_priv *pstapriv;
13050 		struct sta_info *psta;
13051 
13052 		pmlmepriv = &adapter->mlmepriv;
13053 		pstapriv = &adapter->stapriv;
13054 		psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
13055 		if (psta)
13056 			*((int *)value) = psta->cmn.rssi_stat.rssi;
13057 	}
13058 	break;
13059 	case HAL_DEF_DBG_DUMP_RXPKT:
13060 		*((u8 *)value) = hal_data->bDumpRxPkt;
13061 		break;
13062 	case HAL_DEF_DBG_DUMP_TXPKT:
13063 		*((u8 *)value) = hal_data->bDumpTxPkt;
13064 		break;
13065 	case HAL_DEF_ANT_DETECT:
13066 		*((u8 *)value) = hal_data->AntDetection;
13067 		break;
13068 	case HAL_DEF_TX_PAGE_SIZE:
13069 		*((u32 *)value) = _get_page_size(adapter);
13070 		break;
13071 	case HAL_DEF_TX_STBC:
13072 		#ifdef CONFIG_ALPHA_SMART_ANTENNA
13073 		*(u8 *)value = 0;
13074 		#else
13075 		*(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
13076 		#endif
13077 		break;
13078 	case HAL_DEF_EXPLICIT_BEAMFORMER:
13079 	case HAL_DEF_EXPLICIT_BEAMFORMEE:
13080 	case HAL_DEF_VHT_MU_BEAMFORMER:
13081 	case HAL_DEF_VHT_MU_BEAMFORMEE:
13082 		*(u8 *)value = _FALSE;
13083 		break;
13084 #ifdef CONFIG_BEAMFORMING
13085 	case HAL_DEF_BEAMFORMER_CAP:
13086 		*(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
13087 		break;
13088 	case HAL_DEF_BEAMFORMEE_CAP:
13089 		*(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
13090 		break;
13091 #endif
13092 	default:
13093 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
13094 		bResult = _FAIL;
13095 		break;
13096 	}
13097 
13098 	return bResult;
13099 }
13100 
13101 /*
13102  *	Description:
13103  *		Translate a character to hex digit.
13104  *   */
13105 u32
MapCharToHexDigit(char chTmp)13106 MapCharToHexDigit(
13107 			char		chTmp
13108 )
13109 {
13110 	if (chTmp >= '0' && chTmp <= '9')
13111 		return chTmp - '0';
13112 	else if (chTmp >= 'a' && chTmp <= 'f')
13113 		return 10 + (chTmp - 'a');
13114 	else if (chTmp >= 'A' && chTmp <= 'F')
13115 		return 10 + (chTmp - 'A');
13116 	else
13117 		return 0;
13118 }
13119 
13120 
13121 
13122 /*
13123  *	Description:
13124  *		Parse hex number from the string pucStr.
13125  *   */
13126 BOOLEAN
GetHexValueFromString(char * szStr,u32 * pu4bVal,u32 * pu4bMove)13127 GetHexValueFromString(
13128 		char			*szStr,
13129 		u32			*pu4bVal,
13130 		u32			*pu4bMove
13131 )
13132 {
13133 	char		*szScan = szStr;
13134 
13135 	/* Check input parameter. */
13136 	if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
13137 		RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
13138 		return _FALSE;
13139 	}
13140 
13141 	/* Initialize output. */
13142 	*pu4bMove = 0;
13143 	*pu4bVal = 0;
13144 
13145 	/* Skip leading space. */
13146 	while (*szScan != '\0' &&
13147 	       (*szScan == ' ' || *szScan == '\t')) {
13148 		szScan++;
13149 		(*pu4bMove)++;
13150 	}
13151 
13152 	/* Skip leading '0x' or '0X'. */
13153 	if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
13154 		szScan += 2;
13155 		(*pu4bMove) += 2;
13156 	}
13157 
13158 	/* Check if szScan is now pointer to a character for hex digit, */
13159 	/* if not, it means this is not a valid hex number. */
13160 	if (!IsHexDigit(*szScan))
13161 		return _FALSE;
13162 
13163 	/* Parse each digit. */
13164 	do {
13165 		(*pu4bVal) <<= 4;
13166 		*pu4bVal += MapCharToHexDigit(*szScan);
13167 
13168 		szScan++;
13169 		(*pu4bMove)++;
13170 	} while (IsHexDigit(*szScan));
13171 
13172 	return _TRUE;
13173 }
13174 
13175 BOOLEAN
GetFractionValueFromString(char * szStr,u8 * pInteger,u8 * pFraction,u32 * pu4bMove)13176 GetFractionValueFromString(
13177 		char			*szStr,
13178 		u8				*pInteger,
13179 		u8				*pFraction,
13180 		u32			*pu4bMove
13181 )
13182 {
13183 	char	*szScan = szStr;
13184 
13185 	/* Initialize output. */
13186 	*pu4bMove = 0;
13187 	*pInteger = 0;
13188 	*pFraction = 0;
13189 
13190 	/* Skip leading space. */
13191 	while (*szScan != '\0' &&	(*szScan == ' ' || *szScan == '\t')) {
13192 		++szScan;
13193 		++(*pu4bMove);
13194 	}
13195 
13196 	if (*szScan < '0' || *szScan > '9')
13197 		return _FALSE;
13198 
13199 	/* Parse each digit. */
13200 	do {
13201 		(*pInteger) *= 10;
13202 		*pInteger += (*szScan - '0');
13203 
13204 		++szScan;
13205 		++(*pu4bMove);
13206 
13207 		if (*szScan == '.') {
13208 			++szScan;
13209 			++(*pu4bMove);
13210 
13211 			if (*szScan < '0' || *szScan > '9')
13212 				return _FALSE;
13213 
13214 			*pFraction += (*szScan - '0') * 10;
13215 			++szScan;
13216 			++(*pu4bMove);
13217 
13218 			if (*szScan >= '0' && *szScan <= '9') {
13219 				*pFraction += *szScan - '0';
13220 				++szScan;
13221 				++(*pu4bMove);
13222 			}
13223 			return _TRUE;
13224 		}
13225 	} while (*szScan >= '0' && *szScan <= '9');
13226 
13227 	return _TRUE;
13228 }
13229 
13230 /*
13231  *	Description:
13232  * Return TRUE if szStr is comment out with leading " */ /* ".
13233  *   */
13234 BOOLEAN
IsCommentString(char * szStr)13235 IsCommentString(
13236 		char			*szStr
13237 )
13238 {
13239 	if (*szStr == '/' && *(szStr + 1) == '/')
13240 		return _TRUE;
13241 	else
13242 		return _FALSE;
13243 }
13244 
13245 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)13246 GetU1ByteIntegerFromStringInDecimal(
13247 		char	*Str,
13248 		u8		*pInt
13249 )
13250 {
13251 	u16 i = 0;
13252 	*pInt = 0;
13253 
13254 	while (Str[i] != '\0') {
13255 		if (Str[i] >= '0' && Str[i] <= '9') {
13256 			*pInt *= 10;
13257 			*pInt += (Str[i] - '0');
13258 		} else
13259 			return _FALSE;
13260 		++i;
13261 	}
13262 
13263 	return _TRUE;
13264 }
13265 
13266 /* <20121004, Kordan> For example,
13267  * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
13268  * If RightQualifier does not exist, it will hang on in the while loop */
13269 BOOLEAN
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)13270 ParseQualifiedString(
13271 			char	*In,
13272 			u32	*Start,
13273 			char	*Out,
13274 			char		LeftQualifier,
13275 			char		RightQualifier
13276 )
13277 {
13278 	u32	i = 0, j = 0;
13279 	char	c = In[(*Start)++];
13280 
13281 	if (c != LeftQualifier)
13282 		return _FALSE;
13283 
13284 	i = (*Start);
13285 	c = In[(*Start)++];
13286 	while (c != RightQualifier && c != '\0')
13287 		c = In[(*Start)++];
13288 
13289 	if (c == '\0')
13290 		return _FALSE;
13291 
13292 	j = (*Start) - 2;
13293 	strncpy((char *)Out, (const char *)(In + i), j - i + 1);
13294 
13295 	return _TRUE;
13296 }
13297 
13298 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)13299 isAllSpaceOrTab(
13300 	u8	*data,
13301 	u8	size
13302 )
13303 {
13304 	u8	cnt = 0, NumOfSpaceAndTab = 0;
13305 
13306 	while (size > cnt) {
13307 		if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
13308 			++NumOfSpaceAndTab;
13309 
13310 		++cnt;
13311 	}
13312 
13313 	return size == NumOfSpaceAndTab;
13314 }
13315 
13316 
rtw_hal_check_rxfifo_full(_adapter * adapter)13317 void rtw_hal_check_rxfifo_full(_adapter *adapter)
13318 {
13319 	struct dvobj_priv *psdpriv = adapter->dvobj;
13320 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
13321 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
13322 	struct registry_priv *regsty = &adapter->registrypriv;
13323 	int save_cnt = _FALSE;
13324 
13325 	if (regsty->check_hw_status == 1) {
13326 		/* switch counter to RX fifo */
13327 		if (IS_8188E(pHalData->version_id) ||
13328 		    IS_8188F(pHalData->version_id) ||
13329 		    IS_8188GTV(pHalData->version_id) ||
13330 		    IS_8812_SERIES(pHalData->version_id) ||
13331 		    IS_8821_SERIES(pHalData->version_id) ||
13332 		    IS_8723B_SERIES(pHalData->version_id) ||
13333 		    IS_8192E(pHalData->version_id) ||
13334 		    IS_8703B_SERIES(pHalData->version_id) ||
13335 		    IS_8723D_SERIES(pHalData->version_id) ||
13336 		    IS_8192F_SERIES(pHalData->version_id)) {
13337 			rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
13338 			save_cnt = _TRUE;
13339 		} else {
13340 			/* todo: other chips */
13341 		}
13342 
13343 
13344 		if (save_cnt) {
13345 			pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
13346 			pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
13347 			pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
13348 		} else {
13349 			/* special value to indicate no implementation */
13350 			pdbgpriv->dbg_rx_fifo_last_overflow = 1;
13351 			pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
13352 			pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
13353 		}
13354 	}
13355 }
13356 
linked_info_dump(_adapter * padapter,u8 benable)13357 void linked_info_dump(_adapter *padapter, u8 benable)
13358 {
13359 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
13360 
13361 	if (padapter->bLinkInfoDump == benable)
13362 		return;
13363 
13364 	RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
13365 
13366 	if (benable) {
13367 #ifdef CONFIG_LPS
13368 		pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
13369 		rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
13370 #endif
13371 
13372 #ifdef CONFIG_IPS
13373 		pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
13374 		rtw_pm_set_ips(padapter, IPS_NONE);
13375 #endif
13376 	} else {
13377 #ifdef CONFIG_IPS
13378 		rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
13379 #endif /* CONFIG_IPS */
13380 
13381 #ifdef CONFIG_LPS
13382 		rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
13383 #endif /* CONFIG_LPS */
13384 	}
13385 	padapter->bLinkInfoDump = benable ;
13386 }
13387 
13388 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)13389 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
13390 {
13391 	u8 isCCKrate, rf_path;
13392 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13393 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13394 	RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
13395 		HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
13396 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13397 
13398 	if (isCCKrate)
13399 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13400 
13401 	for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13402 		if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13403 			continue;
13404 		RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
13405 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13406 
13407 		if (!isCCKrate) {
13408 			RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
13409 				psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
13410 		}
13411 	}
13412 }
13413 
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)13414 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
13415 {
13416 	u8 isCCKrate, rf_path;
13417 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13418 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13419 	_RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
13420 	_RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
13421 
13422 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13423 
13424 	if (isCCKrate)
13425 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13426 
13427 	for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13428 		if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13429 			continue;
13430 		_RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
13431 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13432 
13433 		if (!isCCKrate)
13434 			_RTW_PRINT_SEL(sel , ",rx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n", psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
13435 		else
13436 			_RTW_PRINT_SEL(sel , "\n");
13437 
13438 	}
13439 }
13440 #endif
13441 
13442 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)13443 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
13444 {
13445 #define DBG_RX_DFRAME_RAW_DATA_UC		0
13446 #define DBG_RX_DFRAME_RAW_DATA_BMC		1
13447 #define DBG_RX_DFRAME_RAW_DATA_TYPES	2
13448 
13449 	_irqL irqL;
13450 	u8 isCCKrate, rf_path;
13451 	struct recv_priv *precvpriv = &(padapter->recvpriv);
13452 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13453 	struct sta_priv *pstapriv = &padapter->stapriv;
13454 	struct sta_info *psta;
13455 	struct sta_recv_dframe_info *psta_dframe_info;
13456 	int i, j;
13457 	_list	*plist, *phead;
13458 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13459 	u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
13460 
13461 	if (precvpriv->store_law_data_flag) {
13462 
13463 		_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13464 
13465 		for (i = 0; i < NUM_STA; i++) {
13466 			phead = &(pstapriv->sta_hash[i]);
13467 			plist = get_next(phead);
13468 
13469 			while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13470 
13471 				psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
13472 				plist = get_next(plist);
13473 
13474 				if (psta) {
13475 					if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN)  !=   _TRUE)
13476 					    && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN)  !=  _TRUE)
13477 					    && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN)  !=  _TRUE)) {
13478 
13479 						RTW_PRINT_SEL(sel, "==============================\n");
13480 						RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
13481 
13482 						for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
13483 							if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
13484 								psta_dframe_info = &psta->sta_dframe_info;
13485 								RTW_PRINT_SEL(sel, "\n");
13486 								RTW_PRINT_SEL(sel, "Unicast:\n");
13487 							} else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
13488 								psta_dframe_info = &psta->sta_dframe_info_bmc;
13489 								RTW_PRINT_SEL(sel, "\n");
13490 								RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
13491 							}
13492 
13493 							isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13494 
13495 							RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
13496 							RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
13497 
13498 							for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13499 								if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13500 									continue;
13501 								if (!isCCKrate) {
13502 									RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
13503 									_RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
13504 								} else
13505 									RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
13506 							}
13507 						}
13508 
13509 					}
13510 				}
13511 			}
13512 		}
13513 		_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13514 	}
13515 }
13516 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)13517 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
13518 {
13519 	u8 isCCKrate, rf_path , dframe_type;
13520 	u8 *ptr;
13521 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13522 #ifdef DBG_RX_DFRAME_RAW_DATA
13523 	struct sta_recv_dframe_info *psta_dframe_info;
13524 #endif
13525 	struct recv_priv *precvpriv = &(padapter->recvpriv);
13526 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13527 	struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
13528 	struct sta_info *psta = prframe->u.hdr.psta;
13529 	struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
13530 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13531 	psample_pkt_rssi->data_rate = pattrib->data_rate;
13532 	ptr = prframe->u.hdr.rx_data;
13533 	dframe_type = GetFrameType(ptr);
13534 	/*RTW_INFO("=>%s\n", __FUNCTION__);*/
13535 
13536 
13537 	if (precvpriv->store_law_data_flag) {
13538 		isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13539 
13540 		psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
13541 		psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
13542 
13543 		for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13544 			psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
13545 			psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
13546 			if (!isCCKrate) {
13547 				psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13548 				psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13549 			}
13550 		}
13551 #ifdef DBG_RX_DFRAME_RAW_DATA
13552 		if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
13553 
13554 			/*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
13555 			if (psta) {
13556 				if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
13557 					psta_dframe_info = &psta->sta_dframe_info_bmc;
13558 				else
13559 					psta_dframe_info = &psta->sta_dframe_info;
13560 				/*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
13561 					__FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
13562 				if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
13563 					psta_dframe_info->sta_data_rate = pattrib->data_rate;
13564 					psta_dframe_info->sta_sgi = pattrib->sgi;
13565 					psta_dframe_info->sta_bw_mode = pattrib->bw;
13566 					for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13567 
13568 						psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
13569 
13570 						if (!isCCKrate) {
13571 							psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13572 							psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13573 						}
13574 					}
13575 				}
13576 			}
13577 		}
13578 #endif
13579 	}
13580 
13581 }
13582 
hal_efuse_macaddr_offset(_adapter * adapter)13583 int hal_efuse_macaddr_offset(_adapter *adapter)
13584 {
13585 	u8 interface_type = 0;
13586 	int addr_offset = -1;
13587 
13588 	interface_type = rtw_get_intf_type(adapter);
13589 
13590 	switch (rtw_get_chip_type(adapter)) {
13591 #ifdef CONFIG_RTL8723B
13592 	case RTL8723B:
13593 		if (interface_type == RTW_USB)
13594 			addr_offset = EEPROM_MAC_ADDR_8723BU;
13595 		else if (interface_type == RTW_SDIO)
13596 			addr_offset = EEPROM_MAC_ADDR_8723BS;
13597 		else if (interface_type == RTW_PCIE)
13598 			addr_offset = EEPROM_MAC_ADDR_8723BE;
13599 		break;
13600 #endif
13601 #ifdef CONFIG_RTL8703B
13602 	case RTL8703B:
13603 		if (interface_type == RTW_USB)
13604 			addr_offset = EEPROM_MAC_ADDR_8703BU;
13605 		else if (interface_type == RTW_SDIO)
13606 			addr_offset = EEPROM_MAC_ADDR_8703BS;
13607 		break;
13608 #endif
13609 #ifdef CONFIG_RTL8723D
13610 	case RTL8723D:
13611 		if (interface_type == RTW_USB)
13612 			addr_offset = EEPROM_MAC_ADDR_8723DU;
13613 		else if (interface_type == RTW_SDIO)
13614 			addr_offset = EEPROM_MAC_ADDR_8723DS;
13615 		else if (interface_type == RTW_PCIE)
13616 			addr_offset = EEPROM_MAC_ADDR_8723DE;
13617 		break;
13618 #endif
13619 
13620 #ifdef CONFIG_RTL8188E
13621 	case RTL8188E:
13622 		if (interface_type == RTW_USB)
13623 			addr_offset = EEPROM_MAC_ADDR_88EU;
13624 		else if (interface_type == RTW_SDIO)
13625 			addr_offset = EEPROM_MAC_ADDR_88ES;
13626 		else if (interface_type == RTW_PCIE)
13627 			addr_offset = EEPROM_MAC_ADDR_88EE;
13628 		break;
13629 #endif
13630 #ifdef CONFIG_RTL8188F
13631 	case RTL8188F:
13632 		if (interface_type == RTW_USB)
13633 			addr_offset = EEPROM_MAC_ADDR_8188FU;
13634 		else if (interface_type == RTW_SDIO)
13635 			addr_offset = EEPROM_MAC_ADDR_8188FS;
13636 		break;
13637 #endif
13638 #ifdef CONFIG_RTL8188GTV
13639 	case RTL8188GTV:
13640 		if (interface_type == RTW_USB)
13641 			addr_offset = EEPROM_MAC_ADDR_8188GTVU;
13642 		else if (interface_type == RTW_SDIO)
13643 			addr_offset = EEPROM_MAC_ADDR_8188GTVS;
13644 		break;
13645 #endif
13646 #ifdef CONFIG_RTL8812A
13647 	case RTL8812:
13648 		if (interface_type == RTW_USB)
13649 			addr_offset = EEPROM_MAC_ADDR_8812AU;
13650 		else if (interface_type == RTW_PCIE)
13651 			addr_offset = EEPROM_MAC_ADDR_8812AE;
13652 		break;
13653 #endif
13654 #ifdef CONFIG_RTL8821A
13655 	case RTL8821:
13656 		if (interface_type == RTW_USB)
13657 			addr_offset = EEPROM_MAC_ADDR_8821AU;
13658 		else if (interface_type == RTW_SDIO)
13659 			addr_offset = EEPROM_MAC_ADDR_8821AS;
13660 		else if (interface_type == RTW_PCIE)
13661 			addr_offset = EEPROM_MAC_ADDR_8821AE;
13662 		break;
13663 #endif
13664 #ifdef CONFIG_RTL8192E
13665 	case RTL8192E:
13666 		if (interface_type == RTW_USB)
13667 			addr_offset = EEPROM_MAC_ADDR_8192EU;
13668 		else if (interface_type == RTW_SDIO)
13669 			addr_offset = EEPROM_MAC_ADDR_8192ES;
13670 		else if (interface_type == RTW_PCIE)
13671 			addr_offset = EEPROM_MAC_ADDR_8192EE;
13672 		break;
13673 #endif
13674 #ifdef CONFIG_RTL8814A
13675 	case RTL8814A:
13676 		if (interface_type == RTW_USB)
13677 			addr_offset = EEPROM_MAC_ADDR_8814AU;
13678 		else if (interface_type == RTW_PCIE)
13679 			addr_offset = EEPROM_MAC_ADDR_8814AE;
13680 		break;
13681 #endif
13682 
13683 #ifdef CONFIG_RTL8822B
13684 	case RTL8822B:
13685 		if (interface_type == RTW_USB)
13686 			addr_offset = EEPROM_MAC_ADDR_8822BU;
13687 		else if (interface_type == RTW_SDIO)
13688 			addr_offset = EEPROM_MAC_ADDR_8822BS;
13689 		else if (interface_type == RTW_PCIE)
13690 			addr_offset = EEPROM_MAC_ADDR_8822BE;
13691 		break;
13692 #endif /* CONFIG_RTL8822B */
13693 
13694 #ifdef CONFIG_RTL8821C
13695 	case RTL8821C:
13696 		if (interface_type == RTW_USB)
13697 			addr_offset = EEPROM_MAC_ADDR_8821CU;
13698 		else if (interface_type == RTW_SDIO)
13699 			addr_offset = EEPROM_MAC_ADDR_8821CS;
13700 		else if (interface_type == RTW_PCIE)
13701 			addr_offset = EEPROM_MAC_ADDR_8821CE;
13702 		break;
13703 #endif /* CONFIG_RTL8821C */
13704 
13705 #ifdef CONFIG_RTL8710B
13706 	case RTL8710B:
13707 		if (interface_type == RTW_USB)
13708 			addr_offset = EEPROM_MAC_ADDR_8710B;
13709 		break;
13710 #endif
13711 
13712 #ifdef CONFIG_RTL8192F
13713 	case RTL8192F:
13714 		if (interface_type == RTW_USB)
13715 			addr_offset = EEPROM_MAC_ADDR_8192FU;
13716 		else if (interface_type == RTW_SDIO)
13717 			addr_offset = EEPROM_MAC_ADDR_8192FS;
13718 		else if (interface_type == RTW_PCIE)
13719 			addr_offset = EEPROM_MAC_ADDR_8192FE;
13720 		break;
13721 #endif /* CONFIG_RTL8192F */
13722 
13723 #ifdef CONFIG_RTL8822C
13724 	case RTL8822C:
13725 		if (interface_type == RTW_USB)
13726 			addr_offset = EEPROM_MAC_ADDR_8822CU;
13727 		else if (interface_type == RTW_SDIO)
13728 			addr_offset = EEPROM_MAC_ADDR_8822CS;
13729 		else if (interface_type == RTW_PCIE)
13730 			addr_offset = EEPROM_MAC_ADDR_8822CE;
13731 		break;
13732 #endif /* CONFIG_RTL8822C */
13733 
13734 #ifdef CONFIG_RTL8814B
13735 	case RTL8814B:
13736 		if (interface_type == RTW_USB)
13737 			addr_offset = EEPROM_MAC_ADDR_8814BU;
13738 		else if (interface_type == RTW_PCIE)
13739 			addr_offset = EEPROM_MAC_ADDR_8814BE;
13740 		break;
13741 #endif /* CONFIG_RTL8814B */
13742 	}
13743 
13744 	if (addr_offset == -1) {
13745 		RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
13746 			, __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
13747 	}
13748 
13749 	return addr_offset;
13750 }
13751 
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)13752 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
13753 {
13754 	int ret = _FAIL;
13755 	int addr_offset;
13756 
13757 	addr_offset = hal_efuse_macaddr_offset(padapter);
13758 	if (addr_offset == -1)
13759 		goto exit;
13760 
13761 	ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
13762 
13763 exit:
13764 	return ret;
13765 }
13766 
rtw_dump_cur_efuse(PADAPTER padapter)13767 void rtw_dump_cur_efuse(PADAPTER padapter)
13768 {
13769 	int mapsize =0;
13770 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13771 
13772 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
13773 
13774 	if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
13775 		RTW_ERR("wrong map size %d\n", mapsize);
13776 		return;
13777 	}
13778 
13779 #ifdef CONFIG_RTW_DEBUG
13780 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13781 		RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
13782 	else
13783 		RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
13784 #endif
13785 }
13786 
13787 
13788 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)13789 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
13790 {
13791 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13792 	u32 ret = _FALSE;
13793 	u32 maplen = 0;
13794 
13795 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
13796 
13797 	if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
13798 		RTW_ERR("eFuse length error :%d\n", maplen);
13799 		return _FALSE;
13800 	}
13801 
13802 	ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
13803 
13804 	hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
13805 
13806 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13807 		rtw_dump_cur_efuse(padapter);
13808 
13809 	return ret;
13810 }
13811 
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)13812 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
13813 {
13814 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13815 	u32 ret = _FAIL;
13816 
13817 	if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
13818 		&& rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
13819 	) {
13820 		hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
13821 		ret = _SUCCESS;
13822 	} else
13823 		hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
13824 
13825 	return ret;
13826 }
13827 #endif /* CONFIG_EFUSE_CONFIG_FILE */
13828 
hal_config_macaddr(_adapter * adapter,bool autoload_fail)13829 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
13830 {
13831 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13832 	u8 addr[ETH_ALEN];
13833 	int addr_offset = hal_efuse_macaddr_offset(adapter);
13834 	u8 *hw_addr = NULL;
13835 	int ret = _SUCCESS;
13836 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13837 	u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
13838 #endif
13839 
13840 	if (autoload_fail)
13841 		goto bypass_hw_pg;
13842 
13843 	if (addr_offset != -1)
13844 		hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
13845 
13846 #ifdef CONFIG_EFUSE_CONFIG_FILE
13847 	/* if the hw_addr is written by efuse file, set to NULL */
13848 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13849 		hw_addr = NULL;
13850 #endif
13851 
13852 	if (!hw_addr) {
13853 		/* try getting hw pg data */
13854 		if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
13855 			hw_addr = addr;
13856 	}
13857 
13858 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13859 	if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
13860 		hw_addr[0] = 0xff;
13861 #endif
13862 
13863 	/* check hw pg data */
13864 	if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
13865 		_rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
13866 		goto exit;
13867 	}
13868 
13869 bypass_hw_pg:
13870 
13871 #ifdef CONFIG_EFUSE_CONFIG_FILE
13872 	/* check wifi mac file */
13873 	if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
13874 		_rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
13875 		goto exit;
13876 	}
13877 #endif
13878 
13879 	_rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
13880 	ret = _FAIL;
13881 
13882 exit:
13883 	return ret;
13884 }
13885 
13886 #ifdef CONFIG_RF_POWER_TRIM
13887 u32 Array_kfreemap[] = {
13888 	0x08, 0xe,
13889 	0x06, 0xc,
13890 	0x04, 0xa,
13891 	0x02, 0x8,
13892 	0x00, 0x6,
13893 	0x03, 0x4,
13894 	0x05, 0x2,
13895 	0x07, 0x0,
13896 	0x09, 0x0,
13897 	0x0c, 0x0,
13898 };
13899 
rtw_bb_rf_gain_offset(_adapter * padapter)13900 void rtw_bb_rf_gain_offset(_adapter *padapter)
13901 {
13902 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
13903 	struct registry_priv  *registry_par = &padapter->registrypriv;
13904 	struct kfree_data_t *kfree_data = &pHalData->kfree_data;
13905 	u8		value = pHalData->EEPROMRFGainOffset;
13906 	u8		tmp = 0x3e;
13907 	u32		res, i = 0;
13908 	u32		ArrayLen	= sizeof(Array_kfreemap) / sizeof(u32);
13909 	u32		*Array = Array_kfreemap;
13910 	u32		v1 = 0, v2 = 0, GainValue = 0, target = 0;
13911 
13912 	if (registry_par->RegPwrTrimEnable == 2) {
13913 		RTW_INFO("Registry kfree default force disable.\n");
13914 		return;
13915 	}
13916 
13917 #if defined(CONFIG_RTL8723B)
13918 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
13919 		RTW_INFO("Offset RF Gain.\n");
13920 		RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
13921 
13922 		if (pHalData->EEPROMRFGainVal != 0xff) {
13923 
13924 			if (pHalData->ant_path == RF_PATH_A)
13925 				GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
13926 
13927 			else
13928 				GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
13929 			RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
13930 
13931 			for (i = 0; i < ArrayLen; i += 2) {
13932 				/* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
13933 				v1 = Array[i];
13934 				v2 = Array[i + 1];
13935 				if (v1 == GainValue) {
13936 					RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
13937 					target = v2;
13938 					break;
13939 				}
13940 			}
13941 			RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
13942 
13943 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13944 			RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
13945 			phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
13946 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13947 
13948 			RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
13949 
13950 		} else
13951 
13952 			RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x	!= 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
13953 	} else
13954 		RTW_INFO("Using the default RF gain.\n");
13955 
13956 #elif defined(CONFIG_RTL8188E)
13957 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
13958 		RTW_INFO("8188ES Offset RF Gain.\n");
13959 		RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
13960 			 pHalData->EEPROMRFGainVal);
13961 
13962 		if (pHalData->EEPROMRFGainVal != 0xff) {
13963 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
13964 					 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
13965 
13966 			RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
13967 			res &= 0xfff87fff;
13968 
13969 			res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
13970 			RTW_INFO("Offset RF Gain. res=0x%x\n", res);
13971 
13972 			rtw_hal_write_rfreg(padapter, RF_PATH_A,
13973 					    REG_RF_BB_GAIN_OFFSET,
13974 					    RF_GAIN_OFFSET_MASK, res);
13975 		} else {
13976 			RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
13977 				 pHalData->EEPROMRFGainVal);
13978 		}
13979 	} else
13980 		RTW_INFO("Using the default RF gain.\n");
13981 #else
13982 	/* TODO: call this when channel switch */
13983 	if (kfree_data->flag & KFREE_FLAG_ON)
13984 		rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
13985 #endif
13986 
13987 }
13988 #endif /*CONFIG_RF_POWER_TRIM */
13989 
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)13990 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
13991 {
13992 #ifdef CONFIG_RF_POWER_TRIM
13993 	int i, j;
13994 
13995 	for (i = 0; i < BB_GAIN_NUM; i++)
13996 		for (j = 0; j < RF_PATH_MAX; j++)
13997 			if (data->bb_gain[i][j] != 0)
13998 				return 0;
13999 #endif
14000 	return 1;
14001 }
14002 
14003 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)14004 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
14005 {
14006 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14007 	if (cur_wireless_mode < WIRELESS_11_24N
14008 	    && cur_wireless_mode > 0) { /* ABG mode */
14009 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14010 		u32 remainder = 0;
14011 		u8 quotient = 0;
14012 
14013 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
14014 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14015 
14016 		if (quotient > 5) {
14017 			pHalData->rxagg_usb_size = 0x6;
14018 			pHalData->rxagg_usb_timeout = 0x10;
14019 		} else {
14020 			if (remainder >= 2048) {
14021 				pHalData->rxagg_usb_size = quotient;
14022 				pHalData->rxagg_usb_timeout = 0x10;
14023 			} else {
14024 				pHalData->rxagg_usb_size = (quotient - 1);
14025 				pHalData->rxagg_usb_timeout = 0x10;
14026 			}
14027 		}
14028 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14029 		if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
14030 			pHalData->rxagg_usb_size = 0x6;
14031 			pHalData->rxagg_usb_timeout = 0x10;
14032 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14033 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14034 		}
14035 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14036 
14037 	} else if (cur_wireless_mode >= WIRELESS_11_24N
14038 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14039 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14040 		u32 remainder = 0;
14041 		u8 quotient = 0;
14042 
14043 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
14044 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14045 
14046 		if (quotient > 5) {
14047 			pHalData->rxagg_usb_size = 0x5;
14048 			pHalData->rxagg_usb_timeout = 0x20;
14049 		} else {
14050 			if (remainder >= 2048) {
14051 				pHalData->rxagg_usb_size = quotient;
14052 				pHalData->rxagg_usb_timeout = 0x10;
14053 			} else {
14054 				pHalData->rxagg_usb_size = (quotient - 1);
14055 				pHalData->rxagg_usb_timeout = 0x10;
14056 			}
14057 		}
14058 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14059 		if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
14060 			pHalData->rxagg_usb_size = 0x5;
14061 			pHalData->rxagg_usb_timeout = 0x20;
14062 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14063 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14064 		}
14065 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14066 
14067 	} else {
14068 		/* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14069 	}
14070 }
14071 
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)14072 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
14073 {
14074 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14075 
14076 	if (cur_wireless_mode < WIRELESS_11_24N
14077 	    && cur_wireless_mode > 0) { /* ABG mode */
14078 		if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
14079 		    || 0x10 != pHalData->rxagg_usb_timeout) {
14080 			pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
14081 			pHalData->rxagg_usb_timeout = 0x10;
14082 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14083 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14084 		}
14085 	} else if (cur_wireless_mode >= WIRELESS_11_24N
14086 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14087 		if (UsbDmaSize != pHalData->rxagg_usb_size
14088 		    || 0x20 != pHalData->rxagg_usb_timeout) {
14089 			pHalData->rxagg_usb_size = UsbDmaSize;
14090 			pHalData->rxagg_usb_timeout = 0x20;
14091 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14092 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14093 		}
14094 	} else {
14095 		/* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14096 	}
14097 }
14098 
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)14099 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
14100 {
14101 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14102 	rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
14103 	return;
14104 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14105 
14106 	rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
14107 }
14108 #endif /* CONFIG_USB_RX_AGGREGATION */
14109 
14110 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)14111 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
14112 {
14113 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
14114 	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
14115 	struct registry_priv *registry_par = &padapter->registrypriv;
14116 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14117 	u8 cur_wireless_mode = WIRELESS_INVALID;
14118 
14119 #ifdef CONFIG_USB_RX_AGGREGATION
14120 	if (!registry_par->dynamic_agg_enable)
14121 		return;
14122 
14123 #ifdef RTW_HALMAC
14124 	if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter)
14125 		|| IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter))
14126 		rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
14127 #else /* !RTW_HALMAC */
14128 	if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
14129 		/* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
14130 		if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) {
14131 			if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14132 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
14133 			else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14134 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
14135 			else
14136 				rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
14137 
14138 			/* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
14139 		}
14140 	} else if (IS_HARDWARE_TYPE_8812(padapter)) {
14141 #ifdef CONFIG_CONCURRENT_MODE
14142 		u8 i;
14143 		_adapter *iface;
14144 		u8 bassocaed = _FALSE;
14145 		struct mlme_ext_priv *mlmeext;
14146 
14147 		for (i = 0; i < pdvobjpriv->iface_nums; i++) {
14148 			iface = pdvobjpriv->padapters[i];
14149 			mlmeext = &iface->mlmeextpriv;
14150 			if (rtw_linked_check(iface) == _TRUE) {
14151 				if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
14152 					cur_wireless_mode = mlmeext->cur_wireless_mode;
14153 				bassocaed = _TRUE;
14154 			}
14155 		}
14156 		if (bassocaed)
14157 #endif
14158 			rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14159 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14160 	} else {
14161 		rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14162 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14163 	}
14164 #endif /* RTW_HALMAC */
14165 #endif /* CONFIG_USB_RX_AGGREGATION */
14166 
14167 }
14168 
14169 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)14170 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
14171 {
14172 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14173 	u8 chk_rst = _SUCCESS;
14174 
14175 	if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
14176 		return chk_rst;
14177 
14178 	/* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
14179 	/*	return chk_rst; */
14180 
14181 	if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
14182 	    && (pre_qsel != next_qsel)) {
14183 		/* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
14184 		/*	pre_qsel,next_qsel); */
14185 		chk_rst = _FAIL;
14186 	}
14187 	return chk_rst;
14188 }
14189 
14190 /*
14191  * Description:
14192  * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
14193  * contant.
14194  *
14195  * Input:
14196  * adapter: adapter pointer.
14197  * page_num: The max. page number that user want to dump.
14198  * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
14199  */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)14200 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
14201 {
14202 
14203 	int i;
14204 	u8 val = 0;
14205 	u8 base = 0;
14206 	u32 addr = 0;
14207 	u32 count = (page_size / 8);
14208 
14209 	if (page_num <= 0) {
14210 		RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
14211 		return;
14212 	}
14213 
14214 	if (page_size < 128 || page_size > 512) {
14215 		RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
14216 		return;
14217 	}
14218 
14219 	RTW_INFO("+%s+\n", __func__);
14220 	val = rtw_read8(padapter, 0x106);
14221 	rtw_write8(padapter, 0x106, 0x69);
14222 	RTW_INFO("0x106: 0x%02x\n", val);
14223 	base = rtw_read8(padapter, 0x209);
14224 	RTW_INFO("0x209: 0x%02x\n", base);
14225 
14226 	addr = ((base)*page_size) / 8;
14227 	for (i = 0 ; i < page_num * count ; i += 2) {
14228 		rtw_write32(padapter, 0x140, addr + i);
14229 		printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14230 		rtw_write32(padapter, 0x140, addr + i + 1);
14231 		printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14232 	}
14233 }
14234 
14235 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)14236 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
14237 {
14238 	u8 value = 0;
14239 	u8 direction = 0;
14240 	u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
14241 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
14242 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
14243 	u8 gpio_num_to_set = gpio_num;
14244 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
14245 
14246 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14247 		return value;
14248 
14249 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14250 
14251 	RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
14252 	LeaveAllPowerSaveModeDirect(adapter);
14253 
14254 	if (gpio_num > 7) {
14255 		gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
14256 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
14257 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
14258 		gpio_num_to_set = gpio_num - 8;
14259 	}
14260 
14261 	/* Read GPIO Direction */
14262 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14263 
14264 	/* According the direction to read register value */
14265 	if (direction)
14266 		value =  (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14267 	else
14268 		value =  (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14269 
14270 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14271 	RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
14272 
14273 	return value;
14274 }
14275 
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)14276 int  rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
14277 {
14278 	u8 direction = 0;
14279 	u8 res = -1;
14280 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
14281 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
14282 	u8 gpio_num_to_set = gpio_num;
14283 
14284 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14285 		return -1;
14286 
14287 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14288 
14289 	LeaveAllPowerSaveModeDirect(adapter);
14290 
14291 	if (gpio_num > 7) {
14292 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
14293 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
14294 		gpio_num_to_set = gpio_num - 8;
14295 	}
14296 
14297 	/* Read GPIO direction */
14298 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14299 
14300 	/* If GPIO is output direction, setting value. */
14301 	if (direction) {
14302 		if (isHigh)
14303 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
14304 		else
14305 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
14306 
14307 		RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
14308 		res = 0;
14309 	} else {
14310 		RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
14311 		res = -1;
14312 	}
14313 
14314 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14315 	return res;
14316 }
14317 
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)14318 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
14319 {
14320 	u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
14321 	u8 gpio_num_to_set = gpio_num;
14322 
14323 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14324 		return -1;
14325 
14326 	RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
14327 
14328 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14329 
14330 	LeaveAllPowerSaveModeDirect(adapter);
14331 
14332 	rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
14333 
14334 	if (gpio_num > 7) {
14335 		gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
14336 		gpio_num_to_set = gpio_num - 8;
14337 	}
14338 
14339 	if (isOutput)
14340 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
14341 	else
14342 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
14343 
14344 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14345 
14346 	return 0;
14347 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))14348 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
14349 {
14350 	u8 value;
14351 	u8 direction;
14352 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14353 
14354 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
14355 		if (gpio_num > 7 || gpio_num < 4) {
14356 			RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14357 			return -1;
14358 		}
14359 	}
14360 
14361 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14362 
14363 	LeaveAllPowerSaveModeDirect(adapter);
14364 
14365 	/* Read GPIO direction */
14366 	direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
14367 	if (direction) {
14368 		RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
14369 		return -1;
14370 	}
14371 
14372 	/* Config GPIO Mode */
14373 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
14374 
14375 	/* Register GPIO interrupt handler*/
14376 	adapter->gpiointpriv.callback[gpio_num] = callback;
14377 
14378 	/* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
14379 	value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
14380 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
14381 	rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
14382 
14383 	/* Enable GPIO interrupt */
14384 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
14385 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14386 
14387 	rtw_hal_update_hisr_hsisr_ind(adapter, 1);
14388 
14389 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14390 
14391 	return 0;
14392 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)14393 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
14394 {
14395 	u8 value;
14396 	u8 direction;
14397 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14398 
14399 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
14400 		if (gpio_num > 7 || gpio_num < 4) {
14401 			RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14402 			return -1;
14403 		}
14404 	}
14405 
14406 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14407 
14408 	LeaveAllPowerSaveModeDirect(adapter);
14409 
14410 	/* Config GPIO Mode */
14411 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
14412 
14413 	/* Unregister GPIO interrupt handler*/
14414 	adapter->gpiointpriv.callback[gpio_num] = NULL;
14415 
14416 	/* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
14417 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
14418 	rtw_write8(adapter, REG_GPIO_INTM, 0x00);
14419 
14420 	/* Disable GPIO interrupt */
14421 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
14422 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14423 
14424 	if (!adapter->gpiointpriv.interrupt_enable_mask)
14425 		rtw_hal_update_hisr_hsisr_ind(adapter, 0);
14426 
14427 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14428 
14429 	return 0;
14430 }
14431 #endif
14432 
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)14433 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
14434 {
14435 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14436 	u8 i;
14437 
14438 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14439 		if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
14440 			if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
14441 			    && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
14442 				return i;
14443 		}
14444 	}
14445 
14446 	return -1;
14447 }
14448 
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)14449 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
14450 {
14451 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14452 	s8 res;
14453 	u8 i;
14454 
14455 	/* If it's an existed record, overwrite it */
14456 	res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
14457 	if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
14458 		rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
14459 		return;
14460 	}
14461 
14462 	/* Search for the empty record to use */
14463 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14464 		if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
14465 			rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
14466 			return;
14467 		}
14468 	}
14469 
14470 	/* Else, overwrite the oldest record */
14471 	for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
14472 		_rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
14473 
14474 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
14475 }
14476 
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)14477 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
14478 {
14479 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
14480 }
14481 
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14482 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14483 {
14484 	u32	mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
14485 	u32	mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
14486 	u32	mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
14487 	u32	DropPacket = 0;
14488 
14489 	if (!rx_counter) {
14490 		rtw_warn_on(1);
14491 		return;
14492 	}
14493 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
14494 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14495 
14496 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
14497 	mac_cck_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	  */
14498 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14499 	mac_ofdm_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14500 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
14501 	mac_ht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14502 	mac_vht_ok	= 0;
14503 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14504 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14505 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14506 		mac_vht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14507 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14508 	}
14509 
14510 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
14511 	mac_cck_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14512 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14513 	mac_ofdm_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14514 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
14515 	mac_ht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
14516 	mac_vht_err	= 0;
14517 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14518 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14519 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14520 		mac_vht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14521 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14522 	}
14523 
14524 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
14525 	mac_cck_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14526 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
14527 	mac_ofdm_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14528 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
14529 	mac_ht_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
14530 
14531 	/* Mac_DropPacket */
14532 	rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
14533 	DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
14534 
14535 	rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
14536 	rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
14537 	rx_counter->rx_cck_fa = mac_cck_fa;
14538 	rx_counter->rx_ofdm_fa = mac_ofdm_fa;
14539 	rx_counter->rx_ht_fa = mac_ht_fa;
14540 	rx_counter->rx_pkt_drop = DropPacket;
14541 }
rtw_reset_mac_rx_counters(_adapter * padapter)14542 void rtw_reset_mac_rx_counters(_adapter *padapter)
14543 {
14544 
14545 	/* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
14546 	if (IS_HARDWARE_TYPE_8703B(padapter) ||
14547 		IS_HARDWARE_TYPE_8723D(padapter) ||
14548 		IS_HARDWARE_TYPE_8188F(padapter) ||
14549 		IS_HARDWARE_TYPE_8188GTV(padapter) ||
14550 		IS_HARDWARE_TYPE_8192F(padapter) ||
14551 		IS_HARDWARE_TYPE_8822C(padapter))
14552 		phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
14553 
14554 	/* reset mac counter */
14555 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
14556 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
14557 }
14558 
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14559 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14560 {
14561 	u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0, vht_ok = 0, vht_err = 0;
14562 	if (!rx_counter) {
14563 		rtw_warn_on(1);
14564 		return;
14565 	}
14566 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14567 		cckok	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF);	     /* [13:0] */
14568 		ofdmok	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF);	     /* [13:0] */
14569 		htok		= phy_query_bb_reg(padapter, 0xF10, 0x3FFF);     /* [13:0] */
14570 		vht_ok	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF);     /* [13:0] */
14571 		cckcrc	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16]	 */
14572 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
14573 		htcrc	= phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
14574 		vht_err	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
14575 		CCK_FA	= phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
14576 		OFDM_FA	= phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
14577 	} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
14578 		cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
14579 		ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
14580 		htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
14581 		vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
14582 		cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
14583 		ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
14584 		htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
14585 		vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
14586 		CCK_FA	= phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
14587 		OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
14588 
14589 	} else {
14590 		cckok	= phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
14591 		ofdmok	= phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
14592 		htok		= phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
14593 		vht_ok	= 0;
14594 		cckcrc	= phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
14595 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
14596 		htcrc	= phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
14597 		vht_err	= 0;
14598 		OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
14599 			phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
14600 			phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
14601 
14602 		CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
14603 	}
14604 
14605 	rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
14606 	rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
14607 	rx_counter->rx_ofdm_fa = OFDM_FA;
14608 	rx_counter->rx_cck_fa = CCK_FA;
14609 
14610 }
14611 
rtw_reset_phy_trx_ok_counters(_adapter * padapter)14612 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
14613 {
14614 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14615 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
14616 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
14617 	} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14618 		phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
14619 		phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
14620 	} else {
14621 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14622 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14623 	}
14624 }
14625 
rtw_reset_phy_rx_counters(_adapter * padapter)14626 void rtw_reset_phy_rx_counters(_adapter *padapter)
14627 {
14628 	/* reset phy counter */
14629 	if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14630 		/* reset CCK FA counter */
14631 		phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
14632 		phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
14633 
14634 		/* reset CCK CCA counter */
14635 		phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
14636 		phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
14637 		rtw_reset_phy_trx_ok_counters(padapter);
14638 
14639 	} else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14640 		rtw_reset_phy_trx_ok_counters(padapter);
14641 
14642 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset  OFDA FA counter */
14643 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
14644 
14645 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
14646 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14647 	} else {
14648 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14649 		rtw_msleep_os(10);
14650 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14651 
14652 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset  OFDA FA counter */
14653 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset  OFDA FA counter */
14654 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
14655 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
14656 
14657 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
14658 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14659 	}
14660 }
14661 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14662 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14663 {
14664 	struct recv_priv *precvpriv = &padapter->recvpriv;
14665 	if (!rx_counter) {
14666 		rtw_warn_on(1);
14667 		return;
14668 	}
14669 	rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
14670 	rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
14671 	rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
14672 }
rtw_reset_drv_rx_counters(_adapter * padapter)14673 void rtw_reset_drv_rx_counters(_adapter *padapter)
14674 {
14675 	struct recv_priv *precvpriv = &padapter->recvpriv;
14676 	padapter->drv_rx_cnt_ok = 0;
14677 	padapter->drv_rx_cnt_crcerror = 0;
14678 	padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
14679 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)14680 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
14681 {
14682 	u8 initialgain;
14683 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14684 
14685 	if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
14686 		rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
14687 		RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
14688 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14689 		/*disable dynamic functions, such as high power, DIG*/
14690 		rtw_phydm_ability_backup(padapter);
14691 		rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
14692 	} else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
14693 		/* turn on phy-dynamic functions */
14694 		rtw_phydm_ability_restore(padapter);
14695 		initialgain = 0xff; /* restore RX GAIN */
14696 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14697 
14698 	}
14699 }
14700 
rtw_dump_rx_counters(_adapter * padapter)14701 void rtw_dump_rx_counters(_adapter *padapter)
14702 {
14703 	struct dbg_rx_counter rx_counter;
14704 
14705 	if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
14706 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14707 		rtw_dump_drv_rx_counters(padapter, &rx_counter);
14708 		RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
14709 			rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
14710 		rtw_reset_drv_rx_counters(padapter);
14711 	}
14712 
14713 	if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
14714 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14715 		rtw_dump_mac_rx_counters(padapter, &rx_counter);
14716 		RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
14717 			 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
14718 			rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
14719 			 rx_counter.rx_pkt_drop);
14720 		rtw_reset_mac_rx_counters(padapter);
14721 	}
14722 
14723 	if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
14724 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14725 		rtw_dump_phy_rx_counters(padapter, &rx_counter);
14726 		/* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
14727 		/* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
14728 		RTW_INFO("Phy Received packet OK:%d CRC error:%d FA Counter: %d\n", rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
14729 			 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
14730 		rtw_reset_phy_rx_counters(padapter);
14731 	}
14732 }
14733 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)14734 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
14735 {
14736 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14737 	u8 curr_tx_sgi = 0;
14738 	struct ra_sta_info *ra_info;
14739 
14740 	if (!psta)
14741 		return curr_tx_sgi;
14742 
14743 	if (padapter->fix_rate == 0xff) {
14744 #if defined(CONFIG_RTL8188E)
14745 #if (RATE_ADAPTIVE_SUPPORT == 1)
14746 		curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
14747 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14748 #else
14749 		ra_info = &psta->cmn.ra_info;
14750 		curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
14751 #endif
14752 	} else {
14753 		curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
14754 	}
14755 
14756 	return curr_tx_sgi;
14757 }
14758 
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)14759 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
14760 {
14761 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14762 	u8 rate_id = 0;
14763 	struct ra_sta_info *ra_info;
14764 
14765 	if (!psta)
14766 		return rate_id;
14767 
14768 	if (padapter->fix_rate == 0xff) {
14769 #if defined(CONFIG_RTL8188E)
14770 #if (RATE_ADAPTIVE_SUPPORT == 1)
14771 		rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
14772 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14773 #else
14774 		ra_info = &psta->cmn.ra_info;
14775 		rate_id = ra_info->curr_tx_rate & 0x7f;
14776 #endif
14777 	} else {
14778 		rate_id = padapter->fix_rate & 0x7f;
14779 	}
14780 
14781 	return rate_id;
14782 }
14783 
update_IOT_info(_adapter * padapter)14784 void update_IOT_info(_adapter *padapter)
14785 {
14786 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
14787 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14788 
14789 	switch (pmlmeinfo->assoc_AP_vendor) {
14790 	case HT_IOT_PEER_MARVELL:
14791 		pmlmeinfo->turboMode_cts2self = 1;
14792 		pmlmeinfo->turboMode_rtsen = 0;
14793 		break;
14794 
14795 	case HT_IOT_PEER_RALINK:
14796 		pmlmeinfo->turboMode_cts2self = 0;
14797 		pmlmeinfo->turboMode_rtsen = 1;
14798 		break;
14799 	case HT_IOT_PEER_REALTEK:
14800 		/* rtw_write16(padapter, 0x4cc, 0xffff); */
14801 		/* rtw_write16(padapter, 0x546, 0x01c0); */
14802 		break;
14803 	default:
14804 		pmlmeinfo->turboMode_cts2self = 0;
14805 		pmlmeinfo->turboMode_rtsen = 1;
14806 		break;
14807 	}
14808 
14809 }
14810 #ifdef CONFIG_RTS_FULL_BW
14811 /*
14812 8188E: not support full RTS BW feature(mac REG no define 480[5])
14813 */
rtw_set_rts_bw(_adapter * padapter)14814 void rtw_set_rts_bw(_adapter *padapter) {
14815 	int i;
14816 	u8 enable = 1;
14817 	bool connect_to_8812 = _FALSE;
14818 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14819 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14820 	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
14821 	struct sta_info *station = NULL;
14822 
14823 	for (i = 0; i < macid_ctl->num; i++) {
14824 		if (rtw_macid_is_used(macid_ctl, i)) {
14825 
14826 			station = NULL;
14827 			station = macid_ctl->sta[i];
14828 			if(station) {
14829 
14830 				 _adapter *sta_adapter =station->padapter;
14831 				struct mlme_ext_priv	*pmlmeext = &(sta_adapter->mlmeextpriv);
14832 				struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14833 
14834 				if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
14835 					if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) !=  _TRUE) {
14836 						if (  macid_ctl->sta[i]->vendor_8812) {
14837 							connect_to_8812 = _TRUE;
14838 							enable = 0;
14839 						}
14840 					}
14841 				}
14842 			}
14843 		}
14844 
14845 		if(connect_to_8812)
14846 			break;
14847 	}
14848 
14849 		RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
14850 		rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
14851 }
14852 #endif/*CONFIG_RTS_FULL_BW*/
14853 
hal_spec_init(_adapter * adapter)14854 int hal_spec_init(_adapter *adapter)
14855 {
14856 	u8 interface_type = 0;
14857 	int ret = _SUCCESS;
14858 
14859 	interface_type = rtw_get_intf_type(adapter);
14860 
14861 	switch (rtw_get_chip_type(adapter)) {
14862 #ifdef CONFIG_RTL8723B
14863 	case RTL8723B:
14864 		init_hal_spec_8723b(adapter);
14865 		break;
14866 #endif
14867 #ifdef CONFIG_RTL8703B
14868 	case RTL8703B:
14869 		init_hal_spec_8703b(adapter);
14870 		break;
14871 #endif
14872 #ifdef CONFIG_RTL8723D
14873 	case RTL8723D:
14874 		init_hal_spec_8723d(adapter);
14875 		break;
14876 #endif
14877 #ifdef CONFIG_RTL8188E
14878 	case RTL8188E:
14879 		init_hal_spec_8188e(adapter);
14880 		break;
14881 #endif
14882 #ifdef CONFIG_RTL8188F
14883 	case RTL8188F:
14884 		init_hal_spec_8188f(adapter);
14885 		break;
14886 #endif
14887 #ifdef CONFIG_RTL8188GTV
14888 	case RTL8188GTV:
14889 		init_hal_spec_8188gtv(adapter);
14890 		break;
14891 #endif
14892 #ifdef CONFIG_RTL8812A
14893 	case RTL8812:
14894 		init_hal_spec_8812a(adapter);
14895 		break;
14896 #endif
14897 #ifdef CONFIG_RTL8821A
14898 	case RTL8821:
14899 		init_hal_spec_8821a(adapter);
14900 		break;
14901 #endif
14902 #ifdef CONFIG_RTL8192E
14903 	case RTL8192E:
14904 		init_hal_spec_8192e(adapter);
14905 		break;
14906 #endif
14907 #ifdef CONFIG_RTL8814A
14908 	case RTL8814A:
14909 		init_hal_spec_8814a(adapter);
14910 		break;
14911 #endif
14912 #ifdef CONFIG_RTL8822B
14913 	case RTL8822B:
14914 		rtl8822b_init_hal_spec(adapter);
14915 		break;
14916 #endif
14917 #ifdef CONFIG_RTL8821C
14918 	case RTL8821C:
14919 		init_hal_spec_rtl8821c(adapter);
14920 		break;
14921 #endif
14922 #ifdef CONFIG_RTL8710B
14923 	case RTL8710B:
14924 		init_hal_spec_8710b(adapter);
14925 		break;
14926 #endif
14927 #ifdef CONFIG_RTL8192F
14928 	case RTL8192F:
14929 		init_hal_spec_8192f(adapter);
14930 		break;
14931 #endif
14932 #ifdef CONFIG_RTL8822C
14933 	case RTL8822C:
14934 		rtl8822c_init_hal_spec(adapter);
14935 		break;
14936 #endif
14937 #ifdef CONFIG_RTL8814B
14938 	case RTL8814B:
14939 		rtl8814b_init_hal_spec(adapter);
14940 		break;
14941 #endif
14942 	default:
14943 		RTW_ERR("%s: unknown chip_type:%u\n"
14944 			, __func__, rtw_get_chip_type(adapter));
14945 		ret = _FAIL;
14946 		break;
14947 	}
14948 
14949 	return ret;
14950 }
14951 
14952 static const char *const _band_cap_str[] = {
14953 	/* BIT0 */"2G",
14954 	/* BIT1 */"5G",
14955 };
14956 
14957 static const char *const _bw_cap_str[] = {
14958 	/* BIT0 */"5M",
14959 	/* BIT1 */"10M",
14960 	/* BIT2 */"20M",
14961 	/* BIT3 */"40M",
14962 	/* BIT4 */"80M",
14963 	/* BIT5 */"160M",
14964 	/* BIT6 */"80_80M",
14965 };
14966 
14967 static const char *const _proto_cap_str[] = {
14968 	/* BIT0 */"b",
14969 	/* BIT1 */"g",
14970 	/* BIT2 */"n",
14971 	/* BIT3 */"ac",
14972 };
14973 
14974 static const char *const _wl_func_str[] = {
14975 	/* BIT0 */"P2P",
14976 	/* BIT1 */"MIRACAST",
14977 	/* BIT2 */"TDLS",
14978 	/* BIT3 */"FTM",
14979 };
14980 
dump_hal_spec(void * sel,_adapter * adapter)14981 void dump_hal_spec(void *sel, _adapter *adapter)
14982 {
14983 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
14984 	int i;
14985 
14986 	RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
14987 	RTW_PRINT_SEL(sel, "macid_cap:%u\n", hal_spec->macid_cap);
14988 	RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
14989 	RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
14990 
14991 	RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
14992 	RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
14993 	RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
14994 	RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num);
14995 	RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp);
14996 	RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
14997 
14998 	RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
14999 	RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
15000 
15001 	RTW_PRINT_SEL(sel, "band_cap:");
15002 	for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
15003 		if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
15004 			_RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
15005 	}
15006 	_RTW_PRINT_SEL(sel, "\n");
15007 
15008 	RTW_PRINT_SEL(sel, "bw_cap:");
15009 	for (i = 0; i < BW_CAP_BIT_NUM; i++) {
15010 		if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
15011 			_RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
15012 	}
15013 	_RTW_PRINT_SEL(sel, "\n");
15014 
15015 	RTW_PRINT_SEL(sel, "proto_cap:");
15016 	for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
15017 		if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
15018 			_RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
15019 	}
15020 	_RTW_PRINT_SEL(sel, "\n");
15021 
15022 	RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
15023 	RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
15024 
15025 	RTW_PRINT_SEL(sel, "wl_func:");
15026 	for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
15027 		if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
15028 			_RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
15029 	}
15030 	_RTW_PRINT_SEL(sel, "\n");
15031 
15032 #if CONFIG_TX_AC_LIFETIME
15033 	RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
15034 		, hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
15035 #endif
15036 
15037 	RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
15038 
15039 	RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
15040 	RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
15041 }
15042 
hal_chk_band_cap(_adapter * adapter,u8 cap)15043 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
15044 {
15045 	return GET_HAL_SPEC(adapter)->band_cap & cap;
15046 }
15047 
hal_chk_bw_cap(_adapter * adapter,u8 cap)15048 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
15049 {
15050 	return GET_HAL_SPEC(adapter)->bw_cap & cap;
15051 }
15052 
hal_chk_proto_cap(_adapter * adapter,u8 cap)15053 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
15054 {
15055 	return GET_HAL_SPEC(adapter)->proto_cap & cap;
15056 }
15057 
hal_chk_wl_func(_adapter * adapter,u8 func)15058 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
15059 {
15060 	return GET_HAL_SPEC(adapter)->wl_func & func;
15061 }
15062 
hal_is_band_support(_adapter * adapter,u8 band)15063 inline bool hal_is_band_support(_adapter *adapter, u8 band)
15064 {
15065 	return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
15066 }
15067 
hal_is_bw_support(_adapter * adapter,u8 bw)15068 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
15069 {
15070 	return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
15071 }
15072 
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)15073 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
15074 {
15075 	u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
15076 
15077 	if (mode == WIRELESS_11B)
15078 		if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15079 			return 1;
15080 
15081 	if (mode == WIRELESS_11G)
15082 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15083 			return 1;
15084 
15085 	if (mode == WIRELESS_11A)
15086 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15087 			return 1;
15088 
15089 	if (mode == WIRELESS_11_24N)
15090 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15091 			return 1;
15092 
15093 	if (mode == WIRELESS_11_5N)
15094 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15095 			return 1;
15096 
15097 	if (mode == WIRELESS_11AC)
15098 		if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15099 			return 1;
15100 
15101 	return 0;
15102 }
hal_is_mimo_support(_adapter * adapter)15103 inline bool hal_is_mimo_support(_adapter *adapter)
15104 {
15105 	if ((GET_HAL_TX_NSS(adapter) == 1) &&
15106 		(GET_HAL_RX_NSS(adapter) == 1))
15107 		return 0;
15108 	return 1;
15109 }
15110 
15111 /*
15112 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
15113 * @adapter:
15114 * @in_bw: starting bw, value of enum channel_width
15115 *
15116 * Returns: value of enum channel_width
15117 */
hal_largest_bw(_adapter * adapter,u8 in_bw)15118 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
15119 {
15120 	for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
15121 		if (hal_is_bw_support(adapter, in_bw))
15122 			break;
15123 	}
15124 
15125 	if (!hal_is_bw_support(adapter, in_bw))
15126 		rtw_warn_on(1);
15127 
15128 	return in_bw;
15129 }
15130 
15131 #ifndef CONFIG_HAS_TX_BEACON_PAUSE
ResumeTxBeacon(_adapter * padapter)15132 void ResumeTxBeacon(_adapter *padapter)
15133 {
15134 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15135 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
15136 
15137 #ifdef RTW_HALMAC
15138 	/* Add this for driver using HALMAC because driver doesn't have setup time init by self */
15139 	/* TBTT setup time */
15140 	rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
15141 #endif
15142 
15143 	/* TBTT hold time: 0x540[19:8] */
15144 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
15145 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15146 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
15147 }
15148 
StopTxBeacon(_adapter * padapter)15149 void StopTxBeacon(_adapter *padapter)
15150 {
15151 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15152 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
15153 
15154 	/* TBTT hold time: 0x540[19:8] */
15155 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
15156 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15157 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
15158 }
15159 #endif /* CONFIG_HAS_TX_BEACON_PAUSE */
15160 
15161 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
15162 
15163 #ifdef CONFIG_CLIENT_PORT_CFG
15164 const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
15165 	CLT_PORT0,
15166 	CLT_PORT1,
15167 	CLT_PORT2,
15168 	CLT_PORT3
15169 };
15170 
rtw_clt_port_init(struct clt_port_t * cltp)15171 void rtw_clt_port_init(struct clt_port_t  *cltp)
15172 {
15173 	cltp->bmp = 0;
15174 	cltp->num = 0;
15175 	_rtw_spinlock_init(&cltp->lock);
15176 }
rtw_clt_port_deinit(struct clt_port_t * cltp)15177 void rtw_clt_port_deinit(struct clt_port_t *cltp)
15178 {
15179 	_rtw_spinlock_free(&cltp->lock);
15180 }
_hw_client_port_alloc(_adapter * adapter)15181 static void _hw_client_port_alloc(_adapter *adapter)
15182 {
15183 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15184 	struct clt_port_t  *cltp = &dvobj->clt_port;
15185 	_irqL irql;
15186 	int i;
15187 
15188 	#if 0
15189 	if (cltp->num > MAX_CLIENT_PORT_NUM) {
15190 		RTW_ERR(ADPT_FMT" cann't  alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
15191 		rtw_warn_on(1);
15192 		return;
15193 	}
15194 	#endif
15195 
15196 	if (adapter->client_id !=  MAX_CLIENT_PORT_NUM) {
15197 		RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
15198 			ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
15199 		return;
15200 	}
15201 	_enter_critical_bh(&cltp->lock, &irql);
15202 	for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
15203 		if (!(cltp->bmp & BIT(i)))
15204 			break;
15205 	}
15206 
15207 	if (i < MAX_CLIENT_PORT_NUM) {
15208 		adapter->client_id = i;
15209 		cltp->bmp |= BIT(i);
15210 		adapter->client_port = _clt_port_id[i];
15211 	}
15212 	cltp->num++;
15213 	_exit_critical_bh(&cltp->lock, &irql);
15214 	RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
15215 		__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
15216 }
_hw_client_port_free(_adapter * adapter)15217 static void _hw_client_port_free(_adapter *adapter)
15218 {
15219 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15220 	struct clt_port_t  *cltp = &dvobj->clt_port;
15221 	_irqL irql;
15222 
15223 	#if 0
15224 	if (adapter->client_id >=  MAX_CLIENT_PORT_NUM) {
15225 		RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
15226 		/*rtw_warn_on(1);*/
15227 	}
15228 	#endif
15229 
15230 	RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
15231 		__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
15232 
15233 	_enter_critical_bh(&cltp->lock, &irql);
15234 	if (adapter->client_id !=  MAX_CLIENT_PORT_NUM) {
15235 		cltp->bmp &= ~ BIT(adapter->client_id);
15236 		adapter->client_id = MAX_CLIENT_PORT_NUM;
15237 		adapter->client_port = CLT_PORT_INVALID;
15238 	}
15239 	cltp->num--;
15240 	if (cltp->num < 0)
15241 		cltp->num = 0;
15242 	_exit_critical_bh(&cltp->lock, &irql);
15243 }
rtw_hw_client_port_allocate(_adapter * adapter)15244 void rtw_hw_client_port_allocate(_adapter *adapter)
15245 {
15246 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15247 
15248 	if (hal_spec->port_num != 5)
15249 		return;
15250 
15251 	_hw_client_port_alloc(adapter);
15252 }
rtw_hw_client_port_release(_adapter * adapter)15253 void rtw_hw_client_port_release(_adapter *adapter)
15254 {
15255 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15256 
15257 	if (hal_spec->port_num != 5)
15258 		return;
15259 
15260 	_hw_client_port_free(adapter);
15261 }
15262 #endif /*CONFIG_CLIENT_PORT_CFG*/
15263 
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)15264 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
15265 {
15266 	RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
15267 
15268 	rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
15269 
15270 	/* set net_type */
15271 	Set_MSR(Adapter, mode);
15272 
15273 	if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
15274 		if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
15275 			StopTxBeacon(Adapter);
15276 	} else if (mode == _HW_STATE_ADHOC_)
15277 		ResumeTxBeacon(Adapter);
15278 	else if (mode == _HW_STATE_AP_)
15279 		/* enable rx ps-poll */
15280 		rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
15281 
15282 	/* enable rx data frame */
15283 	rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
15284 
15285 #ifdef CONFIG_CLIENT_PORT_CFG
15286 	if (mode == _HW_STATE_STATION_)
15287 		rtw_hw_client_port_allocate(Adapter);
15288 	else
15289 		rtw_hw_client_port_release(Adapter);
15290 #endif
15291 #if defined(CONFIG_RTL8192F)
15292 		rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
15293 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
15294 #endif
15295 }
15296 #endif
15297 
15298 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)15299 u8	rtw_hal_antdiv_before_linked(_adapter *padapter)
15300 {
15301 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15302 	u8 cur_ant, change_ant;
15303 
15304 	if (!pHalData->AntDivCfg)
15305 		return _FALSE;
15306 
15307 	if (pHalData->sw_antdiv_bl_state == 0) {
15308 		pHalData->sw_antdiv_bl_state = 1;
15309 
15310 		rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
15311 		change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
15312 
15313 		return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
15314 	}
15315 
15316 	pHalData->sw_antdiv_bl_state = 0;
15317 	return _FALSE;
15318 }
15319 
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)15320 void	rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
15321 {
15322 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15323 
15324 	if (pHalData->AntDivCfg) {
15325 		/*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
15326 		/*select optimum_antenna for before linked =>For antenna diversity*/
15327 		if (dst->Rssi >=  src->Rssi) {/*keep org parameter*/
15328 			src->Rssi = dst->Rssi;
15329 			src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
15330 		}
15331 	}
15332 }
15333 #endif
15334 
15335 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)15336 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
15337 {
15338 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
15339 	struct phy_spec_t *phy_spec = &pHalData->phy_spec;
15340 
15341 	RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
15342 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
15343 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
15344 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index	[15:8]*/
15345 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index	[7:0]*/
15346 
15347 	RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
15348 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT STBC Tx [31:24]*/
15349 	/*VHT STBC Rx [23:16]
15350 	0 = not support
15351 	1 = support for 1 spatial stream
15352 	2 = support for 1 or 2 spatial streams
15353 	3 = support for 1 or 2 or 3 spatial streams
15354 	4 = support for 1 or 2 or 3 or 4 spatial streams*/
15355 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
15356 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT STBC Tx [15:8]*/
15357 	/*HT STBC Rx [7:0]
15358 	0 = not support
15359 	1 = support for 1 spatial stream
15360 	2 = support for 1 or 2 spatial streams
15361 	3 = support for 1 or 2 or 3 spatial streams*/
15362 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
15363 
15364 	RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
15365 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Tx [31:24]*/
15366 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Rx : %s\n", ((phy_spec->ldpc_cap >> 16) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Rx [23:16]*/
15367 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Tx [15:8]*/
15368 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Rx : %s\n\n", (phy_spec->ldpc_cap & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Rx [7:0]*/
15369 	#ifdef CONFIG_BEAMFORMING
15370 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
15371 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfer : %s\n", ((phy_spec->txbf_cap >> 28) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfer [31:28]*/
15372 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfee : %s\n", ((phy_spec->txbf_cap >> 24) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfee [27:24]*/
15373 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfer : %s\n", ((phy_spec->txbf_cap >> 20) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfer [23:20]*/
15374 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfee : %s\n", ((phy_spec->txbf_cap >> 16) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfee [19:16]*/
15375 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF)  ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
15376 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
15377 
15378 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
15379 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
15380 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
15381 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
15382 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
15383 	#endif
15384 }
15385 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)15386 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
15387 {
15388 	u8 phy_cap = _FALSE;
15389 
15390 	/* STBC */
15391 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
15392 	RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15393 
15394 	phy_cap = _FALSE;
15395 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
15396 	RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15397 
15398 	/* LDPC support */
15399 	phy_cap = _FALSE;
15400 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
15401 	RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15402 
15403 	phy_cap = _FALSE;
15404 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
15405 	RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15406 
15407 	#ifdef CONFIG_BEAMFORMING
15408 	phy_cap = _FALSE;
15409 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
15410 	RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15411 
15412 	phy_cap = _FALSE;
15413 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
15414 	RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15415 
15416 	phy_cap = _FALSE;
15417 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
15418 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15419 
15420 	phy_cap = _FALSE;
15421 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
15422 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15423 	#endif
15424 }
15425 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)15426 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
15427 {
15428 	RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
15429 #ifdef CONFIG_PHY_CAPABILITY_QUERY
15430 	rtw_dump_phy_cap_by_phydmapi(sel, adapter);
15431 #else
15432 	rtw_dump_phy_cap_by_hal(sel, adapter);
15433 #endif
15434 }
15435 
translate_dbm_to_percentage(s16 signal)15436 inline s16 translate_dbm_to_percentage(s16 signal)
15437 {
15438 	if ((signal <= -100) || (signal >= 20))
15439 		return	0;
15440 	else if (signal >= 0)
15441 		return	100;
15442 	else
15443 		return 100 + signal;
15444 }
15445 
15446 #ifdef CONFIG_SWTIMER_BASED_TXBCN
15447 #ifdef CONFIG_BCN_RECOVERY
15448 #define REG_CPU_MGQ_INFO	0x041C
15449 #define BIT_BCN_POLL			BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)15450 u8 rtw_ap_bcn_recovery(_adapter *padapter)
15451 {
15452 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15453 
15454 	if (hal_data->issue_bcn_fail >= 2) {
15455 		RTW_ERR("%s ISSUE BCN Fail\n", __func__);
15456 		rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
15457 		hal_data->issue_bcn_fail = 0;
15458 	}
15459 	return _SUCCESS;
15460 }
15461 #endif /*CONFIG_BCN_RECOVERY*/
15462 
15463 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)15464 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
15465 {
15466 	u32 start_time = rtw_get_current_time();
15467 	u8 bcn_queue_empty = _FALSE;
15468 
15469 	do {
15470 		if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
15471 			bcn_queue_empty = _TRUE;
15472 			break;
15473 		}
15474 	} while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
15475 
15476 	if (bcn_queue_empty == _FALSE)
15477 		RTW_ERR("%s BCN queue not empty\n", __func__);
15478 
15479 	return bcn_queue_empty;
15480 }
15481 #endif /*CONFIG_BCN_XMIT_PROTECT*/
15482 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
15483 
15484 /**
15485  * rtw_hal_get_trx_path() - Get RF path related information
15486  * @d:		struct dvobj_priv*
15487  * @type:	RF type, nTnR
15488  * @tx:		Tx path
15489  * @rx:		Rx path
15490  *
15491  * Get RF type, TX path and RX path information.
15492  */
rtw_hal_get_trx_path(struct dvobj_priv * d,enum rf_type * type,enum bb_path * tx,enum bb_path * rx)15493 void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
15494 			 enum bb_path *tx, enum bb_path *rx)
15495 {
15496 	struct _ADAPTER *a = dvobj_get_primary_adapter(d);
15497 	enum rf_type t = GET_HAL_RFPATH(a);
15498 
15499 	if (type)
15500 		*type = t;
15501 
15502 	if (tx || rx) {
15503 		u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
15504 		u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
15505 
15506 		if (!tx_bmp && !rx_bmp)
15507 			rf_type_to_default_trx_bmp(t, tx, rx);
15508 		else {
15509 			if (tx)
15510 				*tx = GET_HAL_TX_PATH_BMP(a);
15511 			if (rx)
15512 				*rx = GET_HAL_RX_PATH_BMP(a);
15513 		}
15514 	}
15515 }
15516 
15517 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
rtw_hal_switch_chnl_and_set_bw_offload(_adapter * adapter,u8 central_ch,u8 pri_ch_idx,u8 bw)15518 void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
15519 {
15520 	u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
15521 	PHAL_DATA_TYPE hal;
15522 	struct submit_ctx *chsw_sctx;
15523 
15524 	hal = GET_HAL_DATA(adapter);
15525 	chsw_sctx = &hal->chsw_sctx;
15526 
15527 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
15528 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
15529 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
15530 
15531 	rtw_sctx_init(chsw_sctx, 10);
15532 	rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
15533 	rtw_sctx_wait(chsw_sctx, __func__);
15534 }
15535 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
15536 
phy_get_current_tx_num(PADAPTER pAdapter,u8 Rate)15537 u8 phy_get_current_tx_num(
15538 		PADAPTER		pAdapter,
15539 		u8				Rate
15540 )
15541 {
15542 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(pAdapter);
15543 	u8	tx_num = 0;
15544 
15545 	if (IS_1T_RATE(Rate))
15546 		tx_num = hal_data->txpath_num_nss[0];
15547 	else if (IS_2T_RATE(Rate))
15548 		tx_num = hal_data->txpath_num_nss[1];
15549 	else if (IS_3T_RATE(Rate))
15550 		tx_num = hal_data->txpath_num_nss[2];
15551 	else if (IS_4T_RATE(Rate))
15552 		tx_num = hal_data->txpath_num_nss[3];
15553 	else
15554 		rtw_warn_on(1);
15555 
15556 	return tx_num == 0 ? RF_1TX : tx_num - 1;
15557 }
15558 
15559 #ifdef CONFIG_RTL8812A
rtw_hal_set_8812a_vendor_ie(_adapter * padapter,u8 * pframe,uint * frlen)15560 u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
15561 	int vender_len = 7;
15562 	unsigned char	vendor_info[vender_len];
15563 	unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
15564 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
15565 
15566 	if( !IS_HARDWARE_TYPE_8812(padapter) )
15567 		return pframe;
15568 
15569 	_rtw_memset(vendor_info,0,vender_len);
15570 	_rtw_memcpy(vendor_info, REALTEK_OUI, 3);
15571 	vendor_info[4] =2;
15572 	if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
15573 		vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
15574 	else
15575 		vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
15576 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
15577 
15578 	return pframe;
15579 }
15580 #endif /*CONFIG_RTL8812A*/
15581 
rtw_enter_protsel(struct protsel * protsel,u32 sel)15582 static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
15583 {
15584 	int refcnt;
15585 
15586 	_enter_critical_mutex(&protsel->mutex, NULL);
15587 
15588 	refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
15589 
15590 	WARN_ON(refcnt > 1 && protsel->sel != sel);
15591 
15592 	protsel->sel = sel;
15593 
15594 	_exit_critical_mutex(&protsel->mutex, NULL);
15595 }
15596 
rtw_leave_protsel(struct protsel * protsel)15597 static inline void rtw_leave_protsel(struct protsel *protsel)
15598 {
15599 	int refcnt;
15600 
15601 	_enter_critical_mutex(&protsel->mutex, NULL);
15602 
15603 	refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
15604 
15605 	_exit_critical_mutex(&protsel->mutex, NULL);
15606 
15607 	WARN_ON(refcnt < 0);
15608 }
15609 
rtw_assert_protsel(struct protsel * protsel)15610 static inline bool rtw_assert_protsel(struct protsel *protsel)
15611 {
15612 	int refcnt = ATOMIC_READ(&protsel->refcnt);
15613 
15614 	if (refcnt > 0)
15615 		return true;
15616 
15617 	return false;
15618 }
15619 
15620 #ifdef CONFIG_PROTSEL_PORT
rtw_enter_protsel_port(_adapter * padapter,u8 port_sel)15621 void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
15622 {
15623 	u8 val8;
15624 
15625 	rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
15626 
15627 	val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
15628 	val8 &= ~BIT_MASK_PORT_CTRL_SEL;
15629 	val8 |= BIT_PORT_CTRL_SEL(port_sel);
15630 	rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
15631 }
15632 
rtw_assert_protsel_port(_adapter * padapter,u32 addr,u8 len)15633 bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
15634 {
15635 	if (!padapter->bup)	/* don't assert before IF up */
15636 		return true;
15637 
15638 	return rtw_assert_protsel(&padapter->dvobj->protsel_port);
15639 }
15640 
rtw_leave_protsel_port(_adapter * padapter)15641 void rtw_leave_protsel_port(_adapter *padapter)
15642 {
15643 	rtw_leave_protsel(&padapter->dvobj->protsel_port);
15644 }
15645 #endif
15646 
15647 #ifdef CONFIG_PROTSEL_ATIMDTIM
rtw_enter_protsel_atimdtim(_adapter * padapter,u8 port_sel)15648 void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
15649 {
15650 	/* 0~15 is for port 0 MBSSID setting
15651 	 * 16 is for port 1 setting
15652 	 * 17 is for port 2 setting
15653 	 * 18 is for port 3 setting
15654 	 * 19 is for port 4 setting
15655 	 */
15656 	u8 val8;
15657 
15658 	if (port_sel >= 1 && port_sel <= 4)
15659 		port_sel += 15;
15660 
15661 	rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
15662 
15663 	val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
15664 	val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
15665 	val8 |= BIT_ATIM_DTIM_SEL(port_sel);
15666 	rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
15667 }
15668 
rtw_assert_protsel_atimdtim(_adapter * padapter,u32 addr,u8 len)15669 bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
15670 {
15671 	return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
15672 }
15673 
rtw_leave_protsel_atimdtim(_adapter * padapter)15674 void rtw_leave_protsel_atimdtim(_adapter *padapter)
15675 {
15676 	rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
15677 }
15678 #endif
15679 
15680 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_enter_protsel_macsleep(_adapter * padapter,u8 sel)15681 void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
15682 {
15683 	u32 val32;
15684 
15685 	rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
15686 
15687 	val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
15688 	val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
15689 	val32 |= BIT_MACID_SLEEP_SEL(sel);
15690 	rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
15691 }
15692 
rtw_assert_protsel_macsleep(_adapter * padapter,u32 addr,u8 len)15693 bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
15694 {
15695 	return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
15696 }
15697 
rtw_leave_protsel_macsleep(_adapter * padapter)15698 void rtw_leave_protsel_macsleep(_adapter *padapter)
15699 {
15700 	rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
15701 }
15702 #endif
15703