xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/hal_com.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2017 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define _HAL_COM_C_
16 
17 #include <drv_types.h>
18 #include "hal_com_h2c.h"
19 
20 #include "hal_data.h"
21 
22 #ifdef RTW_HALMAC
23 #include "../../hal/hal_halmac.h"
24 #endif
25 
rtw_dump_fw_info(void * sel,_adapter * adapter)26 void rtw_dump_fw_info(void *sel, _adapter *adapter)
27 {
28 	HAL_DATA_TYPE	*hal_data = NULL;
29 
30 	if (!adapter)
31 		return;
32 
33 	hal_data = GET_HAL_DATA(adapter);
34 	if (hal_data->bFWReady)
35 		RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);
36 	else
37 		RTW_PRINT_SEL(sel, "FW not ready\n");
38 }
39 
rsvd_page_cache_update_all(struct rsvd_page_cache_t * cache,u8 loc,u8 txdesc_len,u32 page_size,u8 * info,u32 info_len)40 bool rsvd_page_cache_update_all(struct rsvd_page_cache_t *cache, u8 loc
41 	, u8 txdesc_len, u32 page_size, u8 *info, u32 info_len)
42 {
43 	u8 page_num;
44 	bool modified = 0;
45 	bool loc_mod = 0, size_mod = 0, page_num_mod = 0;
46 
47 	page_num = info_len ? (u8)PageNum(txdesc_len + info_len, page_size) : 0;
48 	if (!info_len)
49 		loc = 0;
50 
51 	if (cache->loc != loc) {
52 		RTW_INFO("%s %s loc change (%u -> %u)\n"
53 			, __func__, cache->name, cache->loc, loc);
54 		loc_mod = 1;
55 	}
56 	if (cache->size != info_len) {
57 		RTW_INFO("%s %s size change (%u -> %u)\n"
58 			, __func__, cache->name, cache->size, info_len);
59 		size_mod = 1;
60 	}
61 	if (cache->page_num != page_num) {
62 		RTW_INFO("%s %s page_num change (%u -> %u)\n"
63 			, __func__, cache->name, cache->page_num, page_num);
64 		page_num_mod = 1;
65 	}
66 
67 	if (info && info_len) {
68 		if (cache->data) {
69 			if (cache->size == info_len) {
70 				if (_rtw_memcmp(cache->data, info, info_len) != _TRUE) {
71 					RTW_INFO("%s %s data change\n", __func__, cache->name);
72 					modified = 1;
73 				}
74 			} else
75 				rsvd_page_cache_free_data(cache);
76 		}
77 
78 		if (!cache->data) {
79 			cache->data = rtw_malloc(info_len);
80 			if (!cache->data) {
81 				RTW_ERR("%s %s alloc data with size(%u) fail\n"
82 					, __func__, cache->name, info_len);
83 				rtw_warn_on(1);
84 			} else {
85 				RTW_INFO("%s %s alloc data with size(%u)\n"
86 					, __func__, cache->name, info_len);
87 			}
88 			modified = 1;
89 		}
90 
91 		if (cache->data && modified)
92 			_rtw_memcpy(cache->data, info, info_len);
93 	} else {
94 		if (cache->data && size_mod)
95 			rsvd_page_cache_free_data(cache);
96 	}
97 
98 	cache->loc = loc;
99 	cache->page_num = page_num;
100 	cache->size = info_len;
101 
102 	return modified | loc_mod | size_mod | page_num_mod;
103 }
104 
rsvd_page_cache_update_data(struct rsvd_page_cache_t * cache,u8 * info,u32 info_len)105 bool rsvd_page_cache_update_data(struct rsvd_page_cache_t *cache, u8 *info, u32 info_len)
106 {
107 	bool modified = 0;
108 
109 	if (!info || !info_len) {
110 		RTW_WARN("%s %s invalid input(info:%p, info_len:%u)\n"
111 			, __func__, cache->name, info, info_len);
112 		goto exit;
113 	}
114 
115 	if (!cache->loc || !cache->page_num || !cache->size) {
116 		RTW_ERR("%s %s layout not ready(loc:%u, page_num:%u, size:%u)\n"
117 			, __func__, cache->name, cache->loc, cache->page_num, cache->size);
118 		rtw_warn_on(1);
119 		goto exit;
120 	}
121 
122 	if (cache->size != info_len) {
123 		RTW_ERR("%s %s size(%u) differ with info_len(%u)\n"
124 			, __func__, cache->name, cache->size, info_len);
125 		rtw_warn_on(1);
126 		goto exit;
127 	}
128 
129 	if (!cache->data) {
130 		cache->data = rtw_zmalloc(cache->size);
131 		if (!cache->data) {
132 			RTW_ERR("%s %s alloc data with size(%u) fail\n"
133 				, __func__, cache->name, cache->size);
134 			rtw_warn_on(1);
135 			goto exit;
136 		} else {
137 			RTW_INFO("%s %s alloc data with size(%u)\n"
138 				, __func__, cache->name, info_len);
139 		}
140 		modified = 1;
141 	}
142 
143 	if (_rtw_memcmp(cache->data, info, cache->size) == _FALSE) {
144 		RTW_INFO("%s %s data change\n", __func__, cache->name);
145 		_rtw_memcpy(cache->data, info, cache->size);
146 		modified = 1;
147 	}
148 
149 exit:
150 	return modified;
151 }
152 
rsvd_page_cache_free_data(struct rsvd_page_cache_t * cache)153 void rsvd_page_cache_free_data(struct rsvd_page_cache_t *cache)
154 {
155 	if (cache->data) {
156 		rtw_mfree(cache->data, cache->size);
157 		cache->data = NULL;
158 	}
159 }
160 
rsvd_page_cache_free(struct rsvd_page_cache_t * cache)161 void rsvd_page_cache_free(struct rsvd_page_cache_t *cache)
162 {
163 	cache->loc = 0;
164 	cache->page_num = 0;
165 	rsvd_page_cache_free_data(cache);
166 	cache->size = 0;
167 }
168 
169 /* #define CONFIG_GTK_OL_DBG */
170 
171 /*#define DBG_SEC_CAM_MOVE*/
172 #ifdef DBG_SEC_CAM_MOVE
rtw_hal_move_sta_gk_to_dk(_adapter * adapter)173 void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
174 {
175 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
176 	int cam_id, index = 0;
177 	u8 *addr = NULL;
178 
179 	if (!MLME_IS_STA(adapter))
180 		return;
181 
182 	addr = get_bssid(pmlmepriv);
183 
184 	if (addr == NULL) {
185 		RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
186 		return;
187 	}
188 
189 	rtw_clean_dk_section(adapter);
190 
191 	do {
192 		cam_id = rtw_camid_search(adapter, addr, index, 1);
193 
194 		if (cam_id == -1)
195 			RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
196 		else
197 			rtw_sec_cam_swap(adapter, cam_id, index);
198 
199 		index++;
200 	} while (index < 4);
201 
202 }
203 
rtw_hal_read_sta_dk_key(_adapter * adapter,u8 key_id)204 void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
205 {
206 	struct security_priv *psecuritypriv = &adapter->securitypriv;
207 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
208 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
209 	_irqL irqL;
210 	u8 get_key[16];
211 
212 	_rtw_memset(get_key, 0, sizeof(get_key));
213 
214 	if (key_id > 4) {
215 		RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
216 		rtw_warn_on(1);
217 		return;
218 	}
219 	rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
220 
221 	/*update key into related sw variable*/
222 	_enter_critical_bh(&cam_ctl->lock, &irqL);
223 	if (_rtw_camid_is_gk(adapter, key_id)) {
224 		RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
225 		RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
226 	}
227 	_exit_critical_bh(&cam_ctl->lock, &irqL);
228 
229 }
230 #endif
231 
232 
233 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
234 	char	rtw_phy_para_file_path[PATH_LENGTH_MAX];
235 #endif
236 
dump_chip_info(HAL_VERSION ChipVersion)237 void dump_chip_info(HAL_VERSION	ChipVersion)
238 {
239 	int cnt = 0;
240 	u8 buf[128] = {0};
241 
242 	if (IS_8188E(ChipVersion))
243 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
244 	else if (IS_8188F(ChipVersion))
245 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
246 	else if (IS_8188GTV(ChipVersion))
247 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188GTV_");
248 	else if (IS_8812_SERIES(ChipVersion))
249 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
250 	else if (IS_8192E(ChipVersion))
251 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
252 	else if (IS_8821_SERIES(ChipVersion))
253 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
254 	else if (IS_8723B_SERIES(ChipVersion))
255 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
256 	else if (IS_8703B_SERIES(ChipVersion))
257 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
258 	else if (IS_8723D_SERIES(ChipVersion))
259 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
260 	else if (IS_8814A_SERIES(ChipVersion))
261 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
262 	else if (IS_8822B_SERIES(ChipVersion))
263 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
264 	else if (IS_8821C_SERIES(ChipVersion))
265 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
266 	else if (IS_8710B_SERIES(ChipVersion))
267 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8710B_");
268 	else if (IS_8192F_SERIES(ChipVersion))
269 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192F_");
270 	else if (IS_8822C_SERIES(ChipVersion))
271 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822C_");
272 	else if (IS_8814B_SERIES(ChipVersion))
273 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814B_");
274 	else if (IS_8723F_SERIES(ChipVersion))
275 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723F_");
276 	else
277 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
278 
279 	cnt += sprintf((buf + cnt), "%s", IS_NORMAL_CHIP(ChipVersion) ? "" : "T_");
280 
281 	if (IS_CHIP_VENDOR_TSMC(ChipVersion))
282 		cnt += sprintf((buf + cnt), "%s", "T");
283 	else if (IS_CHIP_VENDOR_UMC(ChipVersion))
284 		cnt += sprintf((buf + cnt), "%s", "U");
285 	else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
286 		cnt += sprintf((buf + cnt), "%s", "S");
287 
288 	if (IS_A_CUT(ChipVersion))
289 		cnt += sprintf((buf + cnt), "1_");
290 	else if (IS_B_CUT(ChipVersion))
291 		cnt += sprintf((buf + cnt), "2_");
292 	else if (IS_C_CUT(ChipVersion))
293 		cnt += sprintf((buf + cnt), "3_");
294 	else if (IS_D_CUT(ChipVersion))
295 		cnt += sprintf((buf + cnt), "4_");
296 	else if (IS_E_CUT(ChipVersion))
297 		cnt += sprintf((buf + cnt), "5_");
298 	else if (IS_F_CUT(ChipVersion))
299 		cnt += sprintf((buf + cnt), "6_");
300 	else if (IS_I_CUT(ChipVersion))
301 		cnt += sprintf((buf + cnt), "9_");
302 	else if (IS_J_CUT(ChipVersion))
303 		cnt += sprintf((buf + cnt), "10_");
304 	else if (IS_K_CUT(ChipVersion))
305 		cnt += sprintf((buf + cnt), "11_");
306 	else
307 		cnt += sprintf((buf + cnt), "UNKNOWN_Cv(%d)_", ChipVersion.CUTVersion);
308 
309 	if (IS_1T1R(ChipVersion))
310 		cnt += sprintf((buf + cnt), "1T1R_");
311 	else if (IS_1T2R(ChipVersion))
312 		cnt += sprintf((buf + cnt), "1T2R_");
313 	else if (IS_2T2R(ChipVersion))
314 		cnt += sprintf((buf + cnt), "2T2R_");
315 	else if (IS_3T3R(ChipVersion))
316 		cnt += sprintf((buf + cnt), "3T3R_");
317 	else if (IS_3T4R(ChipVersion))
318 		cnt += sprintf((buf + cnt), "3T4R_");
319 	else if (IS_4T4R(ChipVersion))
320 		cnt += sprintf((buf + cnt), "4T4R_");
321 	else
322 		cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
323 
324 	cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
325 
326 	RTW_INFO("%s", buf);
327 }
328 
rtw_hal_get_port(_adapter * adapter)329 u8 rtw_hal_get_port(_adapter *adapter)
330 {
331 	u8 hw_port = get_hw_port(adapter);
332 #ifdef CONFIG_CLIENT_PORT_CFG
333 	u8 clt_port = get_clt_port(adapter);
334 
335 	if (clt_port)
336 		hw_port = clt_port;
337 
338 #ifdef DBG_HW_PORT
339 	if (MLME_IS_STA(adapter) && (adapter->client_id != MAX_CLIENT_PORT_NUM)) {
340 		if(hw_port == CLT_PORT_INVALID) {
341 			RTW_ERR(ADPT_FMT" @@@@@ Client port == 0 @@@@@\n", ADPT_ARG(adapter));
342 			rtw_warn_on(1);
343 		}
344 	}
345 	#ifdef CONFIG_AP_MODE
346 	else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
347 		if (hw_port != HW_PORT0) {
348 			RTW_ERR(ADPT_FMT" @@@@@ AP / MESH port != 0 @@@@@\n", ADPT_ARG(adapter));
349 			rtw_warn_on(1);
350 		}
351 	}
352 	#endif
353 	if (0)
354 		RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter));
355 #endif /*DBG_HW_PORT*/
356 
357 #endif/*CONFIG_CLIENT_PORT_CFG*/
358 
359 	return hw_port;
360 }
361 
362 #define	EEPROM_CHANNEL_PLAN_BY_HW_MASK	0x80
363 
364 /*
365  * Description:
366  *	Use hardware(efuse), driver parameter(registry) and default channel plan
367  *	to decide which one should be used.
368  *
369  * Parameters:
370  *	padapter			pointer of adapter
371  *	hw_alpha2		country code from HW (efuse/eeprom/mapfile)
372  *	hw_chplan		channel plan from HW (efuse/eeprom/mapfile)
373  *						BIT[7] software configure mode; 0:Enable, 1:disable
374  *						BIT[6:0] Channel Plan
375  *	sw_alpha2		country code from HW (registry/module param)
376  *	sw_chplan		channel plan from SW (registry/module param)
377  *	AutoLoadFail		efuse autoload fail or not
378  *
379  */
hal_com_config_channel_plan(PADAPTER padapter,char * hw_alpha2,u8 hw_chplan,char * sw_alpha2,u8 sw_chplan,BOOLEAN AutoLoadFail)380 void hal_com_config_channel_plan(
381 		PADAPTER padapter,
382 		char *hw_alpha2,
383 		u8 hw_chplan,
384 		char *sw_alpha2,
385 		u8 sw_chplan,
386 		BOOLEAN AutoLoadFail
387 )
388 {
389 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
390 	PHAL_DATA_TYPE	pHalData;
391 	u8 force_hw_chplan = _FALSE;
392 	int chplan = -1;
393 	const struct country_chplan *country_ent = NULL, *ent;
394 	u8 def_chplan = 0x7F; /* Realtek define,  used when HW, SW both invalid */
395 
396 	pHalData = GET_HAL_DATA(padapter);
397 
398 	/* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
399 	if (hw_chplan == 0xFF)
400 		goto chk_hw_country_code;
401 
402 	if (AutoLoadFail == _TRUE)
403 		goto chk_sw_config;
404 
405 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
406 	if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
407 		force_hw_chplan = _TRUE;
408 #endif
409 
410 	hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
411 
412 chk_hw_country_code:
413 	if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
414 		ent = rtw_get_chplan_from_country(hw_alpha2);
415 		if (ent) {
416 			/* get chplan from hw country code, by pass hw chplan setting */
417 			country_ent = ent;
418 			chplan = ent->chplan;
419 			goto chk_sw_config;
420 		} else
421 			RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
422 	}
423 
424 	if (rtw_is_channel_plan_valid(hw_chplan))
425 		chplan = hw_chplan;
426 	else if (force_hw_chplan == _TRUE) {
427 		RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
428 		/* hw infomaton invalid, refer to sw information */
429 		force_hw_chplan = _FALSE;
430 	}
431 
432 chk_sw_config:
433 	if (force_hw_chplan == _TRUE)
434 		goto done;
435 
436 	if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
437 		ent = rtw_get_chplan_from_country(sw_alpha2);
438 		if (ent) {
439 			/* get chplan from sw country code, by pass sw chplan setting */
440 			country_ent = ent;
441 			chplan = ent->chplan;
442 			goto done;
443 		} else
444 			RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
445 	}
446 
447 	if (rtw_is_channel_plan_valid(sw_chplan)) {
448 		/* cancel hw_alpha2 because chplan is specified by sw_chplan*/
449 		country_ent = NULL;
450 		chplan = sw_chplan;
451 	} else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
452 		RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
453 
454 done:
455 	if (chplan == -1) {
456 		RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
457 		chplan = def_chplan;
458 	} else if (country_ent) {
459 		RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
460 			, country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
461 	} else
462 		RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
463 
464 	rfctl->country_ent = country_ent;
465 	rfctl->ChannelPlan = chplan;
466 	pHalData->bDisableSWChannelPlan = force_hw_chplan;
467 }
468 
469 BOOLEAN
HAL_IsLegalChannel(PADAPTER Adapter,u32 Channel)470 HAL_IsLegalChannel(
471 		PADAPTER	Adapter,
472 		u32			Channel
473 )
474 {
475 	BOOLEAN bLegalChannel = _TRUE;
476 
477 	if (Channel > 14) {
478 		if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
479 			bLegalChannel = _FALSE;
480 			RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
481 		}
482 	} else if ((Channel <= 14) && (Channel >= 1)) {
483 		if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
484 			bLegalChannel = _FALSE;
485 			RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
486 		}
487 	} else {
488 		bLegalChannel = _FALSE;
489 		RTW_INFO("Channel is Invalid !!!\n");
490 	}
491 
492 	return bLegalChannel;
493 }
494 
495 static const u8 _MRateToHwRate[MGN_UNKNOWN] = {
496 	[MGN_1M] = DESC_RATE1M,
497 	[MGN_2M] = DESC_RATE2M,
498 	[MGN_5_5M] = DESC_RATE5_5M,
499 	[MGN_11M] = DESC_RATE11M,
500 	[MGN_6M] = DESC_RATE6M,
501 	[MGN_9M] = DESC_RATE9M,
502 	[MGN_12M] = DESC_RATE12M,
503 	[MGN_18M] = DESC_RATE18M,
504 	[MGN_24M] = DESC_RATE24M,
505 	[MGN_36M] = DESC_RATE36M,
506 	[MGN_48M] = DESC_RATE48M,
507 	[MGN_54M] = DESC_RATE54M,
508 	[MGN_MCS0] = DESC_RATEMCS0,
509 	[MGN_MCS1] = DESC_RATEMCS1,
510 	[MGN_MCS2] = DESC_RATEMCS2,
511 	[MGN_MCS3] = DESC_RATEMCS3,
512 	[MGN_MCS4] = DESC_RATEMCS4,
513 	[MGN_MCS5] = DESC_RATEMCS5,
514 	[MGN_MCS6] = DESC_RATEMCS6,
515 	[MGN_MCS7] = DESC_RATEMCS7,
516 	[MGN_MCS8] = DESC_RATEMCS8,
517 	[MGN_MCS9] = DESC_RATEMCS9,
518 	[MGN_MCS10] = DESC_RATEMCS10,
519 	[MGN_MCS11] = DESC_RATEMCS11,
520 	[MGN_MCS12] = DESC_RATEMCS12,
521 	[MGN_MCS13] = DESC_RATEMCS13,
522 	[MGN_MCS14] = DESC_RATEMCS14,
523 	[MGN_MCS15] = DESC_RATEMCS15,
524 	[MGN_MCS16] = DESC_RATEMCS16,
525 	[MGN_MCS17] = DESC_RATEMCS17,
526 	[MGN_MCS18] = DESC_RATEMCS18,
527 	[MGN_MCS19] = DESC_RATEMCS19,
528 	[MGN_MCS20] = DESC_RATEMCS20,
529 	[MGN_MCS21] = DESC_RATEMCS21,
530 	[MGN_MCS22] = DESC_RATEMCS22,
531 	[MGN_MCS23] = DESC_RATEMCS23,
532 	[MGN_MCS24] = DESC_RATEMCS24,
533 	[MGN_MCS25] = DESC_RATEMCS25,
534 	[MGN_MCS26] = DESC_RATEMCS26,
535 	[MGN_MCS27] = DESC_RATEMCS27,
536 	[MGN_MCS28] = DESC_RATEMCS28,
537 	[MGN_MCS29] = DESC_RATEMCS29,
538 	[MGN_MCS30] = DESC_RATEMCS30,
539 	[MGN_MCS31] = DESC_RATEMCS31,
540 	[MGN_VHT1SS_MCS0] = DESC_RATEVHTSS1MCS0,
541 	[MGN_VHT1SS_MCS1] = DESC_RATEVHTSS1MCS1,
542 	[MGN_VHT1SS_MCS2] = DESC_RATEVHTSS1MCS2,
543 	[MGN_VHT1SS_MCS3] = DESC_RATEVHTSS1MCS3,
544 	[MGN_VHT1SS_MCS4] = DESC_RATEVHTSS1MCS4,
545 	[MGN_VHT1SS_MCS5] = DESC_RATEVHTSS1MCS5,
546 	[MGN_VHT1SS_MCS6] = DESC_RATEVHTSS1MCS6,
547 	[MGN_VHT1SS_MCS7] = DESC_RATEVHTSS1MCS7,
548 	[MGN_VHT1SS_MCS8] = DESC_RATEVHTSS1MCS8,
549 	[MGN_VHT1SS_MCS9] = DESC_RATEVHTSS1MCS9,
550 	[MGN_VHT2SS_MCS0] = DESC_RATEVHTSS2MCS0,
551 	[MGN_VHT2SS_MCS1] = DESC_RATEVHTSS2MCS1,
552 	[MGN_VHT2SS_MCS2] = DESC_RATEVHTSS2MCS2,
553 	[MGN_VHT2SS_MCS3] = DESC_RATEVHTSS2MCS3,
554 	[MGN_VHT2SS_MCS4] = DESC_RATEVHTSS2MCS4,
555 	[MGN_VHT2SS_MCS5] = DESC_RATEVHTSS2MCS5,
556 	[MGN_VHT2SS_MCS6] = DESC_RATEVHTSS2MCS6,
557 	[MGN_VHT2SS_MCS7] = DESC_RATEVHTSS2MCS7,
558 	[MGN_VHT2SS_MCS8] = DESC_RATEVHTSS2MCS8,
559 	[MGN_VHT2SS_MCS9] = DESC_RATEVHTSS2MCS9,
560 	[MGN_VHT3SS_MCS0] = DESC_RATEVHTSS3MCS0,
561 	[MGN_VHT3SS_MCS1] = DESC_RATEVHTSS3MCS1,
562 	[MGN_VHT3SS_MCS2] = DESC_RATEVHTSS3MCS2,
563 	[MGN_VHT3SS_MCS3] = DESC_RATEVHTSS3MCS3,
564 	[MGN_VHT3SS_MCS4] = DESC_RATEVHTSS3MCS4,
565 	[MGN_VHT3SS_MCS5] = DESC_RATEVHTSS3MCS5,
566 	[MGN_VHT3SS_MCS6] = DESC_RATEVHTSS3MCS6,
567 	[MGN_VHT3SS_MCS7] = DESC_RATEVHTSS3MCS7,
568 	[MGN_VHT3SS_MCS8] = DESC_RATEVHTSS3MCS8,
569 	[MGN_VHT3SS_MCS9] = DESC_RATEVHTSS3MCS9,
570 	[MGN_VHT4SS_MCS0] = DESC_RATEVHTSS4MCS0,
571 	[MGN_VHT4SS_MCS1] = DESC_RATEVHTSS4MCS1,
572 	[MGN_VHT4SS_MCS2] = DESC_RATEVHTSS4MCS2,
573 	[MGN_VHT4SS_MCS3] = DESC_RATEVHTSS4MCS3,
574 	[MGN_VHT4SS_MCS4] = DESC_RATEVHTSS4MCS4,
575 	[MGN_VHT4SS_MCS5] = DESC_RATEVHTSS4MCS5,
576 	[MGN_VHT4SS_MCS6] = DESC_RATEVHTSS4MCS6,
577 	[MGN_VHT4SS_MCS7] = DESC_RATEVHTSS4MCS7,
578 	[MGN_VHT4SS_MCS8] = DESC_RATEVHTSS4MCS8,
579 	[MGN_VHT4SS_MCS9] = DESC_RATEVHTSS4MCS9,
580 };
581 
MRateToHwRate(enum MGN_RATE rate)582 u8 MRateToHwRate(enum MGN_RATE rate)
583 {
584 	u8 hw_rate = DESC_RATE1M; /* default value, also is zero */
585 
586 	if (rate < MGN_UNKNOWN)
587 		hw_rate = _MRateToHwRate[rate];
588 
589 	if (rate != MGN_1M && hw_rate == DESC_RATE1M)
590 		RTW_WARN("Invalid rate 0x%x in %s\n", rate, __FUNCTION__);
591 
592 	return hw_rate;
593 }
594 
595 const char * const _HDATA_RATE[DESC_RATE_NUM + 1] = {
596 	[DESC_RATE1M] = "CCK_1M",
597 	[DESC_RATE2M] = "CCK_2M",
598 	[DESC_RATE5_5M] = "CCK5_5M",
599 	[DESC_RATE11M] = "CCK_11M",
600 	[DESC_RATE6M] = "OFDM_6M",
601 	[DESC_RATE9M] = "OFDM_9M",
602 	[DESC_RATE12M] = "OFDM_12M",
603 	[DESC_RATE18M] = "OFDM_18M",
604 	[DESC_RATE24M] = "OFDM_24M",
605 	[DESC_RATE36M] = "OFDM_36M",
606 	[DESC_RATE48M] = "OFDM_48M",
607 	[DESC_RATE54M] = "OFDM_54M",
608 	[DESC_RATEMCS0] = "MCS0",
609 	[DESC_RATEMCS1] = "MCS1",
610 	[DESC_RATEMCS2] = "MCS2",
611 	[DESC_RATEMCS3] = "MCS3",
612 	[DESC_RATEMCS4] = "MCS4",
613 	[DESC_RATEMCS5] = "MCS5",
614 	[DESC_RATEMCS6] = "MCS6",
615 	[DESC_RATEMCS7] = "MCS7",
616 	[DESC_RATEMCS8] = "MCS8",
617 	[DESC_RATEMCS9] = "MCS9",
618 	[DESC_RATEMCS10] = "MCS10",
619 	[DESC_RATEMCS11] = "MCS11",
620 	[DESC_RATEMCS12] = "MCS12",
621 	[DESC_RATEMCS13] = "MCS13",
622 	[DESC_RATEMCS14] = "MCS14",
623 	[DESC_RATEMCS15] = "MCS15",
624 	[DESC_RATEMCS16] = "MCS16",
625 	[DESC_RATEMCS17] = "MCS17",
626 	[DESC_RATEMCS18] = "MCS18",
627 	[DESC_RATEMCS19] = "MCS19",
628 	[DESC_RATEMCS20] = "MCS20",
629 	[DESC_RATEMCS21] = "MCS21",
630 	[DESC_RATEMCS22] = "MCS22",
631 	[DESC_RATEMCS23] = "MCS23",
632 	[DESC_RATEMCS24] = "MCS24",
633 	[DESC_RATEMCS25] = "MCS25",
634 	[DESC_RATEMCS26] = "MCS26",
635 	[DESC_RATEMCS27] = "MCS27",
636 	[DESC_RATEMCS28] = "MCS28",
637 	[DESC_RATEMCS29] = "MCS29",
638 	[DESC_RATEMCS30] = "MCS30",
639 	[DESC_RATEMCS31] = "MCS31",
640 	[DESC_RATEVHTSS1MCS0] = "VHT1SMCS0",
641 	[DESC_RATEVHTSS1MCS1] = "VHT1SMCS1",
642 	[DESC_RATEVHTSS1MCS2] = "VHT1SMCS2",
643 	[DESC_RATEVHTSS1MCS3] = "VHT1SMCS3",
644 	[DESC_RATEVHTSS1MCS4] = "VHT1SMCS4",
645 	[DESC_RATEVHTSS1MCS5] = "VHT1SMCS5",
646 	[DESC_RATEVHTSS1MCS6] = "VHT1SMCS6",
647 	[DESC_RATEVHTSS1MCS7] = "VHT1SMCS7",
648 	[DESC_RATEVHTSS1MCS8] = "VHT1SMCS8",
649 	[DESC_RATEVHTSS1MCS9] = "VHT1SMCS9",
650 	[DESC_RATEVHTSS2MCS0] = "VHT2SMCS0",
651 	[DESC_RATEVHTSS2MCS1] = "VHT2SMCS1",
652 	[DESC_RATEVHTSS2MCS2] = "VHT2SMCS2",
653 	[DESC_RATEVHTSS2MCS3] = "VHT2SMCS3",
654 	[DESC_RATEVHTSS2MCS4] = "VHT2SMCS4",
655 	[DESC_RATEVHTSS2MCS5] = "VHT2SMCS5",
656 	[DESC_RATEVHTSS2MCS6] = "VHT2SMCS6",
657 	[DESC_RATEVHTSS2MCS7] = "VHT2SMCS7",
658 	[DESC_RATEVHTSS2MCS8] = "VHT2SMCS8",
659 	[DESC_RATEVHTSS2MCS9] = "VHT2SMCS9",
660 	[DESC_RATEVHTSS3MCS0] = "VHT3SMCS0",
661 	[DESC_RATEVHTSS3MCS1] = "VHT3SMCS1",
662 	[DESC_RATEVHTSS3MCS2] = "VHT3SMCS2",
663 	[DESC_RATEVHTSS3MCS3] = "VHT3SMCS3",
664 	[DESC_RATEVHTSS3MCS4] = "VHT3SMCS4",
665 	[DESC_RATEVHTSS3MCS5] = "VHT3SMCS5",
666 	[DESC_RATEVHTSS3MCS6] = "VHT3SMCS6",
667 	[DESC_RATEVHTSS3MCS7] = "VHT3SMCS7",
668 	[DESC_RATEVHTSS3MCS8] = "VHT3SMCS8",
669 	[DESC_RATEVHTSS3MCS9] = "VHT3SMCS9",
670 	[DESC_RATEVHTSS4MCS0] = "VHT4SMCS0",
671 	[DESC_RATEVHTSS4MCS1] = "VHT4SMCS1",
672 	[DESC_RATEVHTSS4MCS2] = "VHT4SMCS2",
673 	[DESC_RATEVHTSS4MCS3] = "VHT4SMCS3",
674 	[DESC_RATEVHTSS4MCS4] = "VHT4SMCS4",
675 	[DESC_RATEVHTSS4MCS5] = "VHT4SMCS5",
676 	[DESC_RATEVHTSS4MCS6] = "VHT4SMCS6",
677 	[DESC_RATEVHTSS4MCS7] = "VHT4SMCS7",
678 	[DESC_RATEVHTSS4MCS8] = "VHT4SMCS8",
679 	[DESC_RATEVHTSS4MCS9] = "VHT4SMCS9",
680 	[DESC_RATE_NUM] = "UNKNOWN",
681 };
682 
683 static const u8 _hw_rate_to_m_rate[DESC_RATE_NUM] = {
684 	[DESC_RATE1M] = MGN_1M,
685 	[DESC_RATE2M] = MGN_2M,
686 	[DESC_RATE5_5M] = MGN_5_5M,
687 	[DESC_RATE11M] = MGN_11M,
688 	[DESC_RATE6M] = MGN_6M,
689 	[DESC_RATE9M] = MGN_9M,
690 	[DESC_RATE12M] = MGN_12M,
691 	[DESC_RATE18M] = MGN_18M,
692 	[DESC_RATE24M] = MGN_24M,
693 	[DESC_RATE36M] = MGN_36M,
694 	[DESC_RATE48M] = MGN_48M,
695 	[DESC_RATE54M] = MGN_54M,
696 	[DESC_RATEMCS0] = MGN_MCS0,
697 	[DESC_RATEMCS1] = MGN_MCS1,
698 	[DESC_RATEMCS2] = MGN_MCS2,
699 	[DESC_RATEMCS3] = MGN_MCS3,
700 	[DESC_RATEMCS4] = MGN_MCS4,
701 	[DESC_RATEMCS5] = MGN_MCS5,
702 	[DESC_RATEMCS6] = MGN_MCS6,
703 	[DESC_RATEMCS7] = MGN_MCS7,
704 	[DESC_RATEMCS8] = MGN_MCS8,
705 	[DESC_RATEMCS9] = MGN_MCS9,
706 	[DESC_RATEMCS10] = MGN_MCS10,
707 	[DESC_RATEMCS11] = MGN_MCS11,
708 	[DESC_RATEMCS12] = MGN_MCS12,
709 	[DESC_RATEMCS13] = MGN_MCS13,
710 	[DESC_RATEMCS14] = MGN_MCS14,
711 	[DESC_RATEMCS15] = MGN_MCS15,
712 	[DESC_RATEMCS16] = MGN_MCS16,
713 	[DESC_RATEMCS17] = MGN_MCS17,
714 	[DESC_RATEMCS18] = MGN_MCS18,
715 	[DESC_RATEMCS19] = MGN_MCS19,
716 	[DESC_RATEMCS20] = MGN_MCS20,
717 	[DESC_RATEMCS21] = MGN_MCS21,
718 	[DESC_RATEMCS22] = MGN_MCS22,
719 	[DESC_RATEMCS23] = MGN_MCS23,
720 	[DESC_RATEMCS24] = MGN_MCS24,
721 	[DESC_RATEMCS25] = MGN_MCS25,
722 	[DESC_RATEMCS26] = MGN_MCS26,
723 	[DESC_RATEMCS27] = MGN_MCS27,
724 	[DESC_RATEMCS28] = MGN_MCS28,
725 	[DESC_RATEMCS29] = MGN_MCS29,
726 	[DESC_RATEMCS30] = MGN_MCS30,
727 	[DESC_RATEMCS31] = MGN_MCS31,
728 	[DESC_RATEVHTSS1MCS0] = MGN_VHT1SS_MCS0,
729 	[DESC_RATEVHTSS1MCS1] = MGN_VHT1SS_MCS1,
730 	[DESC_RATEVHTSS1MCS2] = MGN_VHT1SS_MCS2,
731 	[DESC_RATEVHTSS1MCS3] = MGN_VHT1SS_MCS3,
732 	[DESC_RATEVHTSS1MCS4] = MGN_VHT1SS_MCS4,
733 	[DESC_RATEVHTSS1MCS5] = MGN_VHT1SS_MCS5,
734 	[DESC_RATEVHTSS1MCS6] = MGN_VHT1SS_MCS6,
735 	[DESC_RATEVHTSS1MCS7] = MGN_VHT1SS_MCS7,
736 	[DESC_RATEVHTSS1MCS8] = MGN_VHT1SS_MCS8,
737 	[DESC_RATEVHTSS1MCS9] = MGN_VHT1SS_MCS9,
738 	[DESC_RATEVHTSS2MCS0] = MGN_VHT2SS_MCS0,
739 	[DESC_RATEVHTSS2MCS1] = MGN_VHT2SS_MCS1,
740 	[DESC_RATEVHTSS2MCS2] = MGN_VHT2SS_MCS2,
741 	[DESC_RATEVHTSS2MCS3] = MGN_VHT2SS_MCS3,
742 	[DESC_RATEVHTSS2MCS4] = MGN_VHT2SS_MCS4,
743 	[DESC_RATEVHTSS2MCS5] = MGN_VHT2SS_MCS5,
744 	[DESC_RATEVHTSS2MCS6] = MGN_VHT2SS_MCS6,
745 	[DESC_RATEVHTSS2MCS7] = MGN_VHT2SS_MCS7,
746 	[DESC_RATEVHTSS2MCS8] = MGN_VHT2SS_MCS8,
747 	[DESC_RATEVHTSS2MCS9] = MGN_VHT2SS_MCS9,
748 	[DESC_RATEVHTSS3MCS0] = MGN_VHT3SS_MCS0,
749 	[DESC_RATEVHTSS3MCS1] = MGN_VHT3SS_MCS1,
750 	[DESC_RATEVHTSS3MCS2] = MGN_VHT3SS_MCS2,
751 	[DESC_RATEVHTSS3MCS3] = MGN_VHT3SS_MCS3,
752 	[DESC_RATEVHTSS3MCS4] = MGN_VHT3SS_MCS4,
753 	[DESC_RATEVHTSS3MCS5] = MGN_VHT3SS_MCS5,
754 	[DESC_RATEVHTSS3MCS6] = MGN_VHT3SS_MCS6,
755 	[DESC_RATEVHTSS3MCS7] = MGN_VHT3SS_MCS7,
756 	[DESC_RATEVHTSS3MCS8] = MGN_VHT3SS_MCS8,
757 	[DESC_RATEVHTSS3MCS9] = MGN_VHT3SS_MCS9,
758 	[DESC_RATEVHTSS4MCS0] = MGN_VHT4SS_MCS0,
759 	[DESC_RATEVHTSS4MCS1] = MGN_VHT4SS_MCS1,
760 	[DESC_RATEVHTSS4MCS2] = MGN_VHT4SS_MCS2,
761 	[DESC_RATEVHTSS4MCS3] = MGN_VHT4SS_MCS3,
762 	[DESC_RATEVHTSS4MCS4] = MGN_VHT4SS_MCS4,
763 	[DESC_RATEVHTSS4MCS5] = MGN_VHT4SS_MCS5,
764 	[DESC_RATEVHTSS4MCS6] = MGN_VHT4SS_MCS6,
765 	[DESC_RATEVHTSS4MCS7] = MGN_VHT4SS_MCS7,
766 	[DESC_RATEVHTSS4MCS8] = MGN_VHT4SS_MCS8,
767 	[DESC_RATEVHTSS4MCS9] = MGN_VHT4SS_MCS9,
768 };
769 
hw_rate_to_m_rate(u8 hw_rate)770 u8 hw_rate_to_m_rate(u8 hw_rate)
771 {
772 	u8 rate = MGN_1M; /* default value */
773 
774 	if (hw_rate < DESC_RATE_NUM)
775 		rate = _hw_rate_to_m_rate[hw_rate];
776 	else
777 		RTW_WARN("Invalid hw_rate 0x%x in %s\n", hw_rate, __FUNCTION__);
778 
779 	return rate;
780 }
781 
782 #ifdef CONFIG_RTW_DEBUG
dump_hw_rate_map_test(void * sel)783 void dump_hw_rate_map_test(void *sel)
784 {
785 	RATE_SECTION rs;
786 	u8 hw_rate;
787 	enum MGN_RATE m_rate;
788 	int i;
789 
790 	for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
791 		for (i = 0; i < rates_by_sections[rs].rate_num; i++) {
792 			hw_rate = MRateToHwRate(rates_by_sections[rs].rates[i]);
793 			RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
794 				, MGN_RATE_STR(rates_by_sections[rs].rates[i]), rates_by_sections[rs].rates[i]
795 				, HDATA_RATE(hw_rate), hw_rate
796 			);
797 		}
798 		if (rs == HT_4SS) { /* show MCS32 after MCS31 */
799 			hw_rate = MRateToHwRate(MGN_MCS32);
800 			RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
801 				, MGN_RATE_STR(MGN_MCS32), MGN_MCS32
802 				, HDATA_RATE(hw_rate), hw_rate
803 			);
804 		}
805 	}
806 	hw_rate = MRateToHwRate(MGN_UNKNOWN);
807 	RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
808 		, MGN_RATE_STR(MGN_UNKNOWN), MGN_UNKNOWN
809 		, HDATA_RATE(hw_rate), hw_rate
810 	);
811 
812 	for (i = DESC_RATE1M; i <= DESC_RATE_NUM; i++) {
813 		m_rate = hw_rate_to_m_rate(i);
814 		RTW_PRINT_SEL(sel, "hw_rate:%s(%d) to m_rate:%s(%d)\n"
815 			, HDATA_RATE(i), i
816 			, MGN_RATE_STR(m_rate), m_rate
817 		);
818 	}
819 }
820 #endif /* CONFIG_RTW_DEBUG */
821 
HalSetBrateCfg(PADAPTER Adapter,u8 * mBratesOS,u16 * pBrateCfg)822 void	HalSetBrateCfg(
823 	PADAPTER		Adapter,
824 	u8			*mBratesOS,
825 	u16			*pBrateCfg)
826 {
827 	u8	i, is_brate, brate;
828 
829 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
830 		is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
831 		brate = mBratesOS[i] & 0x7f;
832 
833 		if (is_brate) {
834 			switch (brate) {
835 			case IEEE80211_CCK_RATE_1MB:
836 				*pBrateCfg |= RATE_1M;
837 				break;
838 			case IEEE80211_CCK_RATE_2MB:
839 				*pBrateCfg |= RATE_2M;
840 				break;
841 			case IEEE80211_CCK_RATE_5MB:
842 				*pBrateCfg |= RATE_5_5M;
843 				break;
844 			case IEEE80211_CCK_RATE_11MB:
845 				*pBrateCfg |= RATE_11M;
846 				break;
847 			case IEEE80211_OFDM_RATE_6MB:
848 				*pBrateCfg |= RATE_6M;
849 				break;
850 			case IEEE80211_OFDM_RATE_9MB:
851 				*pBrateCfg |= RATE_9M;
852 				break;
853 			case IEEE80211_OFDM_RATE_12MB:
854 				*pBrateCfg |= RATE_12M;
855 				break;
856 			case IEEE80211_OFDM_RATE_18MB:
857 				*pBrateCfg |= RATE_18M;
858 				break;
859 			case IEEE80211_OFDM_RATE_24MB:
860 				*pBrateCfg |= RATE_24M;
861 				break;
862 			case IEEE80211_OFDM_RATE_36MB:
863 				*pBrateCfg |= RATE_36M;
864 				break;
865 			case IEEE80211_OFDM_RATE_48MB:
866 				*pBrateCfg |= RATE_48M;
867 				break;
868 			case IEEE80211_OFDM_RATE_54MB:
869 				*pBrateCfg |= RATE_54M;
870 				break;
871 			}
872 		}
873 	}
874 }
875 
876 static void
_OneOutPipeMapping(PADAPTER pAdapter)877 _OneOutPipeMapping(
878 		PADAPTER	pAdapter
879 )
880 {
881 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
882 
883 	pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
884 	pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
885 	pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
886 	pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
887 
888 	pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
889 	pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
890 	pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
891 	pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
892 }
893 
894 static void
_TwoOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)895 _TwoOutPipeMapping(
896 		PADAPTER	pAdapter,
897 		BOOLEAN		bWIFICfg
898 )
899 {
900 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
901 
902 	if (bWIFICfg) { /* WMM */
903 
904 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
905 		/* {  0, 	1, 	0, 	1, 	0, 	0, 	0, 	0, 		0	}; */
906 		/* 0:ep_0 num, 1:ep_1 num */
907 
908 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
909 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
910 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
911 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
912 
913 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
914 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
915 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
916 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
917 
918 	} else { /* typical setting */
919 
920 
921 		/* BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA */
922 		/* {  1, 	1, 	0, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
923 		/* 0:ep_0 num, 1:ep_1 num */
924 
925 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
926 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
927 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
928 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
929 
930 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
931 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
932 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
933 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
934 
935 	}
936 
937 }
938 
_ThreeOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)939 static void _ThreeOutPipeMapping(
940 		PADAPTER	pAdapter,
941 		BOOLEAN		bWIFICfg
942 )
943 {
944 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
945 
946 	if (bWIFICfg) { /* for WMM */
947 
948 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
949 		/* {  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	}; */
950 		/* 0:H, 1:N, 2:L */
951 
952 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
953 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
954 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
955 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
956 
957 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
958 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
959 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
960 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
961 
962 	} else { /* typical setting */
963 
964 
965 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
966 		/* {  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
967 		/* 0:H, 1:N, 2:L */
968 
969 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
970 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
971 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
972 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
973 
974 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
975 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
976 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
977 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
978 	}
979 
980 }
981 #if 0
982 static void _FourOutPipeMapping(
983 		PADAPTER	pAdapter,
984 		BOOLEAN		bWIFICfg
985 )
986 {
987 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
988 
989 	if (bWIFICfg) { /* for WMM */
990 
991 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
992 		/* {  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	}; */
993 		/* 0:H, 1:N, 2:L ,3:E */
994 
995 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
996 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
997 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
998 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
999 
1000 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1001 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1002 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1003 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1004 
1005 	} else { /* typical setting */
1006 
1007 
1008 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1009 		/* {  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
1010 		/* 0:H, 1:N, 2:L */
1011 
1012 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1013 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1014 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1015 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1016 
1017 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1018 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1019 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1020 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
1021 	}
1022 
1023 }
1024 #endif
1025 BOOLEAN
Hal_MappingOutPipe(PADAPTER pAdapter,u8 NumOutPipe)1026 Hal_MappingOutPipe(
1027 		PADAPTER	pAdapter,
1028 		u8		NumOutPipe
1029 )
1030 {
1031 	struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1032 
1033 	BOOLEAN	 bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1034 
1035 	BOOLEAN result = _TRUE;
1036 
1037 	switch (NumOutPipe) {
1038 	case 2:
1039 		_TwoOutPipeMapping(pAdapter, bWIFICfg);
1040 		break;
1041 	case 3:
1042 	case 4:
1043 	case 5:
1044 	case 6:
1045 		_ThreeOutPipeMapping(pAdapter, bWIFICfg);
1046 		break;
1047 	case 1:
1048 		_OneOutPipeMapping(pAdapter);
1049 		break;
1050 	default:
1051 		result = _FALSE;
1052 		break;
1053 	}
1054 
1055 	return result;
1056 
1057 }
1058 
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1059 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1060 {
1061 	if (padapter->hal_func.reqtxrpt)
1062 		padapter->hal_func.reqtxrpt(padapter, macid);
1063 }
1064 
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1065 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1066 {
1067 	int i;
1068 	_adapter *iface;
1069 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1070 	u8 mac_addr[ETH_ALEN];
1071 
1072 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1073 	rtw_mbid_cam_dump(sel, __func__, adapter);
1074 #else
1075 	rtw_mi_hal_dump_macaddr(sel, adapter);
1076 #endif
1077 }
1078 
1079 #ifdef RTW_HALMAC
rtw_hal_hw_port_enable(_adapter * adapter)1080 void rtw_hal_hw_port_enable(_adapter *adapter)
1081 {
1082 #if 1
1083 	u8 port_enable = _TRUE;
1084 
1085 	rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1086 #else
1087 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1088 	struct rtw_halmac_bcn_ctrl bcn_ctrl;
1089 
1090 	_rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
1091 	bcn_ctrl.enable_bcn = 1;
1092 	bcn_ctrl.rx_bssid_fit = 1;
1093 	bcn_ctrl.rxbcn_rpt = 1;
1094 
1095 	/*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1096 				struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
1097 	if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
1098 		RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
1099 		rtw_warn_on(1);
1100 	}
1101 #endif
1102 }
rtw_hal_hw_port_disable(_adapter * adapter)1103 void rtw_hal_hw_port_disable(_adapter *adapter)
1104 {
1105 	u8 port_enable = _FALSE;
1106 
1107 	rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1108 }
1109 
rtw_restore_hw_port_cfg(_adapter * adapter)1110 void rtw_restore_hw_port_cfg(_adapter *adapter)
1111 {
1112 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1113 
1114 #else
1115 	int i;
1116 	_adapter *iface;
1117 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1118 
1119 	for (i = 0; i < dvobj->iface_nums; i++) {
1120 		iface = dvobj->padapters[i];
1121 		if (iface)
1122 			rtw_hal_hw_port_enable(iface);
1123 	}
1124 #endif
1125 }
1126 #endif
1127 
rtw_mi_set_mac_addr(_adapter * adapter)1128 void rtw_mi_set_mac_addr(_adapter *adapter)
1129 {
1130 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1131 	rtw_mi_set_mbid_cam(adapter);
1132 #else
1133 	int i;
1134 	_adapter *iface;
1135 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1136 
1137 	for (i = 0; i < dvobj->iface_nums; i++) {
1138 		iface = dvobj->padapters[i];
1139 		if (iface)
1140 			rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
1141 	}
1142 #endif
1143 	if (0)
1144 		rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1145 }
1146 
rtw_init_hal_com_default_value(PADAPTER Adapter)1147 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1148 {
1149 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
1150 	struct registry_priv *regsty = adapter_to_regsty(Adapter);
1151 
1152 	pHalData->AntDetection = 1;
1153 	pHalData->antenna_test = _FALSE;
1154 	pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
1155 	pHalData->ch_switch_offload = regsty->ch_switch_offload;
1156 	pHalData->multi_ch_switch_mode = 0;
1157 #ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
1158 	if (pHalData->ch_switch_offload == 0)
1159 		pHalData->ch_switch_offload = 1;
1160 #endif
1161 }
1162 
1163 #ifdef CONFIG_FW_C2H_REG
c2h_evt_clear(_adapter * adapter)1164 void c2h_evt_clear(_adapter *adapter)
1165 {
1166 	rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1167 }
1168 
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1169 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1170 {
1171 	s32 ret = _FAIL;
1172 	int i;
1173 	u8 trigger;
1174 
1175 	if (buf == NULL)
1176 		goto exit;
1177 
1178 	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1179 
1180 	if (trigger == C2H_EVT_HOST_CLOSE) {
1181 		goto exit; /* Not ready */
1182 	} else if (trigger != C2H_EVT_FW_CLOSE) {
1183 		goto clear_evt; /* Not a valid value */
1184 	}
1185 
1186 	_rtw_memset(buf, 0, C2H_REG_LEN);
1187 
1188 	/* Read ID, LEN, SEQ */
1189 	SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1190 	SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1191 	SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1192 
1193 	if (0) {
1194 		RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1195 			, C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1196 	}
1197 
1198 	/* Read the content */
1199 	for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1200 		*(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1201 
1202 	RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1203 
1204 	ret = _SUCCESS;
1205 
1206 clear_evt:
1207 	/*
1208 	* Clear event to notify FW we have read the command.
1209 	* If this field isn't clear, the FW won't update the next command message.
1210 	*/
1211 	c2h_evt_clear(adapter);
1212 
1213 exit:
1214 	return ret;
1215 }
1216 #endif /* CONFIG_FW_C2H_REG */
1217 
1218 #ifdef CONFIG_FW_C2H_PKT
1219 #ifndef DBG_C2H_PKT_PRE_HDL
1220 #define DBG_C2H_PKT_PRE_HDL 0
1221 #endif
1222 #ifndef DBG_C2H_PKT_HDL
1223 #define DBG_C2H_PKT_HDL 0
1224 #endif
rtw_hal_c2h_pkt_pre_hdl(_adapter * adapter,u8 * buf,u16 len)1225 void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1226 {
1227 #ifdef RTW_HALMAC
1228 	/* TODO: extract hal_mac IC's code here*/
1229 #else
1230 	u8 parse_fail = 0;
1231 	u8 hdl_here = 0;
1232 	s32 ret = _FAIL;
1233 	u8 id, seq, plen;
1234 	u8 *payload;
1235 
1236 	if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1237 		parse_fail = 1;
1238 		goto exit;
1239 	}
1240 
1241 	hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1242 	if (hdl_here)
1243 		ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1244 	else
1245 		ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1246 
1247 exit:
1248 	if (parse_fail)
1249 		RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1250 	else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1251 		RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1252 			, hdl_here ? "handle" : "enqueue"
1253 			, ret == _SUCCESS ? "ok" : "fail"
1254 		);
1255 		if (DBG_C2H_PKT_PRE_HDL >= 2)
1256 			RTW_PRINT_DUMP("dump: ", buf, len);
1257 	}
1258 #endif
1259 }
1260 
rtw_hal_c2h_pkt_hdl(_adapter * adapter,u8 * buf,u16 len)1261 void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1262 {
1263 #ifdef RTW_HALMAC
1264 	adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1265 #else
1266 	u8 parse_fail = 0;
1267 	u8 bypass = 0;
1268 	s32 ret = _FAIL;
1269 	u8 id, seq, plen;
1270 	u8 *payload;
1271 
1272 	if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1273 		parse_fail = 1;
1274 		goto exit;
1275 	}
1276 
1277 #ifdef CONFIG_WOWLAN
1278 	if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1279 		bypass = 1;
1280 		ret = _SUCCESS;
1281 		goto exit;
1282 	}
1283 #endif
1284 
1285 	ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1286 
1287 exit:
1288 	if (parse_fail)
1289 		RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1290 	else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1291 		RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1292 			, !bypass ? "handle" : "bypass"
1293 			, ret == _SUCCESS ? "ok" : "fail"
1294 		);
1295 		if (DBG_C2H_PKT_HDL >= 2)
1296 			RTW_PRINT_DUMP("dump: ", buf, len);
1297 	}
1298 #endif
1299 }
1300 #endif /* CONFIG_FW_C2H_PKT */
1301 
c2h_iqk_offload(_adapter * adapter,u8 * data,u8 len)1302 void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1303 {
1304 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1305 	struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1306 
1307 	RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1308 	if (0)
1309 		RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1310 
1311 	rtw_sctx_done(&iqk_sctx);
1312 }
1313 
c2h_iqk_offload_wait(_adapter * adapter,u32 timeout_ms)1314 int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1315 {
1316 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1317 	struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1318 
1319 	iqk_sctx->submit_time = rtw_get_current_time();
1320 	iqk_sctx->timeout_ms = timeout_ms;
1321 	iqk_sctx->status = RTW_SCTX_SUBMITTED;
1322 
1323 	return rtw_sctx_wait(iqk_sctx, __func__);
1324 }
1325 
1326 #ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX
c2h_txpwr_idx_offload_done(_adapter * adapter,u8 * data,u8 len)1327 void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len)
1328 {
1329 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1330 	struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1331 
1332 	if (0)
1333 		RTW_INFO("txpwr_idx offload finish in %dms\n", rtw_get_passing_time_ms(sctx->submit_time));
1334 	rtw_sctx_done(&sctx);
1335 }
1336 
c2h_txpwr_idx_offload_wait(_adapter * adapter)1337 int c2h_txpwr_idx_offload_wait(_adapter *adapter)
1338 {
1339 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1340 	struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1341 
1342 	return rtw_sctx_wait(sctx, __func__);
1343 }
1344 #endif
1345 
1346 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1347 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1348 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1349 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data)			LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1350 #define	GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1351 #define	GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1352 #define	GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1353 #define	GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1354 #define	GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1355 #define	GET_C2H_MAC_HIDDEN_RPT_BW(_data)				LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1356 #define	GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1357 #define	GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1358 #define	GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1359 
1360 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1361 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1362 #endif
1363 
1364 #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1365 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1366 {
1367 	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
1368 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1369 	enum rf_type rf_type;
1370 	u8 tx_path_num, rx_path_num;
1371 	int ret = _FAIL;
1372 
1373 	u8 uuid_x;
1374 	u8 uuid_y;
1375 	u8 uuid_z;
1376 	u16 uuid_crc;
1377 
1378 	u8 hci_type;
1379 	u8 package_type;
1380 	u8 tr_switch;
1381 	u8 wl_func;
1382 	u8 hw_stype;
1383 	u8 bw;
1384 	u8 ss_num = 4;
1385 	u8 ant_num;
1386 	u8 protocol;
1387 	u8 nic;
1388 
1389 	int i;
1390 
1391 	if (len < MAC_HIDDEN_RPT_LEN) {
1392 		RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1393 		goto exit;
1394 	}
1395 
1396 	uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1397 	uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1398 	uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1399 	uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1400 
1401 	hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1402 	package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1403 
1404 	tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1405 
1406 	wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1407 	hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1408 
1409 	bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1410 	ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1411 
1412 	protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1413 	nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1414 
1415 	if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1416 		for (i = 0; i < len; i++)
1417 			RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1418 
1419 		RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1420 		RTW_PRINT("hci_type:0x%x\n", hci_type);
1421 		RTW_PRINT("package_type:0x%x\n", package_type);
1422 		RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1423 		RTW_PRINT("wl_func:0x%x\n", wl_func);
1424 		RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1425 		RTW_PRINT("bw:0x%x\n", bw);
1426 		RTW_PRINT("ant_num:0x%x\n", ant_num);
1427 		RTW_PRINT("protocol:0x%x\n", protocol);
1428 		RTW_PRINT("nic:0x%x\n", nic);
1429 	}
1430 
1431 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
1432 	if (IS_8822C_SERIES(hal_data->version_id) || IS_8814B_SERIES(hal_data->version_id)) {
1433 		#define GET_C2H_MAC_HIDDEN_RPT_SS_NUM(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
1434 		ss_num = GET_C2H_MAC_HIDDEN_RPT_SS_NUM(data);
1435 
1436 		if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1437 			RTW_PRINT("ss_num:0x%x\n", ss_num);
1438 
1439 		if (ss_num == 0x03)
1440 			ss_num = 4;
1441 	}
1442 #endif
1443 
1444 #if defined(CONFIG_RTL8822C)
1445 	if (IS_8822C_SERIES(hal_data->version_id)) {
1446 		if (ant_num == 1)
1447 			hal_spec->rf_reg_trx_path_bmp = 0x22; /* 1T1R pathB */
1448 		if (hw_stype == 0xE)
1449 			hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */
1450 	}
1451 #endif
1452 	hal_data->PackageType = package_type;
1453 	hal_spec->hci_type = hci_type;
1454 	hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1455 	hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1456 	hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1457 
1458 	rf_type = rtw_chip_rftype_to_hal_rftype(adapter, 0);
1459 	if (!RF_TYPE_VALID(rf_type)) {
1460 		RTW_ERR("%s rtw_chip_rftype_to_hal_rftype failed\n", __func__);
1461 		goto exit;
1462 	}
1463 	hal_spec->rf_reg_path_avail_num = rtw_min(hal_spec->rf_reg_path_num, ant_num);
1464 	tx_path_num = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1465 	rx_path_num = rtw_min(rf_type_to_rf_rx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1466 	hal_spec->rf_reg_trx_path_bmp = rtw_restrict_trx_path_bmp_by_trx_num_lmt(
1467 		hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num, &tx_path_num, &rx_path_num);
1468 	if (!hal_spec->rf_reg_trx_path_bmp) {
1469 		RTW_ERR("%s rtw_restrict_trx_path_bmp_by_trx_num_lmt(0x%x, %u, %u) failed\n"
1470 			, __func__, hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num);
1471 		goto exit;
1472 	}
1473 	hal_spec->rf_reg_path_avail_num = rtw_max(tx_path_num, rx_path_num);
1474 
1475 	/*
1476 	* RF TX path num >= max_tx_cnt >= tx_nss_num
1477 	* ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1)
1478 	* Select at most 2 out of 4 TX RF path to do 1SS 2TX
1479 	*/
1480 	hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, tx_path_num);
1481 	hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt);
1482 	hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num);
1483 
1484 	hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rx_path_num);
1485 	hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num);
1486 
1487 	ret = _SUCCESS;
1488 
1489 exit:
1490 	return ret;
1491 }
1492 
c2h_mac_hidden_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1493 int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1494 {
1495 	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
1496 	int ret = _FAIL;
1497 
1498 	int i;
1499 
1500 	if (len < MAC_HIDDEN_RPT_2_LEN) {
1501 		RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1502 		goto exit;
1503 	}
1504 
1505 	if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1506 		for (i = 0; i < len; i++)
1507 			RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1508 	}
1509 
1510 	#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
1511 	if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {
1512 		#define GET_C2H_MAC_HIDDEN_RPT_IRV(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
1513 		u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
1514 
1515 		if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1516 			RTW_PRINT("irv:0x%x\n", irv);
1517 
1518 		if(irv != 0xf)
1519 			hal_data->version_id.CUTVersion = irv;
1520 	}
1521 	#endif
1522 
1523 	ret = _SUCCESS;
1524 
1525 exit:
1526 	return ret;
1527 }
1528 
hal_read_mac_hidden_rpt(_adapter * adapter)1529 int hal_read_mac_hidden_rpt(_adapter *adapter)
1530 {
1531 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(adapter);
1532 	int ret = _FAIL;
1533 	int ret_fwdl;
1534 	u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1535 	systime start = rtw_get_current_time();
1536 	u32 cnt = 0;
1537 	u32 timeout_ms = 800;
1538 	u32 min_cnt = 10;
1539 	u8 id = C2H_DEFEATURE_RSVD;
1540 	int i;
1541 
1542 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1543 	u8 hci_type = rtw_get_intf_type(adapter);
1544 
1545 	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1546 		&& !rtw_is_hw_init_completed(adapter))
1547 		rtw_hal_power_on(adapter);
1548 #endif
1549 
1550 	/* inform FW mac hidden rpt from reg is needed */
1551 	rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1552 
1553 	/* download FW */
1554 	pHalData->not_xmitframe_fw_dl = 1;
1555 	ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1556 	pHalData->not_xmitframe_fw_dl = 0;
1557 	if (ret_fwdl != _SUCCESS)
1558 		goto mac_hidden_rpt_hdl;
1559 
1560 	/* polling for data ready */
1561 	start = rtw_get_current_time();
1562 	do {
1563 		cnt++;
1564 		id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1565 		if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1566 			break;
1567 		rtw_msleep_os(10);
1568 	} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1569 
1570 	if (id == C2H_MAC_HIDDEN_RPT) {
1571 		/* read data */
1572 		for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1573 			mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1574 	}
1575 
1576 	/* inform FW mac hidden rpt has read */
1577 	rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1578 
1579 mac_hidden_rpt_hdl:
1580 	c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1581 	c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1582 
1583 	if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1584 		ret = _SUCCESS;
1585 
1586 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1587 	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1588 		&& !rtw_is_hw_init_completed(adapter))
1589 		rtw_hal_power_off(adapter);
1590 #endif
1591 
1592 	RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1593 		, (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1594 
1595 	return ret;
1596 }
1597 #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1598 
c2h_defeature_dbg_hdl(_adapter * adapter,u8 * data,u8 len)1599 int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1600 {
1601 	int ret = _FAIL;
1602 
1603 	int i;
1604 
1605 	if (len < DEFEATURE_DBG_LEN) {
1606 		RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1607 		goto exit;
1608 	}
1609 
1610 	for (i = 0; i < len; i++)
1611 		RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1612 
1613 	ret = _SUCCESS;
1614 
1615 exit:
1616 	return ret;
1617 }
1618 
1619 #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1620 #define DBG_CUSTOMER_STR_RPT_HANDLE 0
1621 #endif
1622 
1623 #ifdef CONFIG_RTW_CUSTOMER_STR
rtw_hal_h2c_customer_str_req(_adapter * adapter)1624 s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1625 {
1626 	u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1627 
1628 	SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1629 	return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1630 }
1631 
1632 #define	C2H_CUSTOMER_STR_RPT_BYTE0(_data)		((u8 *)(_data))
1633 #define	C2H_CUSTOMER_STR_RPT_2_BYTE8(_data)		((u8 *)(_data))
1634 
c2h_customer_str_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1635 int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1636 {
1637 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1638 	int ret = _FAIL;
1639 	int i;
1640 
1641 	if (len < CUSTOMER_STR_RPT_LEN) {
1642 		RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1643 		goto exit;
1644 	}
1645 
1646 	if (DBG_CUSTOMER_STR_RPT_HANDLE)
1647 		RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1648 
1649 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1650 
1651 	if (dvobj->customer_str_sctx != NULL) {
1652 		if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1653 			RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1654 		_rtw_memcpy(dvobj->customer_str,  C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1655 		dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1656 	} else
1657 		RTW_WARN("%s sctx not set\n", __func__);
1658 
1659 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1660 
1661 	ret = _SUCCESS;
1662 
1663 exit:
1664 	return ret;
1665 }
1666 
c2h_customer_str_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1667 int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1668 {
1669 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1670 	int ret = _FAIL;
1671 	int i;
1672 
1673 	if (len < CUSTOMER_STR_RPT_2_LEN) {
1674 		RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1675 		goto exit;
1676 	}
1677 
1678 	if (DBG_CUSTOMER_STR_RPT_HANDLE)
1679 		RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1680 
1681 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1682 
1683 	if (dvobj->customer_str_sctx != NULL) {
1684 		if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1685 			RTW_WARN("%s rpt not ready\n", __func__);
1686 		_rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN,  C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1687 		rtw_sctx_done(&dvobj->customer_str_sctx);
1688 	} else
1689 		RTW_WARN("%s sctx not set\n", __func__);
1690 
1691 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1692 
1693 	ret = _SUCCESS;
1694 
1695 exit:
1696 	return ret;
1697 }
1698 
1699 /* read customer str */
rtw_hal_customer_str_read(_adapter * adapter,u8 * cs)1700 s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1701 {
1702 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1703 	struct submit_ctx sctx;
1704 	s32 ret = _SUCCESS;
1705 
1706 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1707 	if (dvobj->customer_str_sctx != NULL)
1708 		ret = _FAIL;
1709 	else {
1710 		rtw_sctx_init(&sctx, 2 * 1000);
1711 		dvobj->customer_str_sctx = &sctx;
1712 	}
1713 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1714 
1715 	if (ret == _FAIL) {
1716 		RTW_WARN("%s another handle ongoing\n", __func__);
1717 		goto exit;
1718 	}
1719 
1720 	ret = rtw_customer_str_req_cmd(adapter);
1721 	if (ret != _SUCCESS) {
1722 		RTW_WARN("%s read cmd fail\n", __func__);
1723 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1724 		dvobj->customer_str_sctx = NULL;
1725 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1726 		goto exit;
1727 	}
1728 
1729 	/* wait till rpt done or timeout */
1730 	rtw_sctx_wait(&sctx, __func__);
1731 
1732 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1733 	dvobj->customer_str_sctx = NULL;
1734 	if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1735 		_rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1736 	else
1737 		ret = _FAIL;
1738 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1739 
1740 exit:
1741 	return ret;
1742 }
1743 
rtw_hal_h2c_customer_str_write(_adapter * adapter,const u8 * cs)1744 s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1745 {
1746 	u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1747 	u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1748 	u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1749 	s32 ret;
1750 
1751 	SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1752 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1753 
1754 	SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1755 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1756 
1757 	SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1758 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1759 
1760 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1761 	if (ret != _SUCCESS) {
1762 		RTW_WARN("%s w1 fail\n", __func__);
1763 		goto exit;
1764 	}
1765 
1766 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1767 	if (ret != _SUCCESS) {
1768 		RTW_WARN("%s w2 fail\n", __func__);
1769 		goto exit;
1770 	}
1771 
1772 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1773 	if (ret != _SUCCESS) {
1774 		RTW_WARN("%s w3 fail\n", __func__);
1775 		goto exit;
1776 	}
1777 
1778 exit:
1779 	return ret;
1780 }
1781 
1782 /* write customer str and check if value reported is the same as requested */
rtw_hal_customer_str_write(_adapter * adapter,const u8 * cs)1783 s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1784 {
1785 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1786 	struct submit_ctx sctx;
1787 	s32 ret = _SUCCESS;
1788 
1789 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1790 	if (dvobj->customer_str_sctx != NULL)
1791 		ret = _FAIL;
1792 	else {
1793 		rtw_sctx_init(&sctx, 2 * 1000);
1794 		dvobj->customer_str_sctx = &sctx;
1795 	}
1796 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1797 
1798 	if (ret == _FAIL) {
1799 		RTW_WARN("%s another handle ongoing\n", __func__);
1800 		goto exit;
1801 	}
1802 
1803 	ret = rtw_customer_str_write_cmd(adapter, cs);
1804 	if (ret != _SUCCESS) {
1805 		RTW_WARN("%s write cmd fail\n", __func__);
1806 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1807 		dvobj->customer_str_sctx = NULL;
1808 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1809 		goto exit;
1810 	}
1811 
1812 	ret = rtw_customer_str_req_cmd(adapter);
1813 	if (ret != _SUCCESS) {
1814 		RTW_WARN("%s read cmd fail\n", __func__);
1815 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1816 		dvobj->customer_str_sctx = NULL;
1817 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1818 		goto exit;
1819 	}
1820 
1821 	/* wait till rpt done or timeout */
1822 	rtw_sctx_wait(&sctx, __func__);
1823 
1824 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1825 	dvobj->customer_str_sctx = NULL;
1826 	if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
1827 		if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
1828 			RTW_WARN("%s read back check fail\n", __func__);
1829 			RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
1830 			RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1831 			ret = _FAIL;
1832 		}
1833 	} else
1834 		ret = _FAIL;
1835 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1836 
1837 exit:
1838 	return ret;
1839 }
1840 #endif /* CONFIG_RTW_CUSTOMER_STR */
1841 
1842 #ifdef RTW_PER_CMD_SUPPORT_FW
1843 #define H2C_REQ_PER_RPT_LEN 5
1844 #define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)
1845 #define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)
1846 #define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value)	SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)
1847 
rtw_hal_set_req_per_rpt_cmd(_adapter * adapter,u8 group_macid,u8 rpt_type,u32 macid_bitmap)1848 u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,
1849 				      u8 rpt_type, u32 macid_bitmap)
1850 {
1851 	u8 ret = _FAIL;
1852 	u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};
1853 
1854 	SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);
1855 	SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);
1856 	SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);
1857 
1858 	ret = rtw_hal_fill_h2c_cmd(adapter,
1859 				   H2C_REQ_PER_RPT,
1860 				   H2C_REQ_PER_RPT_LEN,
1861 				   cmd_buf);
1862 	return ret;
1863 }
1864 
1865 #define	GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
1866 #define	GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1867 #define	GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
1868 #define	GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
1869 #define	GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data)	LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)
1870 #define	GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
1871 #define	GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)
1872 #define	GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
1873 #define	GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)
1874 #define	GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data)	LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)
1875 
1876 #define	GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
1877 #define	GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1878 #define	GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
1879 #define	GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
1880 #define	GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)
1881 #define	GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)
1882 #define	GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
1883 #define	GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)
1884 #define	GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
1885 #define	GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)
1886 #define	GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)
1887 #define	GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)
1888 
per_rate_rpt_update(_adapter * adapter,u8 mac_id,u8 per,u8 rate,u8 bw,u8 total_pkt)1889 static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,
1890 				u8 per, u8 rate,
1891 				u8 bw, u8 total_pkt)
1892 {
1893 #ifdef CONFIG_RTW_MESH
1894 	rtw_ieee80211s_update_metric(adapter, mac_id,
1895 				     per, rate,
1896 				     bw, total_pkt);
1897 #endif
1898 }
1899 
c2h_per_rate_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1900 int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1901 {
1902 	/* Now only consider type0, since it covers all params in type1
1903 	 * type0: mac_id, per, rate, bw, total_pkt
1904 	 * type1: mac_id, per, rate, bw
1905 	 */
1906 	u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};
1907 	u16 total_pkt[2] = {0};
1908 	int ret = _FAIL, i, macid_cnt = 0;
1909 
1910 	/* type0:
1911 	 * 1 macid includes   6 bytes info + 1 byte 0xff
1912 	 * 2 macid includes 2*6 bytes info
1913 	 */
1914 	if (!(len == 7 || len == 12)) {
1915 		RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);
1916 		goto exit;
1917 	}
1918 
1919 	macid_cnt++;
1920 	mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);
1921 	per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);
1922 	rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);
1923 	bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);
1924 	total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);
1925 
1926 	mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);
1927 	/* 0xff means no report anymore */
1928 	if (mac_id[1] == 0xff)
1929 		goto update_per;
1930 	if (len != 12) {
1931 		RTW_WARN("%s incorrect format\n", __FUNCTION__);
1932 		goto exit;
1933 	}
1934 	macid_cnt++;
1935 	per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);
1936 	rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);
1937 	bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);
1938 	total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);
1939 
1940 update_per:
1941 	for (i = 0; i < macid_cnt; i++) {
1942 		RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "
1943 			"rate = %u, bw = %u, total_pkt = %u\n",
1944 			__FUNCTION__, i, mac_id[i], per[i],
1945 			rate[i], bw[i], total_pkt[i]);
1946 		per_rate_rpt_update(adapter, mac_id[i],
1947 				    per[i], rate[i],
1948 				    bw[i], total_pkt[i]);
1949 	}
1950 	ret = _SUCCESS;
1951 exit:
1952 	return ret;
1953 }
1954 #endif /* RTW_PER_CMD_SUPPORT_FW */
1955 
1956 #ifdef CONFIG_LPS_ACK
1957 #define	GET_C2H_LPS_STATUS_RPT_GET_ACTION(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
1958 #define	GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1959 #define DBG_LPS_STATUS_RPT 0
1960 
c2h_lps_status_rpt(PADAPTER adapter,u8 * data,u8 len)1961 int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len)
1962 {
1963 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
1964 	struct submit_ctx *lps_sctx = &pwrpriv->lps_ack_sctx;
1965 	u8 action = 0;
1966 	s8 status_code = 0;
1967 	int ret = _FAIL;
1968 
1969 	if (len < LPS_STATUS_RPT_LEN) {
1970 		RTW_WARN("%s len(%u) < %d\n", __func__, len, LPS_STATUS_RPT_LEN);
1971 		goto exit;
1972 	}
1973 
1974 	action = GET_C2H_LPS_STATUS_RPT_GET_ACTION(data);
1975 	status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data);
1976 
1977 	/* action=0: report force leave null data status */
1978 	/* action=1: report Rf on status when receiving a SetPwrMode H2C with PwrState = RFON */
1979 	switch (action) {
1980 		case 0:
1981 			/* status code 0: success, 1: no ack, 2: timeout, 3: cancel */
1982 		case 1:
1983 			/* status code 0: FW has already turn to RFON */
1984 			pwrpriv->lps_ack_status = status_code;
1985 
1986 			if (DBG_LPS_STATUS_RPT)
1987 				RTW_INFO("=== [C2H LPS Action(%d)] LPS Status Code:%d ===\n", action, status_code);
1988 
1989 			break;
1990 		default:
1991 			RTW_INFO("UnKnown Action(%d) for C2H LPS RPT\n", action);
1992 			break;
1993 	}
1994 
1995 	rtw_sctx_done(&lps_sctx);
1996 	ret = _SUCCESS;
1997 
1998 exit:
1999 	return ret;
2000 }
2001 #endif /* CONFIG_LPS_ACK */
2002 
rtw_hal_update_sta_wset(_adapter * adapter,struct sta_info * psta)2003 void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
2004 {
2005 	u8 w_set = 0;
2006 
2007 	if (psta->wireless_mode & WIRELESS_11B)
2008 		w_set |= WIRELESS_CCK;
2009 
2010 	if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
2011 		w_set |= WIRELESS_OFDM;
2012 
2013 	if (psta->wireless_mode & WIRELESS_11_24N)
2014 		w_set |= WIRELESS_HT;
2015 
2016 	if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))
2017 		w_set |= WIRELESS_VHT;
2018 
2019 	psta->cmn.support_wireless_set = w_set;
2020 }
2021 
rtw_hal_update_sta_mimo_type(_adapter * adapter,struct sta_info * psta)2022 void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
2023 {
2024 	s8 tx_nss, rx_nss;
2025 
2026 	tx_nss = rtw_get_sta_tx_nss(adapter, psta);
2027 	rx_nss =  rtw_get_sta_rx_nss(adapter, psta);
2028 	if ((tx_nss == 1) && (rx_nss == 1))
2029 		psta->cmn.mimo_type = RF_1T1R;
2030 	else if ((tx_nss == 1) && (rx_nss == 2))
2031 		psta->cmn.mimo_type = RF_1T2R;
2032 	else if ((tx_nss == 2) && (rx_nss == 2))
2033 		psta->cmn.mimo_type = RF_2T2R;
2034 	else if ((tx_nss == 2) && (rx_nss == 3))
2035 		psta->cmn.mimo_type = RF_2T3R;
2036 	else if ((tx_nss == 2) && (rx_nss == 4))
2037 		psta->cmn.mimo_type = RF_2T4R;
2038 	else if ((tx_nss == 3) && (rx_nss == 3))
2039 		psta->cmn.mimo_type = RF_3T3R;
2040 	else if ((tx_nss == 3) && (rx_nss == 4))
2041 		psta->cmn.mimo_type = RF_3T4R;
2042 	else if ((tx_nss == 4) && (rx_nss == 4))
2043 		psta->cmn.mimo_type = RF_4T4R;
2044 	else
2045 		rtw_warn_on(1);
2046 
2047 #ifdef CONFIG_CTRL_TXSS_BY_TP
2048 	rtw_ctrl_txss_update_mimo_type(adapter, psta);
2049 #endif
2050 
2051 	RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
2052 			psta->cmn.mac_id, tx_nss, rx_nss);
2053 }
2054 
rtw_hal_update_sta_smps_cap(_adapter * adapter,struct sta_info * psta)2055 void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
2056 {
2057 	/*Spatial Multiplexing Power Save*/
2058 #if 0
2059 	if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2060 		#ifdef CONFIG_80211N_HT
2061 		if (psta->htpriv.ht_option) {
2062 			if (psta->htpriv.smps_cap == 0)
2063 				psta->cmn.sm_ps = SM_PS_STATIC;
2064 			else if (psta->htpriv.smps_cap == 1)
2065 				psta->cmn.sm_ps = SM_PS_DYNAMIC;
2066 			else
2067 				psta->cmn.sm_ps = SM_PS_DISABLE;
2068 		}
2069 		#endif /* CONFIG_80211N_HT */
2070 	} else
2071 #endif
2072 		psta->cmn.sm_ps = SM_PS_DISABLE;
2073 
2074 	RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
2075 			psta->cmn.mac_id, psta->cmn.sm_ps);
2076 }
2077 
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)2078 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
2079 {
2080 
2081 	u8 raid;
2082 	if (IS_NEW_GENERATION_IC(adapter)) {
2083 
2084 		raid = (network_type & WIRELESS_11B)	? RATEID_IDX_B
2085 		       : RATEID_IDX_G;
2086 	} else {
2087 		raid = (network_type & WIRELESS_11B)	? RATR_INX_WIRELESS_B
2088 		       : RATR_INX_WIRELESS_G;
2089 	}
2090 	return raid;
2091 }
2092 
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)2093 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
2094 {
2095 	u8 i, tx_nss;
2096 	u64 tx_ra_bitmap = 0, tmp64=0;
2097 
2098 	if (psta == NULL)
2099 		return;
2100 
2101 	/* b/g mode ra_bitmap  */
2102 	for (i = 0; i < sizeof(psta->bssrateset); i++) {
2103 		if (psta->bssrateset[i])
2104 			tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
2105 	}
2106 
2107 #ifdef CONFIG_80211N_HT
2108 if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
2109 	tx_nss = GET_HAL_TX_NSS(padapter);
2110 #ifdef CONFIG_80211AC_VHT
2111 	if (psta->vhtpriv.vht_option) {
2112 		/* AC mode ra_bitmap */
2113 		tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
2114 	} else
2115 #endif /* CONFIG_80211AC_VHT */
2116 	if (psta->htpriv.ht_option) {
2117 		/* n mode ra_bitmap */
2118 
2119 		/* Handling SMPS mode for AP MODE only*/
2120 		if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2121 			/*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
2122 			if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
2123 				/*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
2124 				tx_nss = rtw_min(tx_nss, 1);
2125 			}
2126 		}
2127 
2128 		tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);
2129 		tx_ra_bitmap |= (tmp64 << 12);
2130 	}
2131 }
2132 #endif /* CONFIG_80211N_HT */
2133 	psta->cmn.ra_info.ramask = tx_ra_bitmap;
2134 	psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
2135 }
2136 
rtw_hal_update_sta_ra_info(PADAPTER padapter,struct sta_info * psta)2137 void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
2138 {
2139 	rtw_hal_update_sta_mimo_type(padapter, psta);
2140 	rtw_hal_update_sta_smps_cap(padapter, psta);
2141 	rtw_hal_update_sta_rate_mask(padapter, psta);
2142 }
2143 
2144 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
hw_bcn_ctrl_addr(_adapter * adapter,u8 hw_port)2145 static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)
2146 {
2147 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2148 
2149 	if (hw_port >= hal_spec->port_num) {
2150 		RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);
2151 		rtw_warn_on(1);
2152 		return 0;
2153 	}
2154 
2155 	switch (hw_port) {
2156 	case HW_PORT0:
2157 		return REG_BCN_CTRL;
2158 	case HW_PORT1:
2159 		return REG_BCN_CTRL_1;
2160 	}
2161 
2162 	return 0;
2163 }
2164 #endif
2165 
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2166 static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2167 {
2168 #ifdef RTW_HALMAC
2169 	rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
2170 				adapter->hw_port, net_type);
2171 #else /* !RTW_HALMAC */
2172 	switch (adapter->hw_port) {
2173 	case HW_PORT0:
2174 		/*REG_CR - BIT[17:16]-Network Type for port 1*/
2175 		*net_type = rtw_read8(adapter, MSR) & 0x03;
2176 		break;
2177 	case HW_PORT1:
2178 		/*REG_CR - BIT[19:18]-Network Type for port 1*/
2179 		*net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2180 		break;
2181 #if defined(CONFIG_RTL8814A)
2182 	case HW_PORT2:
2183 		/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2184 		*net_type = rtw_read8(adapter, MSR1) & 0x03;
2185 		break;
2186 	case HW_PORT3:
2187 		/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2188 		*net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2189 		break;
2190 	case HW_PORT4:
2191 		/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2192 		*net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2193 		break;
2194 #endif /*#if defined(CONFIG_RTL8814A)*/
2195 	default:
2196 		RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2197 			 ADPT_ARG(adapter), adapter->hw_port);
2198 		rtw_warn_on(1);
2199 		break;
2200 	}
2201 #endif /* !RTW_HALMAC */
2202 }
2203 
2204 #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)2205 static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
2206 {
2207 	if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
2208 		if (net_type != _HW_STATE_NOLINK_)
2209 			return _HW_STATE_AP_;
2210 	}
2211 	return net_type;
2212 }
2213 #endif
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2214 static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2215 {
2216 #ifdef RTW_HALMAC
2217 	#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2218 	net_type = rtw_hal_net_type_decision(adapter, net_type);
2219 	#endif
2220 	rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
2221 				adapter->hw_port, net_type);
2222 #else /* !RTW_HALMAC */
2223 	u8 val8 = 0;
2224 
2225 	switch (adapter->hw_port) {
2226 	case HW_PORT0:
2227 		#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2228 		net_type = rtw_hal_net_type_decision(adapter, net_type);
2229 		#endif
2230 		/*REG_CR - BIT[17:16]-Network Type for port 0*/
2231 		val8 = rtw_read8(adapter, MSR) & 0x0C;
2232 		val8 |= net_type;
2233 		rtw_write8(adapter, MSR, val8);
2234 		break;
2235 	case HW_PORT1:
2236 		/*REG_CR - BIT[19:18]-Network Type for port 1*/
2237 		val8 = rtw_read8(adapter, MSR) & 0x03;
2238 		val8 |= net_type << 2;
2239 		rtw_write8(adapter, MSR, val8);
2240 		break;
2241 #if defined(CONFIG_RTL8814A)
2242 	case HW_PORT2:
2243 		/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2244 		val8 = rtw_read8(adapter, MSR1) & 0xFC;
2245 		val8 |= net_type;
2246 		rtw_write8(adapter, MSR1, val8);
2247 		break;
2248 	case HW_PORT3:
2249 		/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2250 		val8 = rtw_read8(adapter, MSR1) & 0xF3;
2251 		val8 |= net_type << 2;
2252 		rtw_write8(adapter, MSR1, val8);
2253 		break;
2254 	case HW_PORT4:
2255 		/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2256 		val8 = rtw_read8(adapter, MSR1) & 0xCF;
2257 		val8 |= net_type << 4;
2258 		rtw_write8(adapter, MSR1, val8);
2259 		break;
2260 #endif /* CONFIG_RTL8814A */
2261 	default:
2262 		RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2263 			 ADPT_ARG(adapter), adapter->hw_port);
2264 		rtw_warn_on(1);
2265 		break;
2266 	}
2267 #endif /* !RTW_HALMAC */
2268 }
2269 
2270 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
2271 	#define SEC_CAM_ACCESS_TIMEOUT_MS 200
2272 #endif
2273 
2274 #ifndef DBG_SEC_CAM_ACCESS
2275 	#define DBG_SEC_CAM_ACCESS 0
2276 #endif
2277 
rtw_sec_read_cam(_adapter * adapter,u8 addr)2278 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
2279 {
2280 	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2281 	u32 rdata;
2282 	u32 cnt = 0;
2283 	systime start = 0, end = 0;
2284 	u8 timeout = 0;
2285 	u8 sr = 0;
2286 
2287 	_enter_critical_mutex(mutex, NULL);
2288 
2289 	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
2290 
2291 	start = rtw_get_current_time();
2292 	while (1) {
2293 		if (rtw_is_surprise_removed(adapter)) {
2294 			sr = 1;
2295 			break;
2296 		}
2297 
2298 		cnt++;
2299 		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2300 			break;
2301 
2302 		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2303 			timeout = 1;
2304 			break;
2305 		}
2306 	}
2307 	end = rtw_get_current_time();
2308 
2309 	rdata = rtw_read32(adapter, REG_CAMREAD);
2310 
2311 	_exit_critical_mutex(mutex, NULL);
2312 
2313 	if (DBG_SEC_CAM_ACCESS || timeout) {
2314 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
2315 			, FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2316 	}
2317 
2318 	return rdata;
2319 }
2320 
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)2321 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
2322 {
2323 	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2324 	u32 cnt = 0;
2325 	systime start = 0, end = 0;
2326 	u8 timeout = 0;
2327 	u8 sr = 0;
2328 
2329 	_enter_critical_mutex(mutex, NULL);
2330 
2331 	rtw_write32(adapter, REG_CAMWRITE, wdata);
2332 	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
2333 
2334 	start = rtw_get_current_time();
2335 	while (1) {
2336 		if (rtw_is_surprise_removed(adapter)) {
2337 			sr = 1;
2338 			break;
2339 		}
2340 
2341 		cnt++;
2342 		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2343 			break;
2344 
2345 		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2346 			timeout = 1;
2347 			break;
2348 		}
2349 	}
2350 	end = rtw_get_current_time();
2351 
2352 	_exit_critical_mutex(mutex, NULL);
2353 
2354 	if (DBG_SEC_CAM_ACCESS || timeout) {
2355 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
2356 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2357 	}
2358 }
2359 
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)2360 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
2361 {
2362 	u8 i;
2363 	u32 rdata;
2364 	u8 begin = 0;
2365 	u8 end = 5; /* TODO: consider other key length accordingly */
2366 
2367 	if (!ctrl && !mac && !key) {
2368 		rtw_warn_on(1);
2369 		goto exit;
2370 	}
2371 
2372 	/* TODO: check id range */
2373 
2374 	if (!ctrl && !mac)
2375 		begin = 2; /* read from key */
2376 
2377 	if (!key && !mac)
2378 		end = 0; /* read to ctrl */
2379 	else if (!key)
2380 		end = 2; /* read to mac */
2381 
2382 	for (i = begin; i <= end; i++) {
2383 		rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
2384 
2385 		switch (i) {
2386 		case 0:
2387 			if (ctrl)
2388 				_rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
2389 			if (mac)
2390 				_rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
2391 			break;
2392 		case 1:
2393 			if (mac)
2394 				_rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
2395 			break;
2396 		default:
2397 			if (key)
2398 				_rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2399 			break;
2400 		}
2401 	}
2402 
2403 exit:
2404 	return;
2405 }
2406 
2407 
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)2408 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2409 {
2410 	unsigned int i;
2411 	int j;
2412 	u8 addr, addr1 = 0;
2413 	u32 wdata, wdata1 = 0;
2414 
2415 	/* TODO: consider other key length accordingly */
2416 #if 0
2417 	switch ((ctrl & 0x1c) >> 2) {
2418 	case _WEP40_:
2419 	case _TKIP_:
2420 	case _AES_:
2421 	case _WEP104_:
2422 
2423 	}
2424 #else
2425 	j = 7;
2426 #endif
2427 
2428 	for (; j >= 0; j--) {
2429 		switch (j) {
2430 		case 0:
2431 			wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2432 			break;
2433 		case 1:
2434 			wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2435 			break;
2436 		case 6:
2437 		case 7:
2438 			wdata = 0;
2439 			break;
2440 		default:
2441 			i = (j - 2) << 2;
2442 			wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2443 			break;
2444 		}
2445 
2446 		addr = (id << 3) + j;
2447 
2448 #if defined(CONFIG_RTL8192F)
2449 		if(j == 1) {
2450 			wdata1 = wdata;
2451 			addr1 = addr;
2452 			continue;
2453 		}
2454 #endif
2455 
2456 		rtw_sec_write_cam(adapter, addr, wdata);
2457 	}
2458 
2459 #if defined(CONFIG_RTL8192F)
2460 	rtw_sec_write_cam(adapter, addr1, wdata1);
2461 #endif
2462 }
2463 
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)2464 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2465 {
2466 	u8 addr;
2467 
2468 	addr = (id << 3);
2469 	rtw_sec_write_cam(adapter, addr, 0);
2470 }
2471 
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)2472 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2473 {
2474 	bool res;
2475 	u16 ctrl;
2476 
2477 	rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2478 
2479 	res = (ctrl & BIT6) ? _TRUE : _FALSE;
2480 	return res;
2481 }
2482 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)2483 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2484 {
2485 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2486 
2487 	_rtw_spinlock_init(&mbid_cam_ctl->lock);
2488 	mbid_cam_ctl->bitmap = 0;
2489 	ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2490 	_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2491 }
2492 
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)2493 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2494 {
2495 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2496 
2497 	_rtw_spinlock_free(&mbid_cam_ctl->lock);
2498 }
2499 
rtw_mbid_cam_reset(_adapter * adapter)2500 void rtw_mbid_cam_reset(_adapter *adapter)
2501 {
2502 	_irqL irqL;
2503 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2504 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2505 
2506 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2507 	mbid_cam_ctl->bitmap = 0;
2508 	_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2509 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2510 
2511 	ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2512 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2513 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2514 {
2515 	u8 i;
2516 	u8 cam_id = INVALID_CAM_ID;
2517 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2518 
2519 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2520 		if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2521 			cam_id = i;
2522 			break;
2523 		}
2524 	}
2525 
2526 	RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2527 	return cam_id;
2528 }
2529 
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2530 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2531 {
2532 	_irqL irqL;
2533 
2534 	u8 cam_id = INVALID_CAM_ID;
2535 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2536 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2537 
2538 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2539 	cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2540 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2541 
2542 	return cam_id;
2543 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2544 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2545 {
2546 	u8 i;
2547 	u8 cam_id = INVALID_CAM_ID;
2548 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2549 
2550 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2551 		if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2552 			cam_id = i;
2553 			break;
2554 		}
2555 	}
2556 	if (cam_id != INVALID_CAM_ID)
2557 		RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2558 			__func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2559 
2560 	return cam_id;
2561 }
2562 
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2563 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2564 {
2565 	_irqL irqL;
2566 	u8 cam_id = INVALID_CAM_ID;
2567 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2568 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2569 
2570 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2571 	cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2572 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2573 
2574 	return cam_id;
2575 }
rtw_get_max_mbid_cam_id(_adapter * adapter)2576 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2577 {
2578 	_irqL irqL;
2579 	s8 i;
2580 	u8 cam_id = INVALID_CAM_ID;
2581 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2582 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2583 
2584 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2585 	for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2586 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2587 			cam_id = i;
2588 			break;
2589 		}
2590 	}
2591 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2592 	/*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2593 	return cam_id;
2594 }
2595 
rtw_get_mbid_cam_entry_num(_adapter * adapter)2596 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2597 {
2598 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2599 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2600 
2601 	return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2602 }
2603 
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)2604 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2605 {
2606 	if (adapter && pmbid_cam && mac_addr) {
2607 		_rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2608 		pmbid_cam->iface_id = adapter->iface_id;
2609 	}
2610 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)2611 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2612 {
2613 	if (pmbid_cam) {
2614 		_rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2615 		pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2616 	}
2617 }
2618 
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)2619 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2620 {
2621 	_irqL irqL;
2622 	u8 cam_id = INVALID_CAM_ID, i;
2623 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2624 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2625 	u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2626 
2627 	if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2628 		goto exit;
2629 
2630 	if (entry_num >= TOTAL_MBID_CAM_NUM) {
2631 		RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2632 		rtw_warn_on(1);
2633 	}
2634 
2635 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2636 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2637 		if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2638 			mbid_cam_ctl->bitmap |= BIT(i);
2639 			cam_id = i;
2640 			break;
2641 		}
2642 	}
2643 	if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2644 		mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2645 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2646 
2647 	if (cam_id != INVALID_CAM_ID) {
2648 		ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2649 		RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2650 #ifdef DBG_MBID_CAM_DUMP
2651 		rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2652 #endif
2653 	} else
2654 		RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2655 exit:
2656 	return cam_id;
2657 }
2658 
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)2659 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2660 {
2661 	_irqL irqL;
2662 	u8 entry_id = INVALID_CAM_ID;
2663 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2664 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2665 
2666 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2667 	entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2668 	if (entry_id != INVALID_CAM_ID)
2669 		mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2670 
2671 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2672 
2673 	return entry_id;
2674 }
2675 
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)2676 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2677 {
2678 	_irqL irqL;
2679 	u8 ret = _FALSE;
2680 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2681 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2682 
2683 	if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2684 		RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2685 		rtw_warn_on(1);
2686 	}
2687 	if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2688 		goto exit;
2689 
2690 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2691 	if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2692 		if (mac_addr) {
2693 			mbid_cam_ctl->bitmap |= BIT(camid);
2694 			mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2695 			ret = _TRUE;
2696 		}
2697 	}
2698 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2699 
2700 	if (ret == _TRUE) {
2701 		ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2702 		RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2703 #ifdef DBG_MBID_CAM_DUMP
2704 		rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2705 #endif
2706 	} else
2707 		RTW_INFO("%s  [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2708 
2709 exit:
2710 	return ret;
2711 }
2712 
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)2713 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2714 {
2715 	_irqL irqL;
2716 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2717 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2718 
2719 	if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2720 		RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2721 		rtw_warn_on(1);
2722 	}
2723 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2724 	mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2725 	mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2726 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2727 	ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2728 	RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2729 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)2730 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2731 {
2732 	_irqL irqL;
2733 	u8 i;
2734 	_adapter *iface;
2735 	u8 iface_id;
2736 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2737 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2738 	u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2739 	u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2740 
2741 	RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2742 
2743 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2744 	RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2745 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2746 		RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2747 
2748 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2749 			iface_id = dvobj->mbid_cam_cache[i].iface_id;
2750 			_RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2751 			_RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2752 
2753 			iface = dvobj->padapters[iface_id];
2754 			if (iface) {
2755 				if (MLME_IS_STA(iface))
2756 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2757 				else if (MLME_IS_AP(iface))
2758 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2759 				else if (MLME_IS_MESH(iface))
2760 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
2761 				else
2762 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2763 			}
2764 
2765 		} else
2766 			_RTW_PRINT_SEL(sel, "N/A\n");
2767 	}
2768 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2769 	return 0;
2770 }
2771 
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2772 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2773 {
2774 	u8 poll = 1;
2775 	u8 cam_ready = _FALSE;
2776 	u32 cam_data1 = 0;
2777 	u16 cam_data2 = 0;
2778 
2779 	if (RTW_CANNOT_RUN(padapter))
2780 		return;
2781 
2782 	rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2783 
2784 	do {
2785 		if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2786 			cam_ready = _TRUE;
2787 			break;
2788 		}
2789 		poll++;
2790 	} while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2791 
2792 	if (cam_ready) {
2793 		cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2794 		mac[0] = cam_data1 & 0xFF;
2795 		mac[1] = (cam_data1 >> 8) & 0xFF;
2796 		mac[2] = (cam_data1 >> 16) & 0xFF;
2797 		mac[3] = (cam_data1 >> 24) & 0xFF;
2798 
2799 		cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
2800 		mac[4] = cam_data2 & 0xFF;
2801 		mac[5] = (cam_data2 >> 8) & 0xFF;
2802 	}
2803 
2804 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)2805 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
2806 {
2807 	/*_irqL irqL;*/
2808 	u8 i;
2809 	u8 mac_addr[ETH_ALEN];
2810 
2811 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2812 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2813 
2814 	RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
2815 
2816 	/*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2817 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2818 		RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2819 		_rtw_memset(mac_addr, 0, ETH_ALEN);
2820 		read_mbssid_cam(adapter, i, mac_addr);
2821 		_RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
2822 	}
2823 	/*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2824 	return 0;
2825 }
2826 
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2827 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2828 {
2829 	u32	cam_val[2] = {0};
2830 
2831 	cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
2832 	cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT)  | (mac[5] << 8) | mac[4];
2833 
2834 	rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
2835 }
2836 
2837 /*
2838 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
2839 {
2840 	rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
2841 }
2842 */
2843 
rtw_ap_set_mbid_num(_adapter * adapter,u8 ap_num)2844 void rtw_ap_set_mbid_num(_adapter *adapter, u8 ap_num)
2845 {
2846 	rtw_write8(adapter, REG_MBID_NUM,
2847 		((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | ((ap_num -1) & 0x07)));
2848 
2849 }
rtw_mbid_cam_enable(_adapter * adapter)2850 void rtw_mbid_cam_enable(_adapter *adapter)
2851 {
2852 	/*enable MBSSID*/
2853 	rtw_hal_rcr_add(adapter, RCR_ENMBID);
2854 }
rtw_mi_set_mbid_cam(_adapter * adapter)2855 void rtw_mi_set_mbid_cam(_adapter *adapter)
2856 {
2857 	u8 i;
2858 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2859 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2860 
2861 #ifdef DBG_MBID_CAM_DUMP
2862 	rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2863 #endif
2864 
2865 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2866 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2867 			write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
2868 			RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2869 		}
2870 	}
2871 	rtw_mbid_cam_enable(adapter);
2872 }
2873 #endif /*CONFIG_MBSSID_CAM*/
2874 
2875 #ifdef CONFIG_FW_HANDLE_TXBCN
2876 #define H2C_BCN_OFFLOAD_LEN	1
2877 
2878 #define SET_H2CCMD_BCN_OFFLOAD_EN(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
2879 #define SET_H2CCMD_BCN_ROOT_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
2880 #define SET_H2CCMD_BCN_VAP1_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
2881 #define SET_H2CCMD_BCN_VAP2_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
2882 #define SET_H2CCMD_BCN_VAP3_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)
2883 #define SET_H2CCMD_BCN_VAP4_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)
2884 
rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter * adapter,bool fw_bcn_en,u8 tbtt_rpt_map)2885 void rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter *adapter, bool fw_bcn_en, u8 tbtt_rpt_map)
2886 {
2887 	u8 fw_bcn_offload[1] = {0};
2888 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2889 
2890 	if (fw_bcn_en)
2891 		SET_H2CCMD_BCN_OFFLOAD_EN(fw_bcn_offload, 1);
2892 
2893 	if (tbtt_rpt_map & BIT(0))
2894 		SET_H2CCMD_BCN_ROOT_TBTT_RPT(fw_bcn_offload, 1);
2895 	if (tbtt_rpt_map & BIT(1))
2896 		SET_H2CCMD_BCN_VAP1_TBTT_RPT(fw_bcn_offload, 1);
2897 	if (tbtt_rpt_map & BIT(2))
2898 		SET_H2CCMD_BCN_VAP2_TBTT_RPT(fw_bcn_offload, 1);
2899 	if (tbtt_rpt_map & BIT(3))
2900 			SET_H2CCMD_BCN_VAP3_TBTT_RPT(fw_bcn_offload, 1);
2901 
2902 	dvobj->vap_tbtt_rpt_map = tbtt_rpt_map;
2903 	dvobj->fw_bcn_offload = fw_bcn_en;
2904 	RTW_INFO("[FW BCN] Offload : %s\n", (dvobj->fw_bcn_offload) ? "EN" : "DIS");
2905 	RTW_INFO("[FW BCN] TBTT RPT map : 0x%02x\n", dvobj->vap_tbtt_rpt_map);
2906 
2907 	rtw_hal_fill_h2c_cmd(adapter, H2C_FW_BCN_OFFLOAD,
2908 					H2C_BCN_OFFLOAD_LEN, fw_bcn_offload);
2909 }
2910 
rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter * adapter)2911 void rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter *adapter)
2912 {
2913 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2914 	u8 ret, vap_id;
2915 	u32 page_size = 0;
2916 	u8 bcn_rsvdpage[H2C_BCN_RSVDPAGE_LEN] = {0};
2917 
2918 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
2919 	#if 1
2920 	for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {
2921 		if (dvobj->vap_map & BIT(vap_id))
2922 			bcn_rsvdpage[vap_id] = vap_id * (MAX_BEACON_LEN / page_size);
2923 	}
2924 	#else
2925 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
2926 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 8, __Value)
2927 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 8, __Value)
2928 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 8, __Value)
2929 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 8, __Value)
2930 
2931 	if (dvobj->vap_map & BIT(0))
2932  		SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(bcn_rsvdpage, 0);
2933 	if (dvobj->vap_map & BIT(1))
2934 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(bcn_rsvdpage,
2935 					1 * (MAX_BEACON_LEN / page_size));
2936 	if (dvobj->vap_map & BIT(2))
2937 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(bcn_rsvdpage,
2938 					2 * (MAX_BEACON_LEN / page_size));
2939 	if (dvobj->vap_map & BIT(3))
2940 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(bcn_rsvdpage,
2941 					3 * (MAX_BEACON_LEN / page_size));
2942 	if (dvobj->vap_map & BIT(4))
2943 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(bcn_rsvdpage,
2944 					4 * (MAX_BEACON_LEN / page_size));
2945 	#endif
2946 	if (1) {
2947 		RTW_INFO("[BCN_LOC] vap_map : 0x%02x\n", dvobj->vap_map);
2948 		RTW_INFO("[BCN_LOC] page_size :%d, @bcn_page_num :%d\n"
2949 			, page_size, (MAX_BEACON_LEN / page_size));
2950 		RTW_INFO("[BCN_LOC] root ap : 0x%02x\n", *bcn_rsvdpage);
2951 		RTW_INFO("[BCN_LOC] vap_1 : 0x%02x\n", *(bcn_rsvdpage + 1));
2952 		RTW_INFO("[BCN_LOC] vap_2 : 0x%02x\n", *(bcn_rsvdpage + 2));
2953 		RTW_INFO("[BCN_LOC] vap_3 : 0x%02x\n", *(bcn_rsvdpage + 3));
2954 		RTW_INFO("[BCN_LOC] vap_4 : 0x%02x\n", *(bcn_rsvdpage + 4));
2955 	}
2956 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,
2957 					H2C_BCN_RSVDPAGE_LEN, bcn_rsvdpage);
2958 }
2959 
rtw_ap_multi_bcn_cfg(_adapter * adapter)2960 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
2961 {
2962 	u8 dft_bcn_space = DEFAULT_BCN_INTERVAL;
2963 	u8 sub_bcn_space = (DEFAULT_BCN_INTERVAL / CONFIG_LIMITED_AP_NUM);
2964 
2965 	/*enable to rx data frame*/
2966 	rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
2967 
2968 	/*Disable Port0's beacon function*/
2969 	rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
2970 	/*Reset Port0's TSF*/
2971 	rtw_write8(adapter, REG_DUAL_TSF_RST, BIT_TSFTR_RST);
2972 
2973 	rtw_ap_set_mbid_num(adapter, CONFIG_LIMITED_AP_NUM);
2974 
2975 	/*BCN space & BCN sub-space 0x554[15:0] = 0x64,0x5BC[23:16] = 0x21*/
2976 	rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), HW_PORT0, dft_bcn_space);
2977 	rtw_write8(adapter, REG_MBSSID_BCN_SPACE3 + 2, sub_bcn_space);
2978 
2979 	#if 0 /*setting in hw_var_set_opmode_mbid - ResumeTxBeacon*/
2980 	/*BCN hold time  0x540[19:8] = 0x80*/
2981 	rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
2982 	rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,
2983 		(rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
2984 	#endif
2985 
2986 	/*ATIM window -0x55A = 0x32, reg 0x570 = 0x32, reg 0x5A0 = 0x32 */
2987 	rtw_write8(adapter, REG_ATIMWND, 0x32);
2988 	rtw_write8(adapter, REG_ATIMWND1_V1, 0x32);
2989 	rtw_write8(adapter, REG_ATIMWND2, 0x32);
2990 	rtw_write8(adapter, REG_ATIMWND3, 0x32);
2991 	/*
2992 	rtw_write8(adapter, REG_ATIMWND4, 0x32);
2993 	rtw_write8(adapter, REG_ATIMWND5, 0x32);
2994 	rtw_write8(adapter, REG_ATIMWND6, 0x32);
2995 	rtw_write8(adapter, REG_ATIMWND7, 0x32);*/
2996 
2997 	/*no limit setting - 0x5A7 = 0xFF - Packet in Hi Queue Tx immediately*/
2998 	rtw_write8(adapter, REG_HIQ_NO_LMT_EN, 0xFF);
2999 
3000 	/*Mask all beacon*/
3001 	rtw_write8(adapter, REG_MBSSID_CTRL, 0);
3002 
3003 	/*BCN invalid bit setting 0x454[6] = 1*/
3004 	/*rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);*/
3005 
3006 	/*Enable Port0's beacon function*/
3007 	rtw_write8(adapter, REG_BCN_CTRL,
3008 	rtw_read8(adapter, REG_BCN_CTRL) | BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT  | BIT_EN_BCN_FUNCTION);
3009 
3010 	/* Enable HW seq for BCN
3011 	* 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT  */
3012 	 #ifdef CONFIG_RTL8822B
3013 	if (IS_HARDWARE_TYPE_8822B(adapter))
3014 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3015 	#endif
3016 
3017 	 #ifdef CONFIG_RTL8822C
3018 	if (IS_HARDWARE_TYPE_8822C(adapter))
3019 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3020 	#endif
3021 }
_rtw_mbid_bcn_cfg(_adapter * adapter,bool mbcnq_en,u8 mbcnq_id)3022 static void _rtw_mbid_bcn_cfg(_adapter *adapter, bool mbcnq_en, u8 mbcnq_id)
3023 {
3024 	if (mbcnq_id >= CONFIG_LIMITED_AP_NUM) {
3025 		RTW_ERR(FUNC_ADPT_FMT"- mbid bcnq_id(%d) invalid\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3026 		rtw_warn_on(1);
3027 	}
3028 
3029 	if (mbcnq_en) {
3030 		rtw_write8(adapter, REG_MBSSID_CTRL,
3031 			rtw_read8(adapter, REG_MBSSID_CTRL) | BIT(mbcnq_id));
3032 		RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) enabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3033 	} else {
3034 		rtw_write8(adapter, REG_MBSSID_CTRL,
3035 			rtw_read8(adapter, REG_MBSSID_CTRL) & (~BIT(mbcnq_id)));
3036 		RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) disabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3037 	}
3038 }
3039 /*#define CONFIG_FW_TBTT_RPT*/
rtw_ap_mbid_bcn_en(_adapter * adapter,u8 ap_id)3040 void rtw_ap_mbid_bcn_en(_adapter *adapter, u8 ap_id)
3041 {
3042 	RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3043 
3044 	#ifdef CONFIG_FW_TBTT_RPT
3045 	if (rtw_ap_get_nums(adapter) >= 1) {
3046 		u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3047 
3048 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3049 			tbtt_rpt_map | BIT(ap_id));/*H2C-0xBA*/
3050 	}
3051 	#else
3052 	if (rtw_ap_get_nums(adapter) == 1)
3053 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE, 0);/*H2C-0xBA*/
3054 	#endif
3055 
3056 	rtw_hal_set_bcn_rsvdpage_loc_cmd(adapter);/*H2C-0x09*/
3057 
3058 	_rtw_mbid_bcn_cfg(adapter, _TRUE, ap_id);
3059 }
rtw_ap_mbid_bcn_dis(_adapter * adapter,u8 ap_id)3060 void rtw_ap_mbid_bcn_dis(_adapter *adapter, u8 ap_id)
3061 {
3062 	RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3063 	_rtw_mbid_bcn_cfg(adapter, _FALSE, ap_id);
3064 
3065 	if (rtw_ap_get_nums(adapter) == 0)
3066 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _FALSE, 0);
3067 	#ifdef CONFIG_FW_TBTT_RPT
3068 	else if (rtw_ap_get_nums(adapter) >= 1) {
3069 		u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3070 
3071 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3072 			tbtt_rpt_map & ~BIT(ap_id));/*H2C-0xBA*/
3073 	}
3074 	#endif
3075 }
3076 #endif
3077 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_ap_multi_bcn_cfg(_adapter * adapter)3078 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3079 {
3080 	#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3081 	rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT);
3082 	#else
3083 	rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
3084 	#endif
3085 	/*enable to rx data frame*/
3086 	rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3087 
3088 	/*Beacon Control related register for first time*/
3089 	rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */
3090 
3091 	/*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
3092 	rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */
3093 
3094 	#ifndef CONFIG_HW_P0_TSF_SYNC
3095 	rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3096 	#endif
3097 
3098 	/*reset TSF*/
3099 	rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
3100 
3101 	/*enable BCN0 Function for if1*/
3102 	/*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
3103 	#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3104 	rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
3105 	#else
3106 	rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3107 	#endif
3108 	#ifdef CONFIG_BCN_XMIT_PROTECT
3109 	rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
3110 	#endif
3111 
3112 	if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
3113 		rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
3114 
3115 	/* Enable HW seq for BCN
3116 	 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT  */
3117 	#ifdef CONFIG_RTL8822B
3118 	if (IS_HARDWARE_TYPE_8822B(adapter))
3119 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3120 	#endif
3121 
3122 	#ifdef CONFIG_RTL8822C
3123 	if (IS_HARDWARE_TYPE_8822C(adapter))
3124 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3125 	#endif
3126 }
3127 #endif
3128 
3129 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3130 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3131 {
3132 
3133 #if 0 /*TODO - modify for more flexible*/
3134 	u8 idx = 0;
3135 
3136 	if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
3137 	    (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
3138 		for (idx = 0; idx < 6; idx++)
3139 			rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
3140 	}  else {
3141 		/*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
3142 		u8 entry_id;
3143 
3144 		if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
3145 		    (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
3146 			entry_id = 0;
3147 			if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
3148 				RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
3149 				write_mbssid_cam(adapter, entry_id, val);
3150 			}
3151 		} else {
3152 			entry_id = rtw_mbid_camid_alloc(adapter, val);
3153 			if (entry_id != INVALID_CAM_ID)
3154 				write_mbssid_cam(adapter, entry_id, val);
3155 		}
3156 	}
3157 #else
3158 	{
3159 		/*
3160 			MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
3161 		*/
3162 		u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
3163 
3164 
3165 		if (entry_id != INVALID_CAM_ID) {
3166 			write_mbssid_cam(adapter, entry_id, mac_addr);
3167 			RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
3168 				ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
3169 		}
3170 	}
3171 #endif
3172 }
3173 
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3174 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3175 {
3176 	u8 idx = 0;
3177 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3178 	u8 entry_id;
3179 
3180 	if (!mac_addr) {
3181 		rtw_warn_on(1);
3182 		return;
3183 	}
3184 
3185 
3186 	entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
3187 
3188 	if (entry_id != INVALID_CAM_ID)
3189 		write_mbssid_cam(adapter, entry_id, mac_addr);
3190 }
3191 
3192 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)3193 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
3194 {
3195 	if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
3196 		return adapter_to_dvobj(adapter)->inter_bcn_space;
3197 	else
3198 		return bcn_interval;
3199 }
3200 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
3201 
3202 #else
3203 
3204 #ifndef RTW_HALMAC
_get_macaddr_reg(enum _hw_port hwport)3205 static u32 _get_macaddr_reg(enum _hw_port hwport)
3206 {
3207 	u32 reg_macaddr = REG_MACID;
3208 
3209 	#ifdef CONFIG_CONCURRENT_MODE
3210 	if (hwport == HW_PORT1)
3211 		reg_macaddr = REG_MACID1;
3212 	#if defined(CONFIG_RTL8814A)
3213 	else if (hwport == HW_PORT2)
3214 		reg_macaddr = REG_MACID2;
3215 	else if (hwport == HW_PORT3)
3216 		reg_macaddr = REG_MACID3;
3217 	else if (hwport == HW_PORT4)
3218 		reg_macaddr = REG_MACID4;
3219 	#endif /*CONFIG_RTL8814A*/
3220 	#endif /*CONFIG_CONCURRENT_MODE*/
3221 
3222 	return reg_macaddr;
3223 }
3224 #endif /*!RTW_HALMAC*/
3225 
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * mac_addr)3226 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)
3227 {
3228 	enum _hw_port hwport;
3229 
3230 	if (mac_addr == NULL)
3231 		return;
3232 	hwport = get_hw_port(adapter);
3233 
3234 	RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
3235 		 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3236 
3237 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3238 	rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3239 #else /* !RTW_HALMAC */
3240 	{
3241 		u8 idx = 0;
3242 		u32 reg_macaddr = _get_macaddr_reg(hwport);
3243 
3244 		for (idx = 0; idx < ETH_ALEN; idx++)
3245 			rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);
3246 	}
3247 #endif /* !RTW_HALMAC */
3248 }
3249 
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)3250 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
3251 {
3252 	enum _hw_port hwport;
3253 
3254 	if (mac_addr == NULL)
3255 		return;
3256 	hwport = get_hw_port(adapter);
3257 
3258 	_rtw_memset(mac_addr, 0, ETH_ALEN);
3259 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3260 	rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3261 #else /* !RTW_HALMAC */
3262 	{
3263 		u8 idx = 0;
3264 		u32 reg_macaddr = _get_macaddr_reg(hwport);
3265 
3266 		for (idx = 0; idx < ETH_ALEN; idx++)
3267 			mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));
3268 	}
3269 #endif /* !RTW_HALMAC */
3270 
3271 	RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
3272 		 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3273 }
3274 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
3275 
3276 #ifndef RTW_HALMAC
_get_bssid_reg(enum _hw_port hw_port)3277 static u32 _get_bssid_reg(enum _hw_port hw_port)
3278 {
3279 	u32 reg_bssid = REG_BSSID;
3280 
3281 	#ifdef CONFIG_CONCURRENT_MODE
3282 	if (hw_port == HW_PORT1)
3283 		reg_bssid = REG_BSSID1;
3284 	#if defined(CONFIG_RTL8814A)
3285 	else if (hw_port == HW_PORT2)
3286 		reg_bssid = REG_BSSID2;
3287 	else if (hw_port == HW_PORT3)
3288 		reg_bssid = REG_BSSID3;
3289 	else if (hw_port == HW_PORT4)
3290 		reg_bssid = REG_BSSID4;
3291 	#endif /*CONFIG_RTL8814A*/
3292 	#endif /*CONFIG_CONCURRENT_MODE*/
3293 
3294 	return reg_bssid;
3295 }
3296 #endif /*!RTW_HALMAC*/
rtw_hal_set_bssid(_adapter * adapter,u8 * val)3297 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
3298 {
3299 	enum _hw_port hw_port = rtw_hal_get_port(adapter);
3300 #ifdef RTW_HALMAC
3301 
3302 	rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
3303 #else /* !RTW_HALMAC */
3304 	u8 idx = 0;
3305 	u32 reg_bssid = _get_bssid_reg(hw_port);
3306 
3307 	for (idx = 0 ; idx < ETH_ALEN; idx++)
3308 		rtw_write8(adapter, (reg_bssid + idx), val[idx]);
3309 #endif /* !RTW_HALMAC */
3310 
3311 	RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
3312 		__func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
3313 }
3314 
3315 #ifndef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_tsf_update(_adapter * adapter,u8 en)3316 static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
3317 {
3318 	u32 addr = 0;
3319 	u8 val8;
3320 
3321 	rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
3322 	if (addr) {
3323 		rtw_enter_protsel_port(adapter, get_hw_port(adapter));
3324 		val8 = rtw_read8(adapter, addr);
3325 		if (en && (val8 & DIS_TSF_UDT)) {
3326 			rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
3327 			#ifdef DBG_TSF_UPDATE
3328 			RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3329 			#endif
3330 		}
3331 		if (!en && !(val8 & DIS_TSF_UDT)) {
3332 			rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
3333 			#ifdef DBG_TSF_UPDATE
3334 			RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3335 			#endif
3336 		}
3337 		rtw_leave_protsel_port(adapter);
3338 	} else {
3339 		RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
3340 			, adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
3341 		rtw_warn_on(1);
3342 	}
3343 }
3344 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_set_hw_update_tsf(PADAPTER padapter)3345 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
3346 {
3347 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3348 
3349 #else
3350 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3351 
3352 	if (!pmlmeext->en_hw_update_tsf)
3353 		return;
3354 
3355 	/* check RCR */
3356 	if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
3357 		return;
3358 
3359 	if (pmlmeext->tsf_update_required) {
3360 		pmlmeext->tsf_update_pause_stime = 0;
3361 		rtw_hal_set_tsf_update(padapter, 1);
3362 	}
3363 
3364 	pmlmeext->en_hw_update_tsf = 0;
3365 #endif
3366 }
3367 
rtw_iface_enable_tsf_update(_adapter * adapter)3368 void rtw_iface_enable_tsf_update(_adapter *adapter)
3369 {
3370 	adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3371 	adapter->mlmeextpriv.tsf_update_required = 1;
3372 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3373 
3374 #else
3375 	rtw_hal_set_tsf_update(adapter, 1);
3376 #endif
3377 }
3378 
rtw_iface_disable_tsf_update(_adapter * adapter)3379 void rtw_iface_disable_tsf_update(_adapter *adapter)
3380 {
3381 	adapter->mlmeextpriv.tsf_update_required = 0;
3382 	adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3383 	adapter->mlmeextpriv.en_hw_update_tsf = 0;
3384 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3385 
3386 #else
3387 	rtw_hal_set_tsf_update(adapter, 0);
3388 #endif
3389 }
3390 
rtw_hal_tsf_update_pause(_adapter * adapter)3391 static void rtw_hal_tsf_update_pause(_adapter *adapter)
3392 {
3393 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3394 
3395 #else
3396 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3397 	_adapter *iface;
3398 	int i;
3399 
3400 	for (i = 0; i < dvobj->iface_nums; i++) {
3401 		iface = dvobj->padapters[i];
3402 		if (!iface)
3403 			continue;
3404 
3405 		rtw_hal_set_tsf_update(iface, 0);
3406 		if (iface->mlmeextpriv.tsf_update_required) {
3407 			iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
3408 			if (!iface->mlmeextpriv.tsf_update_pause_stime)
3409 				iface->mlmeextpriv.tsf_update_pause_stime++;
3410 		}
3411 		iface->mlmeextpriv.en_hw_update_tsf = 0;
3412 	}
3413 #endif
3414 }
3415 
rtw_hal_tsf_update_restore(_adapter * adapter)3416 static void rtw_hal_tsf_update_restore(_adapter *adapter)
3417 {
3418 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3419 
3420 #else
3421 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3422 	_adapter *iface;
3423 	int i;
3424 
3425 	for (i = 0; i < dvobj->iface_nums; i++) {
3426 		iface = dvobj->padapters[i];
3427 		if (!iface)
3428 			continue;
3429 
3430 		if (iface->mlmeextpriv.tsf_update_required) {
3431 			/* enable HW TSF update when recive beacon*/
3432 			iface->mlmeextpriv.en_hw_update_tsf = 1;
3433 			#ifdef DBG_TSF_UPDATE
3434 			RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
3435 				, iface->hw_port, ADPT_ARG(iface));
3436 			#endif
3437 		}
3438 	}
3439 #endif
3440 }
3441 
rtw_hal_periodic_tsf_update_chk(_adapter * adapter)3442 void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
3443 {
3444 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3445 
3446 #else
3447 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3448 	_adapter *iface;
3449 	struct mlme_ext_priv *mlmeext;
3450 	int i;
3451 	u32 restore_ms = 0;
3452 
3453 	if (dvobj->periodic_tsf_update_etime) {
3454 		if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
3455 			/* end for restore status */
3456 			dvobj->periodic_tsf_update_etime = 0;
3457 			rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3458 		}
3459 		return;
3460 	}
3461 
3462 	if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
3463 		return;
3464 
3465 	/*
3466 	* all required ifaces can switch to restore status together
3467 	* loop all pause iface to get largest restore time required
3468 	*/
3469 	for (i = 0; i < dvobj->iface_nums; i++) {
3470 		iface = dvobj->padapters[i];
3471 		if (!iface)
3472 			continue;
3473 
3474 		mlmeext = &iface->mlmeextpriv;
3475 
3476 		if (mlmeext->tsf_update_required
3477 			&& mlmeext->tsf_update_pause_stime
3478 			&& rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
3479 				> mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
3480 		) {
3481 			if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
3482 				restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
3483 		}
3484 	}
3485 
3486 	if (!restore_ms)
3487 		return;
3488 
3489 	dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
3490 	if (!dvobj->periodic_tsf_update_etime)
3491 		dvobj->periodic_tsf_update_etime++;
3492 
3493 	rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3494 
3495 	/* set timer to end restore status */
3496 	_set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
3497 #endif
3498 }
3499 
rtw_hal_periodic_tsf_update_end_timer_hdl(void * ctx)3500 void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
3501 {
3502 	struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
3503 
3504 	if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
3505 		return;
3506 
3507 	rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
3508 }
3509 
hw_var_rcr_config(_adapter * adapter,u32 rcr)3510 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
3511 {
3512 	int err;
3513 
3514 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3515 	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;
3516 #endif
3517 	err = rtw_write32(adapter, REG_RCR, rcr);
3518 	if (err == _SUCCESS)
3519 		GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
3520 	return err;
3521 }
3522 
hw_var_rcr_get(_adapter * adapter,u32 * rcr)3523 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
3524 {
3525 	u32 v32;
3526 
3527 	v32 = rtw_read32(adapter, REG_RCR);
3528 	if (rcr)
3529 		*rcr = v32;
3530 	GET_HAL_DATA(adapter)->ReceiveConfig = v32;
3531 	return _SUCCESS;
3532 }
3533 
3534 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)3535 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
3536 {
3537 	PHAL_DATA_TYPE hal;
3538 	u32 rcr;
3539 
3540 	hal = GET_HAL_DATA(adapter);
3541 
3542 	rcr = hal->ReceiveConfig;
3543 	if ((rcr & check_bit) == check_bit)
3544 		return 1;
3545 
3546 	return 0;
3547 }
3548 
rtw_hal_rcr_add(_adapter * adapter,u32 add)3549 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
3550 {
3551 	PHAL_DATA_TYPE hal;
3552 	u32 rcr;
3553 	u8 ret = _SUCCESS;
3554 
3555 	hal = GET_HAL_DATA(adapter);
3556 
3557 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3558 	rcr |= add;
3559 	if (rcr != hal->ReceiveConfig)
3560 		ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3561 
3562 	return ret;
3563 }
3564 
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)3565 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
3566 {
3567 	PHAL_DATA_TYPE hal;
3568 	u32 rcr;
3569 	u8 ret = _SUCCESS;
3570 
3571 	hal = GET_HAL_DATA(adapter);
3572 
3573 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3574 	rcr &= ~clear;
3575 	if (rcr != hal->ReceiveConfig)
3576 		ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3577 
3578 	return ret;
3579 }
3580 
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)3581 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
3582 {
3583 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3584 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3585 	u32 rcr, rcr_new;
3586 	struct mi_state mstate, mstate_s;
3587 
3588 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3589 	rcr_new = rcr;
3590 
3591 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
3592 	rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
3593 #else
3594 	rtw_mi_status_no_self(adapter, &mstate);
3595 	rtw_mi_status_no_others(adapter, &mstate_s);
3596 
3597 	/* only adjust parameters interested */
3598 	switch (self_action) {
3599 	case MLME_SCAN_ENTER:
3600 		mstate_s.scan_num = 1;
3601 		mstate_s.scan_enter_num = 1;
3602 		break;
3603 	case MLME_SCAN_DONE:
3604 		mstate_s.scan_enter_num = 0;
3605 		break;
3606 	case MLME_STA_CONNECTING:
3607 		mstate_s.lg_sta_num = 1;
3608 		mstate_s.ld_sta_num = 0;
3609 		break;
3610 	case MLME_STA_CONNECTED:
3611 		mstate_s.lg_sta_num = 0;
3612 		mstate_s.ld_sta_num = 1;
3613 		break;
3614 	case MLME_STA_DISCONNECTED:
3615 		mstate_s.lg_sta_num = 0;
3616 		mstate_s.ld_sta_num = 0;
3617 		break;
3618 #ifdef CONFIG_TDLS
3619 	case MLME_TDLS_LINKED:
3620 		mstate_s.ld_tdls_num = 1;
3621 		break;
3622 	case MLME_TDLS_NOLINK:
3623 		mstate_s.ld_tdls_num = 0;
3624 		break;
3625 #endif
3626 #ifdef CONFIG_AP_MODE
3627 	case MLME_AP_STARTED:
3628 		mstate_s.ap_num = 1;
3629 		break;
3630 	case MLME_AP_STOPPED:
3631 		mstate_s.ap_num = 0;
3632 		mstate_s.ld_ap_num = 0;
3633 		break;
3634 #endif
3635 #ifdef CONFIG_RTW_MESH
3636 	case MLME_MESH_STARTED:
3637 		mstate_s.mesh_num = 1;
3638 		break;
3639 	case MLME_MESH_STOPPED:
3640 		mstate_s.mesh_num = 0;
3641 		mstate_s.ld_mesh_num = 0;
3642 		break;
3643 #endif
3644 	case MLME_ACTION_NONE:
3645 	case MLME_ADHOC_STARTED:
3646 		/* caller without effect of decision */
3647 		break;
3648 	default:
3649 		rtw_warn_on(1);
3650 	};
3651 
3652 	rtw_mi_status_merge(&mstate, &mstate_s);
3653 
3654 	if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
3655 		#ifdef CONFIG_FIND_BEST_CHANNEL
3656 		|| MSTATE_SCAN_ENTER_NUM(&mstate)
3657 		#endif
3658 		|| hal_data->in_cta_test
3659 	)
3660 		rcr_new &= ~RCR_CBSSID_DATA;
3661 	else
3662 		rcr_new |= RCR_CBSSID_DATA;
3663 
3664 	if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
3665 		rcr_new &= ~RCR_CBSSID_BCN;
3666 	else if (MSTATE_STA_LG_NUM(&mstate)
3667 		|| adapter_to_dvobj(adapter)->periodic_tsf_update_etime
3668 	)
3669 		rcr_new |= RCR_CBSSID_BCN;
3670 	else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
3671 		|| MSTATE_MESH_NUM(&mstate)
3672 	)
3673 		rcr_new &= ~RCR_CBSSID_BCN;
3674 	else
3675 		rcr_new |= RCR_CBSSID_BCN;
3676 
3677 	#ifdef CONFIG_CLIENT_PORT_CFG
3678 	if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
3679 		rcr_new &= ~RCR_CBSSID_BCN;
3680 	#endif
3681 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
3682 
3683 #ifdef CONFIG_RTW_MULTI_AP
3684 	if (MSTATE_AP_NUM(&mstate)
3685 		&& rtw_unassoc_sta_src_chk(adapter, UNASOC_STA_SRC_RX_NMY_UC)
3686 	) {
3687 		rcr_new |= RCR_AAP;
3688 	} else
3689 		rcr_new &= ~RCR_AAP;
3690 #endif
3691 
3692 	if (rcr == rcr_new)
3693 		return;
3694 
3695 	if (!hal_spec->rx_tsf_filter
3696 		&& (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
3697 		rtw_hal_tsf_update_pause(adapter);
3698 
3699 	rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
3700 
3701 	if (!hal_spec->rx_tsf_filter
3702 		&& !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
3703 		&& self_action != MLME_STA_CONNECTING)
3704 		rtw_hal_tsf_update_restore(adapter);
3705 }
3706 
rtw_hal_rcr_set_chk_bssid_act_non(_adapter * adapter)3707 void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter)
3708 {
3709 	rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3710 }
3711 
hw_var_set_rcr_am(_adapter * adapter,u8 enable)3712 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
3713 {
3714 	u32 rcr = RCR_AM;
3715 
3716 	if (enable)
3717 		rtw_hal_rcr_add(adapter, rcr);
3718 	else
3719 		rtw_hal_rcr_clear(adapter, rcr);
3720 }
3721 
hw_var_set_bcn_interval(_adapter * adapter,u16 interval)3722 static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
3723 {
3724 #ifdef CONFIG_SWTIMER_BASED_TXBCN
3725 	interval = rtw_hal_bcn_interval_adjust(adapter, interval);
3726 #endif
3727 
3728 #ifdef RTW_HALMAC
3729 	rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
3730 #else
3731 	rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
3732 #endif
3733 
3734 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3735 	{
3736 		struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
3737 		struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3738 
3739 		if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3740 			RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
3741 			rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
3742 		}
3743 	}
3744 #endif
3745 }
3746 
3747 #if CONFIG_TX_AC_LIFETIME
3748 const char *const _tx_aclt_conf_str[] = {
3749 	"DEFAULT",
3750 	"AP_M2U",
3751 	"MESH",
3752 	"INVALID",
3753 };
3754 
dump_tx_aclt_force_val(void * sel,struct dvobj_priv * dvobj)3755 void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)
3756 {
3757 #define TX_ACLT_FORCE_MSG_LEN 64
3758 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3759 	struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3760 	char buf[TX_ACLT_FORCE_MSG_LEN];
3761 	int cnt = 0;
3762 
3763 	RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3764 		, hal_spec->tx_aclt_unit_factor * 32
3765 		, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3766 
3767 	RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");
3768 	RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"
3769 		, conf->en
3770 		, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3771 		, conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3772 	);
3773 
3774 	cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");
3775 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3776 		goto exit;
3777 
3778 	if (conf->vo_vi)
3779 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);
3780 	else
3781 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "         AUTO");
3782 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3783 		goto exit;
3784 
3785 
3786 	if (conf->be_bk)
3787 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);
3788 	else
3789 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "         AUTO");
3790 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3791 		goto exit;
3792 
3793 	RTW_PRINT_SEL(sel, "%s\n", buf);
3794 
3795 exit:
3796 	return;
3797 }
3798 
rtw_hal_set_tx_aclt_force_val(_adapter * adapter,struct tx_aclt_conf_t * input,u8 arg_num)3799 void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)
3800 {
3801 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3802 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3803 	struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3804 
3805 	if (arg_num >= 1) {
3806 		if (input->en == 0xFF)
3807 			conf->en = input->en;
3808 		else
3809 			conf->en = input->en & 0xF;
3810 	}
3811 	if (arg_num >= 2) {
3812 		conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3813 		if (conf->vo_vi > 0xFFFF)
3814 			conf->vo_vi = 0xFFFF;
3815 	}
3816 	if (arg_num >= 3) {
3817 		conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3818 		if (conf->be_bk > 0xFFFF)
3819 			conf->be_bk = 0xFFFF;
3820 	}
3821 }
3822 
dump_tx_aclt_confs(void * sel,struct dvobj_priv * dvobj)3823 void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)
3824 {
3825 #define TX_ACLT_CONF_MSG_LEN 32
3826 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3827 	struct tx_aclt_conf_t *conf;
3828 	char buf[TX_ACLT_CONF_MSG_LEN];
3829 	int cnt;
3830 	int i;
3831 
3832 	RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3833 		, hal_spec->tx_aclt_unit_factor * 32
3834 		, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3835 
3836 	RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"
3837 		, "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");
3838 
3839 	for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3840 		conf = &dvobj->tx_aclt_confs[i];
3841 		cnt = 0;
3842 
3843 		if (conf->vo_vi)
3844 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "     0x%04x", conf->vo_vi);
3845 		else
3846 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "        N/A");
3847 		if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
3848 			continue;
3849 
3850 		if (conf->be_bk)
3851 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "     0x%04x", conf->be_bk);
3852 		else
3853 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "        N/A");
3854 		if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
3855 			continue;
3856 
3857 		RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"
3858 			, tx_aclt_conf_str(i), i
3859 			, conf->en
3860 			, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3861 			, conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3862 			, buf
3863 		);
3864 	}
3865 }
3866 
rtw_hal_set_tx_aclt_conf(_adapter * adapter,u8 conf_idx,struct tx_aclt_conf_t * input,u8 arg_num)3867 void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)
3868 {
3869 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3870 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3871 	struct tx_aclt_conf_t *conf;
3872 
3873 	if (conf_idx >= TX_ACLT_CONF_NUM)
3874 		return;
3875 
3876 	conf = &dvobj->tx_aclt_confs[conf_idx];
3877 
3878 	if (arg_num >= 1) {
3879 		if (input->en != 0xFF)
3880 			conf->en = input->en & 0xF;
3881 	}
3882 	if (arg_num >= 2) {
3883 		conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3884 		if (conf->vo_vi > 0xFFFF)
3885 			conf->vo_vi = 0xFFFF;
3886 	}
3887 	if (arg_num >= 3) {
3888 		conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3889 		if (conf->be_bk > 0xFFFF)
3890 			conf->be_bk = 0xFFFF;
3891 	}
3892 }
3893 
rtw_hal_update_tx_aclt(_adapter * adapter)3894 void rtw_hal_update_tx_aclt(_adapter *adapter)
3895 {
3896 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3897 	struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);
3898 	u8 lt_en = 0, lt_en_ori;
3899 	u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;
3900 	u32 lt, lt_ori;
3901 	struct tx_aclt_conf_t *conf;
3902 	int i;
3903 #ifdef CONFIG_AP_MODE
3904 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
3905 	_adapter *iface;
3906 	u8 ap_m2u_num = 0;
3907 
3908 	for (i = 0; i < dvobj->iface_nums; i++) {
3909 		iface = dvobj->padapters[i];
3910 		if (!iface)
3911 			continue;
3912 
3913 		if (MLME_IS_AP(iface)
3914 			&& ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST)
3915 				|| (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST))
3916 		)
3917 			ap_m2u_num++;
3918 	}
3919 #endif
3920 #endif /* CONFIG_AP_MODE */
3921 
3922 	lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);
3923 	lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);
3924 
3925 	for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3926 		if (!(dvobj->tx_aclt_flags & BIT(i)))
3927 			continue;
3928 
3929 		conf = &dvobj->tx_aclt_confs[i];
3930 
3931 		if (i == TX_ACLT_CONF_DEFAULT) {
3932 			/* first and default status, assign directly */
3933 			lt_en = conf->en;
3934 			if (conf->vo_vi)
3935 				lt_vo_vi = conf->vo_vi;
3936 			if (conf->be_bk)
3937 				lt_be_bk = conf->be_bk;
3938 		}
3939 		#ifdef CONFIG_AP_MODE
3940 		#if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH)
3941 		else if (0
3942 			#if CONFIG_RTW_AP_DATA_BMC_TO_UC
3943 			|| (i == TX_ACLT_CONF_AP_M2U
3944 				&& ap_m2u_num
3945 				&& macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)
3946 			#endif
3947 			#ifdef CONFIG_RTW_MESH
3948 			|| (i == TX_ACLT_CONF_MESH
3949 				&& macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)
3950 			#endif
3951 		) {
3952 			/* long term status, OR en and MIN lifetime */
3953 			lt_en |= conf->en;
3954 			if (conf->vo_vi && lt_vo_vi > conf->vo_vi)
3955 				lt_vo_vi = conf->vo_vi;
3956 			if (conf->be_bk && lt_be_bk > conf->be_bk)
3957 				lt_be_bk = conf->be_bk;
3958 		}
3959 		#endif
3960 		#endif /* CONFIG_AP_MODE */
3961 	}
3962 
3963 	if (dvobj->tx_aclt_force_val.en != 0xFF)
3964 		lt_en = dvobj->tx_aclt_force_val.en;
3965 	if (dvobj->tx_aclt_force_val.vo_vi)
3966 		lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;
3967 	if (dvobj->tx_aclt_force_val.be_bk)
3968 		lt_be_bk = dvobj->tx_aclt_force_val.be_bk;
3969 
3970 	lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);
3971 	lt = (lt_be_bk << 16) | lt_vo_vi;
3972 
3973 	if (0)
3974 		RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);
3975 
3976 	if (lt_en != lt_en_ori)
3977 		rtw_write8(adapter, REG_LIFETIME_EN, lt_en);
3978 	if (lt != lt_ori)
3979 		rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);
3980 }
3981 #endif /* CONFIG_TX_AC_LIFETIME */
3982 
hw_var_port_switch(_adapter * adapter)3983 void hw_var_port_switch(_adapter *adapter)
3984 {
3985 #ifdef CONFIG_CONCURRENT_MODE
3986 #ifdef CONFIG_RUNTIME_PORT_SWITCH
3987 	/*
3988 	0x102: MSR
3989 	0x550: REG_BCN_CTRL
3990 	0x551: REG_BCN_CTRL_1
3991 	0x55A: REG_ATIMWND
3992 	0x560: REG_TSFTR
3993 	0x568: REG_TSFTR1
3994 	0x570: REG_ATIMWND_1
3995 	0x610: REG_MACID
3996 	0x618: REG_BSSID
3997 	0x700: REG_MACID1
3998 	0x708: REG_BSSID1
3999 	*/
4000 
4001 	int i;
4002 	u8 msr;
4003 	u8 bcn_ctrl;
4004 	u8 bcn_ctrl_1;
4005 	u8 atimwnd[2];
4006 	u8 atimwnd_1[2];
4007 	u8 tsftr[8];
4008 	u8 tsftr_1[8];
4009 	u8 macid[6];
4010 	u8 bssid[6];
4011 	u8 macid_1[6];
4012 	u8 bssid_1[6];
4013 #if defined(CONFIG_RTL8192F)
4014 	u16 wlan_act_mask_ctrl = 0;
4015 	u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
4016 #endif
4017 
4018 	u8 hw_port;
4019 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4020 	_adapter *iface = NULL;
4021 
4022 	msr = rtw_read8(adapter, MSR);
4023 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4024 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4025 #if defined(CONFIG_RTL8192F)
4026 	wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4027 #endif
4028 
4029 	for (i = 0; i < 2; i++)
4030 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4031 	for (i = 0; i < 2; i++)
4032 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4033 
4034 	for (i = 0; i < 8; i++)
4035 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4036 	for (i = 0; i < 8; i++)
4037 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4038 
4039 	for (i = 0; i < 6; i++)
4040 		macid[i] = rtw_read8(adapter, REG_MACID + i);
4041 
4042 	for (i = 0; i < 6; i++)
4043 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4044 
4045 	for (i = 0; i < 6; i++)
4046 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4047 
4048 	for (i = 0; i < 6; i++)
4049 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4050 
4051 #ifdef DBG_RUNTIME_PORT_SWITCH
4052 	RTW_INFO(FUNC_ADPT_FMT" before switch\n"
4053 		 "msr:0x%02x\n"
4054 		 "bcn_ctrl:0x%02x\n"
4055 		 "bcn_ctrl_1:0x%02x\n"
4056 #if defined(CONFIG_RTL8192F)
4057 		 "wlan_act_mask_ctrl:0x%02x\n"
4058 #endif
4059 		 "atimwnd:0x%04x\n"
4060 		 "atimwnd_1:0x%04x\n"
4061 		 "tsftr:%llu\n"
4062 		 "tsftr1:%llu\n"
4063 		 "macid:"MAC_FMT"\n"
4064 		 "bssid:"MAC_FMT"\n"
4065 		 "macid_1:"MAC_FMT"\n"
4066 		 "bssid_1:"MAC_FMT"\n"
4067 		 , FUNC_ADPT_ARG(adapter)
4068 		 , msr
4069 		 , bcn_ctrl
4070 		 , bcn_ctrl_1
4071 #if defined(CONFIG_RTL8192F)
4072 		 , wlan_act_mask_ctrl
4073 #endif
4074 		 , *((u16 *)atimwnd)
4075 		 , *((u16 *)atimwnd_1)
4076 		 , *((u64 *)tsftr)
4077 		 , *((u64 *)tsftr_1)
4078 		 , MAC_ARG(macid)
4079 		 , MAC_ARG(bssid)
4080 		 , MAC_ARG(macid_1)
4081 		 , MAC_ARG(bssid_1)
4082 		);
4083 #endif /* DBG_RUNTIME_PORT_SWITCH */
4084 
4085 	/* disable bcn function, disable update TSF */
4086 	rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4087 	rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4088 
4089 #if defined(CONFIG_RTL8192F)
4090 	rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
4091 #endif
4092 
4093 	/* switch msr */
4094 	msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
4095 	rtw_write8(adapter, MSR, msr);
4096 
4097 	/* write port0 */
4098 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
4099 	for (i = 0; i < 2; i++)
4100 		rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
4101 	for (i = 0; i < 8; i++)
4102 		rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
4103 	for (i = 0; i < 6; i++)
4104 		rtw_write8(adapter, REG_MACID + i, macid_1[i]);
4105 	for (i = 0; i < 6; i++)
4106 		rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
4107 
4108 	/* write port1 */
4109 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
4110 	for (i = 0; i < 2; i++)
4111 		rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
4112 	for (i = 0; i < 8; i++)
4113 		rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
4114 	for (i = 0; i < 6; i++)
4115 		rtw_write8(adapter, REG_MACID1 + i, macid[i]);
4116 	for (i = 0; i < 6; i++)
4117 		rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
4118 
4119 	/* write bcn ctl */
4120 #ifdef CONFIG_BT_COEXIST
4121 	/* always enable port0 beacon function for PSTDMA */
4122 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
4123 	    || IS_HARDWARE_TYPE_8723D(adapter))
4124 		bcn_ctrl_1 |= EN_BCN_FUNCTION;
4125 	/* always disable port1 beacon function for PSTDMA */
4126 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
4127 		bcn_ctrl &= ~EN_BCN_FUNCTION;
4128 #endif
4129 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
4130 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
4131 
4132 #if defined(CONFIG_RTL8192F)
4133 	/* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
4134 	if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
4135 		!= (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
4136 		wlan_act_mask_ctrl ^= en_port_mask;
4137 	rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
4138 #endif
4139 
4140 	if (adapter->iface_id == IFACE_ID0)
4141 		iface = dvobj->padapters[IFACE_ID1];
4142 	else if (adapter->iface_id == IFACE_ID1)
4143 		iface = dvobj->padapters[IFACE_ID0];
4144 
4145 
4146 	if (adapter->hw_port == HW_PORT0) {
4147 		adapter->hw_port = HW_PORT1;
4148 		iface->hw_port = HW_PORT0;
4149 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4150 			  ADPT_ARG(iface), ADPT_ARG(adapter));
4151 	} else {
4152 		adapter->hw_port = HW_PORT0;
4153 		iface->hw_port = HW_PORT1;
4154 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4155 			  ADPT_ARG(adapter), ADPT_ARG(iface));
4156 	}
4157 
4158 #ifdef DBG_RUNTIME_PORT_SWITCH
4159 	msr = rtw_read8(adapter, MSR);
4160 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4161 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4162 #if defined(CONFIG_RTL8192F)
4163 	wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4164 #endif
4165 
4166 	for (i = 0; i < 2; i++)
4167 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4168 	for (i = 0; i < 2; i++)
4169 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4170 
4171 	for (i = 0; i < 8; i++)
4172 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4173 	for (i = 0; i < 8; i++)
4174 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4175 
4176 	for (i = 0; i < 6; i++)
4177 		macid[i] = rtw_read8(adapter, REG_MACID + i);
4178 
4179 	for (i = 0; i < 6; i++)
4180 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4181 
4182 	for (i = 0; i < 6; i++)
4183 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4184 
4185 	for (i = 0; i < 6; i++)
4186 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4187 
4188 	RTW_INFO(FUNC_ADPT_FMT" after switch\n"
4189 		 "msr:0x%02x\n"
4190 		 "bcn_ctrl:0x%02x\n"
4191 		 "bcn_ctrl_1:0x%02x\n"
4192 #if defined(CONFIG_RTL8192F)
4193 		 "wlan_act_mask_ctrl:0x%02x\n"
4194 #endif
4195 		 "atimwnd:%u\n"
4196 		 "atimwnd_1:%u\n"
4197 		 "tsftr:%llu\n"
4198 		 "tsftr1:%llu\n"
4199 		 "macid:"MAC_FMT"\n"
4200 		 "bssid:"MAC_FMT"\n"
4201 		 "macid_1:"MAC_FMT"\n"
4202 		 "bssid_1:"MAC_FMT"\n"
4203 		 , FUNC_ADPT_ARG(adapter)
4204 		 , msr
4205 		 , bcn_ctrl
4206 		 , bcn_ctrl_1
4207 #if defined(CONFIG_RTL8192F)
4208 		 , wlan_act_mask_ctrl
4209 #endif
4210 		 , *((u16 *)atimwnd)
4211 		 , *((u16 *)atimwnd_1)
4212 		 , *((u64 *)tsftr)
4213 		 , *((u64 *)tsftr_1)
4214 		 , MAC_ARG(macid)
4215 		 , MAC_ARG(bssid)
4216 		 , MAC_ARG(macid_1)
4217 		 , MAC_ARG(bssid_1)
4218 		);
4219 #endif /* DBG_RUNTIME_PORT_SWITCH */
4220 
4221 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
4222 #endif /* CONFIG_CONCURRENT_MODE */
4223 }
4224 
4225 const char *const _h2c_msr_role_str[] = {
4226 	"RSVD",
4227 	"STA",
4228 	"AP",
4229 	"GC",
4230 	"GO",
4231 	"TDLS",
4232 	"ADHOC",
4233 	"MESH",
4234 	"INVALID",
4235 };
4236 
4237 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)4238 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
4239 {
4240 	s32 ret = _SUCCESS;
4241 	u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
4242 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4243 	u8 port_id = rtw_hal_get_port(adapter);
4244 
4245 	if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
4246 		return ret;
4247 
4248 	SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
4249 	SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
4250 
4251 	RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
4252 	RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
4253 		__func__, ADPT_ARG(adapter), port_id, mac_id);
4254 
4255 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
4256 	dvobj->dft.port_id = port_id;
4257 	dvobj->dft.mac_id = mac_id;
4258 
4259 	return ret;
4260 }
rtw_set_default_port_id(_adapter * adapter)4261 s32 rtw_set_default_port_id(_adapter *adapter)
4262 {
4263 	s32 ret = _SUCCESS;
4264 	struct sta_info		*psta;
4265 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4266 
4267 	if (is_client_associated_to_ap(adapter)) {
4268 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
4269 		if (psta)
4270 			ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
4271 	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
4272 
4273 	} else {
4274 	}
4275 
4276 	return ret;
4277 }
rtw_set_ps_rsvd_page(_adapter * adapter)4278 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
4279 {
4280 	s32 ret = _SUCCESS;
4281 	u16 media_status_rpt = RT_MEDIA_CONNECT;
4282 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4283 
4284 	if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
4285 		return ret;
4286 
4287 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
4288 			  (u8 *)&media_status_rpt);
4289 
4290 	return ret;
4291 }
4292 
4293 #if 0
4294 _adapter * _rtw_search_dp_iface(_adapter *adapter)
4295 {
4296 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4297 	_adapter *iface;
4298 	_adapter *target_iface = NULL;
4299 	int i;
4300 	u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
4301 	u8 p2p_go_num = 0, p2p_gc_num = 0;
4302 	_adapter *sta_ifs[8];
4303 	_adapter *ap_ifs[8];
4304 	_adapter *mesh_ifs[8];
4305 	_adapter *gc_ifs[8];
4306 	_adapter *go_ifs[8];
4307 
4308 	for (i = 0; i < dvobj->iface_nums; i++) {
4309 		iface = dvobj->padapters[i];
4310 
4311 		if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
4312 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4313 				sta_ifs[sta_num++] = iface;
4314 
4315 				#ifdef CONFIG_TDLS
4316 				if (iface->tdlsinfo.link_established == _TRUE)
4317 					tdls_num++;
4318 				#endif
4319 				#ifdef CONFIG_P2P
4320 				if (MLME_IS_GC(iface))
4321 					gc_ifs[p2p_gc_num++] = iface;
4322 				#endif
4323 			}
4324 #ifdef CONFIG_AP_MODE
4325 		} else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
4326 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4327 				ap_ifs[ap_num++] = iface;
4328 				#ifdef CONFIG_P2P
4329 				if (MLME_IS_GO(iface))
4330 					go_ifs[p2p_go_num++] = iface;
4331 				#endif
4332 			}
4333 #endif
4334 		} else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
4335 			&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4336 		) {
4337 			adhoc_num++;
4338 
4339 #ifdef CONFIG_RTW_MESH
4340 		} else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
4341 			&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4342 		) {
4343 			mesh_ifs[mesh_num++] = iface;
4344 #endif
4345 		}
4346 	}
4347 
4348 	if (p2p_gc_num) {
4349 		target_iface = gc_ifs[0];
4350 	}
4351 	else if (sta_num) {
4352 		if(sta_num == 1) {
4353 			target_iface = sta_ifs[0];
4354 		} else if (sta_num >= 2) {
4355 			/*TODO get target_iface by timestamp*/
4356 			target_iface = sta_ifs[0];
4357 		}
4358 	} else if (ap_num) {
4359 		target_iface = ap_ifs[0];
4360 	}
4361 
4362 	RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
4363 	RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
4364 	RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
4365 	RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
4366 	RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
4367 	RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
4368 	RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
4369 
4370 	if (target_iface)
4371 		RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
4372 			__func__, ADPT_ARG(target_iface));
4373 	else
4374 		RTW_INFO("%s => target_iface NULL\n", __func__);
4375 
4376 	return target_iface;
4377 }
4378 
4379 void rtw_search_default_port(_adapter *adapter)
4380 {
4381 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4382 	_adapter *adp_iface = NULL;
4383 #ifdef CONFIG_WOWLAN
4384 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
4385 
4386 	if (pwrpriv->wowlan_mode == _TRUE) {
4387 		adp_iface = adapter;
4388 		goto exit;
4389 	}
4390 #endif
4391 	adp_iface = _rtw_search_dp_iface(adapter);
4392 
4393 exit :
4394 	if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
4395 		rtw_set_default_port_id(adp_iface);
4396 	else
4397 		rtw_hal_set_default_port_id_cmd(adapter, 0);
4398 
4399 	if (1) {
4400 		_adapter *tmp_adp;
4401 
4402 		tmp_adp = (adp_iface) ? adp_iface : adapter;
4403 
4404 		RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
4405 			__func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
4406 	}
4407 }
4408 #endif
4409 #endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
4410 
4411 #ifdef CONFIG_P2P_PS
4412 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)4413 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
4414 {
4415 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4416 	struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4417 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
4418 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4419 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
4420 	struct sta_priv		*pstapriv = &adapter->stapriv;
4421 	struct sta_info		*psta;
4422 	HAL_P2P_PS_PARA p2p_ps_para;
4423 	int status = -1;
4424 	u8 i;
4425 	u8 hw_port = rtw_hal_get_port(adapter);
4426 
4427 	_rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
4428 	_rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
4429 
4430 	(&p2p_ps_para)->p2p_port_id = hw_port;
4431 	(&p2p_ps_para)->p2p_group = 0;
4432 	psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4433 	if (psta) {
4434 		(&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
4435 	} else {
4436 		if (p2p_ps_state != P2P_PS_DISABLE) {
4437 			RTW_ERR("%s , psta was NULL\n", __func__);
4438 			return;
4439 		}
4440 	}
4441 
4442 
4443 	switch (p2p_ps_state) {
4444 	case P2P_PS_DISABLE:
4445 		RTW_INFO("P2P_PS_DISABLE\n");
4446 		_rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
4447 		break;
4448 
4449 	case P2P_PS_ENABLE:
4450 		RTW_INFO("P2P_PS_ENABLE\n");
4451 		/* update CTWindow value. */
4452 		if (pwdinfo->ctwindow > 0) {
4453 			(&p2p_ps_para)->ctwindow_en = 1;
4454 			(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4455 			/*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
4456 		}
4457 
4458 
4459 		if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
4460 			(&p2p_ps_para)->offload_en = 1;
4461 			if (pwdinfo->role == P2P_ROLE_GO) {
4462 				(&p2p_ps_para)->role = 1;
4463 				(&p2p_ps_para)->all_sta_sleep = 0;
4464 			} else
4465 				(&p2p_ps_para)->role = 0;
4466 
4467 			(&p2p_ps_para)->discovery = 0;
4468 		}
4469 		/* hw only support 2 set of NoA */
4470 		for (i = 0; i < pwdinfo->noa_num; i++) {
4471 			/* To control the register setting for which NOA */
4472 			(&p2p_ps_para)->noa_sel = i;
4473 			(&p2p_ps_para)->noa_en = 1;
4474 			(&p2p_ps_para)->disable_close_rf = 0;
4475 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
4476 #ifdef CONFIG_CONCURRENT_MODE
4477 			if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))
4478 #endif /* CONFIG_CONCURRENT_MODE */
4479 				(&p2p_ps_para)->disable_close_rf = 1;
4480 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
4481 			/* config P2P NoA Descriptor Register */
4482 			/* config NOA duration */
4483 			(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
4484 			/* config NOA interval */
4485 			(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
4486 			/* config NOA start time */
4487 			(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
4488 			/* config NOA count */
4489 			(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
4490 			/*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
4491 				(&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
4492 				(&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
4493 			status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4494 			if (status == -1)
4495 				RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4496 		}
4497 
4498 		break;
4499 
4500 	case P2P_PS_SCAN:
4501 		/*This feature FW not ready 20161116 YiWei*/
4502 		return;
4503 		/*
4504 		RTW_INFO("P2P_PS_SCAN\n");
4505 		(&p2p_ps_para)->discovery = 1;
4506 		(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4507 		(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4508 		(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4509 		(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4510 		(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4511 		*/
4512 		break;
4513 
4514 	case P2P_PS_SCAN_DONE:
4515 		/*This feature FW not ready 20161116 YiWei*/
4516 		return;
4517 		/*
4518 		RTW_INFO("P2P_PS_SCAN_DONE\n");
4519 		(&p2p_ps_para)->discovery = 0;
4520 		pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
4521 		(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4522 		(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4523 		(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4524 		(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4525 		(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4526 		*/
4527 		break;
4528 
4529 	default:
4530 		break;
4531 	}
4532 
4533 	if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
4534 		status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4535 		if (status == -1)
4536 			RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4537 	}
4538 	_rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
4539 
4540 }
4541 #endif /* RTW_HALMAC */
4542 #endif /* CONFIG_P2P */
4543 
4544 #if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR)
_rtw_hal_dtp_macid_set(_adapter * padapter,u8 opmode,u8 mac_id)4545 static void _rtw_hal_dtp_macid_set(
4546 	_adapter *padapter, u8 opmode, u8 mac_id)
4547 {
4548 	struct macid_ctl_t *macid_ctl = &(padapter->dvobj->macid_ctl);
4549 	struct sta_info *psta;
4550 	u8 h2c_cmd[H2C_FW_CRC5_SEARCH_LEN] = {0};
4551 	u8 mac_addr[ETH_ALEN] = {0};
4552 
4553 	if (opmode) {
4554 		psta = macid_ctl->sta[mac_id];
4555 		if (psta)
4556 			_rtw_memcpy(mac_addr, psta->cmn.mac_addr, ETH_ALEN);
4557 
4558 		if (rtw_check_invalid_mac_address(mac_addr, _FALSE))
4559 			return;
4560 	}
4561 	/* else DON'T CARE H2C_FW_CRC5_SEARCH mac addr in disconnected case */
4562 
4563 	if (rtw_get_chip_type(padapter) == RTL8822C) {
4564 		SET_H2CCMD_FW_CRC5_SEARCH_EN(h2c_cmd, opmode);
4565 		SET_H2CCMD_FW_CRC5_SEARCH_MACID(h2c_cmd, mac_id);
4566 		SET_H2CCMD_FW_CRC5_SEARCH_MAC(&h2c_cmd[1], mac_addr);
4567 		if (rtw_hal_fill_h2c_cmd(padapter, H2C_FW_CRC5_SEARCH,
4568 						H2C_FW_CRC5_SEARCH_LEN, h2c_cmd) != _SUCCESS)
4569 			RTW_WARN("%s : set h2c - 0x%02x fail!\n", __func__, H2C_FW_CRC5_SEARCH);
4570 	}
4571 }
4572 
rtw_hal_dtp_macid_set(_adapter * padapter,u8 opmode,bool macid_ind,u8 mac_id,u8 macid_end)4573 static void rtw_hal_dtp_macid_set(_adapter *padapter, u8 opmode,
4574 	bool macid_ind, u8 mac_id, u8 macid_end)
4575 {
4576 	int i;
4577 
4578 	if (macid_ind == 0) {
4579 		_rtw_hal_dtp_macid_set(padapter, opmode, mac_id);
4580 	} else {
4581 		for (i = mac_id; i <= macid_end; i++)
4582 			_rtw_hal_dtp_macid_set(padapter, opmode, i);
4583 	}
4584 }
4585 #endif
4586 
4587 /*
4588 * rtw_hal_set_FwMediaStatusRpt_cmd -
4589 *
4590 * @adapter:
4591 * @opmode:  0:disconnect, 1:connect
4592 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
4593 * @miracast_sink: 0:source. 1:sink
4594 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
4595 * @macid:
4596 * @macid_ind:  0:update Media Status to macid.  1:update Media Status from macid to macid_end
4597 * @macid_end:
4598 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)4599 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)
4600 {
4601 	struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4602 	u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
4603 	int i;
4604 	s32 ret;
4605 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4606 	u8 hw_port = rtw_hal_get_port(adapter);
4607 #endif
4608 	u8 op_num_change_bmp = 0;
4609 
4610 #if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR)
4611 	rtw_hal_dtp_macid_set(adapter, opmode, macid_ind, macid, macid_end);
4612 #endif
4613 
4614 	SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
4615 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
4616 	SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
4617 	SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
4618 	SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
4619 	SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
4620 	SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
4621 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4622 	SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
4623 #endif
4624 	RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
4625 
4626 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
4627 	if (ret != _SUCCESS)
4628 		goto exit;
4629 
4630 #if defined(CONFIG_RTL8188E)
4631 	if (rtw_get_chip_type(adapter) == RTL8188E) {
4632 		HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4633 
4634 		/* 8188E FW doesn't set macid no link, driver does it by self */
4635 		if (opmode)
4636 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
4637 		else
4638 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
4639 
4640 		/* for 8188E RA */
4641 #if (RATE_ADAPTIVE_SUPPORT == 1)
4642 		if (hal_data->fw_ractrl == _FALSE) {
4643 			u8 max_macid;
4644 
4645 			max_macid = rtw_search_max_mac_id(adapter);
4646 			rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
4647 		}
4648 #endif
4649 	}
4650 #endif
4651 
4652 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
4653 	/* TODO: this should move to IOT issue area */
4654 	if (rtw_get_chip_type(adapter) == RTL8812
4655 		|| rtw_get_chip_type(adapter) == RTL8821
4656 	) {
4657 		if (MLME_IS_STA(adapter))
4658 			Hal_PatchwithJaguar_8812(adapter, opmode);
4659 	}
4660 #endif
4661 
4662 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
4663 	if (macid_ind == 0)
4664 		macid_end = macid;
4665 
4666 	for (i = macid; macid <= macid_end; macid++) {
4667 		op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
4668 		if (!opmode) {
4669 			rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
4670 			rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
4671 			rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
4672 			rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
4673 		}
4674 	}
4675 
4676 #if CONFIG_TX_AC_LIFETIME
4677 	if (op_num_change_bmp)
4678 		rtw_hal_update_tx_aclt(adapter);
4679 #endif
4680 
4681 	if (!opmode)
4682 		rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
4683 
4684 exit:
4685 	return ret;
4686 }
4687 
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)4688 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
4689 {
4690 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
4691 }
4692 
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)4693 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
4694 {
4695 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
4696 }
4697 
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4698 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4699 {
4700 	u8	u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
4701 	u8	ret = 0;
4702 
4703 	RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
4704 		 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
4705 		 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
4706 		 rsvdpageloc->LocBTQosNull);
4707 
4708 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
4709 	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
4710 	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
4711 	SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
4712 	SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
4713 
4714 	ret = rtw_hal_fill_h2c_cmd(padapter,
4715 				   H2C_RSVD_PAGE,
4716 				   H2C_RSVDPAGE_LOC_LEN,
4717 				   u1H2CRsvdPageParm);
4718 
4719 }
4720 
4721 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)4722 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
4723 {
4724 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4725 
4726 	if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)
4727 		|| IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)
4728 		|| IS_8822C_SERIES(pHalData->version_id))
4729 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4730 	/*
4731 	* Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
4732 	* It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
4733 	* and implement HAL function.
4734 	* TODO: GPIO_8 multi function?
4735 	*/
4736 
4737 	if ((index == 13 || index == 14)
4738 		#if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
4739 		/* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
4740 		&& (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
4741 		#endif
4742 	)
4743 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4744 }
4745 
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)4746 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
4747 {
4748 #if defined(CONFIG_RTL8192F)
4749 	rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval));
4750 #else
4751 	if (index <= 7) {
4752 		/* config GPIO mode */
4753 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4754 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4755 
4756 		/* config GPIO Sel */
4757 		/* 0: input */
4758 		/* 1: output */
4759 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4760 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
4761 
4762 		/* set output value */
4763 		if (outputval) {
4764 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4765 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
4766 		} else {
4767 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4768 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
4769 		}
4770 	} else if (index <= 15) {
4771 		/* 88C Series: */
4772 		/* index: 11~8 transform to 3~0 */
4773 		/* 8723 Series: */
4774 		/* index: 12~8 transform to 4~0 */
4775 
4776 		index -= 8;
4777 
4778 		/* config GPIO mode */
4779 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4780 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4781 
4782 		/* config GPIO Sel */
4783 		/* 0: input */
4784 		/* 1: output */
4785 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4786 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
4787 
4788 		/* set output value */
4789 		if (outputval) {
4790 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4791 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
4792 		} else {
4793 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4794 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
4795 		}
4796 	} else {
4797 		RTW_INFO("%s: invalid GPIO%d=%d\n",
4798 			 __FUNCTION__, index, outputval);
4799 	}
4800 #endif
4801 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)4802 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
4803 {
4804 #if defined(CONFIG_RTL8192F)
4805 	rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));
4806 #else
4807 	if (index <= 7) {
4808 		/* config GPIO mode */
4809 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4810 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4811 
4812 		/* config GPIO Sel */
4813 		/* 0: input */
4814 		/* 1: output */
4815 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4816 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
4817 
4818 	} else if (index <= 15) {
4819 		/* 88C Series: */
4820 		/* index: 11~8 transform to 3~0 */
4821 		/* 8723 Series: */
4822 		/* index: 12~8 transform to 4~0 */
4823 
4824 		index -= 8;
4825 
4826 		/* config GPIO mode */
4827 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4828 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4829 
4830 		/* config GPIO Sel */
4831 		/* 0: input */
4832 		/* 1: output */
4833 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4834 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
4835 	} else
4836 		RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
4837 #endif
4838 }
4839 
4840 #endif
4841 
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4842 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4843 {
4844 	struct	pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
4845 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
4846 	u8 ret = 0;
4847 #ifdef CONFIG_WOWLAN
4848 	u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
4849 
4850 	RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
4851 		 __func__, rsvdpageloc->LocRemoteCtrlInfo,
4852 		 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
4853 		 rsvdpageloc->LocNDPInfo);
4854 	RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
4855 		 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
4856 		 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
4857 
4858 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
4859 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
4860 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
4861 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
4862 							rsvdpageloc->LocNbrAdv);
4863 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
4864 						      rsvdpageloc->LocNDPInfo);
4865 #ifdef CONFIG_GTK_OL
4866 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
4867 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
4868 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
4869 #endif /* CONFIG_GTK_OL */
4870 		ret = rtw_hal_fill_h2c_cmd(padapter,
4871 					   H2C_AOAC_RSVD_PAGE,
4872 					   H2C_AOAC_RSVDPAGE_LOC_LEN,
4873 					   u1H2CAoacRsvdPageParm);
4874 
4875 		RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
4876 		_rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
4877 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
4878 					 rsvdpageloc->LocAOACReport);
4879 		ret = rtw_hal_fill_h2c_cmd(padapter,
4880 				   H2C_AOAC_RSVDPAGE3,
4881 				   H2C_AOAC_RSVDPAGE_LOC_LEN,
4882 				   u1H2CAoacRsvdPageParm);
4883 		pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
4884 	}
4885 #ifdef CONFIG_PNO_SUPPORT
4886 	else {
4887 
4888 		if (!pwrpriv->wowlan_in_resume) {
4889 			RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
4890 			_rtw_memset(&u1H2CAoacRsvdPageParm, 0,
4891 				    sizeof(u1H2CAoacRsvdPageParm));
4892 			SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
4893 						      rsvdpageloc->LocPNOInfo);
4894 			ret = rtw_hal_fill_h2c_cmd(padapter,
4895 						   H2C_AOAC_RSVDPAGE3,
4896 						   H2C_AOAC_RSVDPAGE_LOC_LEN,
4897 						   u1H2CAoacRsvdPageParm);
4898 		}
4899 	}
4900 #endif /* CONFIG_PNO_SUPPORT */
4901 #endif /* CONFIG_WOWLAN */
4902 }
4903 
4904 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4905 void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4906 {
4907 	struct	hal_ops *pHalFunc = &padapter->hal_func;
4908 	u8	u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
4909 	u8	ret = 0;
4910 
4911 
4912 	RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
4913 
4914 	SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
4915 	SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
4916 	ret = rtw_hal_fill_h2c_cmd(padapter,
4917 				   H2C_FW_DBG_MSG_PKT,
4918 				   H2C_FW_DBG_MSG_PKT_LEN,
4919 				   u1H2C_fw_dbg_msg_pkt_parm);
4920 
4921 }
4922 #endif /*DBG_FW_DEBUG_MSG_PKT*/
4923 
4924 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)4925 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
4926 	u32 page_num, u8 *buffer, u32 buffer_size)
4927 {
4928 	u32 addr = 0, size = 0, count = 0;
4929 	u32 page_size = 0, data_low = 0, data_high = 0;
4930 	u16 txbndy = 0, offset = 0;
4931 	u8 i = 0;
4932 	bool rst = _FALSE;
4933 
4934 #ifdef DBG_LA_MODE
4935 	struct registry_priv *registry_par = &adapter->registrypriv;
4936 
4937 	if(registry_par->la_mode_en == 1) {
4938 		RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
4939 		return rst;
4940 	}
4941 #endif
4942 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
4943 
4944 	addr = page_offset * page_size;
4945 	size = page_num * page_size;
4946 
4947 	if (buffer_size < size) {
4948 		RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
4949 			__func__, buffer_size, size);
4950 		return rst;
4951 	}
4952 #ifdef RTW_HALMAC
4953 	if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
4954 		rst = _FALSE;
4955 	else
4956 		rst = _TRUE;
4957 #else
4958 	txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
4959 
4960 	offset = (txbndy + page_offset) * page_size / 8;
4961 	count = (buffer_size / 8) + 1;
4962 
4963 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
4964 
4965 	for (i = 0 ; i < count ; i++) {
4966 		rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
4967 		data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
4968 		data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
4969 		_rtw_memcpy(buffer + (i * 8),
4970 			&data_low, sizeof(data_low));
4971 		_rtw_memcpy(buffer + ((i * 8) + 4),
4972 			&data_high, sizeof(data_high));
4973 	}
4974 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
4975 	rst = _TRUE;
4976 #endif /*RTW_HALMAC*/
4977 
4978 #ifdef DBG_GET_RSVD_PAGE
4979 	RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
4980 		 __func__, page_offset, page_num, addr, size);
4981 	RTW_INFO_DUMP("\n", buffer, size);
4982 	RTW_INFO(" ==================================================\n");
4983 #endif
4984 	return rst;
4985 }
4986 
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)4987 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
4988 {
4989 #if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG)
4990 	u32 page_size = 0;
4991 	u8 *buffer = NULL;
4992 	u32 buf_size = 0;
4993 
4994 	if (page_num == 0)
4995 		return;
4996 
4997 	RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
4998 	RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
4999 
5000 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5001 	if (page_size) {
5002 		buf_size = page_size * page_num;
5003 		buffer = rtw_zvmalloc(buf_size);
5004 
5005 		if (buffer) {
5006 			rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
5007 			RTW_DUMP_SEL(sel, buffer, buf_size);
5008 			rtw_vmfree(buffer, buf_size);
5009 		} else
5010 			RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
5011 	} else
5012 			RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
5013 
5014 	RTW_PRINT_SEL(sel, "==========================\n");
5015 #endif
5016 }
5017 
5018 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)5019 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
5020 {
5021 	u8 *buffer = NULL;
5022 	u32 buff_size = 0;
5023 	static const char * const fifo_sel_str[] = {
5024 		"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
5025 	};
5026 
5027 	if (fifo_sel > 5) {
5028 		RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
5029 		return;
5030 	}
5031 
5032 	RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
5033 	RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
5034 
5035 	if (fifo_size) {
5036 		buff_size = RND4(fifo_size);
5037 		buffer = rtw_zvmalloc(buff_size);
5038 		if (buffer == NULL)
5039 			buff_size = 0;
5040 	}
5041 
5042 	rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
5043 
5044 	if (buffer) {
5045 		RTW_DUMP_SEL(sel, buffer, fifo_size);
5046 		rtw_vmfree(buffer, buff_size);
5047 	}
5048 
5049 	RTW_PRINT_SEL(sel, "==========================\n");
5050 }
5051 #endif
5052 
5053 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)5054 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
5055 {
5056 	RTW_INFO("%s: Set 0x690=0x00\n", __func__);
5057 	rtw_write8(adapter, REG_WOW_CTRL,
5058 		   (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
5059 	RTW_PRINT("%s: Release RXDMA\n", __func__);
5060 	rtw_write32(adapter, REG_RXPKT_NUM,
5061 		    (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
5062 }
5063 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)5064 static void rtw_hal_disable_tx_report(_adapter *adapter)
5065 {
5066 	rtw_write8(adapter, REG_TX_RPT_CTRL,
5067 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
5068 	RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5069 }
5070 
rtw_hal_enable_tx_report(_adapter * adapter)5071 static void rtw_hal_enable_tx_report(_adapter *adapter)
5072 {
5073 	rtw_write8(adapter, REG_TX_RPT_CTRL,
5074 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
5075 	RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5076 }
5077 #endif
rtw_hal_release_rx_dma(_adapter * adapter)5078 static void rtw_hal_release_rx_dma(_adapter *adapter)
5079 {
5080 	u32 val32 = 0;
5081 
5082 	val32 = rtw_read32(adapter, REG_RXPKT_NUM);
5083 
5084 	rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
5085 
5086 	RTW_INFO("%s, [0x%04x]: 0x%08x\n",
5087 		 __func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));
5088 }
5089 
rtw_hal_pause_rx_dma(_adapter * adapter)5090 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
5091 {
5092 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
5093 	u8 ret = 0;
5094 	s8 trycnt = 100;
5095 	u32 tmp = 0;
5096 	int res = 0;
5097 	/* RX DMA stop */
5098 	RTW_PRINT("Pause DMA\n");
5099 	rtw_write32(adapter, REG_RXPKT_NUM,
5100 		    (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
5101 	do {
5102 		if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
5103 #ifdef CONFIG_USB_HCI
5104 			/* stop interface before leave */
5105 			if (_TRUE == hal->usb_intf_start) {
5106 				rtw_intf_stop(adapter);
5107 				RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
5108 				RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
5109 			}
5110 #endif /* CONFIG_USB_HCI */
5111 
5112 			RTW_PRINT("RX_DMA_IDLE is true\n");
5113 			ret = _SUCCESS;
5114 			break;
5115 		}
5116 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5117 		else {
5118 			res = RecvOnePkt(adapter);
5119 			RTW_PRINT("RecvOnePkt Result: %d\n", res);
5120 		}
5121 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
5122 
5123 #ifdef CONFIG_USB_HCI
5124 		else {
5125 			/* to avoid interface start repeatedly  */
5126 			if (_FALSE == hal->usb_intf_start)
5127 				rtw_intf_start(adapter);
5128 		}
5129 #endif /* CONFIG_USB_HCI */
5130 	} while (trycnt--);
5131 
5132 	if (trycnt < 0) {
5133 		tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
5134 
5135 		RTW_PRINT("Stop RX DMA failed......\n");
5136 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
5137 		RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
5138 			  __func__, rtw_read16(adapter, REG_RXPKTNUM));
5139 #else
5140 		RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
5141 			  __func__, ((tmp & 0xFF00) >> 8));
5142 #endif
5143 		if (tmp & BIT(3))
5144 			RTW_PRINT("%s, RX DMA has req\n",
5145 				  __func__);
5146 		else
5147 			RTW_PRINT("%s, RX DMA no req\n",
5148 				  __func__);
5149 		ret = _FAIL;
5150 	}
5151 
5152 	return ret;
5153 }
5154 
5155 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5156 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)5157 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
5158 {
5159 	u8 ret = 0;
5160 	int res = 0;
5161 	u32 tmp = 0;
5162 #ifdef CONFIG_GPIO_WAKEUP
5163 	return _SUCCESS;
5164 #else
5165 	RTW_PRINT("%s\n", __func__);
5166 
5167 	res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5168 	if (!res)
5169 		RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
5170 	else
5171 		RTW_INFO("sdio_local_read fail\n");
5172 
5173 	tmp = SDIO_HIMR_CPWM2_MSK;
5174 
5175 	res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5176 
5177 	if (!res) {
5178 		res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5179 		RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
5180 		ret = _SUCCESS;
5181 	} else {
5182 		RTW_INFO("sdio_local_write fail\n");
5183 		ret = _FAIL;
5184 	}
5185 	return ret;
5186 #endif /* CONFIG_CPIO_WAKEUP */
5187 }
5188 #endif
5189 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
5190 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
5191 
5192 #ifdef CONFIG_WOWLAN
5193 /*
5194  * rtw_hal_check_wow_ctrl
5195  * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
5196  *									If 0x1C7 == 0 (for 3081), WOW enable successful.
5197  *		     _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
5198  *									If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
5199  */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)5200 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
5201 {
5202 	u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
5203 	u8 mstatus = 0;
5204 	u8 reason = 0xFF;
5205 	u8 trycnt = 25;
5206 	u8 res = _FALSE;
5207 
5208 	if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
5209 		if (chk_type) {
5210 			reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5211 			RTW_INFO("%s reason:0x%02x\n", __func__, reason);
5212 
5213 			while (reason && trycnt > 1) {
5214 				reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5215 				RTW_PRINT("Loop index: %d :0x%02x\n",
5216 					  trycnt, reason);
5217 				trycnt--;
5218 				rtw_msleep_os(20);
5219 			}
5220 			if (!reason)
5221 				res = _TRUE;
5222 			else
5223 				res = _FALSE;
5224 		} else {
5225 			/* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
5226 			fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
5227 			rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
5228 			RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
5229 
5230 			while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
5231 				rtw_msleep_os(20);
5232 				fe1_imr = rtw_read32(adapter, REG_FE1IMR);
5233 				rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
5234 				RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
5235 					  trycnt, fe1_imr, rxpkt_num);
5236 				trycnt--;
5237 			}
5238 
5239 			if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
5240 				res = _FALSE;
5241 			else
5242 				res = _TRUE;
5243 		}
5244 	} else {
5245 		mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5246 		RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
5247 
5248 
5249 		if (chk_type) {
5250 			while (!(mstatus & BIT1) && trycnt > 1) {
5251 				mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5252 				RTW_PRINT("Loop index: %d :0x%02x\n",
5253 					  trycnt, mstatus);
5254 				trycnt--;
5255 				rtw_msleep_os(20);
5256 			}
5257 			if (mstatus & BIT1)
5258 				res = _TRUE;
5259 			else
5260 				res = _FALSE;
5261 		} else {
5262 			while (mstatus & BIT1 && trycnt > 1) {
5263 				mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5264 				RTW_PRINT("Loop index: %d :0x%02x\n",
5265 					  trycnt, mstatus);
5266 				trycnt--;
5267 				rtw_msleep_os(20);
5268 			}
5269 
5270 			if (mstatus & BIT1)
5271 				res = _FALSE;
5272 			else
5273 				res = _TRUE;
5274 		}
5275 	}
5276 
5277 	RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
5278 		  __func__, chk_type, res, (25 - trycnt));
5279 	return res;
5280 }
5281 
5282 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)5283 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
5284 {
5285 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5286 	u8 res = 0, count = 0;
5287 	u8 ret = _FALSE;
5288 
5289 	if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
5290 		res = rtw_read8(adapter, REG_PNO_STATUS);
5291 		while (!(res & BIT(7)) && count < 25) {
5292 			RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
5293 				 count, res);
5294 			res = rtw_read8(adapter, REG_PNO_STATUS);
5295 			count++;
5296 			rtw_msleep_os(2);
5297 		}
5298 		if (res & BIT(7))
5299 			ret = _TRUE;
5300 		else
5301 			ret = _FALSE;
5302 		RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
5303 	}
5304 	return ret;
5305 }
5306 #endif
5307 
rtw_hal_backup_rate(_adapter * adapter)5308 static void rtw_hal_backup_rate(_adapter *adapter)
5309 {
5310 	RTW_INFO("%s\n", __func__);
5311 	/* backup data rate to register 0x8b for wowlan FW */
5312 	rtw_write8(adapter, 0x8d, 1);
5313 	rtw_write8(adapter, 0x8c, 0);
5314 	rtw_write8(adapter, 0x8f, 0x40);
5315 	rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
5316 }
5317 
5318 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)5319 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
5320 {
5321 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5322 	int cam_id, index = 0;
5323 	u8 *addr = NULL;
5324 
5325 	if (!MLME_IS_STA(adapter))
5326 		return;
5327 
5328 	addr = get_bssid(pmlmepriv);
5329 
5330 	if (addr == NULL) {
5331 		RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
5332 		return;
5333 	}
5334 
5335 	rtw_clean_dk_section(adapter);
5336 
5337 	do {
5338 		cam_id = rtw_camid_search(adapter, addr, index, 1);
5339 
5340 		if (cam_id == -1)
5341 			RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
5342 		else
5343 			rtw_sec_cam_swap(adapter, cam_id, index);
5344 
5345 		index++;
5346 	} while (index < 4);
5347 
5348 	rtw_write8(adapter, REG_SECCFG, 0xcc);
5349 }
5350 
rtw_hal_update_gtk_offload_info(_adapter * adapter)5351 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
5352 {
5353 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5354 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5355 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5356 	struct security_priv *psecuritypriv = &adapter->securitypriv;
5357 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5358 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
5359 	_irqL irqL;
5360 	u8 get_key[16];
5361 	u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
5362 	u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
5363 
5364 	if (!MLME_IS_STA(adapter))
5365 		return;
5366 
5367 	_rtw_memset(get_key, 0, sizeof(get_key));
5368 	_rtw_memcpy(&replay_count,
5369 		paoac_rpt->replay_counter_eapol_key, 8);
5370 
5371 	/*read gtk key index*/
5372 	gtk_id = paoac_rpt->key_index;
5373 	aoac_rpt_ver = paoac_rpt->version_info;
5374 
5375 	if (aoac_rpt_ver == 0) {
5376 		/* initial verison */
5377 		if (gtk_id == 5)
5378 			has_rekey = _FALSE;
5379 		else
5380 			has_rekey = _TRUE;
5381 	} else if (aoac_rpt_ver >= 1) {
5382 		/* Add krack patch */
5383 		if (gtk_id == 5)
5384 			RTW_WARN("%s FW check iv fail\n", __func__);
5385 
5386 		if (aoac_rpt_ver == 1)
5387 			RTW_WARN("%s aoac report version should be update to v2\n", __func__);
5388 
5389 		/* Fix key id mismatch */
5390 		if (aoac_rpt_ver == 2)
5391 			has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
5392 	}
5393 
5394 	if (has_rekey == _FALSE) {
5395 		RTW_INFO("%s no rekey event happened.\n", __func__);
5396 	} else if (has_rekey == _TRUE) {
5397 		RTW_INFO("%s update security key.\n", __func__);
5398 		/*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
5399 		rtw_sec_read_cam_ent(adapter, gtk_id,
5400 				     NULL, NULL, get_key);
5401 		rtw_clean_hw_dk_cam(adapter);
5402 
5403 		if (_rtw_camid_is_gk(adapter, gtk_id)) {
5404 			_enter_critical_bh(&cam_ctl->lock, &irqL);
5405 			_rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
5406 				    get_key, 16);
5407 			_exit_critical_bh(&cam_ctl->lock, &irqL);
5408 		} else {
5409 			struct setkey_parm parm_gtk;
5410 
5411 			parm_gtk.algorithm = paoac_rpt->security_type;
5412 			parm_gtk.keyid = gtk_id;
5413 			_rtw_memcpy(parm_gtk.key, get_key, 16);
5414 			setkey_hdl(adapter, (u8 *)&parm_gtk);
5415 		}
5416 
5417 		/*update key into related sw variable and sec-cam cache*/
5418 		psecuritypriv->dot118021XGrpKeyid = gtk_id;
5419 		_rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
5420 				get_key, 16);
5421 		/* update SW TKIP TX/RX MIC value */
5422 		if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
5423 			offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
5424 			_rtw_memcpy(
5425 				&psecuritypriv->dot118021XGrptxmickey[gtk_id],
5426 				&(paoac_rpt->group_key[offset]),
5427 				RTW_TKIP_MIC_LEN);
5428 
5429 			offset = RTW_KEK_LEN;
5430 			_rtw_memcpy(
5431 				&psecuritypriv->dot118021XGrprxmickey[gtk_id],
5432 				&(paoac_rpt->group_key[offset]),
5433 				RTW_TKIP_MIC_LEN);
5434 		}
5435 		RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
5436 			KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
5437 	}
5438 
5439 	/* Update broadcast RX IV */
5440 	if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
5441 		sz = sizeof(psecuritypriv->iv_seq[0]);
5442 		for (i = 0 ; i < 4 ; i++) {
5443 			_rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
5444 			tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
5445 			pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
5446 			_rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
5447 		}
5448 	}
5449 
5450 	rtw_clean_dk_section(adapter);
5451 
5452 	rtw_write8(adapter, REG_SECCFG, 0x0c);
5453 
5454 	#ifdef CONFIG_GTK_OL_DBG
5455 	/* if (gtk_keyindex != 5) */
5456 	dump_sec_cam(RTW_DBGDUMP, adapter);
5457 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
5458 	#endif
5459 }
5460 #endif /*CONFIG_GTK_OL*/
5461 
rtw_dump_aoac_rpt(_adapter * adapter)5462 static void rtw_dump_aoac_rpt(_adapter *adapter)
5463 {
5464 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5465 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5466 	int i = 0;
5467 
5468 	RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
5469 	RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
5470 		paoac_rpt->replay_counter_eapol_key, 8);
5471 	RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
5472 	RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
5473 	RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
5474 	RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
5475 		 paoac_rpt->wow_pattern_idx);
5476 	RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
5477 	RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
5478 	RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
5479 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
5480 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
5481 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
5482 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
5483 }
5484 
rtw_hal_get_aoac_rpt(_adapter * adapter)5485 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
5486 {
5487 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5488 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5489 	u32 page_offset = 0, page_number = 0;
5490 	u32 page_size = 0, buf_size = 0;
5491 	u8 *buffer = NULL;
5492 	u8 i = 0, tmp = 0;
5493 	int ret = -1;
5494 
5495 	/* read aoac report from rsvd page */
5496 	page_offset = pwrctl->wowlan_aoac_rpt_loc;
5497 	page_number = 1;
5498 
5499 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5500 	buf_size = page_size * page_number;
5501 
5502 	buffer = rtw_zvmalloc(buf_size);
5503 
5504 	if (buffer == NULL) {
5505 		RTW_ERR("%s buffer allocate failed size(%d)\n",
5506 			__func__, buf_size);
5507 		return;
5508 	}
5509 
5510 	RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
5511 
5512 	ret = rtw_hal_get_rsvd_page(adapter, page_offset,
5513 		page_number, buffer, buf_size);
5514 
5515 	if (ret == _FALSE) {
5516 		RTW_ERR("%s get aoac report failed\n", __func__);
5517 		rtw_warn_on(1);
5518 		goto _exit;
5519 	}
5520 
5521 	_rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
5522 	_rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
5523 
5524 	for (i = 0 ; i < 4 ; i++) {
5525 		tmp = paoac_rpt->replay_counter_eapol_key[i];
5526 		paoac_rpt->replay_counter_eapol_key[i] =
5527 			paoac_rpt->replay_counter_eapol_key[7 - i];
5528 		paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
5529 	}
5530 
5531 	rtw_dump_aoac_rpt(adapter);
5532 
5533 _exit:
5534 	if (buffer)
5535 		rtw_vmfree(buffer, buf_size);
5536 }
5537 
rtw_hal_update_tx_iv(_adapter * adapter)5538 static void rtw_hal_update_tx_iv(_adapter *adapter)
5539 {
5540 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5541 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5542 	struct sta_info	*psta;
5543 	struct mlme_ext_priv	*pmlmeext = &(adapter->mlmeextpriv);
5544 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5545 	struct security_priv	*psecpriv = &adapter->securitypriv;
5546 
5547 	u16 val16 = 0;
5548 	u32 val32 = 0;
5549 	u64 txiv = 0;
5550 	u8 *pval = NULL;
5551 
5552 	psta = rtw_get_stainfo(&adapter->stapriv,
5553 			       get_my_bssid(&pmlmeinfo->network));
5554 
5555 	/* Update TX iv data. */
5556 	pval = (u8 *)&paoac_rpt->iv;
5557 
5558 	if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
5559 		val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
5560 			((u16)(paoac_rpt->iv[0]) << 8);
5561 		val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5562 			((u32)(paoac_rpt->iv[5]) << 8) +
5563 			((u32)(paoac_rpt->iv[6]) << 16) +
5564 			((u32)(paoac_rpt->iv[7]) << 24);
5565 	} else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
5566 		val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
5567 			((u16)(paoac_rpt->iv[1]) << 8);
5568 		val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5569 			((u32)(paoac_rpt->iv[5]) << 8) +
5570 			((u32)(paoac_rpt->iv[6]) << 16) +
5571 			((u32)(paoac_rpt->iv[7]) << 24);
5572 	}
5573 
5574 	if (psta) {
5575 		txiv = val16 + ((u64)val32 << 16);
5576 		if (txiv != 0)
5577 			psta->dot11txpn.val = txiv;
5578 	}
5579 }
5580 
rtw_hal_update_sw_security_info(_adapter * adapter)5581 static void rtw_hal_update_sw_security_info(_adapter *adapter)
5582 {
5583 	struct security_priv *psecpriv = &adapter->securitypriv;
5584 	u8 sz = sizeof (psecpriv->iv_seq);
5585 
5586 	rtw_hal_update_tx_iv(adapter);
5587 #ifdef CONFIG_GTK_OL
5588 	if (psecpriv->binstallKCK_KEK == _TRUE &&
5589 		(psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5590 		rtw_hal_update_gtk_offload_info(adapter);
5591 #else
5592 	_rtw_memset(psecpriv->iv_seq, 0, sz);
5593 #endif
5594 }
5595 #ifdef CONFIG_CUSTOM_PULSE
rtw_hal_set_gpio_custom_cmd(_adapter * adapter,u8 enable)5596 static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable)
5597 {
5598 	u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0};
5599 	u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1;
5600 	u8 ret = _FAIL;
5601 
5602 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5603 
5604 	if(enable) {
5605 		SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid);
5606 		SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason);
5607 		SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason);
5608 
5609 		ret = rtw_hal_fill_h2c_cmd(adapter,
5610 						H2C_GPIO_CUSTOM,
5611 						H2C_GPIO_CUSTOM_LEN,
5612 						H2CGpioCustomParm);
5613 		RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM,
5614 		H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]);
5615 	}
5616 
5617 	return ret;
5618 }
5619 #endif /* CONFIG_CUSTOM_PULSE */
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)5620 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
5621 {
5622 	u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
5623 	u8 adopt = 1, check_period = 5;
5624 	u8 ret = _FAIL;
5625 	u8 hw_port = rtw_hal_get_port(adapter);
5626 
5627 	SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
5628 	SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
5629 	SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
5630 	SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
5631 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5632 	SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
5633 	RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5634 #else
5635 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5636 #endif
5637 	ret = rtw_hal_fill_h2c_cmd(adapter,
5638 				   H2C_KEEP_ALIVE,
5639 				   H2C_KEEP_ALIVE_CTRL_LEN,
5640 				   u1H2CKeepAliveParm);
5641 
5642 	return ret;
5643 }
5644 
5645 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter,u8 enable)5646 static u8 rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter, u8 enable)
5647 {
5648 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5649 	u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_PATTERN_LEN] = {0};
5650 	u8 ret = _FAIL;
5651 	int i;
5652 
5653 	/* If keep alive pattern is set, FW will use pattern for keep alive action */
5654 	if(enable == 0 || (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_disable)) {
5655 		SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _FALSE);
5656 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE);
5657 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5658 		return ret;
5659 	}
5660 	/*step1:set keep alive period*/
5661 	SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_LOW_BIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_period & 0x00FF);
5662 	SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_HI_BIT(u1H2CKeepAliveParm, ((pwrctl->wowlan_keep_alive_period & 0xFF00)>> 8));
5663 
5664 	if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_tx) {
5665 		SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5666 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE);
5667 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5668 		SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5669 		goto exit;
5670 	}
5671 	if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx) {
5672 		SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5673 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE);
5674 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5675 		SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5676 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index);
5677 		SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval);
5678 		SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter);
5679 		goto exit;
5680 	}
5681 	if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx_with_ack) {
5682 		SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5683 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE);
5684 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _TRUE);
5685 		SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5686 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index);
5687 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_wake_pattern_index);
5688 		SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval);
5689 		SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter);
5690 		goto exit;
5691 	}
5692 exit:
5693 	for(i=0; i<H2C_KEEP_ALIVE_PATTERN_LEN; i++) {
5694 		RTW_INFO("u1H2CKeepAliveParm[%d]= x%0x\n", i, u1H2CKeepAliveParm[i]);
5695 	}
5696 	ret = rtw_hal_fill_h2c_cmd(adapter,
5697 				   H2C_UDP_KEEPALIVE,
5698 				   H2C_KEEP_ALIVE_PATTERN_LEN,
5699 				   u1H2CKeepAliveParm);
5700 
5701 	return ret;
5702 }
5703 #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
5704 
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)5705 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
5706 {
5707 	u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
5708 	u8 adopt = 1, check_period = 100, trypkt_num = 5;
5709 	u8 ret = _FAIL;
5710 	struct registry_priv *pregistry = &adapter->registrypriv;
5711 	u8 hw_port = rtw_hal_get_port(adapter);
5712 
5713 	SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
5714 	SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
5715 	if (!(pregistry->wakeup_event & BIT(2)))
5716 		SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt);
5717 	SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
5718 	SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
5719 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5720 	SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
5721 	RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5722 #else
5723 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5724 #endif
5725 
5726 	ret = rtw_hal_fill_h2c_cmd(adapter,
5727 				   H2C_DISCON_DECISION,
5728 				   H2C_DISCON_DECISION_LEN,
5729 				   u1H2CDisconDecisionParm);
5730 	return ret;
5731 }
5732 
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)5733 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
5734 {
5735 	struct registry_priv  *registry_par = &adapter->registrypriv;
5736 	struct security_priv *psecpriv = &adapter->securitypriv;
5737 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5738 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
5739 
5740 	u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
5741 	u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;
5742 	u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
5743 	u8 sdio_wakeup_enable = 1;
5744 	u8 gpio_high_active = 0;
5745 	u8 magic_pkt = 0;
5746 	u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
5747 	u8 ret = _FAIL;
5748 #ifdef CONFIG_DIS_UPHY
5749 	u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
5750 #endif /* CONFIG_DIS_UPHY */
5751 
5752 #ifdef CONFIG_GPIO_WAKEUP
5753 	gpio_high_active = ppwrpriv->is_high_active;
5754 	gpionum = ppwrpriv->wowlan_gpio_index;
5755 	sdio_wakeup_enable = 0;
5756 #endif /* CONFIG_GPIO_WAKEUP */
5757 
5758 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
5759 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5760 		no_wake = 1;
5761 
5762 	if (!ppwrpriv->wowlan_pno_enable &&
5763 		registry_par->wakeup_event & BIT(0) && !no_wake)
5764 		magic_pkt = enable;
5765 
5766 	if ((registry_par->wakeup_event & BIT(1)) &&
5767 		(psecpriv->dot11PrivacyAlgrthm == _WEP40_ ||
5768 		psecpriv->dot11PrivacyAlgrthm == _WEP104_) && !no_wake)
5769 			hw_unicast = 1;
5770 
5771 	if (registry_par->wakeup_event & BIT(2) && !no_wake)
5772 		discont_wake = enable;
5773 
5774 	RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5775 		 enable, change_unit);
5776 
5777 	/* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5778 	if (enable && change_unit) {
5779 		gpio_dur = 0x40;
5780 		gpio_unit = 1;
5781 		gpio_pulse_en = 1;
5782 	}
5783 
5784 #ifdef CONFIG_PLATFORM_ARM_RK3188
5785 	if (enable) {
5786 		gpio_pulse_en = 1;
5787 		gpio_pulse_cnt = 0x04;
5788 	}
5789 #endif
5790 
5791 	SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5792 	if(!no_wake)
5793 		SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5794 	SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5795 	SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5796 	SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5797 	SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5798 
5799 #ifdef CONFIG_GTK_OL
5800 	if (psecpriv->binstallKCK_KEK == _TRUE &&
5801 		(psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5802 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5803 	else
5804 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5805 #else
5806 	SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5807 #endif
5808 	SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5809 	SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5810 	SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5811 
5812 	SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5813 	SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5814 
5815 	SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5816 	SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5817 
5818 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5819 	if (enable)
5820 		SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5821 #endif
5822 
5823 #ifdef CONFIG_DIS_UPHY
5824 	if (enable) {
5825 		dis_uphy = 1;
5826 		/* time unit: 0 -> ms, 1 -> 256 ms*/
5827 		dis_uphy_unit = 1;
5828 		dis_uphy_time = 0x4;
5829 	}
5830 
5831 	SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5832 	SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5833 	SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5834 	if (ppwrpriv->hst2dev_high_active == 1)
5835 		SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5836 #ifdef CONFIG_RTW_ONE_PIN_GPIO
5837 	SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5838 	SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5839 	SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5840 #else
5841 	SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5842 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
5843 #endif /* CONFIG_DIS_UPHY */
5844 
5845 
5846 	ret = rtw_hal_fill_h2c_cmd(adapter,
5847 				   H2C_WOWLAN,
5848 				   H2C_WOWLAN_LEN,
5849 				   u1H2CWoWlanCtrlParm);
5850 	return ret;
5851 }
5852 
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)5853 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5854 {
5855 	struct security_priv *psecuritypriv = &(adapter->securitypriv);
5856 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5857 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
5858 	u8 arp_en = pregistrypriv->wakeup_event & BIT(3);
5859 	u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5860 	u8 ret = _FAIL, count = 0, no_wake = 0;
5861 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
5862 
5863 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
5864 
5865 	if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5866 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5867 		no_wake = 1;
5868 	if(no_wake) {
5869 		SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5870 			u1H2CRemoteWakeCtrlParm, enable);
5871 	} else {
5872 		if (!ppwrpriv->wowlan_pno_enable) {
5873 			SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5874 				u1H2CRemoteWakeCtrlParm, enable);
5875 			if (arp_en)
5876 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5877 					u1H2CRemoteWakeCtrlParm, 1);
5878 			else
5879 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5880 					u1H2CRemoteWakeCtrlParm, 0);
5881 	#ifdef CONFIG_GTK_OL
5882 			if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5883 				(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) {
5884 				SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5885 					u1H2CRemoteWakeCtrlParm, 1);
5886 			} else {
5887 				RTW_INFO("no kck kek\n");
5888 				SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5889 					u1H2CRemoteWakeCtrlParm, 0);
5890 			}
5891 	#endif /* CONFIG_GTK_OL */
5892 
5893 	#ifdef CONFIG_IPV6
5894 			if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5895 				RTW_INFO("enable NS offload\n");
5896 				SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5897 					u1H2CRemoteWakeCtrlParm, enable);
5898 			}
5899 
5900 			/*
5901 			 * filter NetBios name service pkt to avoid being waked-up
5902 			 * by this kind of unicast pkt this exceptional modification
5903 			 * is used for match competitor's behavior
5904 			 */
5905 
5906 			SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5907 				u1H2CRemoteWakeCtrlParm, enable);
5908 	#endif /*CONFIG_IPV6*/
5909 #if 0 /* replaced by WOWLAN pattern match */
5910 	#ifdef CONFIG_RTL8192F
5911 			if (IS_HARDWARE_TYPE_8192F(adapter)){
5912 				SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
5913 					u1H2CRemoteWakeCtrlParm, enable);
5914 			}
5915 	#endif /* CONFIG_RTL8192F */
5916 #endif
5917 			if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
5918 				(psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
5919 				(psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
5920 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5921 					u1H2CRemoteWakeCtrlParm, 0);
5922 			} else { /* WEP etc. */
5923 				if (arp_en)
5924 					SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5925 						u1H2CRemoteWakeCtrlParm, 1);
5926 			}
5927 
5928 			if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
5929 #ifdef CONFIG_GTK_OL
5930 				if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))
5931 					SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5932 						u1H2CRemoteWakeCtrlParm, enable);
5933 #endif /* CONFIG_GTK_OL */
5934 				if (IS_HARDWARE_TYPE_8188E(adapter) ||
5935 				    IS_HARDWARE_TYPE_8812(adapter)) {
5936 					SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5937 						u1H2CRemoteWakeCtrlParm, 0);
5938 					if (arp_en)
5939 						SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5940 							u1H2CRemoteWakeCtrlParm, 1);
5941 				}
5942 			}
5943 
5944 			SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
5945 				u1H2CRemoteWakeCtrlParm, 1);
5946 		}
5947 	#ifdef CONFIG_PNO_SUPPORT
5948 		else {
5949 			SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5950 				u1H2CRemoteWakeCtrlParm, enable);
5951 			SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
5952 				u1H2CRemoteWakeCtrlParm, enable);
5953 		}
5954 	#endif
5955 
5956 	#ifdef CONFIG_P2P_WOWLAN
5957 		if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
5958 			RTW_INFO("P2P OFFLOAD ENABLE\n");
5959 			SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
5960 		} else {
5961 			RTW_INFO("P2P OFFLOAD DISABLE\n");
5962 			SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
5963 		}
5964 	#endif /* CONFIG_P2P_WOWLAN */
5965 	}
5966 
5967 
5968 	ret = rtw_hal_fill_h2c_cmd(adapter,
5969 				   H2C_REMOTE_WAKE_CTRL,
5970 				   H2C_REMOTE_WAKE_CTRL_LEN,
5971 				   u1H2CRemoteWakeCtrlParm);
5972 	return ret;
5973 }
5974 
5975 #ifdef CONFIG_WAR_OFFLOAD
rtw_hal_set_war_offload_ctrl_cmd(_adapter * adapter,u8 enable)5976 static u8 rtw_hal_set_war_offload_ctrl_cmd(_adapter *adapter, u8 enable)
5977 {
5978 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5979 	u8 u1H2CWarOffloadParm[H2C_WAR_OFFLOAD_LEN] = {0};
5980 	u8 ret = _FAIL;
5981 
5982 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
5983 
5984 	if (_TRUE == ppwrpriv->wowlan_war_offload_mode) {
5985 		SET_H2CCMD_WAR_CFG_EN(u1H2CWarOffloadParm, enable);
5986 		SET_H2CCMD_WAR_CFG_ARP_RSP_EN(u1H2CWarOffloadParm, 1);
5987 
5988 #ifdef CONFIG_OFFLOAD_MDNS_V4
5989 		if (WAR_MDNS_V4_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
5990 			SET_H2CCMD_WAR_CFG_MDNSV4_RSP_EN(u1H2CWarOffloadParm, 1);
5991 		}
5992 		if (WAR_MDNS_V4_WAKEUP_EN& ppwrpriv->wowlan_war_offload_ctrl) {
5993 			SET_H2CCMD_WAR_CFG_MDNSV4_WAKE_EN(u1H2CWarOffloadParm, 1);
5994 		}
5995 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
5996 
5997 #ifdef CONFIG_OFFLOAD_MDNS_V6
5998 		if (WAR_MDNS_V6_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
5999 			SET_H2CCMD_WAR_CFG_MDNSV6_RSP_EN(u1H2CWarOffloadParm, 1);
6000 		}
6001 		if (WAR_MDNS_V6_WAKEUP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
6002 			SET_H2CCMD_WAR_CFG_MDNSV6_WAKE_EN(u1H2CWarOffloadParm, 1);
6003 		}
6004 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
6005 
6006 	}
6007 
6008 	ret = rtw_hal_fill_h2c_cmd(adapter,
6009 					H2C_WAR_OFFLOAD,
6010 					H2C_WAR_OFFLOAD_LEN,
6011 					u1H2CWarOffloadParm);
6012 	return ret;
6013 }
6014 
rtw_hal_set_war_offload_parm(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)6015 static u8 rtw_hal_set_war_offload_parm(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
6016 {
6017 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6018 	u8 u1H2CWarOfldParm[H2C_WAROFLD_RSVDPAGE1_LEN] = {0};
6019 	u8 ret = _FAIL;
6020 
6021 	SET_H2CCMD_WAROFLD_RSVDPAGE1_LOC_PARM(u1H2CWarOfldParm, rsvdpageloc->LocIpParm);
6022 	RTW_INFO("%s(): LocIpParm = %d\n", __func__, rsvdpageloc->LocIpParm);
6023 
6024 
6025 	ret = rtw_hal_fill_h2c_cmd(adapter,
6026 					H2C_WAROFLD_RSVDPAGE1,
6027 					H2C_WAROFLD_RSVDPAGE1_LEN,
6028 					u1H2CWarOfldParm);
6029 
6030 	return ret;
6031 }
6032 #endif /* CONFIG_WAR_OFFLOAD */
6033 
6034 
6035 
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)6036 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
6037 {
6038 	u8 ret = _FAIL;
6039 	u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
6040 
6041 	RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
6042 		 __func__, group_alg, pairwise_alg);
6043 	SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
6044 			pairwise_alg);
6045 	SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
6046 			group_alg);
6047 
6048 	ret = rtw_hal_fill_h2c_cmd(adapter,
6049 				   H2C_AOAC_GLOBAL_INFO,
6050 				   H2C_AOAC_GLOBAL_INFO_LEN,
6051 				   u1H2CAOACGlobalInfoParm);
6052 
6053 	return ret;
6054 }
6055 
6056 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)6057 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
6058 		PRSVDPAGE_LOC rsvdpageloc, u8 enable)
6059 {
6060 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6061 	u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
6062 	u8 res = 0, count = 0, ret = _FAIL;
6063 
6064 	RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
6065 		 __func__, rsvdpageloc->LocProbePacket,
6066 		 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
6067 
6068 	SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6069 	SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6070 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6071 					       rsvdpageloc->LocScanInfo);
6072 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6073 			rsvdpageloc->LocProbePacket);
6074 	/*
6075 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6076 				rsvdpageloc->LocSSIDInfo);
6077 	*/
6078 	ret = rtw_hal_fill_h2c_cmd(adapter,
6079 				   H2C_D0_SCAN_OFFLOAD_INFO,
6080 				   H2C_SCAN_OFFLOAD_CTRL_LEN,
6081 				   u1H2CScanOffloadInfoParm);
6082 	return ret;
6083 }
6084 #endif /* CONFIG_PNO_SUPPORT */
6085 
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)6086 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6087 {
6088 	struct security_priv *psecpriv = &padapter->securitypriv;
6089 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6090 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
6091 	struct registry_priv *pregistry = &padapter->registrypriv;
6092 	u8	pkt_type = 0, no_wake = 0;
6093 
6094 	if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6095 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
6096 		no_wake = 1;
6097 
6098 	RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6099 
6100 	rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6101 
6102 	if (enable) {
6103 		if(!no_wake)
6104 			rtw_hal_set_global_info_cmd(padapter,
6105 					    psecpriv->dot118021XGrpPrivacy,
6106 					    psecpriv->dot11PrivacyAlgrthm);
6107 
6108 		if (!(ppwrpriv->wowlan_pno_enable)) {
6109 			if (!no_wake)
6110 				rtw_hal_set_disconnect_decision_cmd(padapter,
6111 								    enable);
6112 #ifdef CONFIG_ARP_KEEP_ALIVE
6113 			if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6114 			    (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6115 				pkt_type = 0;
6116 			else
6117 				pkt_type = 1;
6118 #else
6119 			pkt_type = 0;
6120 #endif /* CONFIG_ARP_KEEP_ALIVE */
6121 			if(!no_wake) {
6122 				#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
6123 				rtw_hal_set_keep_alive_pattern_cmd(padapter,enable);
6124 				#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
6125 				rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6126                         }
6127 		}
6128 #ifdef CONFIG_PNO_SUPPORT
6129 		rtw_hal_check_pno_enabled(padapter);
6130 #endif /* CONFIG_PNO_SUPPORT */
6131 #ifdef CONFIG_WAR_OFFLOAD
6132 		rtw_hal_set_war_offload_ctrl_cmd(padapter, enable);
6133 #endif /* CONFIG_WAR_OFFLOAD */
6134 
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 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
8333 /*
8334  * Description:
8335  *	Construct the Keep Alive packet to support specific Keep Alive packet.
8336  *   */
rtw_hal_construct_keepalive(PADAPTER padapter,u8 * pframe,u32 * pLength)8337 static void rtw_hal_construct_keepalive(	PADAPTER padapter,
8338 	u8			*pframe,
8339 	u32			*pLength
8340 ){
8341 	struct rtw_ieee80211_hdr	*pwlanhdr;
8342 	u16	*fctrl;
8343 	u32	pktlen;
8344 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8345 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8346 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8347 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8348 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
8349 	static u8	LLCHeader[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
8350 	u8	*pKeepAlivePkt = pframe;
8351 	/* for TKIP Cal MIC */
8352 	u8	*payload = pframe;
8353 	u8	EncryptionHeadOverhead = 0, frame_offset = 0;
8354 	int i;
8355 
8356 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8357 
8358 	fctrl = &pwlanhdr->frame_ctl;
8359 	*(fctrl) = 0;
8360 
8361 	RTW_INFO("%s======>\n", __func__);
8362 
8363 
8364 	/* ------------------------------------------------------------------------- */
8365 	/* MAC Header. */
8366 	/* ------------------------------------------------------------------------- */
8367 	SetFrameType(fctrl, WIFI_DATA);
8368 	/* set_frame_sub_type(fctrl, 0); */
8369 	SetToDs(fctrl);
8370 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8371 	_rtw_memcpy(pwlanhdr->addr2, pwrpriv->keep_alive_pattern+6, ETH_ALEN);
8372 	_rtw_memcpy(pwlanhdr->addr3,pwrpriv->keep_alive_pattern, ETH_ALEN);
8373 
8374 	SetSeqNum(pwlanhdr, 0);
8375 	set_duration(pwlanhdr, 0);
8376 
8377 #ifdef CONFIG_WAPI_SUPPORT
8378 	*pLength = sMacHdrLng;
8379 #else
8380 	*pLength = 24;
8381 #endif
8382 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8383 	case _WEP40_:
8384 	case _WEP104_:
8385 		EncryptionHeadOverhead = 4;
8386 		break;
8387 	case _TKIP_:
8388 		EncryptionHeadOverhead = 8;
8389 		break;
8390 	case _AES_:
8391 		EncryptionHeadOverhead = 8;
8392 		break;
8393 #ifdef CONFIG_WAPI_SUPPORT
8394 	case _SMS4_:
8395 		EncryptionHeadOverhead = 18;
8396 		break;
8397 #endif
8398 	default:
8399 		EncryptionHeadOverhead = 0;
8400 	}
8401 
8402 	if (EncryptionHeadOverhead > 0) {
8403 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8404 		*pLength += EncryptionHeadOverhead;
8405 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8406 		SetPrivacy(fctrl);
8407 	}
8408 
8409 	/* ------------------------------------------------------------------------- */
8410 	/* Frame Body. */
8411 	/* ------------------------------------------------------------------------- */
8412 	frame_offset = *pLength;
8413 	pKeepAlivePkt = (u8 *)(pframe + frame_offset);
8414 	payload = pKeepAlivePkt; /* Get Payload pointer */
8415 	/* LLC header */
8416 	_rtw_memcpy(pKeepAlivePkt, LLCHeader, 6);
8417 	*pLength += 6;
8418 
8419 	/*From  protocol type*/
8420 	pKeepAlivePkt+=6;
8421 
8422 	_rtw_memcpy(pKeepAlivePkt,pwrpriv->keep_alive_pattern+12,pwrpriv->keep_alive_pattern_len-12);
8423 
8424 	*pLength+=pwrpriv->keep_alive_pattern_len-12;
8425 
8426 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8427 		*pLength += 8;
8428 	}
8429 
8430 	/* for debug
8431 	for (i=0; i< (*pLength) ;i++) {
8432 		RTW_INFO("KA_Pkt[0x%x]=x%0x", i,pKeepAlivePkt[i]);
8433 		if((i%8) == 7)
8434 			RTW_INFO("\n");
8435 	}
8436 	*/
8437 
8438 	RTW_INFO("%s <======\n", __func__);
8439 }
8440 
8441 #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
8442 
8443 #ifdef CONFIG_IPV6
8444 /*
8445  * Description: Neighbor Discovery Offload.
8446  */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)8447 static void rtw_hal_construct_na_message(_adapter *padapter,
8448 				     u8 *pframe, u32 *pLength)
8449 {
8450 	struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8451 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8452 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8453 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
8454 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8455 
8456 	u32 pktlen = 0;
8457 	u16 *fctrl = NULL;
8458 
8459 	u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8460 	u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8461 	u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8462 	u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8463 	u8 val8 = 0;
8464 
8465 	u8 *p_na_msg = pframe;
8466 	/* for TKIP Cal MIC */
8467 	u8 *payload = pframe;
8468 	u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8469 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8470 
8471 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8472 
8473 	fctrl = &pwlanhdr->frame_ctl;
8474 	*(fctrl) = 0;
8475 
8476 	/* ------------------------------------------------------------------------- */
8477 	/* MAC Header. */
8478 	/* ------------------------------------------------------------------------- */
8479 	SetFrameType(fctrl, WIFI_DATA);
8480 	SetToDs(fctrl);
8481 	_rtw_memcpy(pwlanhdr->addr1,
8482 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8483 	_rtw_memcpy(pwlanhdr->addr2,
8484 		    adapter_mac_addr(padapter), ETH_ALEN);
8485 	_rtw_memcpy(pwlanhdr->addr3,
8486 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8487 
8488 	SetSeqNum(pwlanhdr, 0);
8489 	set_duration(pwlanhdr, 0);
8490 
8491 #ifdef CONFIG_WAPI_SUPPORT
8492 	*pLength = sMacHdrLng;
8493 #else
8494 	*pLength = 24;
8495 #endif
8496 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8497 	case _WEP40_:
8498 	case _WEP104_:
8499 		EncryptionHeadOverhead = 4;
8500 		break;
8501 	case _TKIP_:
8502 		EncryptionHeadOverhead = 8;
8503 		break;
8504 	case _AES_:
8505 		EncryptionHeadOverhead = 8;
8506 		break;
8507 #ifdef CONFIG_WAPI_SUPPORT
8508 	case _SMS4_:
8509 		EncryptionHeadOverhead = 18;
8510 		break;
8511 #endif
8512 	default:
8513 		EncryptionHeadOverhead = 0;
8514 	}
8515 
8516 	if (EncryptionHeadOverhead > 0) {
8517 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8518 		*pLength += EncryptionHeadOverhead;
8519 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8520 		SetPrivacy(fctrl);
8521 	}
8522 
8523 	/* ------------------------------------------------------------------------- */
8524 	/* Frame Body. */
8525 	/* ------------------------------------------------------------------------- */
8526 	na_msg_offset = *pLength;
8527 	p_na_msg = (u8 *)(pframe + na_msg_offset);
8528 	payload = p_na_msg; /* Get Payload pointer */
8529 
8530 	/* LLC header */
8531 	val8 = sizeof(ns_hdr);
8532 	_rtw_memcpy(p_na_msg, ns_hdr, val8);
8533 	*pLength += val8;
8534 	p_na_msg += val8;
8535 
8536 	/* IPv6 Header */
8537 	/* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8538 	val8 = sizeof(ipv6_info);
8539 	_rtw_memcpy(p_na_msg, ipv6_info, val8);
8540 	*pLength += val8;
8541 	p_na_msg += val8;
8542 
8543 	/* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8544 	val8 = sizeof(ipv6_contx);
8545 	_rtw_memcpy(p_na_msg, ipv6_contx, val8);
8546 	*pLength += val8;
8547 	p_na_msg += val8;
8548 
8549 	/* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8550 	_rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8551 	*pLength += 32;
8552 	p_na_msg += 32;
8553 
8554 	/* ICMPv6 */
8555 	/* 1. Type : 0x88 (NA)
8556 	 * 2. Code : 0x00
8557 	 * 3. ChechSum : 0x00 0x00 (RSvd)
8558 	 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8559 	 */
8560 	val8 = sizeof(icmpv6_hdr);
8561 	_rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8562 	*pLength += val8;
8563 	p_na_msg += val8;
8564 
8565 	/* TA: 16 bytes*/
8566 	_rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8567 	*pLength += 16;
8568 	p_na_msg += 16;
8569 
8570 	/* ICMPv6 Target Link Layer Address */
8571 	p_na_msg[0] = 0x02; /* type */
8572 	p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8573 	*pLength += 2;
8574 	p_na_msg += 2;
8575 
8576 	_rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8577 	*pLength += 6;
8578 	p_na_msg += 6;
8579 
8580 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8581 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8582 		    IS_HARDWARE_TYPE_8812(padapter)) {
8583 			rtw_hal_append_tkip_mic(padapter, pframe,
8584 						na_msg_offset);
8585 		}
8586 		*pLength += 8;
8587 	}
8588 }
8589 /*
8590  * Description: Neighbor Discovery Protocol Information.
8591  */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)8592 static void rtw_hal_construct_ndp_info(_adapter *padapter,
8593 				     u8 *pframe, u32 *pLength)
8594 {
8595 	struct mlme_ext_priv *pmlmeext = NULL;
8596 	struct mlme_ext_info *pmlmeinfo = NULL;
8597 	struct rtw_ndp_info ndp_info;
8598 	u8	*pndp_info = pframe;
8599 	u8	len = sizeof(struct rtw_ndp_info);
8600 
8601 	RTW_INFO("%s: len: %d\n", __func__, len);
8602 
8603 	pmlmeext =  &padapter->mlmeextpriv;
8604 	pmlmeinfo = &pmlmeext->mlmext_info;
8605 
8606 	_rtw_memset(pframe, 0, len);
8607 	_rtw_memset(&ndp_info, 0, len);
8608 
8609 	ndp_info.enable = 1;
8610 	ndp_info.check_remote_ip = 0;
8611 	ndp_info.num_of_target_ip = 1;
8612 
8613 	_rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8614 		    ETH_ALEN);
8615 	_rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8616 		    RTW_IPv6_ADDR_LEN);
8617 
8618 	_rtw_memcpy(pndp_info, &ndp_info, len);
8619 }
8620 #endif /* CONFIG_IPV6 */
8621 
8622 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)8623 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8624 				       u32 *pLength, pno_ssid_t *ssid)
8625 {
8626 	struct rtw_ieee80211_hdr	*pwlanhdr;
8627 	u16				*fctrl;
8628 	u32				pktlen;
8629 	unsigned char			*mac;
8630 	unsigned char			bssrate[NumRates];
8631 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
8632 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8633 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8634 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8635 	int	bssrate_len = 0;
8636 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8637 
8638 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8639 	mac = adapter_mac_addr(padapter);
8640 
8641 	fctrl = &(pwlanhdr->frame_ctl);
8642 	*(fctrl) = 0;
8643 
8644 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8645 	_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8646 
8647 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8648 
8649 	SetSeqNum(pwlanhdr, 0);
8650 	set_frame_sub_type(pframe, WIFI_PROBEREQ);
8651 
8652 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8653 	pframe += pktlen;
8654 
8655 	if (ssid == NULL)
8656 		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8657 	else {
8658 		/* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8659 		pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8660 	}
8661 
8662 	get_rate_set(padapter, bssrate, &bssrate_len);
8663 
8664 	if (bssrate_len > 8) {
8665 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8666 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8667 	} else
8668 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8669 
8670 	*pLength = pktlen;
8671 }
8672 
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)8673 static void rtw_hal_construct_PNO_info(_adapter *padapter,
8674 				       u8 *pframe, u32 *pLength)
8675 {
8676 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8677 	int i;
8678 
8679 	u8	*pPnoInfoPkt = pframe;
8680 	pPnoInfoPkt = (u8 *)(pframe + *pLength);
8681 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8682 
8683 	pPnoInfoPkt += 1;
8684 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8685 
8686 	pPnoInfoPkt += 3;
8687 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8688 
8689 	pPnoInfoPkt += 4;
8690 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8691 
8692 	pPnoInfoPkt += 4;
8693 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8694 
8695 	pPnoInfoPkt += 4;
8696 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8697 
8698 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8699 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8700 
8701 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8702 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8703 
8704 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8705 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8706 
8707 	pPnoInfoPkt += MAX_HIDDEN_AP;
8708 
8709 	/*
8710 	SSID is located at 128th Byte in NLO info Page
8711 	*/
8712 
8713 	*pLength += 128;
8714 	pPnoInfoPkt = pframe + 128;
8715 
8716 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8717 		_rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8718 			    pwrctl->pnlo_info->ssid_length[i]);
8719 		*pLength += WLAN_SSID_MAXLEN;
8720 		pPnoInfoPkt += WLAN_SSID_MAXLEN;
8721 	}
8722 }
8723 
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)8724 static void rtw_hal_construct_ssid_list(_adapter *padapter,
8725 					u8 *pframe, u32 *pLength)
8726 {
8727 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8728 	u8 *pSSIDListPkt = pframe;
8729 	int i;
8730 
8731 	pSSIDListPkt = (u8 *)(pframe + *pLength);
8732 
8733 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8734 		_rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8735 			    pwrctl->pnlo_info->ssid_length[i]);
8736 
8737 		*pLength += WLAN_SSID_MAXLEN;
8738 		pSSIDListPkt += WLAN_SSID_MAXLEN;
8739 	}
8740 }
8741 
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)8742 static void rtw_hal_construct_scan_info(_adapter *padapter,
8743 					u8 *pframe, u32 *pLength)
8744 {
8745 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8746 	u8 *pScanInfoPkt = pframe;
8747 	int i;
8748 
8749 	pScanInfoPkt = (u8 *)(pframe + *pLength);
8750 
8751 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8752 
8753 	*pLength += 1;
8754 	pScanInfoPkt += 1;
8755 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8756 
8757 
8758 	*pLength += 1;
8759 	pScanInfoPkt += 1;
8760 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8761 
8762 
8763 	*pLength += 1;
8764 	pScanInfoPkt += 1;
8765 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8766 
8767 	*pLength += 1;
8768 	pScanInfoPkt += 1;
8769 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8770 
8771 	*pLength += 1;
8772 	pScanInfoPkt += 1;
8773 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8774 
8775 	*pLength += 1;
8776 	pScanInfoPkt += 1;
8777 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8778 
8779 	*pLength += 1;
8780 	pScanInfoPkt += 1;
8781 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8782 
8783 	*pLength += 1;
8784 	pScanInfoPkt += 1;
8785 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8786 
8787 	*pLength += 8;
8788 	pScanInfoPkt += 8;
8789 
8790 	for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8791 		_rtw_memcpy(pScanInfoPkt,
8792 			    &pwrctl->pscan_info->ssid_channel_info[i], 4);
8793 		*pLength += 4;
8794 		pScanInfoPkt += 4;
8795 	}
8796 }
8797 #endif /* CONFIG_PNO_SUPPORT */
8798 
8799 #ifdef CONFIG_WAR_OFFLOAD
8800 #ifdef CONFIG_OFFLOAD_MDNS_V4
8801 
8802 /*
8803  * Description:
8804  *	Construct the MDNS V4 response packet to support MDNS offload.
8805  *
8806  */
rtw_hal_construct_mdns_rsp_v4(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8807 static void rtw_hal_construct_mdns_rsp_v4(
8808 	PADAPTER 	padapter,
8809 	u8			*pframe,
8810 	u32			*pLength,
8811 	u8			*pIPAddress
8812 )
8813 {
8814 	struct rtw_ieee80211_hdr	*pwlanhdr;
8815 	u16	*fctrl;
8816 	u32	pktlen;
8817 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8818 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
8819 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8820 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8821 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8822 	static u8	ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00};
8823 	u8	mulicast_ipv4_addr[4] = {0xe0, 0x00, 0x00, 0xfb};
8824 	u8	mulicast_mac_addr_for_mdns[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb};
8825 	u8	*pMdnsRspPkt = pframe;
8826 	/* for TKIP Cal MIC */
8827 	u8	EncryptionHeadOverhead = 0, mdns_offset = 0;
8828 
8829 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
8830 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
8831 
8832 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8833 
8834 	fctrl = &pwlanhdr->frame_ctl;
8835 	*(fctrl) = 0;
8836 
8837 	/* ------------------------------------------------------------------------- */
8838 	/* MAC Header. */
8839 	/* ------------------------------------------------------------------------- */
8840 	SetFrameType(fctrl, WIFI_DATA);
8841 	/* set_frame_sub_type(fctrl, 0); */
8842 	SetToDs(fctrl);
8843 	//_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8844 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8845 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8846 	_rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN );
8847 
8848 	SetSeqNum(pwlanhdr, 0);
8849 	set_duration(pwlanhdr, 0);
8850 
8851 #ifdef CONFIG_WAPI_SUPPORT
8852 	*pLength = sMacHdrLng;
8853 #else
8854 	*pLength = 24;
8855 #endif
8856 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8857 	case _WEP40_:
8858 	case _WEP104_:
8859 		EncryptionHeadOverhead = 4;
8860 		break;
8861 	case _TKIP_:
8862 		EncryptionHeadOverhead = 8;
8863 		break;
8864 	case _AES_:
8865 		EncryptionHeadOverhead = 8;
8866 		break;
8867 #ifdef CONFIG_WAPI_SUPPORT
8868 	case _SMS4_:
8869 		EncryptionHeadOverhead = 18;
8870 		break;
8871 #endif
8872 	default:
8873 		EncryptionHeadOverhead = 0;
8874 	}
8875 
8876 	if (EncryptionHeadOverhead > 0) {
8877 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8878 		*pLength += EncryptionHeadOverhead;
8879 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8880 		SetPrivacy(fctrl);
8881 	}
8882 
8883 	/* ------------------------------------------------------------------------- */
8884 	/* Frame Body. */
8885 	/* ------------------------------------------------------------------------- */
8886 	mdns_offset = *pLength;
8887 	pMdnsRspPkt = (u8 *)(pframe + mdns_offset);
8888 	/* LLC header */
8889 	_rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8);
8890 	*pLength += 8;
8891 
8892 	/* IP element */
8893 	pMdnsRspPkt += 8;
8894 	SET_IPHDR_VERSION(pMdnsRspPkt, 0x45);
8895 	SET_IPHDR_DSCP(pMdnsRspPkt, 0);
8896 	SET_IPHDR_TOTAL_LEN(pMdnsRspPkt, 0);  // filled by fw
8897 	SET_IPHDR_IDENTIFIER(pMdnsRspPkt, 0);  // filled by fw
8898 	SET_IPHDR_FLAGS(pMdnsRspPkt, 0x40);
8899 	SET_IPHDR_FRAG_OFFSET(pMdnsRspPkt, 0);
8900 	SET_IPHDR_TTL(pMdnsRspPkt, 0x40);
8901 	SET_IPHDR_PROTOCOL(pMdnsRspPkt, 0x11);  // ICMP-UDP
8902 	SET_IPHDR_HDR_CHECKSUM(pMdnsRspPkt, 0);  // filled by fw
8903 	SET_IPHDR_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress);
8904 	SET_IPHDR_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv4_addr);  // filled by fw
8905 
8906 	*pLength += 20;
8907 
8908 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8909 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8910 			IS_HARDWARE_TYPE_8812(padapter)) {
8911 			rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset);
8912 		}
8913 		*pLength += 8;
8914 	}
8915 
8916 	/* UDP element */
8917 	pMdnsRspPkt += 20;
8918 	SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // MDNS
8919 	SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // MDNS
8920 	SET_UDP_LEN(pMdnsRspPkt, 0);      //  filled by fw
8921 	SET_UDP_CHECKSUM(pMdnsRspPkt, 0);     // filled by fw
8922 	*pLength += 8;
8923 
8924 	/* MDNS Header */
8925 	pMdnsRspPkt += 8;
8926 	SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84);
8927 	*pLength += 12;
8928 
8929 }
8930 
8931 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
8932 
8933 #ifdef CONFIG_OFFLOAD_MDNS_V6
8934 
8935 /*
8936  * Description:
8937  *	Construct the MDNS response V6 packet to support MDNS offload.
8938  *
8939  */
rtw_hal_construct_mdns_rsp_v6(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8940 static void rtw_hal_construct_mdns_rsp_v6(
8941 	PADAPTER 	padapter,
8942 	u8			*pframe,
8943 	u32			*pLength,
8944 	u8			*pIPAddress
8945 )
8946 {
8947 	struct rtw_ieee80211_hdr        *pwlanhdr;
8948 	u16     *fctrl;
8949 	u32     pktlen;
8950 	struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
8951 	struct wlan_network     *cur_network = &pmlmepriv->cur_network;
8952 	struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
8953 	struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
8954 	struct security_priv    *psecuritypriv = &padapter->securitypriv;
8955 	static u8       ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8956 	u8	mulicast_ipv6_addr[16] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
8957 	u8	mulicast_mac_addr_for_mdns[6] = {0x33, 0x33, 0x00, 0x00, 0x00, 0xfb}; /* could be revise by fw */
8958 	u8      *pMdnsRspPkt = pframe;
8959 	/* for TKIP Cal MIC */
8960 	u8      EncryptionHeadOverhead = 0, mdns_offset = 0;
8961 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8962 
8963 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
8964 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
8965 
8966 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8967 
8968 	fctrl = &pwlanhdr->frame_ctl;
8969 	*(fctrl) = 0;
8970 
8971 	/* ------------------------------------------------------------------------- */
8972 	/* MAC Header. */
8973 	/* ------------------------------------------------------------------------- */
8974 	SetFrameType(fctrl, WIFI_DATA);
8975 	/* set_frame_sub_type(fctrl, 0); */
8976 	SetToDs(fctrl);
8977 	//_rtw_memcpy(pwlanhdr->addr1, mulicast_mac_addr_for_mdns, ETH_ALEN);
8978 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8979 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8980 	//_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8981 	_rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN);
8982 
8983 	SetSeqNum(pwlanhdr, 0);
8984 	set_duration(pwlanhdr, 0);
8985 
8986 #ifdef CONFIG_WAPI_SUPPORT
8987 	*pLength = sMacHdrLng;
8988 #else
8989 	*pLength = 24;
8990 #endif
8991 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8992 	case _WEP40_:
8993 	case _WEP104_:
8994 		EncryptionHeadOverhead = 4;
8995 		break;
8996 	case _TKIP_:
8997 		EncryptionHeadOverhead = 8;
8998 		break;
8999 	case _AES_:
9000 		EncryptionHeadOverhead = 8;
9001 		break;
9002 #ifdef CONFIG_WAPI_SUPPORT
9003 	case _SMS4_:
9004 		EncryptionHeadOverhead = 18;
9005 		break;
9006 #endif
9007 	default:
9008 		EncryptionHeadOverhead = 0;
9009 	}
9010 
9011 	if (EncryptionHeadOverhead > 0) {
9012 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
9013 		*pLength += EncryptionHeadOverhead;
9014 		SetPrivacy(fctrl);
9015 	}
9016 
9017 	/* ------------------------------------------------------------------------- */
9018 	/* Frame Body. */
9019 	/* ------------------------------------------------------------------------- */
9020 	mdns_offset = *pLength;
9021 	pMdnsRspPkt = (u8 *)(pframe + mdns_offset);
9022 	/* LLC header */
9023 	_rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8);
9024 	*pLength += 8;
9025 
9026 	/* ICMP element */
9027 	pMdnsRspPkt += 8;
9028 	SET_IPHDRV6_VERSION(pMdnsRspPkt, 0x06);
9029 	SET_IPHDRV6_PAYLOAD_LENGTH(pMdnsRspPkt, 0); // filled by fw
9030 	SET_IPHDRV6_NEXT_HEADER(pMdnsRspPkt, 0x3A);
9031 	SET_IPHDRV6_HOP_LIMIT(pMdnsRspPkt, 0xFF);
9032 	SET_IPHDRV6_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress);  // filled by fw
9033 	SET_IPHDRV6_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv6_addr);  // filled by fw
9034 
9035 	*pLength += 40;
9036 
9037 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
9038 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
9039 			IS_HARDWARE_TYPE_8812(padapter)) {
9040 				rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset);
9041 		}
9042 		*pLength += 8;
9043 	}
9044 
9045 	/* UDP element */
9046 	pMdnsRspPkt += 40;
9047 	SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // SNMP
9048 	SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // SNMP
9049 	SET_UDP_LEN(pMdnsRspPkt, 0);      //  filled by fw
9050 	SET_UDP_CHECKSUM(pMdnsRspPkt, 0);     // filled by fw
9051 	*pLength += 8;
9052 
9053 	/* MDNS Header */
9054 	pMdnsRspPkt += 8;
9055 	SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84);
9056 	*pLength += 12;
9057 
9058 }
9059 
9060 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
9061 #endif
9062 
9063 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)9064 static void rtw_hal_construct_GTKRsp(
9065 	PADAPTER	padapter,
9066 	u8		*pframe,
9067 	u32		*pLength
9068 )
9069 {
9070 	struct rtw_ieee80211_hdr	*pwlanhdr;
9071 	u16	*fctrl;
9072 	u32	pktlen;
9073 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
9074 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
9075 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9076 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9077 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
9078 	static u8	LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
9079 	static u8	GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
9080 	u8	*pGTKRspPkt = pframe;
9081 	u8	EncryptionHeadOverhead = 0;
9082 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
9083 
9084 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9085 
9086 	fctrl = &pwlanhdr->frame_ctl;
9087 	*(fctrl) = 0;
9088 
9089 	/* ------------------------------------------------------------------------- */
9090 	/* MAC Header. */
9091 	/* ------------------------------------------------------------------------- */
9092 	SetFrameType(fctrl, WIFI_DATA);
9093 	/* set_frame_sub_type(fctrl, 0); */
9094 	SetToDs(fctrl);
9095 
9096 	_rtw_memcpy(pwlanhdr->addr1,
9097 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9098 
9099 	_rtw_memcpy(pwlanhdr->addr2,
9100 		    adapter_mac_addr(padapter), ETH_ALEN);
9101 
9102 	_rtw_memcpy(pwlanhdr->addr3,
9103 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9104 
9105 	SetSeqNum(pwlanhdr, 0);
9106 	set_duration(pwlanhdr, 0);
9107 
9108 #ifdef CONFIG_WAPI_SUPPORT
9109 	*pLength = sMacHdrLng;
9110 #else
9111 	*pLength = 24;
9112 #endif /* CONFIG_WAPI_SUPPORT */
9113 
9114 	/* ------------------------------------------------------------------------- */
9115 	/* Security Header: leave space for it if necessary. */
9116 	/* ------------------------------------------------------------------------- */
9117 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
9118 	case _WEP40_:
9119 	case _WEP104_:
9120 		EncryptionHeadOverhead = 4;
9121 		break;
9122 	case _TKIP_:
9123 		EncryptionHeadOverhead = 8;
9124 		break;
9125 	case _AES_:
9126 		EncryptionHeadOverhead = 8;
9127 		break;
9128 #ifdef CONFIG_WAPI_SUPPORT
9129 	case _SMS4_:
9130 		EncryptionHeadOverhead = 18;
9131 		break;
9132 #endif /* CONFIG_WAPI_SUPPORT */
9133 	default:
9134 		EncryptionHeadOverhead = 0;
9135 	}
9136 
9137 	if (EncryptionHeadOverhead > 0) {
9138 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
9139 		*pLength += EncryptionHeadOverhead;
9140 		/* SET_80211_HDR_WEP(pGTKRspPkt, 1);  */ /* Suggested by CCW. */
9141 		/* GTK's privacy bit is done by FW */
9142 		/* SetPrivacy(fctrl); */
9143 	}
9144 	/* ------------------------------------------------------------------------- */
9145 	/* Frame Body. */
9146 	/* ------------------------------------------------------------------------- */
9147 	pGTKRspPkt = (u8 *)(pframe + *pLength);
9148 	/* LLC header */
9149 	_rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
9150 	*pLength += 8;
9151 
9152 	/* GTK element */
9153 	pGTKRspPkt += 8;
9154 
9155 	/* GTK frame body after LLC, part 1 */
9156 	/* TKIP key_length = 32, AES key_length = 16 */
9157 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
9158 		GTKbody_a[8] = 0x20;
9159 
9160 	/* GTK frame body after LLC, part 1 */
9161 	_rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
9162 	*pLength += 11;
9163 	pGTKRspPkt += 11;
9164 	/* GTK frame body after LLC, part 2 */
9165 	_rtw_memset(&(pframe[*pLength]), 0, 88);
9166 	*pLength += 88;
9167 	pGTKRspPkt += 88;
9168 
9169 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
9170 		*pLength += 8;
9171 }
9172 #endif /* CONFIG_GTK_OL */
9173 
9174 #define PN_2_CCMPH(ch,key_id)	((ch) & 0x000000000000ffff) \
9175 				| (((ch) & 0x0000ffffffff0000) << 16) \
9176 				| (((key_id) << 30)) \
9177 				| BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)9178 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
9179 						  u8 *pframe, u32 *pLength)
9180 {
9181 	struct mlme_priv   *pmlmepriv = &adapter->mlmepriv;
9182 	struct sta_priv *pstapriv = &adapter->stapriv;
9183 	struct security_priv *psecuritypriv = &adapter->securitypriv;
9184 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
9185 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9186 	struct sta_info *psta;
9187 	struct stainfo_rxcache *prxcache;
9188 	u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
9189 	size_t sz = 0, total = 0;
9190 	u64 ccmp_hdr = 0, tmp_key = 0;
9191 
9192 	psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
9193 
9194 	if (psta == NULL) {
9195 		rtw_warn_on(1);
9196 		return;
9197 	}
9198 
9199 	prxcache = &psta->sta_recvpriv.rxcache;
9200 	sz = sizeof(cur_dot11rxiv);
9201 
9202 	/* 3 SEC IV * 1 page */
9203 	rtw_get_sec_iv(adapter, cur_dot11rxiv,
9204 		       get_my_bssid(&pmlmeinfo->network));
9205 
9206 	_rtw_memcpy(pframe, cur_dot11rxiv, sz);
9207 	*pLength += sz;
9208 	pframe += sz;
9209 
9210 	_rtw_memset(&cur_dot11rxiv, 0, sz);
9211 
9212 	if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
9213 		id = psecuritypriv->dot118021XGrpKeyid;
9214 		tid_id = prxcache->last_tid;
9215 		REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
9216 		REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
9217 		REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
9218 		REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
9219 		_rtw_memcpy(pframe, cur_dot11rxiv, sz);
9220 		*pLength += sz;
9221 		pframe += sz;
9222 
9223 		_rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
9224 		*pLength += sz;
9225 		pframe += sz;
9226 
9227 		total = sizeof(psecuritypriv->iv_seq);
9228 		total /= sizeof(psecuritypriv->iv_seq[0]);
9229 
9230 		for (i = 0 ; i < total ; i ++) {
9231 			ccmp_hdr =
9232 				le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
9233 			_rtw_memset(&cur_dot11rxiv, 0, sz);
9234 			if (ccmp_hdr != 0) {
9235 				tmp_key = i;
9236 				ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
9237 				*(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
9238 				_rtw_memcpy(pframe, cur_dot11rxiv, sz);
9239 			}
9240 			*pLength += sz;
9241 			pframe += sz;
9242 		}
9243 	}
9244 }
9245 
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)9246 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
9247 		  u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
9248 				  RSVDPAGE_LOC *rsvd_page_loc)
9249 {
9250 	struct security_priv *psecuritypriv = &adapter->securitypriv;
9251 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
9252 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9253 	struct mlme_ext_priv	*pmlmeext;
9254 	struct mlme_ext_info	*pmlmeinfo;
9255 	u32	ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
9256 	u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
9257 	u8 CurtPktPageNum = 0;
9258 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
9259 	u32 keep_alive_len=0;
9260 	int i;
9261 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN */
9262 #ifdef CONFIG_WAR_OFFLOAD
9263 	u16 tmp_idx = 0;
9264 	u32	buf_len = 0;
9265 #endif
9266 
9267 #ifdef CONFIG_GTK_OL
9268 	struct sta_priv *pstapriv = &adapter->stapriv;
9269 	struct sta_info *psta;
9270 	struct security_priv *psecpriv = &adapter->securitypriv;
9271 	u8 kek[RTW_KEK_LEN];
9272 	u8 kck[RTW_KCK_LEN];
9273 #endif /* CONFIG_GTK_OL */
9274 #ifdef CONFIG_PNO_SUPPORT
9275 	int pno_index;
9276 	u8 ssid_num;
9277 #endif /* CONFIG_PNO_SUPPORT */
9278 
9279 	pmlmeext = &adapter->mlmeextpriv;
9280 	pmlmeinfo = &pmlmeext->mlmext_info;
9281 
9282 	if (pwrctl->wowlan_pno_enable == _FALSE) {
9283 		/* ARP RSP * 1 page */
9284 
9285 		rsvd_page_loc->LocArpRsp = *page_num;
9286 
9287 		RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
9288 
9289 #ifdef CONFIG_WAR_OFFLOAD
9290 		if ((0 != pwrctl->wowlan_war_offload_ipv4.ip_addr[0]) &&
9291 			(_FALSE == _rtw_memcmp(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4))) {
9292 			_rtw_memcpy(pmlmeinfo->ip_addr, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4);
9293 			RTW_INFO("Update IP(%d.%d.%d.%d) to arp rsvd page\n",
9294 			pmlmeinfo->ip_addr[0], pmlmeinfo->ip_addr[1],
9295 			pmlmeinfo->ip_addr[2], pmlmeinfo->ip_addr[3]);
9296 		}
9297 #endif /* CONFIG_WAR_OFFLOAD */
9298 
9299 
9300 		rtw_hal_construct_ARPRsp(adapter, &pframe[index],
9301 					 &ARPLength, pmlmeinfo->ip_addr);
9302 
9303 		rtw_hal_fill_fake_txdesc(adapter,
9304 					 &pframe[index - tx_desc],
9305 					 ARPLength, _FALSE, _FALSE, _TRUE);
9306 
9307 		CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
9308 
9309 		*page_num += CurtPktPageNum;
9310 
9311 		index += (CurtPktPageNum * page_size);
9312 		RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
9313 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
9314 		/* Keep Alive * ? page*/
9315 		if(pwrctl->keep_alive_pattern_len){
9316 			rsvd_page_loc->LocKeepAlive = *page_num;
9317 			pwrctl->keep_alive_pattern_loc = rsvd_page_loc->LocKeepAlive;
9318 			RTW_INFO("pwrctl->keep_alive_pattern_loc: %d\n", pwrctl->keep_alive_pattern_loc);
9319 			rtw_hal_construct_keepalive(adapter,&pframe[index],&keep_alive_len);
9320 			rtw_hal_fill_fake_txdesc(adapter,
9321 					 &pframe[index - tx_desc],
9322 					 keep_alive_len, _FALSE, _FALSE, _TRUE);
9323 			CurtPktPageNum = (u8)PageNum(tx_desc + keep_alive_len, page_size);
9324 			*page_num += CurtPktPageNum;
9325 			index += (CurtPktPageNum * page_size);
9326 			RSVD_PAGE_CFG("WOW-KeepAlive:", CurtPktPageNum, *page_num, 0);
9327 		}
9328 #endif /* CONFIG_WOW_KEEP_ALIVE_PATTERN*/
9329 
9330 #ifdef CONFIG_IPV6
9331 		/* 2 NS offload and NDP Info*/
9332 		if (pwrctl->wowlan_ns_offload_en == _TRUE) {
9333 			rsvd_page_loc->LocNbrAdv = *page_num;
9334 			RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
9335 			rtw_hal_construct_na_message(adapter,
9336 						     &pframe[index], &ns_len);
9337 			rtw_hal_fill_fake_txdesc(adapter,
9338 						 &pframe[index - tx_desc],
9339 						 ns_len, _FALSE,
9340 						 _FALSE, _TRUE);
9341 			CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
9342 						      page_size);
9343 			*page_num += CurtPktPageNum;
9344 			index += (CurtPktPageNum * page_size);
9345 			RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
9346 
9347 			rsvd_page_loc->LocNDPInfo = *page_num;
9348 			RTW_INFO("LocNDPInfo: %d\n",
9349 				 rsvd_page_loc->LocNDPInfo);
9350 
9351 			rtw_hal_construct_ndp_info(adapter,
9352 						   &pframe[index - tx_desc],
9353 						   &ns_len);
9354 			CurtPktPageNum =
9355 				(u8)PageNum(tx_desc + ns_len, page_size);
9356 			*page_num += CurtPktPageNum;
9357 			index += (CurtPktPageNum * page_size);
9358 			RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
9359 
9360 		}
9361 #endif /*CONFIG_IPV6*/
9362 		/* 3 Remote Control Info. * 1 page */
9363 		rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
9364 		RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
9365 		rtw_hal_construct_remote_control_info(adapter,
9366 						      &pframe[index - tx_desc],
9367 						      &rc_len);
9368 		CurtPktPageNum = (u8)PageNum(rc_len, page_size);
9369 		*page_num += CurtPktPageNum;
9370 		*total_pkt_len = index + rc_len;
9371 		RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
9372 #ifdef CONFIG_GTK_OL
9373 		index += (CurtPktPageNum * page_size);
9374 
9375 		/* if the ap staion info. exists, get the kek, kck from staion info. */
9376 		psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
9377 		if (psta == NULL) {
9378 			_rtw_memset(kek, 0, RTW_KEK_LEN);
9379 			_rtw_memset(kck, 0, RTW_KCK_LEN);
9380 			RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
9381 				 __func__);
9382 		} else {
9383 			_rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
9384 			_rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
9385 		}
9386 
9387 		/* 3 KEK, KCK */
9388 		rsvd_page_loc->LocGTKInfo = *page_num;
9389 		RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
9390 
9391 		if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
9392 			struct security_priv *psecpriv = NULL;
9393 
9394 			psecpriv = &adapter->securitypriv;
9395 			_rtw_memcpy(pframe + index - tx_desc,
9396 				    &psecpriv->dot11PrivacyAlgrthm, 1);
9397 			_rtw_memcpy(pframe + index - tx_desc + 1,
9398 				    &psecpriv->dot118021XGrpPrivacy, 1);
9399 			_rtw_memcpy(pframe + index - tx_desc + 2,
9400 				    kck, RTW_KCK_LEN);
9401 			_rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
9402 				    kek, RTW_KEK_LEN);
9403 			CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
9404 		} else {
9405 
9406 			_rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
9407 			_rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
9408 				    kek, RTW_KEK_LEN);
9409 			GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
9410 
9411 			if (psta != NULL &&
9412 				psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
9413 				_rtw_memcpy(pframe + index - tx_desc + 56,
9414 					&psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
9415 				GTKLength += RTW_TKIP_MIC_LEN;
9416 			}
9417 			CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
9418 		}
9419 #if 0
9420 		{
9421 			int i;
9422 			printk("\ntoFW KCK: ");
9423 			for (i = 0; i < 16; i++)
9424 				printk(" %02x ", kck[i]);
9425 			printk("\ntoFW KEK: ");
9426 			for (i = 0; i < 16; i++)
9427 				printk(" %02x ", kek[i]);
9428 			printk("\n");
9429 		}
9430 
9431 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
9432 			 __FUNCTION__, &pframe[index - tx_desc],
9433 			 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
9434 #endif
9435 
9436 		*page_num += CurtPktPageNum;
9437 
9438 		index += (CurtPktPageNum * page_size);
9439 		RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
9440 
9441 		/* 3 GTK Response */
9442 		rsvd_page_loc->LocGTKRsp = *page_num;
9443 		RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
9444 		rtw_hal_construct_GTKRsp(adapter, &pframe[index], &GTKLength);
9445 
9446 		rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
9447 					 GTKLength, _FALSE, _FALSE, _TRUE);
9448 #if 0
9449 		{
9450 			int gj;
9451 			printk("123GTK pkt=>\n");
9452 			for (gj = 0; gj < GTKLength + tx_desc; gj++) {
9453 				printk(" %02x ", pframe[index - tx_desc + gj]);
9454 				if ((gj + 1) % 16 == 0)
9455 					printk("\n");
9456 			}
9457 			printk(" <=end\n");
9458 		}
9459 
9460 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
9461 			 __FUNCTION__, &pframe[index - tx_desc],
9462 			 (tx_desc + GTKLength));
9463 #endif
9464 
9465 		CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
9466 
9467 		*page_num += CurtPktPageNum;
9468 
9469 		index += (CurtPktPageNum * page_size);
9470 		RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
9471 
9472 		/* below page is empty for GTK extension memory */
9473 		/* 3(11) GTK EXT MEM */
9474 		rsvd_page_loc->LocGTKEXTMEM = *page_num;
9475 		RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
9476 		CurtPktPageNum = 2;
9477 
9478 		if (page_size >= 256)
9479 			CurtPktPageNum = 1;
9480 
9481 		*page_num += CurtPktPageNum;
9482 		/* extension memory for FW */
9483 		*total_pkt_len = index + (page_size * CurtPktPageNum);
9484 		RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
9485 #endif /* CONFIG_GTK_OL */
9486 
9487 		index += (CurtPktPageNum * page_size);
9488 
9489 #ifdef CONFIG_WAR_OFFLOAD
9490 		if(_TRUE == pwrctl->wowlan_war_offload_mode) {
9491 			u8 zero_ary[16] = {0x00};
9492 			u8 war_tmp_cnt = 0;
9493 
9494 			/* Reserve 2 page for Ip parameters */
9495 			/* First page
9496 			   | Byte 15 -----------Byte 0 |
9497 			   | IP-4 | IP-3 | IP-2 | IP-1 |
9498 			   | location of each feature | mac addr |
9499 			   | NetBIOS name			   |
9500 			   | location of each feature  |
9501 			Second page
9502 			   | IPv6 - 1				   |
9503 			   | IPv6 - 2				   |
9504 			   | IPv6 - 3				   |
9505 			   | IPv6 - 4				   |
9506 			   | IPv6 - 5				   |
9507 			   | IPv6 - 6				   |
9508 			   | IPv6 - 7				   |
9509 			   | IPv6 - 8				   |
9510 			*/
9511 
9512 			/* location of each feature : Byte 22 ~ Byte 31
9513 			 * Byte22 : location of SNMP RX
9514 			 * Byte23 : location of SNMP V4
9515 			 * Byte24 : location of SNMP V6
9516 			 * Byte25 : location of MDNS Param
9517 			 * Byte26 : location of MDNS V4
9518 			 * Byte27 : location of MDNS V6
9519 			 * Byte28 : location of SSDP pattern
9520 			 * Byte29 : location of WSD pattern
9521 			 * Byte30 : location of SLP pattern
9522 			 * Byte31 : location of LLMNR
9523 			 */
9524 
9525 			/* ipv4 : 4 */
9526 			if (0 == pwrctl->wowlan_war_offload_ipv4.ip_addr[0])
9527 				_rtw_memcpy(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4);
9528 			for(war_tmp_cnt=0; war_tmp_cnt<4 ;war_tmp_cnt++)
9529 				_rtw_memcpy(pframe + index - tx_desc + (war_tmp_cnt*4), &pwrctl->wowlan_war_offload_ipv4.ip_addr[war_tmp_cnt], 4);
9530 
9531 			if (is_zero_mac_addr(pwrctl->wowlan_war_offload_mac)) {
9532 				_rtw_memcpy(pwrctl->wowlan_war_offload_mac, adapter_mac_addr(adapter), 6);
9533 			}
9534 			_rtw_memcpy(pframe + index + 16 - tx_desc, pwrctl->wowlan_war_offload_mac, 6);
9535 
9536 
9537 			/* ipv6 : 8 */
9538 			if (_TRUE == _rtw_memcmp(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], zero_ary, RTW_IPv6_ADDR_LEN))
9539 				_rtw_memcpy(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], pmlmeinfo->ip6_addr, RTW_IPv6_ADDR_LEN);
9540 
9541 			for(war_tmp_cnt=0; war_tmp_cnt<8 ;war_tmp_cnt++)
9542 				_rtw_memcpy(pframe + index + page_size - tx_desc + (war_tmp_cnt*16), pwrctl->wowlan_war_offload_ipv6.ipv6_addr[war_tmp_cnt], 16);
9543 
9544 			rsvd_page_loc->LocIpParm = *page_num;
9545 
9546 			tmp_idx = index;
9547 			CurtPktPageNum = 2;
9548 			*page_num += CurtPktPageNum;
9549 			*total_pkt_len = index + (page_size * CurtPktPageNum);
9550 			index += (CurtPktPageNum * page_size);
9551 
9552 
9553 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
9554 			if ( (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) ||
9555 				 (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) ||
9556 				 (WAR_MDNS_V4_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl) ||
9557 				 (WAR_MDNS_V6_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl)) {
9558 
9559 				struct war_mdns_service_info *psinfo = pwrctl->wowlan_war_offload_mdns_service;
9560 				u8 txt_in_ptr[31]={ 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9561 									 0x00, 0x13, 0x09, 0x74, 0x78, 0x74, 0x76, 0x65, 0x72, 0x73,
9562 									 0x3d, 0x31, 0x08, 0x71, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x3d, 0x31};
9563 				u16 mdns_offset = index - tx_desc;
9564 				u8 i = 0;
9565 
9566 				rsvd_page_loc->LocMdnsPara = *page_num;
9567 				RTW_INFO("LocMdnsPara : %d\n", rsvd_page_loc->LocMdnsPara);
9568 
9569 				/* 1. service info */
9570 				pframe[mdns_offset] = 0x01;  // TLV(T)
9571 				mdns_offset += 1;
9572 				_rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_service_info_num, 1);
9573 				mdns_offset += 1;
9574 
9575 				for(i=0; i<pwrctl->wowlan_war_offload_mdns_service_info_num ;i++)
9576 				{
9577 					u16 srv_rsp_len = 0;
9578 
9579 					// 1.1 : construct service name string
9580 					//	   : length of total service name string (service+transport+domain)
9581 					pframe[mdns_offset] = psinfo[i].service_len + psinfo[i].transport_len + psinfo[i].domain_len + 4;
9582 					mdns_offset += 1;
9583 
9584 					//	   :  service name
9585 					pframe[mdns_offset] = psinfo[i].service_len;
9586 					mdns_offset += 1;
9587 					_rtw_memcpy(pframe + mdns_offset, &psinfo[i].service, psinfo[i].service_len);
9588 					mdns_offset += psinfo[i].service_len;
9589 
9590 					//	   : transport name
9591 					pframe[mdns_offset] = psinfo[i].transport_len;
9592 					mdns_offset += 1;
9593 					_rtw_memcpy(pframe + mdns_offset, &psinfo[i].transport, psinfo[i].transport_len);
9594 					mdns_offset += psinfo[i].transport_len;
9595 
9596 					//	   : domain name
9597 					pframe[mdns_offset] = psinfo[i].domain_len;
9598 					mdns_offset += 1;
9599 					_rtw_memcpy(pframe + mdns_offset, &psinfo[i].domain, psinfo[i].domain_len);
9600 					mdns_offset += psinfo[i].domain_len;
9601 
9602 					//	   : delimiter
9603 					mdns_offset += 1;
9604 
9605 					// 1.2 : construct type srv rsp
9606 					pframe[mdns_offset] = psinfo[i].target_len + 19; // length
9607 					pframe[mdns_offset + 2] = 0x21; // rsp type (srv)
9608 					pframe[mdns_offset + 4] = 0x01; // cache flush + class
9609 					_rtw_memcpy(pframe + mdns_offset + 5, &psinfo[i].ttl, 4); // ttl
9610 					pframe[mdns_offset + 5] = (u8) ( (psinfo[i].ttl & 0xff000000) >> 24);	// ttl - byte0
9611 					pframe[mdns_offset + 6] = (u8) ( (psinfo[i].ttl & 0x00ff0000) >> 16);	// ttl - byte1
9612 					pframe[mdns_offset + 7] = (u8) ( (psinfo[i].ttl & 0x0000ff00) >> 8 );		// ttl - byte2
9613 					pframe[mdns_offset + 8] = (u8) (psinfo[i].ttl & 0x000000ff);			// ttl - byte3
9614 					pframe[mdns_offset + 10] = psinfo[i].target_len + 9;	  // data length
9615 					_rtw_memcpy(pframe + mdns_offset + 15, &psinfo[i].port, 2); // port
9616 					_rtw_memcpy(pframe + mdns_offset + 17, &psinfo[i].target_len, 1); // target len
9617 					_rtw_memcpy(pframe + mdns_offset + 18, &psinfo[i].target, psinfo[i].target_len); // target
9618 					pframe[mdns_offset + 18 + psinfo[i].target_len] = 0xc0; // message compresion, offset will be filled by fw.
9619 					mdns_offset += (1 + psinfo[i].target_len + 19);
9620 
9621 					// 1.3 : set the idx of txt rsp
9622 					pframe[mdns_offset] = psinfo[i].txt_rsp_idx;
9623 					mdns_offset += 1;
9624 				}
9625 
9626 				/* 2. machine name */
9627 				pframe[mdns_offset] = 0x02; // TLV(T)
9628 				mdns_offset += 1;
9629 				_rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_mnane_num, 1); // NUM
9630 				mdns_offset += 1;
9631 
9632 				for(i=0; i<pwrctl->wowlan_war_offload_mdns_mnane_num; i++)
9633 				{
9634 					pframe[mdns_offset] = pwrctl->wowlan_war_offload_mdns_mnane[i].name_len;
9635 					_rtw_memcpy(pframe + mdns_offset + 1, pwrctl->wowlan_war_offload_mdns_mnane[i].name,
9636 						pwrctl->wowlan_war_offload_mdns_mnane[i].name_len); // machine name
9637 					mdns_offset += (1+pwrctl->wowlan_war_offload_mdns_mnane[i].name_len);
9638 				}
9639 
9640 				/* 3. A rsp */
9641 				pframe[mdns_offset] = 0x03; // TLV(T)
9642 				pframe[mdns_offset + 1] = 14;	// TLV(L)
9643 				pframe[mdns_offset + 3] = 0x01; // rsp type (a)
9644 				pframe[mdns_offset + 5] = 0x01; // cache flush + class
9645 				pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec)
9646 				pframe[mdns_offset + 11] = 4;	// length of ipv4 addr.
9647 				_rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4);
9648 				mdns_offset += (2 + 14);
9649 
9650 				/* 4. AAAA rsp */
9651 				pframe[mdns_offset] = 0x04; // TLV(T)
9652 				pframe[mdns_offset + 1] = 26;	// TLV(L)
9653 				pframe[mdns_offset + 3] = 0x1c; // rsp type (aaaa)
9654 				pframe[mdns_offset + 5] = 0x01; // cache flush + class
9655 				pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec)
9656 				pframe[mdns_offset + 11] = 16;	// length of ipv6 addr.
9657 				_rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], 16);
9658 				mdns_offset += (2 + 26);
9659 
9660 				/* 5. PTR rsp */
9661 				pframe[mdns_offset] = 0x05; // TLV(T)
9662 				pframe[mdns_offset + 1] = 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // TLV(L)
9663 				pframe[mdns_offset + 3] = 0x0c; // rsp type (aaaa)
9664 				pframe[mdns_offset + 5] = 0x01; // cache flush + class
9665 				pframe[mdns_offset + 8] = 0x1c; // ttl
9666 				pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec)
9667 				pframe[mdns_offset + 11] = 3 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // data length
9668 				pframe[mdns_offset + 12] = pwrctl->wowlan_war_offload_mdns_domain_name_len; // domain name length
9669 				_rtw_memcpy(pframe + mdns_offset + 13, &pwrctl->wowlan_war_offload_mdns_domain_name,
9670 					pwrctl->wowlan_war_offload_mdns_domain_name_len);
9671 				pframe[mdns_offset + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len] = 0xc0; // message compression
9672 				mdns_offset += (2 + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len);
9673 
9674 				/* 6. TXT in PTR rsp */
9675 				pframe[mdns_offset] = 0x06; 		// TLV(T)
9676 				pframe[mdns_offset + 1] = 31;	// TLV(L)
9677 				_rtw_memcpy(pframe + mdns_offset + 2, &txt_in_ptr, 31);
9678 				mdns_offset += (2 + 31);
9679 
9680 				/* 7. TXT rsp */
9681 				pframe[mdns_offset] = 0x07; // TLV(T)
9682 				mdns_offset += 1;
9683 				_rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_txt_rsp_num, 1); // NUM
9684 				mdns_offset += 1;
9685 
9686 				for(i=0; i<pwrctl->wowlan_war_offload_mdns_txt_rsp_num; i++)
9687 				{
9688 					u16 txt_rsp_len = pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len;
9689 
9690 					if(pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len==0)
9691 					{
9692 						_rtw_memcpy(pframe + mdns_offset, &txt_rsp_len,  2);
9693 						mdns_offset += ( 2 + txt_rsp_len );
9694 						continue;
9695 					}
9696 
9697 					txt_rsp_len += 10;
9698 					_rtw_memcpy(pframe + mdns_offset, &txt_rsp_len,  2);
9699 					pframe[mdns_offset + 3] = 0x10; // rsp type (txt)
9700 					pframe[mdns_offset + 5] = 0x01; // cache flush + class
9701 					pframe[mdns_offset + 8] = 0x1c; // ttl
9702 					pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec)
9703 					pframe[mdns_offset + 10] = (u8) ((pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0xff00) >> 8);
9704 					pframe[mdns_offset + 11] = (u8) (pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0x00ff);
9705 						_rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt,
9706 							pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len);
9707 					mdns_offset  += ( 2 + txt_rsp_len );
9708 				}
9709 
9710 				CurtPktPageNum = (u8)PageNum(mdns_offset - index, page_size)+1;
9711 				*page_num += CurtPktPageNum;
9712 				*total_pkt_len = index + (page_size * CurtPktPageNum);
9713 				index += (CurtPktPageNum * page_size);
9714 			}
9715 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
9716 
9717 #ifdef CONFIG_OFFLOAD_MDNS_V4
9718 			if (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) {
9719 				rsvd_page_loc->LocMdnsv4 = *page_num;
9720 				RTW_INFO("LocMdnsv4: %d\n", rsvd_page_loc->LocMdnsv4);
9721 
9722 				rtw_hal_construct_mdns_rsp_v4(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr);
9723 				rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE);
9724 				CurtPktPageNum = 16;
9725 				*page_num += CurtPktPageNum;
9726 				index += (CurtPktPageNum * page_size);
9727 			}
9728 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
9729 
9730 #ifdef CONFIG_OFFLOAD_MDNS_V6
9731 			if (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) {
9732 				rsvd_page_loc->LocMdnsv6 = *page_num;
9733 				RTW_INFO("LocMdnsv6: %d\n", rsvd_page_loc->LocMdnsv6);
9734 
9735 				rtw_hal_construct_mdns_rsp_v6(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr);
9736 				rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE);
9737 				CurtPktPageNum = 16;
9738 				*page_num += CurtPktPageNum;
9739 				index += (CurtPktPageNum * page_size);
9740 			}
9741 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
9742 
9743 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
9744 			*(pframe+tmp_idx+25-tx_desc) = rsvd_page_loc->LocMdnsPara;
9745 			*(pframe+tmp_idx+26-tx_desc) = rsvd_page_loc->LocMdnsv4;
9746 			*(pframe+tmp_idx+27-tx_desc) = rsvd_page_loc->LocMdnsv6;
9747 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
9748 
9749 			}
9750 			//rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, rsvd_page_loc->LocIpParm, 46);
9751 #endif /* CONFIG_WAR_OFFLOAD */
9752 
9753 
9754 		/*Reserve 1 page for AOAC report*/
9755 		rsvd_page_loc->LocAOACReport = *page_num;
9756 		RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
9757 		*page_num += 1;
9758 		*total_pkt_len = index + (page_size * 1);
9759 		RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
9760 	} else {
9761 #ifdef CONFIG_PNO_SUPPORT
9762 		if (pwrctl->wowlan_in_resume == _FALSE &&
9763 		    pwrctl->pno_inited == _TRUE) {
9764 
9765 			/* Broadcast Probe Request */
9766 			rsvd_page_loc->LocProbePacket = *page_num;
9767 
9768 			RTW_INFO("loc_probe_req: %d\n",
9769 				 rsvd_page_loc->LocProbePacket);
9770 
9771 			rtw_hal_construct_ProbeReq(
9772 				adapter,
9773 				&pframe[index],
9774 				&ProbeReqLength,
9775 				NULL);
9776 
9777 			rtw_hal_fill_fake_txdesc(adapter,
9778 						 &pframe[index - tx_desc],
9779 				 ProbeReqLength, _FALSE, _FALSE, _FALSE);
9780 
9781 			CurtPktPageNum =
9782 				(u8)PageNum(tx_desc + ProbeReqLength, page_size);
9783 
9784 			*page_num += CurtPktPageNum;
9785 
9786 			index += (CurtPktPageNum * page_size);
9787 			RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9788 
9789 			/* Hidden SSID Probe Request */
9790 			ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
9791 
9792 			for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
9793 				pwrctl->pnlo_info->loc_probe_req[pno_index] =
9794 					*page_num;
9795 
9796 				rtw_hal_construct_ProbeReq(
9797 					adapter,
9798 					&pframe[index],
9799 					&ProbeReqLength,
9800 					&pwrctl->pno_ssid_list->node[pno_index]);
9801 
9802 				rtw_hal_fill_fake_txdesc(adapter,
9803 						 &pframe[index - tx_desc],
9804 					ProbeReqLength, _FALSE, _FALSE, _FALSE);
9805 
9806 				CurtPktPageNum =
9807 					(u8)PageNum(tx_desc + ProbeReqLength, page_size);
9808 
9809 				*page_num += CurtPktPageNum;
9810 
9811 				index += (CurtPktPageNum * page_size);
9812 				RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9813 			}
9814 
9815 			/* PNO INFO Page */
9816 			rsvd_page_loc->LocPNOInfo = *page_num;
9817 			RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
9818 			rtw_hal_construct_PNO_info(adapter,
9819 						   &pframe[index - tx_desc],
9820 						   &PNOLength);
9821 
9822 			CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
9823 			*page_num += CurtPktPageNum;
9824 			index += (CurtPktPageNum * page_size);
9825 			RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
9826 
9827 			/* Scan Info Page */
9828 			rsvd_page_loc->LocScanInfo = *page_num;
9829 			RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
9830 			rtw_hal_construct_scan_info(adapter,
9831 						    &pframe[index - tx_desc],
9832 						    &ScanInfoLength);
9833 
9834 			CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
9835 			*page_num += CurtPktPageNum;
9836 			*total_pkt_len = index + ScanInfoLength;
9837 			index += (CurtPktPageNum * page_size);
9838 			RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
9839 		}
9840 #endif /* CONFIG_PNO_SUPPORT */
9841 	}
9842 }
9843 
rtw_hal_gate_bb(_adapter * adapter,bool stop)9844 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9845 {
9846 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9847 	u8 i = 0, val8 = 0, empty = _FAIL;
9848 
9849 	if (stop) {
9850 		/* checking TX queue status */
9851 		for (i = 0 ; i < 5 ; i++) {
9852 			rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9853 			if (empty) {
9854 				break;
9855 			} else {
9856 				RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9857 					 __func__, i);
9858 				rtw_mdelay_os(10);
9859 			}
9860 		}
9861 
9862 		if (val8 == 5)
9863 			RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9864 
9865 		/* Pause TX*/
9866 		pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9867 		rtw_write8(adapter, REG_TXPAUSE, 0xff);
9868 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9869 		val8 &= ~BIT(0);
9870 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9871 		RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9872 			 __func__,
9873 			 rtw_read8(adapter, REG_SYS_FUNC_EN),
9874 			 pwrpriv->wowlan_txpause_status);
9875 	} else {
9876 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9877 		val8 |= BIT(0);
9878 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9879 		RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9880 			 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9881 			 pwrpriv->wowlan_txpause_status);
9882 		/* release TX*/
9883 		rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9884 	}
9885 }
9886 
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)9887 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9888 {
9889 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9890 	 u8 *pattern;
9891 	 u8 len = 0;
9892 	 u8 *mask;
9893 
9894 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
9895 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9896 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9897 	u8 multicast_addr1[2] = {0x33, 0x33};
9898 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9899 	u8 mask_len = 0;
9900 	u8 mac_addr[ETH_ALEN] = {0};
9901 	u16 count = 0;
9902 	int i;
9903 
9904 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9905 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9906 			 __func__, MAX_WKFM_CAM_NUM);
9907 		return _FAIL;
9908 	}
9909 
9910 	pattern = pwrctl->patterns[idx].content;
9911 	len = pwrctl->patterns[idx].len;
9912 	mask = pwrctl->patterns[idx].mask;
9913 
9914 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9915 	_rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9916 
9917 	mask_len = DIV_ROUND_UP(len, 8);
9918 
9919 	/* 1. setup A1 table */
9920 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9921 		pwow_pattern->type = PATTERN_BROADCAST;
9922 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
9923 		pwow_pattern->type = PATTERN_MULTICAST;
9924 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
9925 		pwow_pattern->type = PATTERN_MULTICAST;
9926 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9927 		pwow_pattern->type = PATTERN_UNICAST;
9928 	else
9929 		pwow_pattern->type = PATTERN_INVALID;
9930 
9931 	/* translate mask from os to mask for hw */
9932 
9933 	/******************************************************************************
9934 	 * pattern from OS uses 'ethenet frame', like this:
9935 
9936 		|    6   |    6   |   2  |     20    |  Variable  |  4  |
9937 		|--------+--------+------+-----------+------------+-----|
9938 		|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
9939 		|   DA   |   SA   | Type |
9940 
9941 	 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9942 
9943 		|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
9944 		|-------------------+--------+------+-----------+------------+-----|
9945 		| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
9946 				    | Others | Tpye |
9947 
9948 	 * Therefore, we need translate mask_from_OS to mask_to_hw.
9949 	 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9950 	 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9951 	 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9952 	 ******************************************************************************/
9953 	/* Shift 6 bits */
9954 	for (i = 0; i < mask_len - 1; i++) {
9955 		mask_hw[i] = mask[i] >> 6;
9956 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9957 	}
9958 
9959 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
9960 	/* Set bit 0-5 to zero */
9961 	mask_hw[0] &= 0xC0;
9962 
9963 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9964 		pwow_pattern->mask[i] = mask_hw[i * 4];
9965 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9966 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9967 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9968 	}
9969 
9970 	/* To get the wake up pattern from the mask.
9971 	 * We do not count first 12 bits which means
9972 	 * DA[6] and SA[6] in the pattern to match HW design. */
9973 	count = 0;
9974 	for (i = 12; i < len; i++) {
9975 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
9976 			content[count] = pattern[i];
9977 			count++;
9978 		}
9979 	}
9980 
9981 	pwow_pattern->crc = rtw_calc_crc(content, count);
9982 
9983 	if (pwow_pattern->crc != 0) {
9984 		if (pwow_pattern->type == PATTERN_INVALID)
9985 			pwow_pattern->type = PATTERN_VALID;
9986 	}
9987 
9988 	return _SUCCESS;
9989 }
9990 
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)9991 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
9992 {
9993 	int j;
9994 
9995 	RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
9996 	RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
9997 	RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
9998 	for (j = 0; j < 4; j++)
9999 		RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
10000 }
10001 /*bit definition of pattern match format*/
10002 #define WOW_VALID_BIT	BIT31
10003 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10004 #define WOW_BC_BIT		BIT26
10005 #define WOW_MC_BIT		BIT25
10006 #define WOW_UC_BIT		BIT24
10007 #else
10008 #define WOW_BC_BIT		BIT18
10009 #define WOW_UC_BIT		BIT17
10010 #define WOW_MC_BIT		BIT16
10011 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10012 
10013 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10014 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_hal_reset_mac_rx(_adapter * adapter)10015 static void rtw_hal_reset_mac_rx(_adapter *adapter)
10016 {
10017 	u8 val8 = 0;
10018 	/* Set REG_CR bit1, bit3, bit7 to 0*/
10019 	val8 = rtw_read8(adapter, REG_CR);
10020 	val8 &= 0x75;
10021 	rtw_write8(adapter, REG_CR, val8);
10022 	val8 = rtw_read8(adapter, REG_CR);
10023 	/* Set REG_CR bit1, bit3, bit7 to 1*/
10024 	val8 |= 0x8a;
10025 	rtw_write8(adapter, REG_CR, val8);
10026 	RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
10027 }
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)10028 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
10029 {
10030 	u8 val8 = 0;
10031 	u16 rxff_bndy = 0;
10032 	u32 rx_dma_buff_sz = 0;
10033 
10034 	val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
10035 	if (val8 != 0)
10036 		RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
10037 			 __func__, (REG_FIFOPAGE + 3));
10038 
10039 	rtw_hal_reset_mac_rx(adapter);
10040 
10041 	if (wow_mode) {
10042 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
10043 				    (u8 *)&rx_dma_buff_sz);
10044 		rxff_bndy = rx_dma_buff_sz - 1;
10045 
10046 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
10047 		RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
10048 			 REG_TRXFF_BNDY + 2,
10049 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
10050 	} else {
10051 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
10052 				    (u8 *)&rx_dma_buff_sz);
10053 		rxff_bndy = rx_dma_buff_sz - 1;
10054 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
10055 		RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
10056 			 REG_TRXFF_BNDY + 2,
10057 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
10058 	}
10059 }
10060 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO*/
10061 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)10062 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
10063 {
10064 	u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
10065 	u16 offset, rx_buf_ptr = 0;
10066 	u16 cam_start_offset = 0;
10067 	u16 ctrl_l = 0, ctrl_h = 0;
10068 	u8 count = 0, tmp = 0;
10069 	int i = 0;
10070 	bool res = _TRUE;
10071 
10072 	if (idx > MAX_WKFM_CAM_NUM) {
10073 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
10074 			 __func__);
10075 		return _FALSE;
10076 	}
10077 
10078 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
10079 			    (u8 *)&rx_dma_buff_sz);
10080 
10081 	if (rx_dma_buff_sz == 0) {
10082 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
10083 		return _FALSE;
10084 	}
10085 
10086 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
10087 
10088 	if (page_sz == 0) {
10089 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
10090 		return _FALSE;
10091 	}
10092 
10093 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
10094 	cam_start_offset = offset * page_sz;
10095 
10096 	ctrl_l = 0x0;
10097 	ctrl_h = 0x0;
10098 
10099 	/* Enable RX packet buffer access */
10100 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
10101 
10102 	/* Read the WKFM CAM */
10103 	for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
10104 		/*
10105 		 * Set Rx packet buffer offset.
10106 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
10107 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
10108 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
10109 		 * * Index: The index of the wake up frame mask
10110 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
10111 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
10112 		 */
10113 		rx_buf_ptr =
10114 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
10115 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
10116 
10117 		rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
10118 		data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
10119 		data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
10120 
10121 		RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
10122 
10123 		count = 0;
10124 
10125 		do {
10126 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
10127 			rtw_udelay_os(2);
10128 			count++;
10129 		} while (!tmp && count < 100);
10130 
10131 		if (count >= 100) {
10132 			RTW_INFO("%s count:%d\n", __func__, count);
10133 			res = _FALSE;
10134 		}
10135 	}
10136 
10137 	/* Disable RX packet buffer access */
10138 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
10139 		   DISABLE_TRXPKT_BUF_ACCESS);
10140 	return res;
10141 }
10142 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)10143 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
10144 			     struct  rtl_wow_pattern *context)
10145 {
10146 	u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
10147 	u16 offset, rx_buf_ptr = 0;
10148 	u16 cam_start_offset = 0;
10149 	u16 ctrl_l = 0, ctrl_h = 0;
10150 	u8 count = 0, tmp = 0;
10151 	int res = 0, i = 0;
10152 
10153 	if (idx > MAX_WKFM_CAM_NUM) {
10154 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
10155 			 __func__);
10156 		return _FALSE;
10157 	}
10158 
10159 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
10160 			    (u8 *)&rx_dma_buff_sz);
10161 
10162 	if (rx_dma_buff_sz == 0) {
10163 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
10164 		return _FALSE;
10165 	}
10166 
10167 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
10168 
10169 	if (page_sz == 0) {
10170 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
10171 		return _FALSE;
10172 	}
10173 
10174 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
10175 
10176 	cam_start_offset = offset * page_sz;
10177 
10178 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
10179 		ctrl_l = 0x0001;
10180 		ctrl_h = 0x0001;
10181 	} else {
10182 		ctrl_l = 0x0f01;
10183 		ctrl_h = 0xf001;
10184 	}
10185 
10186 	/* Enable RX packet buffer access */
10187 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
10188 
10189 	/* Write the WKFM CAM */
10190 	for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
10191 		/*
10192 		 * Set Rx packet buffer offset.
10193 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
10194 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
10195 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
10196 		 * * Index: The index of the wake up frame mask
10197 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
10198 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
10199 		 */
10200 		rx_buf_ptr =
10201 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
10202 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
10203 
10204 		if (i == 0) {
10205 			if (context->type == PATTERN_VALID)
10206 				data = WOW_VALID_BIT;
10207 			else if (context->type == PATTERN_BROADCAST)
10208 				data = WOW_VALID_BIT | WOW_BC_BIT;
10209 			else if (context->type == PATTERN_MULTICAST)
10210 				data = WOW_VALID_BIT | WOW_MC_BIT;
10211 			else if (context->type == PATTERN_UNICAST)
10212 				data = WOW_VALID_BIT | WOW_UC_BIT;
10213 
10214 			if (context->crc != 0)
10215 				data |= context->crc;
10216 
10217 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
10218 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
10219 		} else if (i == 1) {
10220 			data = 0;
10221 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
10222 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
10223 		} else if (i == 2 || i == 4) {
10224 			data = context->mask[i - 2];
10225 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
10226 			/* write to RX packet buffer*/
10227 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
10228 		} else if (i == 3 || i == 5) {
10229 			data = context->mask[i - 2];
10230 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
10231 			/* write to RX packet buffer*/
10232 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
10233 		}
10234 
10235 		count = 0;
10236 		do {
10237 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
10238 			rtw_udelay_os(2);
10239 			count++;
10240 		} while (tmp && count < 100);
10241 
10242 		if (count >= 100)
10243 			res = _FALSE;
10244 		else
10245 			res = _TRUE;
10246 	}
10247 
10248 	/* Disable RX packet buffer access */
10249 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
10250 		   DISABLE_TRXPKT_BUF_ACCESS);
10251 
10252 	return res;
10253 }
10254 #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)10255 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
10256 {
10257 	u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
10258 	u16 tx_page_start, tx_buf_ptr = 0;
10259 	u16 cam_start_offset = 0;
10260 	u16 ctrl_l = 0, ctrl_h = 0;
10261 	u8 count = 0, tmp = 0, last_entry = 0;
10262 	int i = 0;
10263 	bool res = _TRUE;
10264 
10265 	if (idx > MAX_WKFM_CAM_NUM) {
10266 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
10267 			 __func__);
10268 		return _FALSE;
10269 	}
10270 
10271 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
10272 	if (page_sz == 0) {
10273 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
10274 		return _FALSE;
10275 	}
10276 
10277 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
10278 	if (last_entry == 0) {
10279 		RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
10280 		return _FALSE;
10281 	}
10282 
10283 	/* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
10284 	tx_page_start = last_entry - 1;
10285 	cam_start_offset = tx_page_start * page_sz / 8;
10286 	ctrl_l = 0x0;
10287 	ctrl_h = 0x0;
10288 
10289 	/* Enable TX packet buffer access */
10290 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
10291 
10292 	/* Read the WKFM CAM */
10293 	for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
10294 		/*
10295 		 * Set Tx packet buffer offset.
10296 		 * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer.
10297 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
10298 		 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
10299 		 * * Index: The index of the wake up frame mask
10300 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
10301 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
10302 		 */
10303 		tx_buf_ptr =
10304 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
10305 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr);
10306 		rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
10307 		data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
10308 		data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
10309 
10310 		RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
10311 
10312 		count = 0;
10313 
10314 		do {
10315 			tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
10316 			rtw_udelay_os(2);
10317 			count++;
10318 		} while (!tmp && count < 100);
10319 
10320 		if (count >= 100) {
10321 			RTW_INFO("%s count:%d\n", __func__, count);
10322 			res = _FALSE;
10323 		}
10324 	}
10325 
10326 	/* Disable RX packet buffer access */
10327 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
10328 		   DISABLE_TRXPKT_BUF_ACCESS);
10329 	return res;
10330 }
10331 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)10332 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
10333 			     struct  rtl_wow_pattern *context)
10334 {
10335 	u32 tx_page_start = 0, page_sz = 0;
10336 	u16 tx_buf_ptr = 0;
10337 	u16 cam_start_offset = 0;
10338 	u32 data_l = 0, data_h = 0;
10339 	u8 count = 0, tmp = 0, last_entry = 0;
10340 	int res = 0, i = 0;
10341 
10342 	if (idx > MAX_WKFM_CAM_NUM) {
10343 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
10344 			 __func__);
10345 		return _FALSE;
10346 	}
10347 
10348 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
10349 	if (page_sz == 0) {
10350 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
10351 		return _FALSE;
10352 	}
10353 
10354 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
10355 	if (last_entry == 0) {
10356 		RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
10357 		return _FALSE;
10358 	}
10359 
10360 	/* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
10361 	tx_page_start = last_entry - 1;
10362 	cam_start_offset = tx_page_start * page_sz / 8;
10363 
10364 	/* Write the PATTERN location to BIT_TXBUF_WKCAM_OFFSET */
10365 	rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET, cam_start_offset & 0xFF);
10366 	rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET + 1, (cam_start_offset >> 8) & 0xFF);
10367 	/* Enable TX packet buffer access */
10368 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
10369 
10370 	/* Write the WKFM CAM */
10371 	for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
10372 		/*
10373 		 * Set Tx packet buffer offset.
10374 		 * TxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
10375 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
10376 		 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
10377 		 * * Index: The index of the wake up frame mask
10378 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
10379 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
10380 		 */
10381 		tx_buf_ptr = cam_start_offset + ((idx * WKFMCAM_SIZE + i * 8) >> 3);
10382 
10383 		if (i == 0) {
10384 			if (context->type == PATTERN_VALID)
10385 				data_l = WOW_VALID_BIT;
10386 			else if (context->type == PATTERN_BROADCAST)
10387 				data_l = WOW_VALID_BIT | WOW_BC_BIT;
10388 			else if (context->type == PATTERN_MULTICAST)
10389 				data_l = WOW_VALID_BIT | WOW_MC_BIT;
10390 			else if (context->type == PATTERN_UNICAST)
10391 				data_l = WOW_VALID_BIT | WOW_UC_BIT;
10392 
10393 			if (context->crc != 0)
10394 				data_l |= context->crc;
10395 
10396 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
10397 		} else {
10398 			data_l = context->mask[i * 2 - 2];
10399 			data_h = context->mask[i * 2 - 1];
10400 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
10401 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h);
10402 		}
10403 
10404 		rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0x1FFF) | BIT23 | (0xff <<24));
10405 		count = 0;
10406 		do {
10407 			tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
10408 			rtw_udelay_os(2);
10409 			count++;
10410 		} while (tmp && count < 100);
10411 
10412 		if (count >= 100) {
10413 			res = _FALSE;
10414 			RTW_INFO("%s write failed\n", __func__);
10415 		} else {
10416 			res = _TRUE;
10417 			RTW_INFO("%s write OK\n", __func__);
10418 		}
10419 	}
10420 
10421 	/* Disable TX packet buffer access */
10422 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
10423 	return res;
10424 }
10425 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
10426 
rtw_clean_pattern(_adapter * adapter)10427 void rtw_clean_pattern(_adapter *adapter)
10428 {
10429 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10430 	struct rtl_wow_pattern zero_pattern;
10431 	int i = 0;
10432 
10433 	_rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
10434 
10435 	zero_pattern.type = PATTERN_INVALID;
10436 
10437 	for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
10438 		rtw_write_to_frame_mask(adapter, i, &zero_pattern);
10439 
10440 	rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
10441 }
10442 #if 0
10443 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
10444 			       u8 len, u8 *mask, u8 idx)
10445 {
10446 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10447 	struct mlme_ext_priv *pmlmeext = NULL;
10448 	struct mlme_ext_info *pmlmeinfo = NULL;
10449 	struct rtl_wow_pattern wow_pattern;
10450 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
10451 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
10452 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
10453 	u8 multicast_addr1[2] = {0x33, 0x33};
10454 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
10455 	u8 res = _FALSE, index = 0, mask_len = 0;
10456 	u8 mac_addr[ETH_ALEN] = {0};
10457 	u16 count = 0;
10458 	int i, j;
10459 
10460 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
10461 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
10462 			 __func__, MAX_WKFM_CAM_NUM);
10463 		return _FALSE;
10464 	}
10465 
10466 	pmlmeext = &adapter->mlmeextpriv;
10467 	pmlmeinfo = &pmlmeext->mlmext_info;
10468 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
10469 	_rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
10470 
10471 	mask_len = DIV_ROUND_UP(len, 8);
10472 
10473 	/* 1. setup A1 table */
10474 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
10475 		wow_pattern.type = PATTERN_BROADCAST;
10476 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
10477 		wow_pattern.type = PATTERN_MULTICAST;
10478 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
10479 		wow_pattern.type = PATTERN_MULTICAST;
10480 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
10481 		wow_pattern.type = PATTERN_UNICAST;
10482 	else
10483 		wow_pattern.type = PATTERN_INVALID;
10484 
10485 	/* translate mask from os to mask for hw */
10486 
10487 /******************************************************************************
10488  * pattern from OS uses 'ethenet frame', like this:
10489 
10490 	|    6   |    6   |   2  |     20    |  Variable  |  4  |
10491 	|--------+--------+------+-----------+------------+-----|
10492 	|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
10493 	|   DA   |   SA   | Type |
10494 
10495  * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
10496 
10497 	|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
10498 	|-------------------+--------+------+-----------+------------+-----|
10499 	| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
10500 			    | Others | Tpye |
10501 
10502  * Therefore, we need translate mask_from_OS to mask_to_hw.
10503  * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
10504  * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
10505  * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
10506  ******************************************************************************/
10507 	/* Shift 6 bits */
10508 	for (i = 0; i < mask_len - 1; i++) {
10509 		mask_hw[i] = mask[i] >> 6;
10510 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
10511 	}
10512 
10513 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
10514 	/* Set bit 0-5 to zero */
10515 	mask_hw[0] &= 0xC0;
10516 
10517 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
10518 		wow_pattern.mask[i] = mask_hw[i * 4];
10519 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
10520 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
10521 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
10522 	}
10523 
10524 	/* To get the wake up pattern from the mask.
10525 	 * We do not count first 12 bits which means
10526 	 * DA[6] and SA[6] in the pattern to match HW design. */
10527 	count = 0;
10528 	for (i = 12; i < len; i++) {
10529 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
10530 			content[count] = pattern[i];
10531 			count++;
10532 		}
10533 	}
10534 
10535 	wow_pattern.crc = rtw_calc_crc(content, count);
10536 
10537 	if (wow_pattern.crc != 0) {
10538 		if (wow_pattern.type == PATTERN_INVALID)
10539 			wow_pattern.type = PATTERN_VALID;
10540 	}
10541 
10542 	index = idx;
10543 
10544 	if (!pwrctl->bInSuspend)
10545 		index += 2;
10546 
10547 	/* write pattern */
10548 	res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
10549 
10550 	if (res == _FALSE)
10551 		RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
10552 			 __func__, idx);
10553 
10554 	return res;
10555 }
10556 #endif
10557 
rtw_fill_pattern(_adapter * adapter)10558 void rtw_fill_pattern(_adapter *adapter)
10559 {
10560 	int i = 0, total = 0, index;
10561 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10562 	struct rtl_wow_pattern wow_pattern;
10563 
10564 	total = pwrpriv->wowlan_pattern_idx;
10565 
10566 	if (total > MAX_WKFM_CAM_NUM)
10567 		total = MAX_WKFM_CAM_NUM;
10568 
10569 	for (i = 0 ; i < total ; i++) {
10570 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10571 
10572 			index = i;
10573 			if (!pwrpriv->bInSuspend)
10574 				index += 2;
10575 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10576 			if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
10577 				RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
10578 		}
10579 
10580 	}
10581 	rtw_write8(adapter, REG_WKFMCAM_NUM, total);
10582 
10583 }
10584 
10585 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
10586 
10587 #define WOW_CAM_ACCESS_TIMEOUT_MS	200
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)10588 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
10589 {
10590 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10591 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10592 
10593 	u32 rdata = 0;
10594 	u32 cnt = 0;
10595 	systime start = 0;
10596 	u8 timeout = 0;
10597 	u8 rst = _FALSE;
10598 
10599 	_enter_critical_mutex(mutex, NULL);
10600 
10601 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
10602 
10603 	start = rtw_get_current_time();
10604 	while (1) {
10605 		if (rtw_is_surprise_removed(adapter))
10606 			break;
10607 
10608 		cnt++;
10609 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10610 			rst = _SUCCESS;
10611 			break;
10612 		}
10613 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10614 			timeout = 1;
10615 			break;
10616 		}
10617 	}
10618 
10619 	rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
10620 
10621 	_exit_critical_mutex(mutex, NULL);
10622 
10623 	/*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
10624 
10625 	if (timeout)
10626 		RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
10627 
10628 	return rdata;
10629 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10630 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
10631 {
10632 	int i;
10633 	u32 rdata;
10634 
10635 	_rtw_memset(context, 0, sizeof(struct  rtl_wow_pattern));
10636 
10637 	for (i = 4; i >= 0; i--) {
10638 		rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
10639 
10640 		switch (i) {
10641 		case 4:
10642 			if (rdata & WOW_BC_BIT)
10643 				context->type = PATTERN_BROADCAST;
10644 			else if (rdata & WOW_MC_BIT)
10645 				context->type = PATTERN_MULTICAST;
10646 			else if (rdata & WOW_UC_BIT)
10647 				context->type = PATTERN_UNICAST;
10648 			else
10649 				context->type = PATTERN_INVALID;
10650 
10651 			context->crc = rdata & 0xFFFF;
10652 			break;
10653 		default:
10654 			_rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
10655 			break;
10656 		}
10657 	}
10658 }
10659 
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)10660 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
10661 {
10662 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10663 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10664 	u32 cnt = 0;
10665 	systime start = 0, end = 0;
10666 	u8 timeout = 0;
10667 
10668 	/*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
10669 	_enter_critical_mutex(mutex, NULL);
10670 
10671 	rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
10672 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
10673 
10674 	start = rtw_get_current_time();
10675 	while (1) {
10676 		if (rtw_is_surprise_removed(adapter))
10677 			break;
10678 
10679 		cnt++;
10680 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
10681 			break;
10682 
10683 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10684 			timeout = 1;
10685 			break;
10686 		}
10687 	}
10688 	end = rtw_get_current_time();
10689 
10690 	_exit_critical_mutex(mutex, NULL);
10691 
10692 	if (timeout) {
10693 		RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
10694 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
10695 	}
10696 }
10697 
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10698 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
10699 {
10700 	int j;
10701 	u8 addr;
10702 	u32 wdata = 0;
10703 
10704 	for (j = 4; j >= 0; j--) {
10705 		switch (j) {
10706 		case 4:
10707 			wdata = context->crc;
10708 
10709 			if (PATTERN_BROADCAST == context->type)
10710 				wdata |= WOW_BC_BIT;
10711 			if (PATTERN_MULTICAST == context->type)
10712 				wdata |= WOW_MC_BIT;
10713 			if (PATTERN_UNICAST == context->type)
10714 				wdata |= WOW_UC_BIT;
10715 			if (PATTERN_INVALID != context->type)
10716 				wdata |= WOW_VALID_BIT;
10717 			break;
10718 		default:
10719 			wdata = context->mask[j];
10720 			break;
10721 		}
10722 
10723 		addr = (id << 3) + j;
10724 
10725 		_rtw_wow_pattern_write_cam(adapter, addr, wdata);
10726 	}
10727 }
10728 
_rtw_wow_pattern_clean_cam(_adapter * adapter)10729 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
10730 {
10731 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10732 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10733 	u32 cnt = 0;
10734 	systime start = 0;
10735 	u8 timeout = 0;
10736 	u8 rst = _FAIL;
10737 
10738 	_enter_critical_mutex(mutex, NULL);
10739 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
10740 
10741 	start = rtw_get_current_time();
10742 	while (1) {
10743 		if (rtw_is_surprise_removed(adapter))
10744 			break;
10745 
10746 		cnt++;
10747 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10748 			rst = _SUCCESS;
10749 			break;
10750 		}
10751 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10752 			timeout = 1;
10753 			break;
10754 		}
10755 	}
10756 	_exit_critical_mutex(mutex, NULL);
10757 
10758 	if (timeout)
10759 		RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
10760 
10761 	return rst;
10762 }
10763 
rtw_clean_pattern(_adapter * adapter)10764 void rtw_clean_pattern(_adapter *adapter)
10765 {
10766 	if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
10767 		RTW_ERR("rtw_clean_pattern failed\n");
10768 }
rtw_fill_pattern(_adapter * adapter)10769 void rtw_fill_pattern(_adapter *adapter)
10770 {
10771 	int i = 0, total = 0;
10772 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10773 	struct rtl_wow_pattern wow_pattern;
10774 
10775 	total = pwrpriv->wowlan_pattern_idx;
10776 
10777 	if (total > MAX_WKFM_CAM_NUM)
10778 		total = MAX_WKFM_CAM_NUM;
10779 
10780 	for (i = 0 ; i < total ; i++) {
10781 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10782 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10783 			rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
10784 		}
10785 	}
10786 }
10787 
10788 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)10789 void rtw_wow_pattern_cam_dump(_adapter *adapter)
10790 {
10791 
10792 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10793 	int i;
10794 
10795 	for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10796 		RTW_INFO("=======[%d]=======\n", i);
10797 		rtw_read_from_frame_mask(adapter, i);
10798 	}
10799 #else
10800 	struct  rtl_wow_pattern context;
10801 	int i;
10802 
10803 	for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10804 		rtw_wow_pattern_read_cam_ent(adapter, i, &context);
10805 		rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
10806 	}
10807 
10808 #endif
10809 }
10810 
10811 
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)10812 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
10813 {
10814 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10815 
10816 	switch (mode) {
10817 	case 0:
10818 		rtw_clean_pattern(adapter);
10819 		RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
10820 		break;
10821 	case 1:
10822 		rtw_set_default_pattern(adapter);
10823 		rtw_fill_pattern(adapter);
10824 		RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
10825 		break;
10826 	case 2:
10827 		rtw_clean_pattern(adapter);
10828 		rtw_wow_pattern_sw_reset(adapter);
10829 		RTW_INFO("%s: clean patterns\n", __func__);
10830 		break;
10831 	default:
10832 		RTW_INFO("%s: unknown mode\n", __func__);
10833 		break;
10834 	}
10835 }
10836 
rtw_hal_wow_enable(_adapter * adapter)10837 static void rtw_hal_wow_enable(_adapter *adapter)
10838 {
10839 	struct registry_priv  *registry_par = &adapter->registrypriv;
10840 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10841 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10842 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10843 	struct sta_info *psta = NULL;
10844 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
10845 	int res;
10846 	u16 media_status_rpt;
10847 	u8 no_wake = 0, i;
10848 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10849 	_adapter *iface;
10850 #ifdef CONFIG_GPIO_WAKEUP
10851 	u8 val8 = 0;
10852 #endif
10853 
10854 #ifdef CONFIG_LPS_PG
10855 	u8 lps_pg_hdl_id = 0;
10856 #endif
10857 
10858 
10859 
10860 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
10861 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
10862 		no_wake = 1;
10863 
10864 	RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
10865 	rtw_hal_gate_bb(adapter, _TRUE);
10866 
10867 	for (i = 0; i < dvobj->iface_nums; i++) {
10868 		iface = dvobj->padapters[i];
10869 		/* Start Usb TxDMA */
10870 		if(iface) {
10871 			RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface));
10872 			RTW_ENABLE_FUNC(iface, DF_TX_BIT);
10873 		}
10874 	}
10875 
10876 #ifdef CONFIG_GTK_OL
10877 	if (psecuritypriv->binstallKCK_KEK == _TRUE)
10878 		rtw_hal_fw_sync_cam_id(adapter);
10879 #endif
10880 	if (IS_HARDWARE_TYPE_8723B(adapter))
10881 		rtw_hal_backup_rate(adapter);
10882 
10883 	rtw_hal_fw_dl(adapter, _TRUE);
10884 	if(no_wake)
10885 		media_status_rpt = RT_MEDIA_DISCONNECT;
10886 	else
10887 		media_status_rpt = RT_MEDIA_CONNECT;
10888 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10889 			  (u8 *)&media_status_rpt);
10890 
10891 	/* RX DMA stop */
10892 	#if defined(CONFIG_RTL8188E)
10893 	if (IS_HARDWARE_TYPE_8188E(adapter))
10894 		rtw_hal_disable_tx_report(adapter);
10895 	#endif
10896 
10897 	res = rtw_hal_pause_rx_dma(adapter);
10898 	if (res == _FAIL)
10899 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
10900 
10901 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
10902 	/* Reconfig RX_FF Boundary */
10903 	#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10904 	rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
10905 	#endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10906 	#endif
10907 
10908 	/* redownload wow pattern */
10909 	if(!no_wake)
10910 		rtw_hal_dl_pattern(adapter, 1);
10911 
10912 	if (!pwrctl->wowlan_pno_enable) {
10913 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10914 
10915 		if (psta != NULL) {
10916 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10917 			adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10918 			adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10919 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10920 			#endif
10921 			if(!no_wake)
10922 				rtw_sta_media_status_rpt(adapter, psta, 1);
10923 		}
10924 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10925 		else {
10926 			if(registry_par->suspend_type == FW_IPS_WRC) {
10927 				adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10928 				adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10929 				rtw_hal_set_default_port_id_cmd(adapter, 0);
10930 			}
10931 		}
10932 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10933 	}
10934 
10935 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10936 	/* Enable CPWM2 only. */
10937 	res = rtw_hal_enable_cpwm2(adapter);
10938 	if (res == _FAIL)
10939 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
10940 #endif
10941 #ifdef CONFIG_GPIO_WAKEUP
10942 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10943 	rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10944 	rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10945 #else
10946 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10947 	if (pwrctl->is_high_active == 0)
10948 		rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10949 	else
10950 		rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10951 			GPIO_OUTPUT_LOW);
10952 #else
10953 	val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10954 	rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8);
10955 	rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10956 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n",
10957 		 __func__, pwrctl->wowlan_gpio_index,
10958 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10959 		 pwrctl->is_high_active ? "HIGI" : "LOW");
10960 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10961 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10962 #endif /* CONFIG_GPIO_WAKEUP */
10963 	/* Set WOWLAN H2C command. */
10964 	RTW_PRINT("Set WOWLan cmd\n");
10965 	rtw_hal_set_fw_wow_related_cmd(adapter, 1);
10966 
10967 	res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
10968 
10969 	if (res == _FALSE)
10970 		RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
10971 
10972 	pwrctl->wowlan_wake_reason =
10973 		rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10974 
10975 	RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
10976 		  pwrctl->wowlan_wake_reason);
10977 #ifdef CONFIG_GTK_OL_DBG
10978 	dump_sec_cam(RTW_DBGDUMP, adapter);
10979 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
10980 #endif
10981 
10982 #ifdef CONFIG_LPS_PG
10983 	if (pwrctl->lps_level == LPS_PG) {
10984 		lps_pg_hdl_id = LPS_PG_INFO_CFG;
10985 		rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
10986 	}
10987 #endif
10988 
10989 #ifdef CONFIG_USB_HCI
10990 	/* free adapter's resource */
10991 	rtw_mi_intf_stop(adapter);
10992 
10993 #endif
10994 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
10995 	/* Invoid SE0 reset signal during suspending*/
10996 	rtw_write8(adapter, REG_RSV_CTRL, 0x20);
10997 	if (IS_8188F(pHalData->version_id) == FALSE
10998 		&& IS_8188GTV(pHalData->version_id) == FALSE)
10999 		rtw_write8(adapter, REG_RSV_CTRL, 0x60);
11000 #endif
11001 
11002 	rtw_hal_gate_bb(adapter, _FALSE);
11003 }
11004 
11005 #define DBG_WAKEUP_REASON
11006 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)11007 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
11008 {
11009 	RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
11010 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)11011 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
11012 {
11013 	if (RX_PAIRWISEKEY == reason)
11014 		_dbg_wake_up_reason_string(adapter, "Rx pairwise key");
11015 	else if (RX_GTK == reason)
11016 		_dbg_wake_up_reason_string(adapter, "Rx GTK");
11017 	else if (RX_FOURWAY_HANDSHAKE == reason)
11018 		_dbg_wake_up_reason_string(adapter, "Rx four way handshake");
11019 	else if (RX_DISASSOC == reason)
11020 		_dbg_wake_up_reason_string(adapter, "Rx disassoc");
11021 	else if (RX_DEAUTH == reason)
11022 		_dbg_wake_up_reason_string(adapter, "Rx deauth");
11023 	else if (RX_ARP_REQUEST == reason)
11024 		_dbg_wake_up_reason_string(adapter, "Rx ARP request");
11025 	else if (FW_DECISION_DISCONNECT == reason)
11026 		_dbg_wake_up_reason_string(adapter, "FW detect disconnect");
11027 	else if (RX_MAGIC_PKT == reason)
11028 		_dbg_wake_up_reason_string(adapter, "Rx magic packet");
11029 	else if (RX_UNICAST_PKT == reason)
11030 		_dbg_wake_up_reason_string(adapter, "Rx unicast packet");
11031 	else if (RX_PATTERN_PKT == reason)
11032 		_dbg_wake_up_reason_string(adapter, "Rx pattern packet");
11033 	else if (RTD3_SSID_MATCH == reason)
11034 		_dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
11035 	else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
11036 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
11037 	else if (RX_REALWOW_V2_ACK_LOST == reason)
11038 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
11039 	else if (ENABLE_FAIL_DMA_IDLE == reason)
11040 		_dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
11041 	else if (ENABLE_FAIL_DMA_PAUSE == reason)
11042 		_dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
11043 	else if (AP_OFFLOAD_WAKEUP == reason)
11044 		_dbg_wake_up_reason_string(adapter, "AP offload wakeup");
11045 	else if (CLK_32K_UNLOCK == reason)
11046 		_dbg_wake_up_reason_string(adapter, "clk 32k unlock");
11047 	else if (RTIME_FAIL_DMA_IDLE == reason)
11048 		_dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
11049 	else if (CLK_32K_LOCK == reason)
11050 		_dbg_wake_up_reason_string(adapter, "clk 32k lock");
11051 	#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
11052 	else if (WOW_KEEPALIVE_ACK_TIMEOUT == reason)
11053 		_dbg_wake_up_reason_string(adapter, "rx keep alive ack timeout");
11054 	else if (WOW_KEEPALIVE_WAKE == reason)
11055 		_dbg_wake_up_reason_string(adapter, "rx keep alive wake pattern");
11056 	#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
11057 	else
11058 		_dbg_wake_up_reason_string(adapter, "unknown reasoen");
11059 }
11060 #endif
11061 
rtw_hal_wow_disable(_adapter * adapter)11062 static void rtw_hal_wow_disable(_adapter *adapter)
11063 {
11064 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
11065 	struct security_priv *psecuritypriv = &adapter->securitypriv;
11066 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11067 	struct sta_info *psta = NULL;
11068 	struct registry_priv  *registry_par = &adapter->registrypriv;
11069 	int res;
11070 	u16 media_status_rpt;
11071 
11072 	RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
11073 
11074 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
11075 		RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
11076 		return;
11077 	}
11078 
11079 	if (!pwrctl->wowlan_pno_enable) {
11080 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
11081 		if (psta != NULL)
11082 			rtw_sta_media_status_rpt(adapter, psta, 0);
11083 		else
11084 			RTW_INFO("%s: psta is null\n", __func__);
11085 	}
11086 
11087 	if (0) {
11088 		RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
11089 		RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
11090 		RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
11091 		RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
11092 	}
11093 
11094 	pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
11095 
11096 	RTW_PRINT("wakeup_reason: 0x%02x\n",
11097 		  pwrctl->wowlan_wake_reason);
11098 	#ifdef DBG_WAKEUP_REASON
11099 	_dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
11100 	#endif
11101 
11102 	rtw_hal_set_fw_wow_related_cmd(adapter, 0);
11103 
11104 	res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
11105 
11106 	#if defined(CONFIG_RTL8188E)
11107 	if (IS_HARDWARE_TYPE_8188E(adapter))
11108 		rtw_hal_enable_tx_report(adapter);
11109 	#endif
11110 
11111 	if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
11112 		(pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
11113 		(pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
11114 		rtw_hal_get_aoac_rpt(adapter);
11115 		rtw_hal_update_sw_security_info(adapter);
11116 	}
11117 
11118 	if (res == _FALSE) {
11119 		RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
11120 		rtw_hal_force_enable_rxdma(adapter);
11121 	}
11122 
11123 	rtw_hal_gate_bb(adapter, _TRUE);
11124 
11125 	res = rtw_hal_pause_rx_dma(adapter);
11126 	if (res == _FAIL)
11127 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
11128 
11129 	/* clean HW pattern match */
11130 	rtw_hal_dl_pattern(adapter, 0);
11131 
11132 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
11133 	/* config RXFF boundary to original */
11134 	#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
11135 	rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
11136 	#endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
11137 	#endif
11138 	rtw_hal_release_rx_dma(adapter);
11139 
11140 	rtw_hal_fw_dl(adapter, _FALSE);
11141 
11142 #ifdef CONFIG_GPIO_WAKEUP
11143 
11144 #ifdef CONFIG_RTW_ONE_PIN_GPIO
11145 	rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
11146 #else
11147 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
11148 	if (pwrctl->is_high_active == 0)
11149 		rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
11150 	else
11151 		rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
11152 			GPIO_OUTPUT_LOW);
11153 #else
11154 	rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index
11155 		, pwrctl->wowlan_gpio_output_state);
11156 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n",
11157 		 __func__, pwrctl->wowlan_gpio_index,
11158 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
11159 		 pwrctl->is_high_active ? "HIGI" : "LOW");
11160 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
11161 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
11162 #endif /* CONFIG_GPIO_WAKEUP */
11163 	if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
11164 	    (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
11165 	    (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
11166 	    (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
11167 
11168 		media_status_rpt = RT_MEDIA_CONNECT;
11169 		rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
11170 				  (u8 *)&media_status_rpt);
11171 
11172 		if (psta != NULL) {
11173 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
11174 			adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
11175 			adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
11176 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
11177 			#endif
11178 			rtw_sta_media_status_rpt(adapter, psta, 1);
11179 		}
11180 	}
11181 	rtw_hal_gate_bb(adapter, _FALSE);
11182 }
11183 #endif /*CONFIG_WOWLAN*/
11184 
11185 #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)11186 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
11187 	      u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
11188 				      RSVDPAGE_LOC *rsvd_page_loc)
11189 {
11190 	u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
11191 	u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
11192 	u8 CurtPktPageNum = 0;
11193 
11194 	/* P2P Beacon */
11195 	rsvd_page_loc->LocP2PBeacon = *page_num;
11196 	rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
11197 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11198 				 P2PBCNLength, _FALSE, _FALSE, _FALSE);
11199 
11200 #if 0
11201 	RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
11202 		__FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
11203 #endif
11204 
11205 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
11206 
11207 	*page_num += CurtPktPageNum;
11208 
11209 	index += (CurtPktPageNum * page_size);
11210 	RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
11211 
11212 	/* P2P Probe rsp */
11213 	rsvd_page_loc->LocP2PProbeRsp = *page_num;
11214 	rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
11215 				      &P2PProbeRspLength);
11216 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11217 				 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
11218 
11219 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",  */
11220 	/*	__FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
11221 
11222 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
11223 
11224 	*page_num += CurtPktPageNum;
11225 
11226 	index += (CurtPktPageNum * page_size);
11227 	RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
11228 
11229 	/* P2P nego rsp */
11230 	rsvd_page_loc->LocNegoRsp = *page_num;
11231 	rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
11232 				     &P2PNegoRspLength);
11233 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11234 				 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
11235 
11236 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
11237 	/*	__FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
11238 
11239 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
11240 
11241 	*page_num += CurtPktPageNum;
11242 
11243 	index += (CurtPktPageNum * page_size);
11244 	RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
11245 
11246 	/* P2P invite rsp */
11247 	rsvd_page_loc->LocInviteRsp = *page_num;
11248 	rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
11249 				       &P2PInviteRspLength);
11250 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11251 				 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
11252 
11253 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
11254 	/* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
11255 
11256 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
11257 
11258 	*page_num += CurtPktPageNum;
11259 
11260 	index += (CurtPktPageNum * page_size);
11261 	RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
11262 
11263 	/* P2P provision discovery rsp */
11264 	rsvd_page_loc->LocPDRsp = *page_num;
11265 	rtw_hal_construct_P2PProvisionDisRsp(adapter,
11266 					     &pframe[index], &P2PPDRspLength);
11267 
11268 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11269 				 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
11270 
11271 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
11272 	/*	__FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
11273 
11274 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
11275 
11276 	*page_num += CurtPktPageNum;
11277 
11278 	*total_pkt_len = index + P2PPDRspLength;
11279 	RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
11280 
11281 	index += (CurtPktPageNum * page_size);
11282 
11283 
11284 }
11285 #endif /* CONFIG_P2P_WOWLAN */
11286 
11287 #ifdef CONFIG_LPS_PG
11288 #ifndef DBG_LPSPG_INFO_DUMP
11289 #define DBG_LPSPG_INFO_DUMP 1
11290 #endif
11291 
11292 #include "hal_halmac.h"
11293 
11294 #ifdef CONFIG_RTL8822C
rtw_lps_pg_set_dpk_info_rsvd_page(_adapter * adapter)11295 static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
11296 {
11297 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11298 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11299 	struct dm_struct *dm = adapter_to_phydm(adapter);
11300 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
11301 	u8 *info = NULL;
11302 	u32 info_len;
11303 	int ret = _FAIL;
11304 
11305 	/* get length */
11306 	halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
11307 	if (!info_len) {
11308 		RTW_ERR("get %s length fail\n", cache->name);
11309 		goto exit;
11310 	}
11311 
11312 	/* allocate buf */
11313 	info = rtw_zmalloc(info_len);
11314 	if (!info) {
11315 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11316 		goto exit;
11317 	}
11318 
11319 	/* get content */
11320 	halrf_dpk_info_rsvd_page(dm, info, NULL);
11321 
11322 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
11323 
11324 		#if (DBG_LPSPG_INFO_DUMP >= 1)
11325 		RTW_INFO_DUMP(cache->name, info, info_len);
11326 		#endif
11327 
11328 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11329 		ret = !ret ? _SUCCESS : _FAIL;
11330 		if (ret != _SUCCESS) {
11331 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11332 			goto free_mem;
11333 		}
11334 
11335 		#if (DBG_LPSPG_INFO_DUMP >= 2)
11336 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11337 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11338 		#endif
11339 	}
11340 
11341 free_mem:
11342 	rtw_mfree(info, info_len);
11343 
11344 exit:
11345 	return ret;
11346 }
11347 
rtw_lps_pg_set_iqk_info_rsvd_page(_adapter * adapter)11348 static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
11349 {
11350 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11351 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11352 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11353 	struct dm_struct *dm = adapter_to_phydm(adapter);
11354 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
11355 	u8 *info = NULL;
11356 	u32 info_len = 0;
11357 	int ret = _FAIL;
11358 
11359 	if (hal_data->RegIQKFWOffload) {
11360 		rsvd_page_cache_free_data(cache);
11361 		ret = _SUCCESS;
11362 		goto exit;
11363 	}
11364 
11365 	/* get length */
11366 	halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
11367 	if (!info_len) {
11368 		RTW_ERR("get %s length fail\n", cache->name);
11369 		goto exit;
11370 	}
11371 
11372 	/* allocate buf */
11373 	info = rtw_zmalloc(info_len);
11374 	if (!info) {
11375 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11376 		goto exit;
11377 	}
11378 
11379 	/* get content */
11380 	halrf_iqk_info_rsvd_page(dm, info, NULL);
11381 
11382 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
11383 
11384 		#if (DBG_LPSPG_INFO_DUMP >= 1)
11385 		RTW_INFO_DUMP(cache->name, info, info_len);
11386 		#endif
11387 
11388 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11389 		ret = !ret ? _SUCCESS : _FAIL;
11390 		if (ret != _SUCCESS) {
11391 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11392 			goto free_mem;
11393 		}
11394 
11395 		#if (DBG_LPSPG_INFO_DUMP >= 2)
11396 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11397 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11398 		#endif
11399 	}
11400 
11401 free_mem:
11402 	rtw_mfree(info, info_len);
11403 
11404 exit:
11405 	return ret;
11406 }
11407 #endif /* CONFIG_RTL8822C */
11408 
rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv * dvobj,_adapter * ld_sta_iface,u8 * buf,u32 * buf_size)11409 static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size)
11410 {
11411 #define LPS_PG_INFO_RSVD_LEN	16
11412 
11413 	if (buf) {
11414 		_adapter *adapter = dvobj_get_primary_adapter(dvobj);
11415 		struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11416 		struct sta_info *psta;
11417 #ifdef CONFIG_MBSSID_CAM
11418 		u8 cam_id = INVALID_CAM_ID;
11419 #endif
11420 		u8 *psec_cam_id = buf + 8;
11421 		u8 sec_cam_num = 0;
11422 		u8 drv_rsvdpage_num = 0;
11423 
11424 		if (ld_sta_iface) {
11425 			psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv));
11426 			if (!psta) {
11427 				RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
11428 				rtw_warn_on(1);
11429 				goto size_chk;
11430 			}
11431 			/*Byte 0 - used macid*/
11432 			LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
11433 			RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
11434 		}
11435 
11436 #ifdef CONFIG_MBSSID_CAM
11437 		/*Byte 1 - used BSSID CAM entry*/
11438 		cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
11439 		if (cam_id != INVALID_CAM_ID)
11440 			LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
11441 		RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
11442 #endif
11443 
11444 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
11445 		/*Btye 2 - Max used Pattern Match CAM entry*/
11446 		if (pwrpriv->wowlan_mode == _TRUE
11447 			&& ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11448 			LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
11449 			RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
11450 		}
11451 #endif
11452 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
11453 		/*Btye 3 - Max MU rate table Group ID*/
11454 		LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
11455 		RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
11456 #endif
11457 
11458 		/*Btye 8 ~15 - used Security CAM entry */
11459 		sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
11460 
11461 		/*Btye 4 - used Security CAM entry number*/
11462 		if (sec_cam_num < 8)
11463 			LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
11464 		RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
11465 
11466 		/*Btye 5 - Txbuf used page number for fw offload*/
11467 		if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
11468 			drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11469 		else
11470 			drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11471 		LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
11472 		RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
11473 	}
11474 
11475 size_chk:
11476 	if (buf_size)
11477 		*buf_size = LPS_PG_INFO_RSVD_LEN;
11478 }
11479 
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)11480 static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
11481 {
11482 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11483 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11484 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
11485 	u8 *info = NULL;
11486 	u32 info_len = 0;
11487 	int ret = _FAIL;
11488 
11489 	/* get length */
11490 	rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len);
11491 	if (!info_len) {
11492 		RTW_ERR("get %s length fail\n", cache->name);
11493 		goto exit;
11494 	}
11495 
11496 	/* allocate buf */
11497 	info = rtw_zmalloc(info_len);
11498 	if (!info) {
11499 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11500 		goto exit;
11501 	}
11502 
11503 	/* get content */
11504 	rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL);
11505 
11506 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
11507 
11508 		#if (DBG_LPSPG_INFO_DUMP >= 1)
11509 		RTW_INFO_DUMP(cache->name, info, info_len);
11510 		#endif
11511 
11512 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11513 		ret = !ret ? _SUCCESS : _FAIL;
11514 		if (ret != _SUCCESS) {
11515 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11516 			goto free_mem;
11517 		}
11518 
11519 		#if (DBG_LPSPG_INFO_DUMP >= 2)
11520 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11521 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11522 		#endif
11523 	}
11524 
11525 free_mem:
11526 	rtw_mfree(info, info_len);
11527 
11528 exit:
11529 	return ret;
11530 }
11531 
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)11532 static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
11533 	, u8 txdesc_size, u32 page_size, u8 *total_page_num
11534 	, bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num)
11535 {
11536 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11537 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
11538 	struct rsvd_page_cache_t *cache;
11539 	bool rsvd = 1;
11540 	u8 *pos;
11541 	u32 len;
11542 
11543 	if (is_wow_mode) {
11544 		/* lps_level will not change when enter wow_mode */
11545 		if (pwrctl->lps_level != LPS_PG)
11546 			rsvd = 0;
11547 	} else {
11548 		if (!only_get_page_num && !ld_sta_iface)
11549 			rsvd = 0;
11550 	}
11551 
11552 	pos = only_get_page_num ? NULL : frame + *index;
11553 
11554 #ifdef CONFIG_RTL8822C
11555 	if (IS_8822C_SERIES(hal_data->version_id)) {
11556 		/* LPSPG_DPK_INFO */
11557 		cache = &pwrctl->lpspg_dpk_info;
11558 		if (rsvd) {
11559 			if (pwrctl->lps_level != LPS_PG)
11560 				pos = NULL;
11561 			len = 0;
11562 			halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
11563 			#if (DBG_LPSPG_INFO_DUMP >= 1)
11564 			if (pos)
11565 				RTW_INFO_DUMP(cache->name, pos, len);
11566 			#endif
11567 			rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11568 			*total_page_num += cache->page_num;
11569 			*index += page_size * cache->page_num;
11570 			pos = only_get_page_num ? NULL : frame + *index;
11571 			RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11572 		} else
11573 			rsvd_page_cache_free(cache);
11574 
11575 		/* LPSPG_IQK_INFO */
11576 		cache = &pwrctl->lpspg_iqk_info;
11577 		if (rsvd
11578 			/* RegIQKFWOffload will not change when enter wow_mode */
11579 			&& !(is_wow_mode && hal_data->RegIQKFWOffload)
11580 		) {
11581 			if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
11582 				pos = NULL;
11583 			len = 0;
11584 			halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
11585 			#if (DBG_LPSPG_INFO_DUMP >= 1)
11586 			if (pos)
11587 				RTW_INFO_DUMP(cache->name, pos, len);
11588 			#endif
11589 			rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11590 			*total_page_num += cache->page_num;
11591 			*index += page_size * cache->page_num;
11592 			pos = only_get_page_num ? NULL : frame + *index;
11593 			RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11594 		} else
11595 			rsvd_page_cache_free(cache);
11596 	}
11597 #endif
11598 
11599 	/* LPSPG_INFO */
11600 	cache = &pwrctl->lpspg_info;
11601 	if (rsvd) {
11602 		if (pwrctl->lps_level != LPS_PG)
11603 			pos = NULL;
11604 		rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len);
11605 		#if (DBG_LPSPG_INFO_DUMP >= 1)
11606 		if (pos)
11607 			RTW_INFO_DUMP(cache->name, pos, len);
11608 		#endif
11609 		rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11610 		*total_page_num += cache->page_num;
11611 		*index += page_size * cache->page_num;
11612 		pos = only_get_page_num ? NULL : frame + *index;
11613 		RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11614 	} else
11615 		rsvd_page_cache_free(cache);
11616 }
11617 
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)11618 u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
11619 {
11620 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11621 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11622 
11623 	u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
11624 	u8 ret = _FAIL;
11625 
11626 	if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
11627 		SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1);	/*SecurityCAM_En*/
11628 
11629 #ifdef CONFIG_MBSSID_CAM
11630 	SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1);		/*BSSIDCAM_En*/
11631 #endif
11632 
11633 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
11634 	if (pwrpriv->wowlan_mode == _TRUE &&
11635 	    check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11636 
11637 		SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1);	/*PatternMatchCAM_En*/
11638 	}
11639 #endif
11640 
11641 #ifdef CONFIG_MACID_SEARCH
11642 	SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1);	/*MACIDSearch_En*/
11643 #endif
11644 
11645 #ifdef CONFIG_TX_SC
11646 	SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1);	/*TXSC_En*/
11647 #endif
11648 
11649 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
11650 	SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1);	/*MURateTable_En*/
11651 #endif
11652 
11653 	SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
11654 
11655 #ifdef CONFIG_RTL8822C
11656 	if (pwrpriv->bFwCurrentInPSMode == _FALSE) {
11657 		SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
11658 		if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11659 			SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
11660 	} else {
11661 		SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0);
11662 		if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11663 			SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0);
11664 	}
11665 #endif
11666 
11667 #if (DBG_LPSPG_INFO_DUMP >= 1)
11668 	RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
11669 #endif
11670 
11671 	ret = rtw_hal_fill_h2c_cmd(adapter,
11672 				   H2C_LPS_PG_INFO,
11673 				   H2C_LPS_PG_INFO_LEN,
11674 				   lpspg_info);
11675 	return ret;
11676 }
rtw_hal_set_lps_pg_info(_adapter * adapter)11677 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
11678 {
11679 	u8 ret = _FAIL;
11680 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11681 
11682 	if (pwrpriv->lpspg_info.loc == 0) {
11683 		RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
11684 		rtw_warn_on(1);
11685 		return ret;
11686 	}
11687 	#ifdef CONFIG_RTL8822C
11688 	rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
11689 	rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
11690 	#endif
11691 	rtw_hal_set_lps_pg_info_rsvd_page(adapter);
11692 
11693 	ret = rtw_hal_set_lps_pg_info_cmd(adapter);
11694 
11695 	return ret;
11696 }
11697 
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)11698 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
11699 {
11700 #if 0
11701 	if (sta->cmn.ra_info.rssi_level >= 4)
11702 		sta->lps_pg_rssi_lv = 3;	/*RSSI High - 1SS_VHT_MCS7*/
11703 	else if (sta->cmn.ra_info.rssi_level >=  2)
11704 		sta->lps_pg_rssi_lv = 2;	/*RSSI Middle - 1SS_VHT_MCS3*/
11705 	else
11706 		sta->lps_pg_rssi_lv = 1;	/*RSSI Lower - Lowest_rate*/
11707 #else
11708 	sta->lps_pg_rssi_lv = 0;
11709 #endif
11710 	RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
11711 		__func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
11712 }
11713 
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)11714 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
11715 {
11716 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
11717 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11718 	struct sta_priv *pstapriv = &adapter->stapriv;
11719 	struct sta_info *sta;
11720 
11721 	sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
11722 
11723 	switch (hdl_id) {
11724 	case LPS_PG_INFO_CFG:
11725 		rtw_hal_set_lps_pg_info(adapter);
11726 		break;
11727 	case LPS_PG_REDLEMEM:
11728 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11729 			break;
11730 
11731 		/*set xmit_block*/
11732 		rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11733 		if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
11734 			rtw_warn_on(1);
11735 		/*clearn xmit_block*/
11736 		rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11737 		break;
11738 	case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
11739 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11740 			break;
11741 
11742 		if (sta)
11743 			rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
11744 		break;
11745 	case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
11746 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11747 			break;
11748 
11749 		if (sta) {
11750 			rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
11751 			rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
11752 			sta->lps_pg_rssi_lv = 0;
11753 		}
11754 		break;
11755 
11756 	default:
11757 		break;
11758 	}
11759 }
11760 
11761 #endif /*CONFIG_LPS_PG*/
11762 
_rtw_mi_assoc_if_num(_adapter * adapter)11763 static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
11764 {
11765 	u8 mi_iface_num = 0;
11766 
11767 	if (0) {
11768 		RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
11769 		RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
11770 		RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11771 		RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
11772 		RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
11773 		/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
11774 		/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
11775 	}
11776 
11777 	mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
11778 		DEV_AP_NUM(adapter_to_dvobj(adapter)) +
11779 		DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11780 	return mi_iface_num;
11781 }
11782 #ifdef CONFIG_CONCURRENT_MODE
_rtw_search_sta_iface(_adapter * adapter)11783 static _adapter *_rtw_search_sta_iface(_adapter *adapter)
11784 {
11785 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11786 	_adapter *iface = NULL;
11787 	_adapter *sta_iface = NULL;
11788 	int i;
11789 
11790 	for (i = 0; i < dvobj->iface_nums; i++) {
11791 		iface = dvobj->padapters[i];
11792 		if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
11793 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11794 				sta_iface = iface;
11795 				break;
11796 			}
11797 		}
11798 	}
11799 	return sta_iface;
11800 }
11801 #if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
_rtw_search_ap_iface(_adapter * adapter)11802 static _adapter *_rtw_search_ap_iface(_adapter *adapter)
11803 {
11804 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11805 	_adapter *iface = NULL;
11806 	_adapter *ap_iface = NULL;
11807 	int i;
11808 
11809 	for (i = 0; i < dvobj->iface_nums; i++) {
11810 		iface = dvobj->padapters[i];
11811 		if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
11812 			ap_iface = iface;
11813 			break;
11814 		}
11815 	}
11816 	return ap_iface;
11817 }
11818 #endif/*CONFIG_AP_MODE*/
11819 #endif/*CONFIG_CONCURRENT_MODE*/
11820 
11821 #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
rtw_hal_set_pathb_phase(_adapter * adapter,u8 phase_idx)11822 void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
11823 {
11824 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(adapter);
11825 	struct PHY_DM_STRUCT		*pDM_Odm = &pHalData->odmpriv;
11826 
11827 	return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
11828 }
11829 #endif
11830 
11831 /*
11832  * Description: Fill the reserved packets that FW will use to RSVD page.
11833  *			Now we just send 4 types packet to rsvd page.
11834  *			(1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
11835  * Input:
11836  * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
11837  *		    so we need to set the packet length to total lengh.
11838  *	      TRUE: At the second time, we should send the first packet (default:beacon)
11839  *		    to Hw again and set the lengh in descriptor to the real beacon lengh.
11840  * page_num - The amount of reserved page which driver need.
11841  *	      If this is not NULL, this function doesn't real download reserved
11842  *	      page, but just count the number of reserved page.
11843  *
11844  * 2009.10.15 by tynli.
11845  * 2017.06.20 modified by Lucas.
11846  *
11847  * Page Size = 128: 8188e, 8723a/b, 8192c/d,
11848  * Page Size = 256: 8192e, 8821a
11849  * Page Size = 512: 8812a
11850  */
11851 
11852 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)11853 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
11854 {
11855 	PHAL_DATA_TYPE pHalData;
11856 	struct xmit_frame	*pcmdframe = NULL;
11857 	struct pkt_attrib	*pattrib;
11858 	struct xmit_priv	*pxmitpriv;
11859 	struct pwrctrl_priv *pwrctl;
11860 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11861 	u32	BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
11862 	u32	NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
11863 	u32	ProbeReqLength = 0, NullFunctionDataLength = 0;
11864 	u8	TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
11865 	u8	TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
11866 	u8	*ReservedPagePacket;
11867 	u16	BufIndex = 0;
11868 	u32	TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
11869 	RSVDPAGE_LOC	RsvdPageLoc;
11870 	struct registry_priv  *registry_par = &adapter->registrypriv;
11871 
11872 #ifdef DBG_FW_DEBUG_MSG_PKT
11873 	u32	fw_dbg_msg_pkt_len = 0;
11874 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11875 
11876 #ifdef DBG_CONFIG_ERROR_DETECT
11877 	struct sreset_priv *psrtpriv;
11878 #endif /* DBG_CONFIG_ERROR_DETECT */
11879 
11880 #ifdef CONFIG_MCC_MODE
11881 	u8 dl_mcc_page = _FAIL;
11882 #endif /* CONFIG_MCC_MODE */
11883 	u8 nr_assoc_if;
11884 
11885 	_adapter *sta_iface = NULL;
11886 	_adapter *ap_iface = NULL;
11887 
11888 	bool is_wow_mode = _FALSE;
11889 
11890 	pHalData = GET_HAL_DATA(adapter);
11891 #ifdef DBG_CONFIG_ERROR_DETECT
11892 	psrtpriv = &pHalData->srestpriv;
11893 #endif
11894 	pxmitpriv = &adapter->xmitpriv;
11895 	pwrctl = adapter_to_pwrctl(adapter);
11896 
11897 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
11898 
11899 	if (PageSize == 0) {
11900 		RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
11901 		return;
11902 	}
11903 	nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
11904 
11905 	if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
11906 		pwrctl->wowlan_ap_mode == _TRUE ||
11907 		pwrctl->wowlan_p2p_mode == _TRUE)
11908 		is_wow_mode = _TRUE;
11909 
11910 	/*page_num for init time to get rsvd page number*/
11911 	/* Prepare ReservedPagePacket */
11912 	if (page_num) {
11913 		ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
11914 		if (!ReservedPagePacket) {
11915 			RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11916 			*page_num = 0xFF;
11917 			return;
11918 		}
11919 		RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm  ==>\n",
11920 			FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11921 
11922 	} else {
11923 		if (is_wow_mode)
11924 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11925 		else
11926 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11927 
11928 		RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
11929 			FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
11930 
11931 		MaxRsvdPageBufSize = RsvdPageNum * PageSize;
11932 		if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
11933 			RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
11934 				 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
11935 			rtw_warn_on(1);
11936 			return;
11937 		}
11938 
11939 		pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
11940 		if (pcmdframe == NULL) {
11941 			RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11942 			return;
11943 		}
11944 
11945 		ReservedPagePacket = pcmdframe->buf_addr;
11946 	}
11947 
11948 	_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
11949 
11950 	BufIndex = TxDescOffset;
11951 
11952 	/*======== beacon content =======*/
11953 	rtw_hal_construct_beacon(adapter,
11954 				 &ReservedPagePacket[BufIndex], &BeaconLength);
11955 
11956 	/*
11957 	* When we count the first page size, we need to reserve description size for the RSVD
11958 	* packet, it will be filled in front of the packet in TXPKTBUF.
11959 	*/
11960 	BeaconLength = MAX_BEACON_LEN - TxDescLen;
11961 	CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
11962 
11963 #if defined(CONFIG_FW_HANDLE_TXBCN) || defined(CONFIG_PORT_BASED_TXBCN)
11964 	CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
11965 #endif
11966 	TotalPageNum += CurtPktPageNum;
11967 
11968 	BufIndex += (CurtPktPageNum * PageSize);
11969 
11970 	RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11971 
11972 	/*======== probe response content ========*/
11973 	if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
11974 		#ifdef CONFIG_CONCURRENT_MODE
11975 		if (nr_assoc_if >= 2)
11976 			RTW_ERR("Not support > 2 net-interface in WOW\n");
11977 		#endif
11978 		/* (4) probe response*/
11979 		RsvdPageLoc.LocProbeRsp = TotalPageNum;
11980 		rtw_hal_construct_ProbeRsp(
11981 			adapter, &ReservedPagePacket[BufIndex],
11982 			&ProbeRspLength,
11983 			_FALSE);
11984 		rtw_hal_fill_fake_txdesc(adapter,
11985 				 &ReservedPagePacket[BufIndex - TxDescLen],
11986 				 ProbeRspLength, _FALSE, _FALSE, _FALSE);
11987 
11988 		CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
11989 		TotalPageNum += CurtPktPageNum;
11990 		TotalPacketLen = BufIndex + ProbeRspLength;
11991 		BufIndex += (CurtPktPageNum * PageSize);
11992 		RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11993 		goto download_page;
11994 	}
11995 
11996 	/*======== ps-poll content * 1 page ========*/
11997 	sta_iface = adapter;
11998 	#ifdef CONFIG_CONCURRENT_MODE
11999 	if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
12000 		sta_iface = _rtw_search_sta_iface(adapter);
12001 		RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
12002 	}
12003 	#endif
12004 
12005 	if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12006 		RsvdPageLoc.LocPsPoll = TotalPageNum;
12007 		RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
12008 		rtw_hal_construct_PSPoll(sta_iface,
12009 					 &ReservedPagePacket[BufIndex], &PSPollLength);
12010 		rtw_hal_fill_fake_txdesc(sta_iface,
12011 					 &ReservedPagePacket[BufIndex - TxDescLen],
12012 					 PSPollLength, _TRUE, _FALSE, _FALSE);
12013 
12014 		CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
12015 
12016 		TotalPageNum += CurtPktPageNum;
12017 
12018 		BufIndex += (CurtPktPageNum * PageSize);
12019 		RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12020 	}
12021 
12022 #ifdef CONFIG_MCC_MODE
12023 	/*======== MCC * n page ======== */
12024 	if (MCC_EN(adapter)) {/*Normal mode*/
12025 		dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
12026 				&BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
12027 	} else {
12028 		dl_mcc_page = _FAIL;
12029 	}
12030 
12031 	if (dl_mcc_page == _FAIL)
12032 #endif /* CONFIG_MCC_MODE */
12033 	{	/*======== null data * 1 page ======== */
12034 		if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12035 			RsvdPageLoc.LocNullData = TotalPageNum;
12036 			RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
12037 			rtw_hal_construct_NullFunctionData(
12038 				sta_iface,
12039 				&ReservedPagePacket[BufIndex],
12040 				&NullDataLength,
12041 				_FALSE, 0, 0, _FALSE);
12042 			rtw_hal_fill_fake_txdesc(sta_iface,
12043 				 &ReservedPagePacket[BufIndex - TxDescLen],
12044 				 NullDataLength, _FALSE, _FALSE, _FALSE);
12045 
12046 			CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
12047 
12048 			TotalPageNum += CurtPktPageNum;
12049 
12050 			BufIndex += (CurtPktPageNum * PageSize);
12051 			RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12052 		}
12053 	}
12054 
12055 	/*======== Qos null data * 1 page ======== */
12056 	if (pwrctl->wowlan_mode == _FALSE ||
12057 		pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
12058 		if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12059 			RsvdPageLoc.LocQosNull = TotalPageNum;
12060 			RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
12061 			rtw_hal_construct_NullFunctionData(sta_iface,
12062 						&ReservedPagePacket[BufIndex],
12063 						&QosNullLength,
12064 						_TRUE, 0, 0, _FALSE);
12065 			rtw_hal_fill_fake_txdesc(sta_iface,
12066 					 &ReservedPagePacket[BufIndex - TxDescLen],
12067 					 QosNullLength, _FALSE, _FALSE, _FALSE);
12068 
12069 			CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
12070 						     PageSize);
12071 
12072 			TotalPageNum += CurtPktPageNum;
12073 
12074 			BufIndex += (CurtPktPageNum * PageSize);
12075 			RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12076 		}
12077 	}
12078 
12079 #ifdef CONFIG_BT_COEXIST
12080 	/*======== BT Qos null data * 1 page ======== */
12081 	if (pwrctl->wowlan_mode == _FALSE ||
12082 		pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
12083 
12084 		ap_iface = adapter;
12085 		#if defined (CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
12086 		if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) {	/*DEV_AP_STARTING_NUM*/
12087 			ap_iface = _rtw_search_ap_iface(adapter);
12088 			RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
12089 		}
12090 		#endif
12091 
12092 		if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
12093 			RsvdPageLoc.LocBTQosNull = TotalPageNum;
12094 
12095 			RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
12096 
12097 			rtw_hal_construct_NullFunctionData(ap_iface,
12098 						&ReservedPagePacket[BufIndex],
12099 						&BTQosNullLength,
12100 						_TRUE, 0, 0, _FALSE);
12101 
12102 			rtw_hal_fill_fake_txdesc(ap_iface,
12103 					&ReservedPagePacket[BufIndex - TxDescLen],
12104 					BTQosNullLength, _FALSE, _TRUE, _FALSE);
12105 
12106 			CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
12107 							 PageSize);
12108 
12109 			TotalPageNum += CurtPktPageNum;
12110 			BufIndex += (CurtPktPageNum * PageSize);
12111 
12112 			RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12113 		}
12114 	}
12115 #endif /* CONFIG_BT_COEXIT */
12116 
12117 	TotalPacketLen = BufIndex;
12118 
12119 #ifdef DBG_FW_DEBUG_MSG_PKT
12120 		/*======== FW DEBUG MSG * n page ======== */
12121 		RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
12122 		RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
12123 		rtw_hal_construct_fw_dbg_msg_pkt(
12124 			adapter,
12125 			&ReservedPagePacket[BufIndex],
12126 			&fw_dbg_msg_pkt_len);
12127 
12128 		rtw_hal_fill_fake_txdesc(adapter,
12129 				 &ReservedPagePacket[BufIndex - TxDescLen],
12130 				 fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
12131 
12132 		CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
12133 
12134 		if (CurtPktPageNum < 2)
12135 			CurtPktPageNum = 2; /*Need at least 2 rsvd page*/
12136 		TotalPageNum += CurtPktPageNum;
12137 
12138 		TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
12139 		BufIndex += (CurtPktPageNum * PageSize);
12140 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12141 
12142 #ifdef CONFIG_LPS_PG
12143 	rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
12144 		, TxDescLen, PageSize, &TotalPageNum, is_wow_mode
12145 		, (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL
12146 		, page_num ? 1 : 0
12147 	);
12148 	TotalPacketLen = BufIndex;
12149 #endif
12150 
12151 #ifdef CONFIG_WOWLAN
12152 	/*======== WOW * n page ======== */
12153 	if (pwrctl->wowlan_mode == _TRUE &&
12154 		pwrctl->wowlan_in_resume == _FALSE &&
12155 		check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {/*WOW mode*/
12156 		rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
12157 					     BufIndex, TxDescLen, PageSize,
12158 			     &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
12159 #ifdef CONFIG_WAR_OFFLOAD
12160 		rtw_hal_set_war_offload_parm(adapter, &RsvdPageLoc);
12161 #endif /* CONFIG_WAR_OFFLOAD */
12162 	}
12163 #endif /* CONFIG_WOWLAN */
12164 
12165 #ifdef CONFIG_P2P_WOWLAN
12166 	/*======== P2P WOW * n page ======== */
12167 	if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
12168 		rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
12169 						 BufIndex, TxDescLen, PageSize,
12170 				 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
12171 	}
12172 #endif /* CONFIG_P2P_WOWLAN */
12173 
12174 	/*Note:  BufIndex already add a TxDescOffset offset in first Beacon page
12175 	* The "TotalPacketLen" is calculate by BufIndex.
12176 	* We need to decrease TxDescOffset before doing length check. by yiwei
12177 	*/
12178 	TotalPacketLen = TotalPacketLen - TxDescOffset;
12179 
12180 download_page:
12181 	if (page_num) {
12182 		*page_num = TotalPageNum;
12183 		rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
12184 		ReservedPagePacket = NULL;
12185 		RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
12186 			FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
12187 		return;
12188 	}
12189 
12190 	/* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
12191 	RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
12192 		 __func__, TotalPageNum, TotalPacketLen);
12193 
12194 	if (TotalPacketLen > MaxRsvdPageBufSize) {
12195 		RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
12196 			 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
12197 		rtw_warn_on(1);
12198 		goto error;
12199 	} else {
12200 		/* update attribute */
12201 		pattrib = &pcmdframe->attrib;
12202 		update_mgntframe_attrib(adapter, pattrib);
12203 		pattrib->qsel = QSLT_BEACON;
12204 		pattrib->pktlen = TotalPacketLen;
12205 		pattrib->last_txcmdsz = TotalPacketLen;
12206 #ifdef CONFIG_PCI_HCI
12207 		dump_mgntframe(adapter, pcmdframe);
12208 #else
12209 		dump_mgntframe_and_wait(adapter, pcmdframe, 100);
12210 #endif
12211 	}
12212 
12213 	RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
12214 		 __func__, TotalPacketLen, TotalPageNum);
12215 #ifdef DBG_DUMP_SET_RSVD_PAGE
12216 	RTW_INFO(" ==================================================\n");
12217 	RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
12218 	RTW_INFO(" ==================================================\n");
12219 #endif
12220 
12221 
12222 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
12223 		|| MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
12224 		rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
12225 #ifdef DBG_FW_DEBUG_MSG_PKT
12226 		rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
12227 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12228 #ifdef CONFIG_WOWLAN
12229 		if (pwrctl->wowlan_mode == _TRUE &&
12230 			pwrctl->wowlan_in_resume == _FALSE)
12231 			rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
12232 #endif /* CONFIG_WOWLAN */
12233 #ifdef CONFIG_AP_WOWLAN
12234 		if (pwrctl->wowlan_ap_mode == _TRUE)
12235 			rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
12236 #endif /* CONFIG_AP_WOWLAN */
12237 	} else if (pwrctl->wowlan_pno_enable) {
12238 #ifdef CONFIG_PNO_SUPPORT
12239 		rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
12240 		if (pwrctl->wowlan_in_resume)
12241 			rtw_hal_set_scan_offload_info_cmd(adapter,
12242 							  &RsvdPageLoc, 0);
12243 		else
12244 			rtw_hal_set_scan_offload_info_cmd(adapter,
12245 							  &RsvdPageLoc, 1);
12246 #endif /* CONFIG_PNO_SUPPORT */
12247 	}
12248 
12249 #ifdef CONFIG_P2P_WOWLAN
12250 	if (_TRUE == pwrctl->wowlan_p2p_mode)
12251 		rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
12252 #endif /* CONFIG_P2P_WOWLAN */
12253 
12254 	return;
12255 error:
12256 	rtw_free_xmitframe(pxmitpriv, pcmdframe);
12257 }
12258 
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)12259 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
12260 {
12261 #ifdef CONFIG_AP_MODE
12262 	if (finished)
12263 		rtw_mi_tx_beacon_hdl(adapter);
12264 	else
12265 #endif
12266 		_rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
12267 }
12268 
rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER * adapter,u8 enable)12269 static u8 rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER *adapter, u8 enable)
12270 {
12271 	u8	u1H2CSetPwrMode[H2C_PWRMODE_LEN] = {0};
12272 	u8	ret = _FAIL;
12273 
12274 #ifdef CONFIG_TDLS
12275 #ifdef CONFIG_TDLS_CH_SW
12276 	if (ATOMIC_READ(&adapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12277 	{
12278 		SET_H2CCMD_PWRMODE_PARM_RLBM(u1H2CSetPwrMode, 1);
12279 		SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, 0);
12280 	}
12281 #endif
12282 #endif
12283 
12284 	SET_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, 0);
12285 	SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CSetPwrMode, 0x0C);
12286 	SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_C2H_RPT(u1H2CSetPwrMode, enable);
12287 
12288 	ret = rtw_hal_fill_h2c_cmd(adapter,
12289 					H2C_SET_PWR_MODE,
12290 					H2C_PWRMODE_LEN,
12291 					u1H2CSetPwrMode);
12292 
12293 	RTW_PRINT("-%s()-\n", __func__);
12294 
12295 	return ret;
12296 }
12297 
12298 /**
12299  * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
12300  * @adapter:	struct _ADAPTER*
12301  *
12302  * Caculate needed reserved page number.
12303  * In different state would get different number, for example normal mode and
12304  * WOW mode would need different reserved page size.
12305  *
12306  * Return the number of reserved page which driver need.
12307  */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)12308 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
12309 {
12310 	u8 num = 0;
12311 
12312 
12313 	_rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
12314 
12315 	return num;
12316 }
12317 
12318 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
hw_var_set_bcn_func(_adapter * adapter,u8 enable)12319 static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
12320 {
12321 	u32 bcn_ctrl_reg;
12322 
12323 #ifdef CONFIG_CONCURRENT_MODE
12324 	if (adapter->hw_port == HW_PORT1)
12325 		bcn_ctrl_reg = REG_BCN_CTRL_1;
12326 	else
12327 #endif
12328 		bcn_ctrl_reg = REG_BCN_CTRL;
12329 
12330 	if (enable)
12331 		rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
12332 	else {
12333 		u8 val8;
12334 
12335 		val8 = rtw_read8(adapter, bcn_ctrl_reg);
12336 		val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
12337 
12338 #ifdef CONFIG_BT_COEXIST
12339 		if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
12340 			/* Always enable port0 beacon function for PSTDMA */
12341 			if (REG_BCN_CTRL == bcn_ctrl_reg)
12342 				val8 |= EN_BCN_FUNCTION;
12343 		}
12344 #endif
12345 
12346 		rtw_write8(adapter, bcn_ctrl_reg, val8);
12347 	}
12348 
12349 #ifdef CONFIG_RTL8192F
12350 	if (IS_HARDWARE_TYPE_8192F(adapter)) {
12351 		u16 val16, val16_ori;
12352 
12353 		val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
12354 
12355 		#ifdef CONFIG_CONCURRENT_MODE
12356 		if (adapter->hw_port == HW_PORT1) {
12357 			if (enable)
12358 				val16 |= EN_PORT_1_FUNCTION;
12359 			else
12360 				val16 &= ~EN_PORT_1_FUNCTION;
12361 		} else
12362 		#endif
12363 		{
12364 			if (enable)
12365 				val16 |= EN_PORT_0_FUNCTION;
12366 			else
12367 				val16 &= ~EN_PORT_0_FUNCTION;
12368 
12369 			#ifdef CONFIG_BT_COEXIST
12370 			if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
12371 				val16 |= EN_PORT_0_FUNCTION;
12372 			#endif
12373 		}
12374 
12375 		if (val16 != val16_ori)
12376 			rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1,  val16);
12377 	}
12378 #endif
12379 }
12380 #endif
12381 
12382 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
hw_var_set_mlme_disconnect(_adapter * adapter)12383 static void hw_var_set_mlme_disconnect(_adapter *adapter)
12384 {
12385 	u8 val8;
12386 
12387 	/* reject all data frames */
12388 #ifdef CONFIG_CONCURRENT_MODE
12389 	if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
12390 #endif
12391 		rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
12392 
12393 #ifdef CONFIG_CONCURRENT_MODE
12394 	if (adapter->hw_port == HW_PORT1) {
12395 		/* reset TSF1 */
12396 		rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
12397 
12398 		/* disable update TSF1 */
12399 		rtw_iface_disable_tsf_update(adapter);
12400 
12401 		if (!IS_HARDWARE_TYPE_8723D(adapter)
12402 			&& !IS_HARDWARE_TYPE_8192F(adapter)
12403 			&& !IS_HARDWARE_TYPE_8710B(adapter)
12404 		) {
12405 			/* disable Port1's beacon function */
12406 			val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
12407 			val8 &= ~EN_BCN_FUNCTION;
12408 			rtw_write8(adapter, REG_BCN_CTRL_1, val8);
12409 		}
12410 	} else
12411 #endif
12412 	{
12413 		/* reset TSF */
12414 		rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
12415 
12416 		/* disable update TSF */
12417 		rtw_iface_disable_tsf_update(adapter);
12418 	}
12419 }
12420 #endif
12421 
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 enable)12422 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
12423 {
12424 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12425 	u16 value_rxfltmap2;
12426 
12427 #ifdef DBG_IFACE_STATUS
12428 	DBG_IFACE_STATUS_DUMP(adapter);
12429 #endif
12430 
12431 #ifdef CONFIG_FIND_BEST_CHANNEL
12432 	/* Receive all data frames */
12433 	value_rxfltmap2 = 0xFFFF;
12434 #else
12435 	/* not to receive data frame */
12436 	value_rxfltmap2 = 0;
12437 #endif
12438 
12439 	if (enable) { /* under sitesurvey */
12440 		/*
12441 		* 1. configure REG_RXFLTMAP2
12442 		* 2. disable TSF update &  buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
12443 		* 3. config RCR to receive different BSSID BCN or probe rsp
12444 		*/
12445 		rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
12446 
12447 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
12448 
12449 		/* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
12450 		#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
12451 		hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
12452 		hal_data->RegRRSR &= 0x000FFFFF;
12453 		#endif
12454 
12455 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
12456 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
12457 			/* set 718[1:0]=2'b00 to avoid BF scan hang */
12458 			hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
12459 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
12460 		}
12461 		#endif
12462 
12463 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12464 			StopTxBeacon(adapter);
12465 	} else { /* sitesurvey done */
12466 		/*
12467 		* 1. enable rx data frame
12468 		* 2. config RCR not to receive different BSSID BCN or probe rsp
12469 		* 3. doesn't enable TSF update &  buddy TSF right now to avoid HW conflict
12470 		*	 so, we enable TSF update when rx first BCN after sitesurvey done
12471 		*/
12472 		if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) {
12473 			/* enable to rx data frame */
12474 			rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12475 		}
12476 
12477 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
12478 
12479 		/* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
12480 		#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
12481 			rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
12482 		#endif
12483 
12484 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
12485 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
12486 			/* Restore orignal 0x718 setting*/
12487 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
12488 		}
12489 		#endif
12490 
12491 		#ifdef CONFIG_AP_MODE
12492 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12493 			ResumeTxBeacon(adapter);
12494 			rtw_mi_tx_beacon_hdl(adapter);
12495 		}
12496 		#endif
12497 	}
12498 }
12499 
12500 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
hw_var_set_mlme_join(_adapter * adapter,u8 type)12501 static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
12502 {
12503 	u8 val8;
12504 	u16 val16;
12505 	u32 val32;
12506 	u8 RetryLimit = RL_VAL_STA;
12507 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12508 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12509 
12510 #ifdef CONFIG_CONCURRENT_MODE
12511 	if (type == 0) {
12512 		/* prepare to join */
12513 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12514 			StopTxBeacon(adapter);
12515 
12516 		/* enable to rx data frame.Accept all data frame */
12517 		rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12518 
12519 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
12520 			RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
12521 		else /* Ad-hoc Mode */
12522 			RetryLimit = RL_VAL_AP;
12523 
12524 		rtw_iface_enable_tsf_update(adapter);
12525 
12526 	} else if (type == 1) {
12527 		/* joinbss_event call back when join res < 0 */
12528 		if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
12529 			rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
12530 
12531 		rtw_iface_disable_tsf_update(adapter);
12532 
12533 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12534 			ResumeTxBeacon(adapter);
12535 
12536 			/* reset TSF 1/2 after ResumeTxBeacon */
12537 			rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
12538 		}
12539 
12540 	} else if (type == 2) {
12541 		/* sta add event call back */
12542 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
12543 			/* fixed beacon issue for 8191su........... */
12544 			rtw_write8(adapter, 0x542 , 0x02);
12545 			RetryLimit = RL_VAL_AP;
12546 		}
12547 
12548 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12549 			ResumeTxBeacon(adapter);
12550 
12551 			/* reset TSF 1/2 after ResumeTxBeacon */
12552 			rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
12553 		}
12554 	}
12555 
12556 	val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
12557 	rtw_write16(adapter, REG_RETRY_LIMIT, val16);
12558 #else /* !CONFIG_CONCURRENT_MODE */
12559 	if (type == 0) { /* prepare to join */
12560 		/* enable to rx data frame.Accept all data frame */
12561 		rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12562 
12563 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
12564 			RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
12565 		else /* Ad-hoc Mode */
12566 			RetryLimit = RL_VAL_AP;
12567 
12568 		rtw_iface_enable_tsf_update(adapter);
12569 
12570 	} else if (type == 1) { /* joinbss_event call back when join res < 0 */
12571 		rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
12572 
12573 		rtw_iface_disable_tsf_update(adapter);
12574 
12575 	} else if (type == 2) { /* sta add event call back */
12576 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
12577 			RetryLimit = RL_VAL_AP;
12578 	}
12579 
12580 	val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
12581 	rtw_write16(adapter, REG_RETRY_LIMIT, val16);
12582 #endif /* !CONFIG_CONCURRENT_MODE */
12583 }
12584 #endif
12585 
12586 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)12587 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
12588 {
12589 	u8 buf[2];
12590 	int ret;
12591 
12592 	if (reset_port == HW_PORT0) {
12593 		buf[0] = 0x1;
12594 		buf[1] = 0;
12595 	} else {
12596 		buf[0] = 0x0;
12597 		buf[1] = 0x1;
12598 	}
12599 
12600 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
12601 
12602 	return ret;
12603 }
12604 
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)12605 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
12606 {
12607 	u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
12608 	u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
12609 				REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
12610 	int ret;
12611 
12612 	/* site survey will cause reset tsf fail */
12613 	rtw_mi_buddy_scan_abort(adapter, _FALSE);
12614 	reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
12615 	ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
12616 	if (ret != _SUCCESS)
12617 		return ret;
12618 
12619 	while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
12620 		rtw_msleep_os(100);
12621 		loop_cnt++;
12622 		reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
12623 	}
12624 
12625 	return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
12626 }
12627 #endif /* CONFIG_TSF_RESET_OFFLOAD */
12628 
12629 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12630 #ifdef CONFIG_HW_P0_TSF_SYNC
12631 #ifdef CONFIG_CONCURRENT_MODE
hw_port0_tsf_sync_sel(_adapter * adapter,u8 benable,u8 hw_port,u16 tr_offset)12632 static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
12633 {
12634 	u8 val8;
12635 	u8 client_id = 0;
12636 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12637 
12638 #ifdef CONFIG_MCC_MODE
12639 	if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
12640 		RTW_INFO("[MCC] do not set HW TSF sync\n");
12641 		return;
12642 	}
12643 #endif
12644 	/* check if port0 is already synced */
12645 	if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
12646 		RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
12647 			FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
12648 		return;
12649 	}
12650 
12651 	/* check if port0 already disable sync */
12652 	if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
12653 		RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
12654 		return;
12655 	}
12656 
12657 	/* check if port0 sync to port0 */
12658 	if (benable && hw_port == HW_PORT0) {
12659 		RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
12660 		rtw_warn_on(1);
12661 		return;
12662 	}
12663 
12664 	/*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
12665 	/*	Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
12666 		Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
12667 
12668 	val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
12669 
12670 	if (benable) {
12671 		/*Disable Port0's beacon function*/
12672 		rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
12673 
12674 		/*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
12675 		if (tr_offset)
12676 			rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
12677 
12678 		/*reg 0x577[6]=1*/	/*auto sync by tbtt*/
12679 		rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
12680 
12681 		if (HW_PORT1 == hw_port)
12682 			client_id = 0;
12683 		else if (HW_PORT2 == hw_port)
12684 			client_id = 1;
12685 		else if (HW_PORT3 == hw_port)
12686 			client_id = 2;
12687 		else if (HW_PORT4 == hw_port)
12688 			client_id = 3;
12689 
12690 		val8 &= 0x8F;
12691 		val8 |= (BIT(6) | (client_id << 4));
12692 
12693 		dvobj->p0_tsf.sync_port = hw_port;
12694 		dvobj->p0_tsf.offset = tr_offset;
12695 		rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12696 
12697 		/*Enable Port0's beacon function*/
12698 		rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)  | BIT_EN_BCN_FUNCTION);
12699 		RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
12700 	} else {
12701 		val8 &= ~BIT(6);
12702 
12703 		dvobj->p0_tsf.sync_port = MAX_HW_PORT;
12704 		dvobj->p0_tsf.offset = 0;
12705 		rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12706 		RTW_INFO("%s P0 TSF sync disable\n", __func__);
12707 	}
12708 }
_search_ld_sta(_adapter * adapter,u8 include_self)12709 static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
12710 {
12711 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12712 	u8 i;
12713 	_adapter *iface = NULL;
12714 
12715 	if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
12716 		RTW_ERR("STA_LD_NUM == 0\n");
12717 		rtw_warn_on(1);
12718 	}
12719 
12720 	for (i = 0; i < dvobj->iface_nums; i++) {
12721 		iface = dvobj->padapters[i];
12722 		if (!iface)
12723 			continue;
12724 		if (include_self == _FALSE && adapter == iface)
12725 			continue;
12726 		if (is_client_associated_to_ap(iface))
12727 			break;
12728 	}
12729 	if (iface)
12730 		RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
12731 	return iface;
12732 }
12733 #endif /*CONFIG_CONCURRENT_MODE*/
12734 /*Correct port0's TSF*/
12735 /*#define DBG_P0_TSF_SYNC*/
hw_var_set_correct_tsf(PADAPTER adapter,u8 mlme_state)12736 void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
12737 {
12738 #ifdef CONFIG_CONCURRENT_MODE
12739 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12740 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12741 	_adapter *sta_if = NULL;
12742 	u8 hw_port;
12743 
12744 	RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
12745 	#ifdef DBG_P0_TSF_SYNC
12746 	RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
12747 	RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
12748 	RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
12749 	if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12750 		RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
12751 	else
12752 		RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12753 	RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12754 	#endif
12755 	switch (mlme_state) {
12756 		case MLME_STA_CONNECTED :
12757 			{
12758 				hw_port = rtw_hal_get_port(adapter);
12759 
12760 				if (!MLME_IS_STA(adapter)) {
12761 					RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12762 					rtw_warn_on(1);
12763 				}
12764 
12765 				if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
12766 					RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
12767 					rtw_warn_on(1);
12768 					hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12769 				}
12770 
12771 				if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12772 					(rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
12773 					hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12774 					#ifdef DBG_P0_TSF_SYNC
12775 					RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
12776 					#endif
12777 				}
12778 			}
12779 			break;
12780 		case MLME_STA_DISCONNECTED :
12781 			{
12782 				hw_port = rtw_hal_get_port(adapter);
12783 
12784 				if (!MLME_IS_STA(adapter)) {
12785 					RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12786 					rtw_warn_on(1);
12787 				}
12788 
12789 				if (dvobj->p0_tsf.sync_port == hw_port) {
12790 					if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
12791 						/* search next appropriate sta*/
12792 						sta_if = _search_ld_sta(adapter, _FALSE);
12793 						if (sta_if) {
12794 							hw_port = rtw_hal_get_port(sta_if);
12795 							hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12796 							#ifdef DBG_P0_TSF_SYNC
12797 							RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
12798 							#endif
12799 						}
12800 					} else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
12801 						hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12802 						#ifdef DBG_P0_TSF_SYNC
12803 						RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
12804 						#endif
12805 					}
12806 				}
12807 			}
12808 			break;
12809 #ifdef CONFIG_AP_MODE
12810 		case MLME_AP_STARTED :
12811 		case MLME_MESH_STARTED :
12812 			{
12813 				if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12814 					RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12815 					rtw_warn_on(1);
12816 				}
12817 
12818 				if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12819 					rtw_mi_get_assoced_sta_num(adapter)) {
12820 					/* get port of sta */
12821 					sta_if = _search_ld_sta(adapter, _FALSE);
12822 					if (sta_if) {
12823 						hw_port = rtw_hal_get_port(sta_if);
12824 						hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12825 						#ifdef DBG_P0_TSF_SYNC
12826 						RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
12827 						#endif
12828 					}
12829 				}
12830 			}
12831 			break;
12832 		case MLME_AP_STOPPED :
12833 		case MLME_MESH_STOPPED :
12834 			{
12835 				if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12836 					RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12837 					rtw_warn_on(1);
12838 				}
12839 				/*stop ap mode*/
12840 				if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
12841 					(dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
12842 					hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12843 					#ifdef DBG_P0_TSF_SYNC
12844 					RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
12845 					#endif
12846 				}
12847 			}
12848 			break;
12849 #endif /* CONFIG_AP_MODE */
12850 		default :
12851 			RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
12852 			break;
12853 	}
12854 
12855 	/*#ifdef DBG_P0_TSF_SYNC*/
12856 	#if 1
12857 	if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12858 		RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
12859 	else
12860 		RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12861 	RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12862 	#endif
12863 #endif /*CONFIG_CONCURRENT_MODE*/
12864 }
12865 
12866 #else /*! CONFIG_HW_P0_TSF_SYNC*/
12867 
12868 #ifdef CONFIG_MI_WITH_MBSSID_CAM
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12869 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12870 {
12871 	/*do nothing*/
12872 }
12873 #else /* !CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)12874 static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
12875 {
12876 	if (hw_port == HW_PORT0) {
12877 		/*disable related TSF function*/
12878 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
12879 #if defined(CONFIG_RTL8192F)
12880 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12881 					REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
12882 #endif
12883 
12884 		rtw_write32(padapter, REG_TSFTR, tsf);
12885 		rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
12886 
12887 		/*enable related TSF function*/
12888 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
12889 #if defined(CONFIG_RTL8192F)
12890 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12891 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
12892 #endif
12893 	} else if (hw_port == HW_PORT1) {
12894 		/*disable related TSF function*/
12895 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
12896 #if defined(CONFIG_RTL8192F)
12897 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12898 					REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
12899 #endif
12900 
12901 		rtw_write32(padapter, REG_TSFTR1, tsf);
12902 		rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
12903 
12904 		/*enable related TSF function*/
12905 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
12906 #if defined(CONFIG_RTL8192F)
12907 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12908 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
12909 #endif
12910 	} else
12911 		RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
12912 }
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12913 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12914 {
12915 	u64 tsf;
12916 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
12917 	struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
12918 
12919 	tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
12920 
12921 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12922 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12923 		StopTxBeacon(adapter);
12924 
12925 	rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
12926 
12927 #ifdef CONFIG_CONCURRENT_MODE
12928 	/* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
12929 	if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
12930 		&& (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12931 	) {
12932 		struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12933 		int i;
12934 		_adapter *iface;
12935 
12936 		for (i = 0; i < dvobj->iface_nums; i++) {
12937 			iface = dvobj->padapters[i];
12938 			if (!iface)
12939 				continue;
12940 			if (iface == adapter)
12941 				continue;
12942 
12943 			#ifdef CONFIG_AP_MODE
12944 			if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
12945 				&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
12946 			) {
12947 				rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
12948 				#ifdef CONFIG_TSF_RESET_OFFLOAD
12949 				if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
12950 					RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
12951 						, __func__, ADPT_ARG(iface), iface->hw_port);
12952 				#endif	/* CONFIG_TSF_RESET_OFFLOAD*/
12953 			}
12954 			#endif /* CONFIG_AP_MODE */
12955 		}
12956 	}
12957 #endif /* CONFIG_CONCURRENT_MODE */
12958 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12959 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12960 		ResumeTxBeacon(adapter);
12961 }
12962 #endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
12963 #endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
12964 #endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
12965 
rtw_hal_get_tsftr_by_port(_adapter * adapter,u8 port)12966 u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
12967 {
12968 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
12969 	u64 tsftr = 0;
12970 
12971 	if (port >= hal_spec->port_num) {
12972 		RTW_ERR("%s invalid port(%d) \n", __func__, port);
12973 		goto exit;
12974 	}
12975 
12976 	switch (rtw_get_chip_type(adapter)) {
12977 #if defined(CONFIG_RTL8814B)
12978 	case RTL8814B:
12979 	{
12980 		u8 val8;
12981 
12982 		/* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
12983 		val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
12984 		val8 &= ~0x70;
12985 		val8 |= port << 4;
12986 		rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
12987 
12988 		tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
12989 		tsftr = tsftr << 32;
12990 		tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
12991 
12992 		break;
12993 	}
12994 #endif
12995 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
12996 	case RTL8814A:
12997 	case RTL8822B:
12998 	case RTL8821C:
12999 	case RTL8822C:
13000 	{
13001 		u8 val8;
13002 
13003 		/* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
13004 		val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
13005 		val8 &= 0x8F;
13006 		val8 |= port << 4;
13007 		rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
13008 
13009 		tsftr = rtw_read32(adapter, REG_TSFTR + 4);
13010 		tsftr = tsftr << 32;
13011 		tsftr |= rtw_read32(adapter, REG_TSFTR);
13012 
13013 		break;
13014 	}
13015 #endif
13016 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
13017 		|| defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
13018 		|| defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
13019 		|| defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
13020 		|| defined(CONFIG_RTL8710B)
13021 	case RTL8188E:
13022 	case RTL8188F:
13023 	case RTL8188GTV:
13024 	case RTL8192E:
13025 	case RTL8192F:
13026 	case RTL8723B:
13027 	case RTL8703B:
13028 	case RTL8723D:
13029 	case RTL8812:
13030 	case RTL8821:
13031 	case RTL8710B:
13032 	{
13033 		u32 addr;
13034 
13035 		if (port == HW_PORT0)
13036 			addr = REG_TSFTR;
13037 		else if (port == HW_PORT1)
13038 			addr = REG_TSFTR1;
13039 		else {
13040 			RTW_ERR("%s unknown port(%d) \n", __func__, port);
13041 			goto exit;
13042 		}
13043 
13044 		tsftr = rtw_read32(adapter, addr + 4);
13045 		tsftr = tsftr << 32;
13046 		tsftr |= rtw_read32(adapter, addr);
13047 
13048 		break;
13049 	}
13050 #endif
13051 	default:
13052 		RTW_ERR("%s unknow chip type\n", __func__);
13053 	}
13054 
13055 exit:
13056 	return tsftr;
13057 }
13058 
13059 #ifdef CONFIG_TDLS
13060 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)13061 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
13062 {
13063 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
13064 	u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
13065 
13066 
13067 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
13068 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
13069 	switch (bwmode) {
13070 	case CHANNEL_WIDTH_40:
13071 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
13072 		break;
13073 	case CHANNEL_WIDTH_80:
13074 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
13075 		break;
13076 	case CHANNEL_WIDTH_20:
13077 	default:
13078 		break;
13079 	}
13080 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
13081 
13082 	return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
13083 }
13084 #endif
13085 #endif
13086 
13087 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)13088 void rtw_hal_update_uapsd_tid(_adapter *adapter)
13089 {
13090 	struct mlme_priv		*pmlmepriv = &adapter->mlmepriv;
13091 	struct qos_priv		*pqospriv = &pmlmepriv->qospriv;
13092 
13093 	/* write complement of pqospriv->uapsd_tid to mac register 0x693 because
13094 	    it's designed  for "0" represents "enable" and "1" represents "disable" */
13095 	rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
13096 }
13097 #endif /* CONFIG_WMMPS_STA */
13098 
13099 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
13100 /* 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)13101 s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
13102 {
13103 	u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
13104 	u8 hw_port = rtw_hal_get_port(adapter);
13105 
13106 	SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
13107 	RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
13108 	return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
13109 }
13110 #endif
13111 
13112 #define LPS_ACTIVE_TIMEOUT	50 /*number of times*/
rtw_lps_state_chk(_adapter * adapter,u8 ps_mode)13113 void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
13114 {
13115 	struct pwrctrl_priv 		*pwrpriv = adapter_to_pwrctl(adapter);
13116 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
13117 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13118 	struct sta_priv		*pstapriv = &adapter->stapriv;
13119 	struct sta_info		*psta = NULL;
13120 	u8 ps_ready = _FALSE;
13121 	s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
13122 
13123 	if (ps_mode == PS_MODE_ACTIVE) {
13124 #ifdef CONFIG_LPS_ACK
13125 		if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
13126 			if (pwrpriv->lps_ack_status > 0) {
13127 				psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
13128 				if (psta != NULL) {
13129 					if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
13130 						RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
13131 				}
13132 			}
13133 		} else {
13134 			RTW_WARN("LPS sctx query timeout, operation abort!!\n");
13135 			return;
13136 		}
13137 		pwrpriv->lps_ack_status = -1;
13138 #else
13139 		do {
13140 			if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
13141 				ps_ready = _TRUE;
13142 				break;
13143 			}
13144 			rtw_msleep_os(1);
13145 		} while (leave_wait_count--);
13146 
13147 		if (ps_ready == _FALSE) {
13148 			RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
13149 			return;
13150 		}
13151 #endif /* CONFIG_LPS_ACK */
13152 		}
13153 	}
13154 
rtw_var_set_basic_rate(PADAPTER padapter,u8 * val)13155 void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
13156 
13157 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
13158 	struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
13159 	u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
13160 	u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
13161 	u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
13162 	#if CONFIG_IEEE80211_BAND_5GHZ
13163 	u16 rrsr_5g_force_mask = (RRSR_6M);
13164 	u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
13165 	#endif
13166 	u32 temp_RRSR;
13167 
13168 	HalSetBrateCfg(padapter, val, &BrateCfg);
13169 	input_b = BrateCfg;
13170 
13171 	/* apply force and allow mask */
13172 	#if CONFIG_IEEE80211_BAND_5GHZ
13173 	if (pHalData->current_band_type != BAND_ON_2_4G) {
13174 		BrateCfg |= rrsr_5g_force_mask;
13175 		BrateCfg &= rrsr_5g_allow_mask;
13176 	} else
13177 	#endif
13178 	{ /* 2.4G */
13179 		BrateCfg |= rrsr_2g_force_mask;
13180 		BrateCfg &= rrsr_2g_allow_mask;
13181 	}
13182 	masked = BrateCfg;
13183 
13184 #ifdef CONFIG_CMCC_TEST
13185 	BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
13186 	BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
13187 #endif
13188 
13189 	/* IOT consideration */
13190 	if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
13191 		/* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
13192 		if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
13193 			BrateCfg |= RRSR_6M;
13194 	}
13195 		ioted = BrateCfg;
13196 
13197 #ifdef CONFIG_NARROWBAND_SUPPORTING
13198 	if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
13199 		|| (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
13200 		BrateCfg &= ~RRSR_CCK_RATES;
13201 		BrateCfg |= RRSR_6M;
13202 	}
13203 #endif
13204 	pHalData->BasicRateSet = BrateCfg;
13205 
13206 	RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
13207 
13208 	/* Set RRSR rate table. */
13209 		temp_RRSR = rtw_read32(padapter, REG_RRSR);
13210 		temp_RRSR &=0xFFFF0000;
13211 		temp_RRSR |=BrateCfg;
13212 		rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
13213 
13214 	rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
13215 
13216 	#if defined(CONFIG_RTL8188E)
13217 	rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
13218 	#endif
13219 }
13220 
SetHwReg(_adapter * adapter,u8 variable,u8 * val)13221 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
13222 {
13223 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13224 	u8 ret = _SUCCESS;
13225 
13226 	switch (variable) {
13227 	case HW_VAR_MEDIA_STATUS: {
13228 		u8 net_type = *((u8 *)val);
13229 
13230 		rtw_hal_set_msr(adapter, net_type);
13231 	}
13232 	break;
13233 	case HW_VAR_DO_IQK:
13234 		if (*val)
13235 			hal_data->bNeedIQK = _TRUE;
13236 		else
13237 			hal_data->bNeedIQK = _FALSE;
13238 		break;
13239 	case HW_VAR_MAC_ADDR:
13240 #ifdef CONFIG_MI_WITH_MBSSID_CAM
13241 		rtw_hal_set_macaddr_mbid(adapter, val);
13242 #else
13243 		rtw_hal_set_macaddr_port(adapter, val);
13244 #endif
13245 		break;
13246 	case HW_VAR_BSSID:
13247 		rtw_hal_set_bssid(adapter, val);
13248 		break;
13249 	case HW_VAR_RCR:
13250 		ret = hw_var_rcr_config(adapter, *((u32 *)val));
13251 		break;
13252 	case HW_VAR_ON_RCR_AM:
13253 		hw_var_set_rcr_am(adapter, 1);
13254 		break;
13255 	case HW_VAR_OFF_RCR_AM:
13256 		hw_var_set_rcr_am(adapter, 0);
13257 		break;
13258 	case HW_VAR_BEACON_INTERVAL:
13259 		hw_var_set_bcn_interval(adapter, *(u16 *)val);
13260 		break;
13261 #ifdef CONFIG_MBSSID_CAM
13262 	case HW_VAR_MBSSID_CAM_WRITE: {
13263 		u32	cmd = 0;
13264 		u32	*cam_val = (u32 *)val;
13265 
13266 		rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
13267 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
13268 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
13269 	}
13270 		break;
13271 	case HW_VAR_MBSSID_CAM_CLEAR: {
13272 		u32 cmd;
13273 		u8 entry_id = *(u8 *)val;
13274 
13275 		rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
13276 
13277 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
13278 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
13279 	}
13280 		break;
13281 	case HW_VAR_RCR_MBSSID_EN:
13282 		if (*((u8 *)val))
13283 			rtw_hal_rcr_add(adapter, RCR_ENMBID);
13284 		else
13285 			rtw_hal_rcr_clear(adapter, RCR_ENMBID);
13286 		break;
13287 #endif
13288 	case HW_VAR_PORT_SWITCH:
13289 		hw_var_port_switch(adapter);
13290 		break;
13291 	case HW_VAR_INIT_RTS_RATE: {
13292 		u16 brate_cfg = *((u16 *)val);
13293 		u8 rate_index = 0;
13294 		HAL_VERSION *hal_ver = &hal_data->version_id;
13295 
13296 		if (IS_8188E(*hal_ver)) {
13297 
13298 			while (brate_cfg > 0x1) {
13299 				brate_cfg = (brate_cfg >> 1);
13300 				rate_index++;
13301 			}
13302 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
13303 		} else
13304 			rtw_warn_on(1);
13305 	}
13306 		break;
13307 	case HW_VAR_SEC_CFG: {
13308 		u16 reg_scr_ori;
13309 		u16 reg_scr;
13310 
13311 		reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
13312 		reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
13313 
13314 		if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
13315 			reg_scr |= SCR_CHK_BMC;
13316 
13317 		if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
13318 			reg_scr |= SCR_NoSKMC;
13319 
13320 		if (reg_scr != reg_scr_ori)
13321 			rtw_write16(adapter, REG_SECCFG, reg_scr);
13322 	}
13323 		break;
13324 	case HW_VAR_SEC_DK_CFG: {
13325 		struct security_priv *sec = &adapter->securitypriv;
13326 		u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
13327 
13328 		if (val) { /* Enable default key related setting */
13329 			reg_scr |= SCR_TXBCUSEDK;
13330 			if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
13331 				reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
13332 		} else /* Disable default key related setting */
13333 			reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
13334 
13335 		rtw_write8(adapter, REG_SECCFG, reg_scr);
13336 	}
13337 		break;
13338 
13339 	case HW_VAR_ASIX_IOT:
13340 		/* enable  ASIX IOT function */
13341 		if (*((u8 *)val) == _TRUE) {
13342 			/* 0xa2e[0]=0 (disable rake receiver) */
13343 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
13344 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
13345 			/* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
13346 			rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
13347 		} else {
13348 			/* restore reg:0xa2e,   reg:0xa1c */
13349 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
13350 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
13351 			rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
13352 		}
13353 		break;
13354 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
13355 	case HW_VAR_WOWLAN: {
13356 		struct wowlan_ioctl_param *poidparam;
13357 
13358 		poidparam = (struct wowlan_ioctl_param *)val;
13359 		switch (poidparam->subcode) {
13360 #ifdef CONFIG_WOWLAN
13361 		case WOWLAN_PATTERN_CLEAN:
13362 			rtw_hal_dl_pattern(adapter, 2);
13363 			break;
13364 		case WOWLAN_ENABLE:
13365 			rtw_hal_wow_enable(adapter);
13366 			break;
13367 		case WOWLAN_DISABLE:
13368 			rtw_hal_wow_disable(adapter);
13369 			break;
13370 #endif /*CONFIG_WOWLAN*/
13371 #ifdef CONFIG_AP_WOWLAN
13372 		case WOWLAN_AP_ENABLE:
13373 			rtw_hal_ap_wow_enable(adapter);
13374 			break;
13375 		case WOWLAN_AP_DISABLE:
13376 			rtw_hal_ap_wow_disable(adapter);
13377 			break;
13378 #endif /*CONFIG_AP_WOWLAN*/
13379 		default:
13380 			break;
13381 		}
13382 	}
13383 		break;
13384 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
13385 
13386 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
13387 	case HW_VAR_BCN_FUNC:
13388 		hw_var_set_bcn_func(adapter, *val);
13389 		break;
13390 #endif
13391 
13392 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
13393 	case HW_VAR_MLME_DISCONNECT:
13394 		hw_var_set_mlme_disconnect(adapter);
13395 		break;
13396 #endif
13397 
13398 	case HW_VAR_MLME_SITESURVEY:
13399 		hw_var_set_mlme_sitesurvey(adapter, *val);
13400 		#ifdef CONFIG_BT_COEXIST
13401 		if (hal_data->EEPROMBluetoothCoexist == 1)
13402 			rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
13403 		#endif
13404 		break;
13405 
13406 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
13407 	case HW_VAR_MLME_JOIN:
13408 		hw_var_set_mlme_join(adapter, *val);
13409 		break;
13410 #endif
13411 
13412 	case HW_VAR_EN_HW_UPDATE_TSF:
13413 		rtw_hal_set_hw_update_tsf(adapter);
13414 		break;
13415 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
13416 	case HW_VAR_CORRECT_TSF:
13417 		hw_var_set_correct_tsf(adapter, *val);
13418 		break;
13419 #endif
13420 
13421 #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
13422 	case HW_VAR_TSF_AUTO_SYNC:
13423 		if (*val == _TRUE)
13424 			hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
13425 		else
13426 			hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
13427 		break;
13428 #endif
13429 	case HW_VAR_APFM_ON_MAC:
13430 		hal_data->bMacPwrCtrlOn = *val;
13431 		RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
13432 		break;
13433 #ifdef CONFIG_WMMPS_STA
13434 	case  HW_VAR_UAPSD_TID:
13435 		rtw_hal_update_uapsd_tid(adapter);
13436 		break;
13437 #endif /* CONFIG_WMMPS_STA */
13438 #ifdef CONFIG_LPS_PG
13439 	case HW_VAR_LPS_PG_HANDLE:
13440 		rtw_hal_lps_pg_handler(adapter, *val);
13441 		break;
13442 #endif
13443 #ifdef CONFIG_LPS_LCLK_WD_TIMER
13444 	case HW_VAR_DM_IN_LPS_LCLK:
13445 		rtw_phydm_wd_lps_lclk_hdl(adapter);
13446 		break;
13447 #endif
13448 	case HW_VAR_ENABLE_RX_BAR:
13449 		if (*val == _TRUE) {
13450 			/* enable RX BAR */
13451 			u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
13452 
13453 			val16 |= BIT(8);
13454 			rtw_write16(adapter, REG_RXFLTMAP1, val16);
13455 		} else {
13456 			/* disable RX BAR */
13457 			u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
13458 
13459 			val16 &= (~BIT(8));
13460 			rtw_write16(adapter, REG_RXFLTMAP1, val16);
13461 		}
13462 		RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
13463 			REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
13464 		break;
13465 	case HW_VAR_HCI_SUS_STATE:
13466 		hal_data->hci_sus_state = *(u8 *)val;
13467 		RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
13468 		break;
13469 #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
13470 		case HW_VAR_BCN_HEAD_SEL:
13471 		{
13472 			u8 vap_id = *(u8 *)val;
13473 
13474 			if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
13475 				RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
13476 				rtw_warn_on(1);
13477 			}
13478 			if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
13479 				u16 drv_pg_bndy = 0, bcn_addr = 0;
13480 				u32 page_size = 0;
13481 
13482 				/*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
13483 				rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
13484 				rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
13485 
13486 				if (vap_id != 0xFF)
13487 					bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
13488 				else
13489 					bcn_addr = drv_pg_bndy;
13490 				RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
13491 					ADPT_ARG(adapter), vap_id, bcn_addr);
13492 				rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
13493 					(bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
13494 			}
13495 		}
13496 		break;
13497 #endif
13498 	case HW_VAR_LPS_STATE_CHK :
13499 		rtw_lps_state_chk(adapter, *(u8 *)val);
13500 		break;
13501 
13502 #ifdef CONFIG_RTS_FULL_BW
13503 	case HW_VAR_SET_RTS_BW:
13504 	{
13505 		#ifdef RTW_HALMAC
13506 			rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
13507 		#else
13508 			u8 temp;
13509 			if(*val)
13510 				temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
13511 			else
13512 				temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
13513 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
13514 			/*RTW_INFO("HW_VAR_SET_RTS_BW	val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
13515 		#endif
13516 	}
13517 	break;
13518 #endif/*CONFIG_RTS_FULL_BW*/
13519 #if defined(CONFIG_PCI_HCI)
13520 	case HW_VAR_ENSWBCN:
13521 	if (*val == _TRUE) {
13522 		rtw_write8(adapter, REG_CR + 1,
13523 			   rtw_read8(adapter, REG_CR + 1) | BIT(0));
13524 	} else
13525 		rtw_write8(adapter, REG_CR + 1,
13526 			   rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
13527 	break;
13528 #endif
13529 	case HW_VAR_BCN_EARLY_C2H_RPT:
13530 		rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(adapter, *(u8 *)val);
13531 		break;
13532 	default:
13533 		if (0)
13534 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
13535 				  FUNC_ADPT_ARG(adapter), variable);
13536 		ret = _FAIL;
13537 		break;
13538 	}
13539 
13540 	return ret;
13541 }
13542 
GetHwReg(_adapter * adapter,u8 variable,u8 * val)13543 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
13544 {
13545 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13546 	u64 val64;
13547 
13548 
13549 	switch (variable) {
13550 	case HW_VAR_MAC_ADDR:
13551 		#ifndef CONFIG_MI_WITH_MBSSID_CAM
13552 		rtw_hal_get_macaddr_port(adapter, val);
13553 		#endif
13554 		break;
13555 	case HW_VAR_BASIC_RATE:
13556 		*((u16 *)val) = hal_data->BasicRateSet;
13557 		break;
13558 	case HW_VAR_MEDIA_STATUS:
13559 		rtw_hal_get_msr(adapter, val);
13560 		break;
13561 	case HW_VAR_DO_IQK:
13562 		*val = hal_data->bNeedIQK;
13563 		break;
13564 	case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
13565 		if (hal_is_band_support(adapter, BAND_ON_5G))
13566 			*val = _TRUE;
13567 		else
13568 			*val = _FALSE;
13569 		break;
13570 	case HW_VAR_APFM_ON_MAC:
13571 		*val = hal_data->bMacPwrCtrlOn;
13572 		break;
13573 	case HW_VAR_RCR:
13574 		hw_var_rcr_get(adapter, (u32 *)val);
13575 		break;
13576 	case HW_VAR_FWLPS_RF_ON:
13577 		/* When we halt NIC, we should check if FW LPS is leave. */
13578 		if (rtw_is_surprise_removed(adapter)
13579 			|| (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
13580 		) {
13581 			/*
13582 			 * If it is in HW/SW Radio OFF or IPS state,
13583 			 * we do not check Fw LPS Leave,
13584 			 * because Fw is unload.
13585 			 */
13586 			*val = _TRUE;
13587 		} else {
13588 			u32 rcr = 0;
13589 
13590 			rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
13591 			if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
13592 				*val = _FALSE;
13593 			else
13594 				*val = _TRUE;
13595 		}
13596 		break;
13597 
13598 	case HW_VAR_HCI_SUS_STATE:
13599 		*((u8 *)val) = hal_data->hci_sus_state;
13600 		break;
13601 
13602 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
13603 	case HW_VAR_BCN_CTRL_ADDR:
13604 		*((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
13605 		break;
13606 #endif
13607 
13608 #ifdef CONFIG_WAPI_SUPPORT
13609 	case HW_VAR_CAM_EMPTY_ENTRY: {
13610 		u8	ucIndex = *((u8 *)val);
13611 		u8	i;
13612 		u32	ulCommand = 0;
13613 		u32	ulContent = 0;
13614 		u32	ulEncAlgo = CAM_AES;
13615 
13616 		for (i = 0; i < CAM_CONTENT_COUNT; i++) {
13617 			/* filled id in CAM config 2 byte */
13618 			if (i == 0)
13619 				ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
13620 			else
13621 				ulContent = 0;
13622 			/* polling bit, and No Write enable, and address */
13623 			ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
13624 			ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
13625 			/* write content 0 is equall to mark invalid */
13626 			rtw_write32(adapter, REG_CAMWRITE, ulContent);  /* delay_ms(40); */
13627 			rtw_write32(adapter, REG_CAMCMD, ulCommand);  /* delay_ms(40); */
13628 		}
13629 	}
13630 #endif
13631 
13632 	default:
13633 		if (0)
13634 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
13635 				  FUNC_ADPT_ARG(adapter), variable);
13636 		break;
13637 	}
13638 
13639 }
13640 
_get_page_size(struct _ADAPTER * a)13641 static u32 _get_page_size(struct _ADAPTER *a)
13642 {
13643 #ifdef RTW_HALMAC
13644 	struct dvobj_priv *d;
13645 	u32 size = 0;
13646 	int err = 0;
13647 
13648 
13649 	d = adapter_to_dvobj(a);
13650 
13651 	err = rtw_halmac_get_page_size(d, &size);
13652 	if (!err)
13653 		return size;
13654 
13655 	RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
13656 		 FUNC_ADPT_ARG(a), err);
13657 #endif /* RTW_HALMAC */
13658 
13659 	return PAGE_SIZE_128;
13660 }
13661 
13662 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13663 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13664 {
13665 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13666 	u8 bResult = _SUCCESS;
13667 
13668 	switch (variable) {
13669 
13670 	case HAL_DEF_DBG_DUMP_RXPKT:
13671 		hal_data->bDumpRxPkt = *((u8 *)value);
13672 		break;
13673 	case HAL_DEF_DBG_DUMP_TXPKT:
13674 		hal_data->bDumpTxPkt = *((u8 *)value);
13675 		break;
13676 	case HAL_DEF_ANT_DETECT:
13677 		hal_data->AntDetection = *((u8 *)value);
13678 		break;
13679 	default:
13680 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
13681 		bResult = _FAIL;
13682 		break;
13683 	}
13684 
13685 	return bResult;
13686 }
13687 
13688 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)13689 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
13690 {
13691 	struct registry_priv	*pregistrypriv = &adapter->registrypriv;
13692 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13693 
13694 	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)))
13695 		return pregistrypriv->beamformer_rf_num;
13696 	else if (IS_HARDWARE_TYPE_8814AE(adapter)
13697 #if 0
13698 #if defined(CONFIG_USB_HCI)
13699 		|| (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2))  /* for USB3.0 */
13700 #endif
13701 #endif
13702 		) {
13703 		/*BF cap provided by Yu Chen, Sean, 2015, 01 */
13704 		if (hal_data->rf_type == RF_3T3R)
13705 			return 2;
13706 		else if (hal_data->rf_type == RF_4T4R)
13707 			return 3;
13708 		else
13709 			return 1;
13710 	} else
13711 		return 1;
13712 
13713 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)13714 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
13715 {
13716 	struct registry_priv		*pregistrypriv = &adapter->registrypriv;
13717 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
13718 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13719 
13720 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13721 
13722 	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)))
13723 		return pregistrypriv->beamformee_rf_num;
13724 	else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
13725 		if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
13726 			return 2;
13727 		else
13728 			return 2;/*TODO: May be 3 in the future, by ChenYu. */
13729 	} else
13730 		return 1;
13731 
13732 }
13733 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_hal_beamforming_config_csirate(PADAPTER adapter)13734 void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
13735 {
13736 	struct dm_struct *p_dm_odm;
13737 	struct beamforming_info *bf_info;
13738 	u8 fix_rate_enable = 0;
13739 	u8 new_csi_rate_idx;
13740 	u8 rrsr_54_en;
13741 	u32 temp_rrsr;
13742 
13743 	/* Acting as BFee */
13744 	if (IS_BEAMFORMEE(adapter)) {
13745 	#if 0
13746 		/* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
13747 		if (IS_HARDWARE_TYPE_8821C(Adapter))
13748 			FixRateEnable = 1;	/* Support after 8821C */
13749 	#endif
13750 
13751 		p_dm_odm = adapter_to_phydm(adapter);
13752 		bf_info = GET_BEAMFORM_INFO(adapter);
13753 
13754 		rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
13755 				p_dm_odm->rssi_min,
13756 				bf_info->cur_csi_rpt_rate,
13757 				fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
13758 
13759 		temp_rrsr = rtw_read32(adapter, REG_RRSR);
13760 		if (rrsr_54_en == 1)
13761 			temp_rrsr |= RRSR_54M;
13762 		else if (rrsr_54_en == 0)
13763 			temp_rrsr &= ~RRSR_54M;
13764 		rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
13765 
13766 		if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
13767 			bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
13768 	}
13769 }
13770 #endif
13771 #endif
13772 
13773 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13774 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13775 {
13776 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13777 	u8 bResult = _SUCCESS;
13778 
13779 	switch (variable) {
13780 	case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
13781 		struct mlme_priv *pmlmepriv;
13782 		struct sta_priv *pstapriv;
13783 		struct sta_info *psta;
13784 
13785 		pmlmepriv = &adapter->mlmepriv;
13786 		pstapriv = &adapter->stapriv;
13787 		psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
13788 		if (psta)
13789 			*((int *)value) = psta->cmn.rssi_stat.rssi;
13790 	}
13791 	break;
13792 	case HAL_DEF_DBG_DUMP_RXPKT:
13793 		*((u8 *)value) = hal_data->bDumpRxPkt;
13794 		break;
13795 	case HAL_DEF_DBG_DUMP_TXPKT:
13796 		*((u8 *)value) = hal_data->bDumpTxPkt;
13797 		break;
13798 	case HAL_DEF_ANT_DETECT:
13799 		*((u8 *)value) = hal_data->AntDetection;
13800 		break;
13801 	case HAL_DEF_TX_PAGE_SIZE:
13802 		*((u32 *)value) = _get_page_size(adapter);
13803 		break;
13804 	case HAL_DEF_TX_STBC:
13805 		#ifdef CONFIG_ALPHA_SMART_ANTENNA
13806 		*(u8 *)value = 0;
13807 		#else
13808 		*(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
13809 		#endif
13810 		break;
13811 	case HAL_DEF_EXPLICIT_BEAMFORMER:
13812 	case HAL_DEF_EXPLICIT_BEAMFORMEE:
13813 	case HAL_DEF_VHT_MU_BEAMFORMER:
13814 	case HAL_DEF_VHT_MU_BEAMFORMEE:
13815 		*(u8 *)value = _FALSE;
13816 		break;
13817 #ifdef CONFIG_BEAMFORMING
13818 	case HAL_DEF_BEAMFORMER_CAP:
13819 		*(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
13820 		break;
13821 	case HAL_DEF_BEAMFORMEE_CAP:
13822 		*(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
13823 		break;
13824 #endif
13825 	default:
13826 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
13827 		bResult = _FAIL;
13828 		break;
13829 	}
13830 
13831 	return bResult;
13832 }
13833 
13834 /*
13835  *	Description:
13836  *		Translate a character to hex digit.
13837  *   */
13838 u32
MapCharToHexDigit(char chTmp)13839 MapCharToHexDigit(
13840 			char		chTmp
13841 )
13842 {
13843 	if (chTmp >= '0' && chTmp <= '9')
13844 		return chTmp - '0';
13845 	else if (chTmp >= 'a' && chTmp <= 'f')
13846 		return 10 + (chTmp - 'a');
13847 	else if (chTmp >= 'A' && chTmp <= 'F')
13848 		return 10 + (chTmp - 'A');
13849 	else
13850 		return 0;
13851 }
13852 
13853 
13854 
13855 /*
13856  *	Description:
13857  *		Parse hex number from the string pucStr.
13858  *   */
13859 BOOLEAN
GetHexValueFromString(char * szStr,u32 * pu4bVal,u32 * pu4bMove)13860 GetHexValueFromString(
13861 		char			*szStr,
13862 		u32			*pu4bVal,
13863 		u32			*pu4bMove
13864 )
13865 {
13866 	char		*szScan = szStr;
13867 
13868 	/* Check input parameter. */
13869 	if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
13870 		RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
13871 		return _FALSE;
13872 	}
13873 
13874 	/* Initialize output. */
13875 	*pu4bMove = 0;
13876 	*pu4bVal = 0;
13877 
13878 	/* Skip leading space. */
13879 	while (*szScan != '\0' &&
13880 	       (*szScan == ' ' || *szScan == '\t')) {
13881 		szScan++;
13882 		(*pu4bMove)++;
13883 	}
13884 
13885 	/* Skip leading '0x' or '0X'. */
13886 	if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
13887 		szScan += 2;
13888 		(*pu4bMove) += 2;
13889 	}
13890 
13891 	/* Check if szScan is now pointer to a character for hex digit, */
13892 	/* if not, it means this is not a valid hex number. */
13893 	if (!IsHexDigit(*szScan))
13894 		return _FALSE;
13895 
13896 	/* Parse each digit. */
13897 	do {
13898 		(*pu4bVal) <<= 4;
13899 		*pu4bVal += MapCharToHexDigit(*szScan);
13900 
13901 		szScan++;
13902 		(*pu4bMove)++;
13903 	} while (IsHexDigit(*szScan));
13904 
13905 	return _TRUE;
13906 }
13907 
13908 BOOLEAN
GetFractionValueFromString(char * szStr,u8 * pInteger,u8 * pFraction,u32 * pu4bMove)13909 GetFractionValueFromString(
13910 		char			*szStr,
13911 		u8				*pInteger,
13912 		u8				*pFraction,
13913 		u32			*pu4bMove
13914 )
13915 {
13916 	char	*szScan = szStr;
13917 
13918 	/* Initialize output. */
13919 	*pu4bMove = 0;
13920 	*pInteger = 0;
13921 	*pFraction = 0;
13922 
13923 	/* Skip leading space. */
13924 	while (*szScan != '\0' &&	(*szScan == ' ' || *szScan == '\t')) {
13925 		++szScan;
13926 		++(*pu4bMove);
13927 	}
13928 
13929 	if (*szScan < '0' || *szScan > '9')
13930 		return _FALSE;
13931 
13932 	/* Parse each digit. */
13933 	do {
13934 		(*pInteger) *= 10;
13935 		*pInteger += (*szScan - '0');
13936 
13937 		++szScan;
13938 		++(*pu4bMove);
13939 
13940 		if (*szScan == '.') {
13941 			++szScan;
13942 			++(*pu4bMove);
13943 
13944 			if (*szScan < '0' || *szScan > '9')
13945 				return _FALSE;
13946 
13947 			*pFraction += (*szScan - '0') * 10;
13948 			++szScan;
13949 			++(*pu4bMove);
13950 
13951 			if (*szScan >= '0' && *szScan <= '9') {
13952 				*pFraction += *szScan - '0';
13953 				++szScan;
13954 				++(*pu4bMove);
13955 			}
13956 			return _TRUE;
13957 		}
13958 	} while (*szScan >= '0' && *szScan <= '9');
13959 
13960 	return _TRUE;
13961 }
13962 
13963 /*
13964  *	Description:
13965  * Return TRUE if szStr is comment out with leading " */ /* ".
13966  *   */
13967 BOOLEAN
IsCommentString(char * szStr)13968 IsCommentString(
13969 		char			*szStr
13970 )
13971 {
13972 	if (*szStr == '/' && *(szStr + 1) == '/')
13973 		return _TRUE;
13974 	else
13975 		return _FALSE;
13976 }
13977 
13978 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)13979 GetU1ByteIntegerFromStringInDecimal(
13980 		char	*Str,
13981 		u8		*pInt
13982 )
13983 {
13984 	u16 i = 0;
13985 	*pInt = 0;
13986 
13987 	while (Str[i] != '\0') {
13988 		if (Str[i] >= '0' && Str[i] <= '9') {
13989 			*pInt *= 10;
13990 			*pInt += (Str[i] - '0');
13991 		} else
13992 			return _FALSE;
13993 		++i;
13994 	}
13995 
13996 	return _TRUE;
13997 }
13998 
13999 /* <20121004, Kordan> For example,
14000  * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
14001  * If RightQualifier does not exist, it will hang on in the while loop */
14002 BOOLEAN
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)14003 ParseQualifiedString(
14004 			char	*In,
14005 			u32	*Start,
14006 			char	*Out,
14007 			char		LeftQualifier,
14008 			char		RightQualifier
14009 )
14010 {
14011 	u32	i = 0, j = 0;
14012 	char	c = In[(*Start)++];
14013 
14014 	if (c != LeftQualifier)
14015 		return _FALSE;
14016 
14017 	i = (*Start);
14018 	c = In[(*Start)++];
14019 	while (c != RightQualifier && c != '\0')
14020 		c = In[(*Start)++];
14021 
14022 	if (c == '\0')
14023 		return _FALSE;
14024 
14025 	j = (*Start) - 2;
14026 	strncpy((char *)Out, (const char *)(In + i), j - i + 1);
14027 
14028 	return _TRUE;
14029 }
14030 
14031 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)14032 isAllSpaceOrTab(
14033 	u8	*data,
14034 	u8	size
14035 )
14036 {
14037 	u8	cnt = 0, NumOfSpaceAndTab = 0;
14038 
14039 	while (size > cnt) {
14040 		if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
14041 			++NumOfSpaceAndTab;
14042 
14043 		++cnt;
14044 	}
14045 
14046 	return size == NumOfSpaceAndTab;
14047 }
14048 
14049 
rtw_hal_check_rxfifo_full(_adapter * adapter)14050 void rtw_hal_check_rxfifo_full(_adapter *adapter)
14051 {
14052 	struct dvobj_priv *psdpriv = adapter->dvobj;
14053 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
14054 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
14055 	struct registry_priv *regsty = &adapter->registrypriv;
14056 	int save_cnt = _FALSE;
14057 
14058 	if (regsty->check_hw_status == 1) {
14059 		/* switch counter to RX fifo */
14060 		if (IS_8188E(pHalData->version_id) ||
14061 		    IS_8188F(pHalData->version_id) ||
14062 		    IS_8188GTV(pHalData->version_id) ||
14063 		    IS_8812_SERIES(pHalData->version_id) ||
14064 		    IS_8821_SERIES(pHalData->version_id) ||
14065 		    IS_8723B_SERIES(pHalData->version_id) ||
14066 		    IS_8192E(pHalData->version_id) ||
14067 		    IS_8703B_SERIES(pHalData->version_id) ||
14068 		    IS_8723D_SERIES(pHalData->version_id) ||
14069 		    IS_8192F_SERIES(pHalData->version_id)) {
14070 			rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
14071 			save_cnt = _TRUE;
14072 		} else {
14073 			/* todo: other chips */
14074 		}
14075 
14076 
14077 		if (save_cnt) {
14078 			pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
14079 			pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
14080 			pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
14081 		} else {
14082 			/* special value to indicate no implementation */
14083 			pdbgpriv->dbg_rx_fifo_last_overflow = 1;
14084 			pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
14085 			pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
14086 		}
14087 	}
14088 }
14089 
linked_info_dump(_adapter * padapter,u8 benable)14090 void linked_info_dump(_adapter *padapter, u8 benable)
14091 {
14092 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
14093 
14094 	if (padapter->bLinkInfoDump == benable)
14095 		return;
14096 
14097 	RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
14098 
14099 	if (benable) {
14100 #ifdef CONFIG_LPS
14101 		pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
14102 		rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
14103 #endif
14104 
14105 #ifdef CONFIG_IPS
14106 		pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
14107 		rtw_pm_set_ips(padapter, IPS_NONE);
14108 #endif
14109 	} else {
14110 #ifdef CONFIG_IPS
14111 		rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
14112 #endif /* CONFIG_IPS */
14113 
14114 #ifdef CONFIG_LPS
14115 		rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
14116 #endif /* CONFIG_LPS */
14117 	}
14118 	padapter->bLinkInfoDump = benable ;
14119 }
14120 
14121 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)14122 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
14123 {
14124 	u8 isCCKrate, rf_path;
14125 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14126 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14127 	RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
14128 		HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
14129 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14130 
14131 	if (isCCKrate)
14132 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
14133 
14134 	for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14135 		if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14136 			continue;
14137 		RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
14138 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
14139 
14140 		if (!isCCKrate) {
14141 			RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
14142 				psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
14143 		}
14144 	}
14145 }
14146 
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)14147 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
14148 {
14149 	u8 isCCKrate, rf_path;
14150 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14151 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14152 	_RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
14153 	_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);
14154 
14155 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14156 
14157 	if (isCCKrate)
14158 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
14159 
14160 	for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14161 		if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14162 			continue;
14163 		_RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
14164 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
14165 
14166 		if (!isCCKrate)
14167 			_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]);
14168 		else
14169 			_RTW_PRINT_SEL(sel , "\n");
14170 
14171 	}
14172 }
14173 #endif
14174 
14175 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)14176 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
14177 {
14178 #define DBG_RX_DFRAME_RAW_DATA_UC		0
14179 #define DBG_RX_DFRAME_RAW_DATA_BMC		1
14180 #define DBG_RX_DFRAME_RAW_DATA_TYPES	2
14181 
14182 	_irqL irqL;
14183 	u8 isCCKrate, rf_path;
14184 	struct recv_priv *precvpriv = &(padapter->recvpriv);
14185 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14186 	struct sta_priv *pstapriv = &padapter->stapriv;
14187 	struct sta_info *psta;
14188 	struct sta_recv_dframe_info *psta_dframe_info;
14189 	int i, j;
14190 	_list	*plist, *phead;
14191 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14192 	u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14193 
14194 	if (precvpriv->store_law_data_flag) {
14195 
14196 		_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
14197 
14198 		for (i = 0; i < NUM_STA; i++) {
14199 			phead = &(pstapriv->sta_hash[i]);
14200 			plist = get_next(phead);
14201 
14202 			while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
14203 
14204 				psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
14205 				plist = get_next(plist);
14206 
14207 				if (psta) {
14208 					if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN)  !=   _TRUE)
14209 					    && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN)  !=  _TRUE)
14210 					    && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN)  !=  _TRUE)) {
14211 
14212 						RTW_PRINT_SEL(sel, "==============================\n");
14213 						RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
14214 
14215 						for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
14216 							if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
14217 								psta_dframe_info = &psta->sta_dframe_info;
14218 								RTW_PRINT_SEL(sel, "\n");
14219 								RTW_PRINT_SEL(sel, "Unicast:\n");
14220 							} else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
14221 								psta_dframe_info = &psta->sta_dframe_info_bmc;
14222 								RTW_PRINT_SEL(sel, "\n");
14223 								RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
14224 							}
14225 
14226 							isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14227 
14228 							RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
14229 							RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
14230 
14231 							for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14232 								if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14233 									continue;
14234 								if (!isCCKrate) {
14235 									RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
14236 									_RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
14237 								} else
14238 									RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
14239 							}
14240 						}
14241 
14242 					}
14243 				}
14244 			}
14245 		}
14246 		_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
14247 	}
14248 }
14249 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)14250 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
14251 {
14252 	u8 isCCKrate, rf_path , dframe_type;
14253 	u8 *ptr;
14254 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14255 #ifdef DBG_RX_DFRAME_RAW_DATA
14256 	struct sta_recv_dframe_info *psta_dframe_info;
14257 #endif
14258 	struct recv_priv *precvpriv = &(padapter->recvpriv);
14259 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14260 	struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
14261 	struct sta_info *psta = prframe->u.hdr.psta;
14262 	struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
14263 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14264 	psample_pkt_rssi->data_rate = pattrib->data_rate;
14265 	ptr = prframe->u.hdr.rx_data;
14266 	dframe_type = GetFrameType(ptr);
14267 	/*RTW_INFO("=>%s\n", __FUNCTION__);*/
14268 
14269 
14270 	if (precvpriv->store_law_data_flag) {
14271 		isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14272 
14273 		psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
14274 		psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
14275 
14276 		for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14277 			psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
14278 			psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
14279 			if (!isCCKrate) {
14280 				psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
14281 				psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
14282 			}
14283 		}
14284 #ifdef DBG_RX_DFRAME_RAW_DATA
14285 		if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
14286 
14287 			/*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
14288 			if (psta) {
14289 				if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
14290 					psta_dframe_info = &psta->sta_dframe_info_bmc;
14291 				else
14292 					psta_dframe_info = &psta->sta_dframe_info;
14293 				/*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
14294 					__FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
14295 				if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
14296 					psta_dframe_info->sta_data_rate = pattrib->data_rate;
14297 					psta_dframe_info->sta_sgi = pattrib->sgi;
14298 					psta_dframe_info->sta_bw_mode = pattrib->bw;
14299 					for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14300 
14301 						psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
14302 
14303 						if (!isCCKrate) {
14304 							psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
14305 							psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
14306 						}
14307 					}
14308 				}
14309 			}
14310 		}
14311 #endif
14312 	}
14313 
14314 }
14315 
hal_efuse_macaddr_offset(_adapter * adapter)14316 int hal_efuse_macaddr_offset(_adapter *adapter)
14317 {
14318 	u8 interface_type = 0;
14319 	int addr_offset = -1;
14320 
14321 	interface_type = rtw_get_intf_type(adapter);
14322 
14323 	switch (rtw_get_chip_type(adapter)) {
14324 #ifdef CONFIG_RTL8723B
14325 	case RTL8723B:
14326 		if (interface_type == RTW_USB)
14327 			addr_offset = EEPROM_MAC_ADDR_8723BU;
14328 		else if (interface_type == RTW_SDIO)
14329 			addr_offset = EEPROM_MAC_ADDR_8723BS;
14330 		else if (interface_type == RTW_PCIE)
14331 			addr_offset = EEPROM_MAC_ADDR_8723BE;
14332 		break;
14333 #endif
14334 #ifdef CONFIG_RTL8703B
14335 	case RTL8703B:
14336 		if (interface_type == RTW_USB)
14337 			addr_offset = EEPROM_MAC_ADDR_8703BU;
14338 		else if (interface_type == RTW_SDIO)
14339 			addr_offset = EEPROM_MAC_ADDR_8703BS;
14340 		break;
14341 #endif
14342 #ifdef CONFIG_RTL8723D
14343 	case RTL8723D:
14344 		if (interface_type == RTW_USB)
14345 			addr_offset = EEPROM_MAC_ADDR_8723DU;
14346 		else if (interface_type == RTW_SDIO)
14347 			addr_offset = EEPROM_MAC_ADDR_8723DS;
14348 		else if (interface_type == RTW_PCIE)
14349 			addr_offset = EEPROM_MAC_ADDR_8723DE;
14350 		break;
14351 #endif
14352 
14353 #ifdef CONFIG_RTL8188E
14354 	case RTL8188E:
14355 		if (interface_type == RTW_USB)
14356 			addr_offset = EEPROM_MAC_ADDR_88EU;
14357 		else if (interface_type == RTW_SDIO)
14358 			addr_offset = EEPROM_MAC_ADDR_88ES;
14359 		else if (interface_type == RTW_PCIE)
14360 			addr_offset = EEPROM_MAC_ADDR_88EE;
14361 		break;
14362 #endif
14363 #ifdef CONFIG_RTL8188F
14364 	case RTL8188F:
14365 		if (interface_type == RTW_USB)
14366 			addr_offset = EEPROM_MAC_ADDR_8188FU;
14367 		else if (interface_type == RTW_SDIO)
14368 			addr_offset = EEPROM_MAC_ADDR_8188FS;
14369 		break;
14370 #endif
14371 #ifdef CONFIG_RTL8188GTV
14372 	case RTL8188GTV:
14373 		if (interface_type == RTW_USB)
14374 			addr_offset = EEPROM_MAC_ADDR_8188GTVU;
14375 		else if (interface_type == RTW_SDIO)
14376 			addr_offset = EEPROM_MAC_ADDR_8188GTVS;
14377 		break;
14378 #endif
14379 #ifdef CONFIG_RTL8812A
14380 	case RTL8812:
14381 		if (interface_type == RTW_USB)
14382 			addr_offset = EEPROM_MAC_ADDR_8812AU;
14383 		else if (interface_type == RTW_PCIE)
14384 			addr_offset = EEPROM_MAC_ADDR_8812AE;
14385 		break;
14386 #endif
14387 #ifdef CONFIG_RTL8821A
14388 	case RTL8821:
14389 		if (interface_type == RTW_USB)
14390 			addr_offset = EEPROM_MAC_ADDR_8821AU;
14391 		else if (interface_type == RTW_SDIO)
14392 			addr_offset = EEPROM_MAC_ADDR_8821AS;
14393 		else if (interface_type == RTW_PCIE)
14394 			addr_offset = EEPROM_MAC_ADDR_8821AE;
14395 		break;
14396 #endif
14397 #ifdef CONFIG_RTL8192E
14398 	case RTL8192E:
14399 		if (interface_type == RTW_USB)
14400 			addr_offset = EEPROM_MAC_ADDR_8192EU;
14401 		else if (interface_type == RTW_SDIO)
14402 			addr_offset = EEPROM_MAC_ADDR_8192ES;
14403 		else if (interface_type == RTW_PCIE)
14404 			addr_offset = EEPROM_MAC_ADDR_8192EE;
14405 		break;
14406 #endif
14407 #ifdef CONFIG_RTL8814A
14408 	case RTL8814A:
14409 		if (interface_type == RTW_USB)
14410 			addr_offset = EEPROM_MAC_ADDR_8814AU;
14411 		else if (interface_type == RTW_PCIE)
14412 			addr_offset = EEPROM_MAC_ADDR_8814AE;
14413 		break;
14414 #endif
14415 
14416 #ifdef CONFIG_RTL8822B
14417 	case RTL8822B:
14418 		if (interface_type == RTW_USB)
14419 			addr_offset = EEPROM_MAC_ADDR_8822BU;
14420 		else if (interface_type == RTW_SDIO)
14421 			addr_offset = EEPROM_MAC_ADDR_8822BS;
14422 		else if (interface_type == RTW_PCIE)
14423 			addr_offset = EEPROM_MAC_ADDR_8822BE;
14424 		break;
14425 #endif /* CONFIG_RTL8822B */
14426 
14427 #ifdef CONFIG_RTL8821C
14428 	case RTL8821C:
14429 		if (interface_type == RTW_USB)
14430 			addr_offset = EEPROM_MAC_ADDR_8821CU;
14431 		else if (interface_type == RTW_SDIO)
14432 			addr_offset = EEPROM_MAC_ADDR_8821CS;
14433 		else if (interface_type == RTW_PCIE)
14434 			addr_offset = EEPROM_MAC_ADDR_8821CE;
14435 		break;
14436 #endif /* CONFIG_RTL8821C */
14437 
14438 #ifdef CONFIG_RTL8710B
14439 	case RTL8710B:
14440 		if (interface_type == RTW_USB)
14441 			addr_offset = EEPROM_MAC_ADDR_8710B;
14442 		break;
14443 #endif
14444 
14445 #ifdef CONFIG_RTL8192F
14446 	case RTL8192F:
14447 		if (interface_type == RTW_USB)
14448 			addr_offset = EEPROM_MAC_ADDR_8192FU;
14449 		else if (interface_type == RTW_SDIO)
14450 			addr_offset = EEPROM_MAC_ADDR_8192FS;
14451 		else if (interface_type == RTW_PCIE)
14452 			addr_offset = EEPROM_MAC_ADDR_8192FE;
14453 		break;
14454 #endif /* CONFIG_RTL8192F */
14455 
14456 #ifdef CONFIG_RTL8822C
14457 	case RTL8822C:
14458 		if (interface_type == RTW_USB)
14459 			addr_offset = EEPROM_MAC_ADDR_8822CU;
14460 		else if (interface_type == RTW_SDIO)
14461 			addr_offset = EEPROM_MAC_ADDR_8822CS;
14462 		else if (interface_type == RTW_PCIE)
14463 			addr_offset = EEPROM_MAC_ADDR_8822CE;
14464 		break;
14465 #endif /* CONFIG_RTL8822C */
14466 
14467 #ifdef CONFIG_RTL8814B
14468 	case RTL8814B:
14469 		if (interface_type == RTW_USB)
14470 			addr_offset = EEPROM_MAC_ADDR_8814BU;
14471 		else if (interface_type == RTW_PCIE)
14472 			addr_offset = EEPROM_MAC_ADDR_8814BE;
14473 		break;
14474 #endif /* CONFIG_RTL8814B */
14475 
14476 #ifdef CONFIG_RTL8723F
14477 	case RTL8723F:
14478 		if (interface_type == RTW_USB)
14479 			addr_offset = EEPROM_MAC_ADDR_8723FU;
14480 		else if (interface_type == RTW_SDIO)
14481 			addr_offset = EEPROM_MAC_ADDR_8723FS;
14482 		break;
14483 #endif /* CONFIG_RTL8723F */
14484 	}
14485 
14486 	if (addr_offset == -1) {
14487 		RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
14488 			, __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
14489 	}
14490 
14491 	return addr_offset;
14492 }
14493 
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)14494 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
14495 {
14496 	int ret = _FAIL;
14497 	int addr_offset;
14498 
14499 	addr_offset = hal_efuse_macaddr_offset(padapter);
14500 	if (addr_offset == -1)
14501 		goto exit;
14502 
14503 	ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
14504 
14505 exit:
14506 	return ret;
14507 }
14508 
rtw_dump_cur_efuse(PADAPTER padapter)14509 void rtw_dump_cur_efuse(PADAPTER padapter)
14510 {
14511 	int mapsize =0;
14512 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14513 
14514 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
14515 
14516 	if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
14517 		RTW_ERR("wrong map size %d\n", mapsize);
14518 		return;
14519 	}
14520 
14521 #ifdef CONFIG_RTW_DEBUG
14522 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14523 		RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
14524 	else
14525 		RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
14526 #endif
14527 }
14528 
14529 
14530 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)14531 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
14532 {
14533 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14534 	u32 ret = _FALSE;
14535 	u32 maplen = 0;
14536 #ifdef CONFIG_MP_INCLUDED
14537 		struct mp_priv *pmp_priv = &padapter->mppriv;
14538 #endif
14539 
14540 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
14541 
14542 	if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
14543 		RTW_ERR("eFuse length error :%d\n", maplen);
14544 		return _FALSE;
14545 	}
14546 #ifdef CONFIG_MP_INCLUDED
14547 	if (pmp_priv->efuse_update_file == _TRUE && (rtw_mp_mode_check(padapter))) {
14548 		RTW_INFO("%s, eFuse read from file :%s\n", __func__, pmp_priv->efuse_file_path);
14549 		ret = rtw_read_efuse_from_file(pmp_priv->efuse_file_path, hal_data->efuse_eeprom_data, maplen);
14550 		pmp_priv->efuse_update_file = _FALSE;
14551 	} else
14552 #endif
14553 	{
14554 		ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
14555 	}
14556 
14557 	hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
14558 
14559 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14560 		rtw_dump_cur_efuse(padapter);
14561 
14562 	return ret;
14563 }
14564 
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)14565 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
14566 {
14567 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14568 	u32 ret = _FAIL;
14569 
14570 	if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
14571 		&& rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
14572 	) {
14573 		hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
14574 		ret = _SUCCESS;
14575 	} else
14576 		hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
14577 
14578 	return ret;
14579 }
14580 #endif /* CONFIG_EFUSE_CONFIG_FILE */
14581 
hal_config_macaddr(_adapter * adapter,bool autoload_fail)14582 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
14583 {
14584 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
14585 	u8 addr[ETH_ALEN];
14586 	int addr_offset = hal_efuse_macaddr_offset(adapter);
14587 	u8 *hw_addr = NULL;
14588 	int ret = _SUCCESS;
14589 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
14590 	u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
14591 #endif
14592 
14593 	if (autoload_fail)
14594 		goto bypass_hw_pg;
14595 
14596 	if (addr_offset != -1)
14597 		hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
14598 
14599 #ifdef CONFIG_EFUSE_CONFIG_FILE
14600 	/* if the hw_addr is written by efuse file, set to NULL */
14601 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14602 		hw_addr = NULL;
14603 #endif
14604 
14605 	if (!hw_addr) {
14606 		/* try getting hw pg data */
14607 		if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
14608 			hw_addr = addr;
14609 	}
14610 
14611 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
14612 	if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
14613 		hw_addr[0] = 0xff;
14614 #endif
14615 
14616 	/* check hw pg data */
14617 	if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
14618 		_rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
14619 		goto exit;
14620 	}
14621 
14622 bypass_hw_pg:
14623 
14624 #ifdef CONFIG_EFUSE_CONFIG_FILE
14625 	/* check wifi mac file */
14626 	if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
14627 		_rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
14628 		goto exit;
14629 	}
14630 #endif
14631 
14632 	_rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
14633 	ret = _FAIL;
14634 
14635 exit:
14636 	return ret;
14637 }
14638 
14639 #ifdef CONFIG_RF_POWER_TRIM
14640 u32 Array_kfreemap[] = {
14641 	0x08, 0xe,
14642 	0x06, 0xc,
14643 	0x04, 0xa,
14644 	0x02, 0x8,
14645 	0x00, 0x6,
14646 	0x03, 0x4,
14647 	0x05, 0x2,
14648 	0x07, 0x0,
14649 	0x09, 0x0,
14650 	0x0c, 0x0,
14651 };
14652 
rtw_bb_rf_gain_offset(_adapter * padapter)14653 void rtw_bb_rf_gain_offset(_adapter *padapter)
14654 {
14655 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14656 	struct registry_priv  *registry_par = &padapter->registrypriv;
14657 	struct kfree_data_t *kfree_data = &pHalData->kfree_data;
14658 	u8		value = pHalData->EEPROMRFGainOffset;
14659 	u8		tmp = 0x3e;
14660 	u32		res, i = 0;
14661 	u32		ArrayLen	= sizeof(Array_kfreemap) / sizeof(u32);
14662 	u32		*Array = Array_kfreemap;
14663 	u32		v1 = 0, v2 = 0, GainValue = 0, target = 0;
14664 
14665 	if (registry_par->RegPwrTrimEnable == 2) {
14666 		RTW_INFO("Registry kfree default force disable.\n");
14667 		return;
14668 	}
14669 
14670 #if defined(CONFIG_RTL8723B)
14671 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
14672 		RTW_INFO("Offset RF Gain.\n");
14673 		RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
14674 
14675 		if (pHalData->EEPROMRFGainVal != 0xff) {
14676 
14677 			if (pHalData->ant_path == RF_PATH_A)
14678 				GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
14679 
14680 			else
14681 				GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
14682 			RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
14683 
14684 			for (i = 0; i < ArrayLen; i += 2) {
14685 				/* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
14686 				v1 = Array[i];
14687 				v2 = Array[i + 1];
14688 				if (v1 == GainValue) {
14689 					RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
14690 					target = v2;
14691 					break;
14692 				}
14693 			}
14694 			RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
14695 
14696 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
14697 			RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
14698 			phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
14699 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
14700 
14701 			RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
14702 
14703 		} else
14704 
14705 			RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x	!= 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
14706 	} else
14707 		RTW_INFO("Using the default RF gain.\n");
14708 
14709 #elif defined(CONFIG_RTL8188E)
14710 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
14711 		RTW_INFO("8188ES Offset RF Gain.\n");
14712 		RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
14713 			 pHalData->EEPROMRFGainVal);
14714 
14715 		if (pHalData->EEPROMRFGainVal != 0xff) {
14716 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
14717 					 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
14718 
14719 			RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
14720 			res &= 0xfff87fff;
14721 
14722 			res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
14723 			RTW_INFO("Offset RF Gain. res=0x%x\n", res);
14724 
14725 			rtw_hal_write_rfreg(padapter, RF_PATH_A,
14726 					    REG_RF_BB_GAIN_OFFSET,
14727 					    RF_GAIN_OFFSET_MASK, res);
14728 		} else {
14729 			RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
14730 				 pHalData->EEPROMRFGainVal);
14731 		}
14732 	} else
14733 		RTW_INFO("Using the default RF gain.\n");
14734 #else
14735 	/* TODO: call this when channel switch */
14736 	if (kfree_data->flag & KFREE_FLAG_ON)
14737 		rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
14738 #endif
14739 
14740 }
14741 #endif /*CONFIG_RF_POWER_TRIM */
14742 
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)14743 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
14744 {
14745 #ifdef CONFIG_RF_POWER_TRIM
14746 	int i, j;
14747 
14748 	for (i = 0; i < BB_GAIN_NUM; i++)
14749 		for (j = 0; j < RF_PATH_MAX; j++)
14750 			if (data->bb_gain[i][j] != 0)
14751 				return 0;
14752 #endif
14753 	return 1;
14754 }
14755 
14756 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)14757 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
14758 {
14759 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14760 	if (cur_wireless_mode < WIRELESS_11_24N
14761 	    && cur_wireless_mode > 0) { /* ABG mode */
14762 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14763 		u32 remainder = 0;
14764 		u8 quotient = 0;
14765 
14766 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
14767 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14768 
14769 		if (quotient > 5) {
14770 			pHalData->rxagg_usb_size = 0x6;
14771 			pHalData->rxagg_usb_timeout = 0x10;
14772 		} else {
14773 			if (remainder >= 2048) {
14774 				pHalData->rxagg_usb_size = quotient;
14775 				pHalData->rxagg_usb_timeout = 0x10;
14776 			} else {
14777 				pHalData->rxagg_usb_size = (quotient - 1);
14778 				pHalData->rxagg_usb_timeout = 0x10;
14779 			}
14780 		}
14781 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14782 		if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
14783 			pHalData->rxagg_usb_size = 0x6;
14784 			pHalData->rxagg_usb_timeout = 0x10;
14785 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14786 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14787 		}
14788 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14789 
14790 	} else if (cur_wireless_mode >= WIRELESS_11_24N
14791 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14792 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14793 		u32 remainder = 0;
14794 		u8 quotient = 0;
14795 
14796 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
14797 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14798 
14799 		if (quotient > 5) {
14800 			pHalData->rxagg_usb_size = 0x5;
14801 			pHalData->rxagg_usb_timeout = 0x20;
14802 		} else {
14803 			if (remainder >= 2048) {
14804 				pHalData->rxagg_usb_size = quotient;
14805 				pHalData->rxagg_usb_timeout = 0x10;
14806 			} else {
14807 				pHalData->rxagg_usb_size = (quotient - 1);
14808 				pHalData->rxagg_usb_timeout = 0x10;
14809 			}
14810 		}
14811 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14812 		if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
14813 			pHalData->rxagg_usb_size = 0x5;
14814 			pHalData->rxagg_usb_timeout = 0x20;
14815 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14816 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14817 		}
14818 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14819 
14820 	} else {
14821 		/* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14822 	}
14823 }
14824 
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)14825 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
14826 {
14827 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14828 
14829 	if (cur_wireless_mode < WIRELESS_11_24N
14830 	    && cur_wireless_mode > 0) { /* ABG mode */
14831 		if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
14832 		    || 0x10 != pHalData->rxagg_usb_timeout) {
14833 			pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
14834 			pHalData->rxagg_usb_timeout = 0x10;
14835 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14836 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14837 		}
14838 	} else if (cur_wireless_mode >= WIRELESS_11_24N
14839 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14840 		if (UsbDmaSize != pHalData->rxagg_usb_size
14841 		    || 0x20 != pHalData->rxagg_usb_timeout) {
14842 			pHalData->rxagg_usb_size = UsbDmaSize;
14843 			pHalData->rxagg_usb_timeout = 0x20;
14844 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14845 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14846 		}
14847 	} else {
14848 		/* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14849 	}
14850 }
14851 
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)14852 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
14853 {
14854 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14855 	rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
14856 	return;
14857 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14858 
14859 	rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
14860 }
14861 #endif /* CONFIG_USB_RX_AGGREGATION */
14862 
14863 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)14864 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
14865 {
14866 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
14867 	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
14868 	struct registry_priv *registry_par = &padapter->registrypriv;
14869 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14870 	u8 cur_wireless_mode = WIRELESS_INVALID;
14871 
14872 #ifdef CONFIG_USB_RX_AGGREGATION
14873 	if (!registry_par->dynamic_agg_enable)
14874 		return;
14875 
14876 #ifdef RTW_HALMAC
14877 	if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter)
14878 		|| IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter)
14879 		|| IS_HARDWARE_TYPE_8723FU(padapter))
14880 		rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
14881 #else /* !RTW_HALMAC */
14882 	if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
14883 		/* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
14884 		if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) {
14885 			if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14886 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
14887 			else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14888 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
14889 			else
14890 				rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
14891 
14892 			/* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
14893 		}
14894 	} else if (IS_HARDWARE_TYPE_8812(padapter)) {
14895 #ifdef CONFIG_CONCURRENT_MODE
14896 		u8 i;
14897 		_adapter *iface;
14898 		u8 bassocaed = _FALSE;
14899 		struct mlme_ext_priv *mlmeext;
14900 
14901 		for (i = 0; i < pdvobjpriv->iface_nums; i++) {
14902 			iface = pdvobjpriv->padapters[i];
14903 			mlmeext = &iface->mlmeextpriv;
14904 			if (rtw_linked_check(iface) == _TRUE) {
14905 				if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
14906 					cur_wireless_mode = mlmeext->cur_wireless_mode;
14907 				bassocaed = _TRUE;
14908 			}
14909 		}
14910 		if (bassocaed)
14911 #endif
14912 			rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14913 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14914 	} else {
14915 		rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14916 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14917 	}
14918 #endif /* RTW_HALMAC */
14919 #endif /* CONFIG_USB_RX_AGGREGATION */
14920 
14921 }
14922 
14923 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)14924 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
14925 {
14926 #ifdef CONFIG_AP_MODE
14927 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14928 	u8 chk_rst = _SUCCESS;
14929 
14930 	if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
14931 		return chk_rst;
14932 
14933 	/* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
14934 	/*	return chk_rst; */
14935 
14936 	if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
14937 	    && (pre_qsel != next_qsel)) {
14938 		/* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
14939 		/*	pre_qsel,next_qsel); */
14940 		chk_rst = _FAIL;
14941 	}
14942 	return chk_rst;
14943 #else
14944 	return _SUCCESS;
14945 #endif /* CONFIG_AP_MODE */
14946 }
14947 
14948 #ifdef CONFIG_WOWLAN
14949 /*
14950  * Description:
14951  * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
14952  * contant.
14953  *
14954  * Input:
14955  * adapter: adapter pointer.
14956  * page_num: The max. page number that user want to dump.
14957  * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
14958  */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)14959 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
14960 {
14961 
14962 	int i;
14963 	u8 val = 0;
14964 	u8 base = 0;
14965 	u32 addr = 0;
14966 	u32 count = (page_size / 8);
14967 
14968 	if (page_num <= 0) {
14969 		RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
14970 		return;
14971 	}
14972 
14973 	if (page_size < 128 || page_size > 512) {
14974 		RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
14975 		return;
14976 	}
14977 
14978 	RTW_INFO("+%s+\n", __func__);
14979 	val = rtw_read8(padapter, 0x106);
14980 	rtw_write8(padapter, 0x106, 0x69);
14981 	RTW_INFO("0x106: 0x%02x\n", val);
14982 	base = rtw_read8(padapter, 0x209);
14983 	RTW_INFO("0x209: 0x%02x\n", base);
14984 
14985 	addr = ((base)*page_size) / 8;
14986 	for (i = 0 ; i < page_num * count ; i += 2) {
14987 		rtw_write32(padapter, 0x140, addr + i);
14988 		printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14989 		rtw_write32(padapter, 0x140, addr + i + 1);
14990 		printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14991 	}
14992 }
14993 #endif
14994 
14995 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)14996 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
14997 {
14998 	u8 value = 0;
14999 	u8 direction = 0;
15000 	u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
15001 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
15002 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
15003 	u8 gpio_num_to_set = gpio_num;
15004 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
15005 
15006 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15007 		return value;
15008 
15009 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15010 
15011 	RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
15012 	LeaveAllPowerSaveModeDirect(adapter);
15013 
15014 	if (gpio_num > 7) {
15015 		gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
15016 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
15017 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
15018 		gpio_num_to_set = gpio_num - 8;
15019 	}
15020 
15021 	/* Read GPIO Direction */
15022 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15023 
15024 	/* According the direction to read register value */
15025 	if (direction)
15026 		value =  (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15027 	else
15028 		value =  (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15029 
15030 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15031 	RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
15032 
15033 	return value;
15034 }
15035 
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)15036 int  rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
15037 {
15038 	u8 direction = 0;
15039 	u8 res = -1;
15040 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
15041 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
15042 	u8 gpio_num_to_set = gpio_num;
15043 
15044 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15045 		return -1;
15046 
15047 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15048 
15049 	LeaveAllPowerSaveModeDirect(adapter);
15050 
15051 	if (gpio_num > 7) {
15052 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
15053 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
15054 		gpio_num_to_set = gpio_num - 8;
15055 	}
15056 
15057 	/* Read GPIO direction */
15058 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15059 
15060 	/* If GPIO is output direction, setting value. */
15061 	if (direction) {
15062 		if (isHigh)
15063 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
15064 		else
15065 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
15066 
15067 		RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
15068 		res = 0;
15069 	} else {
15070 		RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
15071 		res = -1;
15072 	}
15073 
15074 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15075 	return res;
15076 }
15077 
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)15078 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
15079 {
15080 	u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
15081 	u8 gpio_num_to_set = gpio_num;
15082 
15083 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15084 		return -1;
15085 
15086 	RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
15087 
15088 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15089 
15090 	LeaveAllPowerSaveModeDirect(adapter);
15091 
15092 	rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
15093 
15094 	if (gpio_num > 7) {
15095 		gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
15096 		gpio_num_to_set = gpio_num - 8;
15097 	}
15098 
15099 	if (isOutput)
15100 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
15101 	else
15102 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
15103 
15104 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15105 
15106 	return 0;
15107 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))15108 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
15109 {
15110 	u8 value;
15111 	u8 direction;
15112 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
15113 
15114 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
15115 		if (gpio_num > 7 || gpio_num < 4) {
15116 			RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
15117 			return -1;
15118 		}
15119 	}
15120 
15121 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15122 
15123 	LeaveAllPowerSaveModeDirect(adapter);
15124 
15125 	/* Read GPIO direction */
15126 	direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
15127 	if (direction) {
15128 		RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
15129 		return -1;
15130 	}
15131 
15132 	/* Config GPIO Mode */
15133 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
15134 
15135 	/* Register GPIO interrupt handler*/
15136 	adapter->gpiointpriv.callback[gpio_num] = callback;
15137 
15138 	/* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
15139 	value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
15140 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
15141 	rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
15142 
15143 	/* Enable GPIO interrupt */
15144 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
15145 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
15146 
15147 	rtw_hal_update_hisr_hsisr_ind(adapter, 1);
15148 
15149 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15150 
15151 	return 0;
15152 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)15153 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
15154 {
15155 	u8 value;
15156 	u8 direction;
15157 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
15158 
15159 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
15160 		if (gpio_num > 7 || gpio_num < 4) {
15161 			RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
15162 			return -1;
15163 		}
15164 	}
15165 
15166 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15167 
15168 	LeaveAllPowerSaveModeDirect(adapter);
15169 
15170 	/* Config GPIO Mode */
15171 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
15172 
15173 	/* Unregister GPIO interrupt handler*/
15174 	adapter->gpiointpriv.callback[gpio_num] = NULL;
15175 
15176 	/* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
15177 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
15178 	rtw_write8(adapter, REG_GPIO_INTM, 0x00);
15179 
15180 	/* Disable GPIO interrupt */
15181 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
15182 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
15183 
15184 	if (!adapter->gpiointpriv.interrupt_enable_mask)
15185 		rtw_hal_update_hisr_hsisr_ind(adapter, 0);
15186 
15187 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15188 
15189 	return 0;
15190 }
15191 #endif
15192 
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)15193 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
15194 {
15195 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15196 	u8 i;
15197 
15198 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
15199 		if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
15200 			if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
15201 			    && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
15202 				return i;
15203 		}
15204 	}
15205 
15206 	return -1;
15207 }
15208 
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)15209 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
15210 {
15211 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15212 	s8 res;
15213 	u8 i;
15214 
15215 	/* If it's an existed record, overwrite it */
15216 	res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
15217 	if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
15218 		rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
15219 		return;
15220 	}
15221 
15222 	/* Search for the empty record to use */
15223 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
15224 		if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
15225 			rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
15226 			return;
15227 		}
15228 	}
15229 
15230 	/* Else, overwrite the oldest record */
15231 	for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
15232 		_rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
15233 
15234 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
15235 }
15236 
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)15237 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
15238 {
15239 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
15240 }
15241 
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15242 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15243 {
15244 	u32	mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
15245 	u32	mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
15246 	u32	mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
15247 	u32	DropPacket = 0;
15248 
15249 	if (!rx_counter) {
15250 		rtw_warn_on(1);
15251 		return;
15252 	}
15253 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
15254 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15255 
15256 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
15257 	mac_cck_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	  */
15258 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
15259 	mac_ofdm_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15260 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
15261 	mac_ht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15262 	mac_vht_ok	= 0;
15263 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15264 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
15265 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
15266 		mac_vht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
15267 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15268 	}
15269 
15270 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
15271 	mac_cck_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15272 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
15273 	mac_ofdm_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15274 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
15275 	mac_ht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
15276 	mac_vht_err	= 0;
15277 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15278 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
15279 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
15280 		mac_vht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
15281 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15282 	}
15283 
15284 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
15285 	mac_cck_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15286 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
15287 	mac_ofdm_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15288 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
15289 	mac_ht_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
15290 
15291 	/* Mac_DropPacket */
15292 	rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
15293 	DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
15294 
15295 	rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
15296 	rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
15297 	rx_counter->rx_cck_fa = mac_cck_fa;
15298 	rx_counter->rx_ofdm_fa = mac_ofdm_fa;
15299 	rx_counter->rx_ht_fa = mac_ht_fa;
15300 	rx_counter->rx_pkt_drop = DropPacket;
15301 }
rtw_reset_mac_rx_counters(_adapter * padapter)15302 void rtw_reset_mac_rx_counters(_adapter *padapter)
15303 {
15304 
15305 	/* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
15306 	if (IS_HARDWARE_TYPE_8703B(padapter) ||
15307 		IS_HARDWARE_TYPE_8723D(padapter) ||
15308 		IS_HARDWARE_TYPE_8188F(padapter) ||
15309 		IS_HARDWARE_TYPE_8188GTV(padapter) ||
15310 		IS_HARDWARE_TYPE_8192F(padapter) ||
15311 		IS_HARDWARE_TYPE_8822C(padapter))
15312 		phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
15313 
15314 	/* reset mac counter */
15315 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
15316 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
15317 }
15318 
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15319 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15320 {
15321 	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;
15322 	if (!rx_counter) {
15323 		rtw_warn_on(1);
15324 		return;
15325 	}
15326 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15327 		cckok	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF);	     /* [13:0] */
15328 		ofdmok	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF);	     /* [13:0] */
15329 		htok		= phy_query_bb_reg(padapter, 0xF10, 0x3FFF);     /* [13:0] */
15330 		vht_ok	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF);     /* [13:0] */
15331 		cckcrc	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16]	 */
15332 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
15333 		htcrc	= phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
15334 		vht_err	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
15335 		CCK_FA	= phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
15336 		OFDM_FA	= phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
15337 	} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
15338 		cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
15339 		ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
15340 		htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
15341 		vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
15342 		cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
15343 		ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
15344 		htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
15345 		vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
15346 		CCK_FA	= phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
15347 		OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
15348 	} else if(IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)){
15349 		cckok = phy_query_bb_reg(padapter, 0x2aac, 0xffff);
15350 		ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
15351 		htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
15352 		cckcrc = phy_query_bb_reg(padapter, 0x2aac, 0xffff0000);
15353 		ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
15354 		htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
15355 		CCK_FA	= phy_query_bb_reg(padapter, 0x2aa8, 0xffff0000) + phy_query_bb_reg(padapter, 0x2aa8, 0x0000ffff);
15356 		OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
15357 	} else {
15358 		cckok	= phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
15359 		ofdmok	= phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
15360 		htok		= phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
15361 		vht_ok	= 0;
15362 		cckcrc	= phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
15363 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
15364 		htcrc	= phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
15365 		vht_err	= 0;
15366 		OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
15367 			phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
15368 			phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
15369 
15370 		CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
15371 	}
15372 
15373 	rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
15374 	rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
15375 	rx_counter->rx_ofdm_fa = OFDM_FA;
15376 	rx_counter->rx_cck_fa = CCK_FA;
15377 
15378 }
15379 
rtw_reset_phy_trx_ok_counters(_adapter * padapter)15380 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
15381 {
15382 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15383 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
15384 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
15385 	} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) {
15386 		phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
15387 		phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
15388 	} else {
15389 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
15390 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
15391 	}
15392 }
15393 
rtw_reset_phy_rx_counters(_adapter * padapter)15394 void rtw_reset_phy_rx_counters(_adapter *padapter)
15395 {
15396 	/* reset phy counter */
15397 	if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
15398 		/* reset CCK FA counter */
15399 		phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
15400 		phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
15401 
15402 		/* reset CCK CCA counter */
15403 		phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
15404 		phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
15405 
15406 	} else if (IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) {
15407 		/* reset CCK FA and CCK CCA counter */
15408 		phy_set_bb_reg(padapter, 0x2a44, BIT21, 0);
15409 		phy_set_bb_reg(padapter, 0x2a44, BIT21, 1);
15410 		rtw_reset_phy_trx_ok_counters(padapter);
15411 
15412 	} else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15413 		rtw_reset_phy_trx_ok_counters(padapter);
15414 
15415 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset  OFDA FA counter */
15416 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
15417 
15418 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
15419 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
15420 	} else {
15421 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
15422 		rtw_msleep_os(10);
15423 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
15424 
15425 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset  OFDA FA counter */
15426 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset  OFDA FA counter */
15427 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
15428 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
15429 
15430 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
15431 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
15432 	}
15433 }
15434 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15435 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15436 {
15437 	struct recv_priv *precvpriv = &padapter->recvpriv;
15438 	if (!rx_counter) {
15439 		rtw_warn_on(1);
15440 		return;
15441 	}
15442 	rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
15443 	rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
15444 	rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
15445 }
rtw_reset_drv_rx_counters(_adapter * padapter)15446 void rtw_reset_drv_rx_counters(_adapter *padapter)
15447 {
15448 	struct recv_priv *precvpriv = &padapter->recvpriv;
15449 	padapter->drv_rx_cnt_ok = 0;
15450 	padapter->drv_rx_cnt_crcerror = 0;
15451 	padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
15452 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)15453 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
15454 {
15455 	u8 initialgain;
15456 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15457 
15458 	if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
15459 		rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
15460 		RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
15461 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
15462 		/*disable dynamic functions, such as high power, DIG*/
15463 		rtw_phydm_ability_backup(padapter);
15464 		rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
15465 	} else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
15466 		/* turn on phy-dynamic functions */
15467 		rtw_phydm_ability_restore(padapter);
15468 		initialgain = 0xff; /* restore RX GAIN */
15469 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
15470 
15471 	}
15472 }
15473 
rtw_dump_rx_counters(_adapter * padapter)15474 void rtw_dump_rx_counters(_adapter *padapter)
15475 {
15476 	struct dbg_rx_counter rx_counter;
15477 
15478 	if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
15479 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15480 		rtw_dump_drv_rx_counters(padapter, &rx_counter);
15481 		RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
15482 			rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
15483 		rtw_reset_drv_rx_counters(padapter);
15484 	}
15485 
15486 	if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
15487 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15488 		rtw_dump_mac_rx_counters(padapter, &rx_counter);
15489 		RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
15490 			 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
15491 			rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
15492 			 rx_counter.rx_pkt_drop);
15493 		rtw_reset_mac_rx_counters(padapter);
15494 	}
15495 
15496 	if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
15497 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15498 		rtw_dump_phy_rx_counters(padapter, &rx_counter);
15499 		/* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
15500 		/* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
15501 		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,
15502 			 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
15503 		rtw_reset_phy_rx_counters(padapter);
15504 	}
15505 }
15506 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)15507 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
15508 {
15509 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15510 	u8 curr_tx_sgi = 0;
15511 	struct ra_sta_info *ra_info;
15512 
15513 	if (!psta)
15514 		return curr_tx_sgi;
15515 
15516 	if (padapter->fix_rate == 0xff) {
15517 #if defined(CONFIG_RTL8188E)
15518 #if (RATE_ADAPTIVE_SUPPORT == 1)
15519 		curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
15520 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
15521 #else
15522 		ra_info = &psta->cmn.ra_info;
15523 		curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
15524 #endif
15525 	} else {
15526 		curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
15527 	}
15528 
15529 	return curr_tx_sgi;
15530 }
15531 
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)15532 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
15533 {
15534 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15535 	u8 rate_id = 0;
15536 	struct ra_sta_info *ra_info;
15537 
15538 	if (!psta)
15539 		return rate_id;
15540 
15541 	if (padapter->fix_rate == 0xff) {
15542 #if defined(CONFIG_RTL8188E)
15543 #if (RATE_ADAPTIVE_SUPPORT == 1)
15544 		rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
15545 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
15546 #else
15547 		ra_info = &psta->cmn.ra_info;
15548 		rate_id = ra_info->curr_tx_rate & 0x7f;
15549 #endif
15550 	} else {
15551 		rate_id = padapter->fix_rate & 0x7f;
15552 	}
15553 
15554 	return rate_id;
15555 }
15556 
update_IOT_info(_adapter * padapter)15557 void update_IOT_info(_adapter *padapter)
15558 {
15559 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
15560 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
15561 
15562 	switch (pmlmeinfo->assoc_AP_vendor) {
15563 	case HT_IOT_PEER_MARVELL:
15564 		pmlmeinfo->turboMode_cts2self = 1;
15565 		pmlmeinfo->turboMode_rtsen = 0;
15566 		break;
15567 
15568 	case HT_IOT_PEER_RALINK:
15569 		pmlmeinfo->turboMode_cts2self = 0;
15570 		pmlmeinfo->turboMode_rtsen = 1;
15571 		break;
15572 	case HT_IOT_PEER_REALTEK:
15573 		/* rtw_write16(padapter, 0x4cc, 0xffff); */
15574 		/* rtw_write16(padapter, 0x546, 0x01c0); */
15575 		break;
15576 	default:
15577 		pmlmeinfo->turboMode_cts2self = 0;
15578 		pmlmeinfo->turboMode_rtsen = 1;
15579 		break;
15580 	}
15581 
15582 }
15583 #ifdef CONFIG_RTS_FULL_BW
15584 /*
15585 8188E: not support full RTS BW feature(mac REG no define 480[5])
15586 */
rtw_set_rts_bw(_adapter * padapter)15587 void rtw_set_rts_bw(_adapter *padapter) {
15588 	int i;
15589 	u8 enable = 1;
15590 	bool connect_to_8812 = _FALSE;
15591 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
15592 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
15593 	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
15594 	struct sta_info *station = NULL;
15595 
15596 	for (i = 0; i < macid_ctl->num; i++) {
15597 		if (rtw_macid_is_used(macid_ctl, i)) {
15598 
15599 			station = NULL;
15600 			station = macid_ctl->sta[i];
15601 			if(station) {
15602 
15603 				 _adapter *sta_adapter =station->padapter;
15604 				struct mlme_ext_priv	*pmlmeext = &(sta_adapter->mlmeextpriv);
15605 				struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
15606 
15607 				if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
15608 					if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) !=  _TRUE) {
15609 						if (  macid_ctl->sta[i]->vendor_8812) {
15610 							connect_to_8812 = _TRUE;
15611 							enable = 0;
15612 						}
15613 					}
15614 				}
15615 			}
15616 		}
15617 
15618 		if(connect_to_8812)
15619 			break;
15620 	}
15621 
15622 		RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
15623 		rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
15624 }
15625 #endif/*CONFIG_RTS_FULL_BW*/
15626 
hal_spec_init(_adapter * adapter)15627 int hal_spec_init(_adapter *adapter)
15628 {
15629 	u8 interface_type = 0;
15630 	int ret = _SUCCESS;
15631 
15632 	interface_type = rtw_get_intf_type(adapter);
15633 
15634 	switch (rtw_get_chip_type(adapter)) {
15635 #ifdef CONFIG_RTL8723B
15636 	case RTL8723B:
15637 		init_hal_spec_8723b(adapter);
15638 		break;
15639 #endif
15640 #ifdef CONFIG_RTL8703B
15641 	case RTL8703B:
15642 		init_hal_spec_8703b(adapter);
15643 		break;
15644 #endif
15645 #ifdef CONFIG_RTL8723D
15646 	case RTL8723D:
15647 		init_hal_spec_8723d(adapter);
15648 		break;
15649 #endif
15650 #ifdef CONFIG_RTL8188E
15651 	case RTL8188E:
15652 		init_hal_spec_8188e(adapter);
15653 		break;
15654 #endif
15655 #ifdef CONFIG_RTL8188F
15656 	case RTL8188F:
15657 		init_hal_spec_8188f(adapter);
15658 		break;
15659 #endif
15660 #ifdef CONFIG_RTL8188GTV
15661 	case RTL8188GTV:
15662 		init_hal_spec_8188gtv(adapter);
15663 		break;
15664 #endif
15665 #ifdef CONFIG_RTL8812A
15666 	case RTL8812:
15667 		init_hal_spec_8812a(adapter);
15668 		break;
15669 #endif
15670 #ifdef CONFIG_RTL8821A
15671 	case RTL8821:
15672 		init_hal_spec_8821a(adapter);
15673 		break;
15674 #endif
15675 #ifdef CONFIG_RTL8192E
15676 	case RTL8192E:
15677 		init_hal_spec_8192e(adapter);
15678 		break;
15679 #endif
15680 #ifdef CONFIG_RTL8814A
15681 	case RTL8814A:
15682 		init_hal_spec_8814a(adapter);
15683 		break;
15684 #endif
15685 #ifdef CONFIG_RTL8822B
15686 	case RTL8822B:
15687 		rtl8822b_init_hal_spec(adapter);
15688 		break;
15689 #endif
15690 #ifdef CONFIG_RTL8821C
15691 	case RTL8821C:
15692 		init_hal_spec_rtl8821c(adapter);
15693 		break;
15694 #endif
15695 #ifdef CONFIG_RTL8710B
15696 	case RTL8710B:
15697 		init_hal_spec_8710b(adapter);
15698 		break;
15699 #endif
15700 #ifdef CONFIG_RTL8192F
15701 	case RTL8192F:
15702 		init_hal_spec_8192f(adapter);
15703 		break;
15704 #endif
15705 #ifdef CONFIG_RTL8822C
15706 	case RTL8822C:
15707 		rtl8822c_init_hal_spec(adapter);
15708 		break;
15709 #endif
15710 #ifdef CONFIG_RTL8814B
15711 	case RTL8814B:
15712 		rtl8814b_init_hal_spec(adapter);
15713 		break;
15714 #endif
15715 #ifdef CONFIG_RTL8723F
15716 	case RTL8723F:
15717 		rtl8723f_init_hal_spec(adapter);
15718 		break;
15719 #endif
15720 	default:
15721 		RTW_ERR("%s: unknown chip_type:%u\n"
15722 			, __func__, rtw_get_chip_type(adapter));
15723 		ret = _FAIL;
15724 		break;
15725 	}
15726 
15727 	return ret;
15728 }
15729 
15730 static const char *const _band_cap_str[] = {
15731 	/* BIT0 */"2G",
15732 	/* BIT1 */"5G",
15733 };
15734 
15735 static const char *const _bw_cap_str[] = {
15736 	/* BIT0 */"5M",
15737 	/* BIT1 */"10M",
15738 	/* BIT2 */"20M",
15739 	/* BIT3 */"40M",
15740 	/* BIT4 */"80M",
15741 	/* BIT5 */"160M",
15742 	/* BIT6 */"80_80M",
15743 };
15744 
15745 static const char *const _proto_cap_str[] = {
15746 	/* BIT0 */"b",
15747 	/* BIT1 */"g",
15748 	/* BIT2 */"n",
15749 	/* BIT3 */"ac",
15750 };
15751 
15752 static const char *const _wl_func_str[] = {
15753 	/* BIT0 */"P2P",
15754 	/* BIT1 */"MIRACAST",
15755 	/* BIT2 */"TDLS",
15756 	/* BIT3 */"FTM",
15757 };
15758 
dump_hal_spec(void * sel,_adapter * adapter)15759 void dump_hal_spec(void *sel, _adapter *adapter)
15760 {
15761 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15762 	int i;
15763 
15764 	RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
15765 	RTW_PRINT_SEL(sel, "macid_cap:%u\n", hal_spec->macid_cap);
15766 	RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
15767 	RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
15768 
15769 	RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
15770 	RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
15771 	RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
15772 	RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num);
15773 	RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp);
15774 	RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
15775 
15776 	RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
15777 	RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
15778 
15779 	RTW_PRINT_SEL(sel, "band_cap:");
15780 	for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
15781 		if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
15782 			_RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
15783 	}
15784 	_RTW_PRINT_SEL(sel, "\n");
15785 
15786 	RTW_PRINT_SEL(sel, "bw_cap:");
15787 	for (i = 0; i < BW_CAP_BIT_NUM; i++) {
15788 		if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
15789 			_RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
15790 	}
15791 	_RTW_PRINT_SEL(sel, "\n");
15792 
15793 	RTW_PRINT_SEL(sel, "proto_cap:");
15794 	for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
15795 		if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
15796 			_RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
15797 	}
15798 	_RTW_PRINT_SEL(sel, "\n");
15799 
15800 	RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
15801 	RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
15802 
15803 	RTW_PRINT_SEL(sel, "wl_func:");
15804 	for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
15805 		if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
15806 			_RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
15807 	}
15808 	_RTW_PRINT_SEL(sel, "\n");
15809 
15810 #if CONFIG_TX_AC_LIFETIME
15811 	RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
15812 		, hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
15813 #endif
15814 
15815 	RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
15816 
15817 	RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
15818 	RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
15819 }
15820 
hal_chk_band_cap(_adapter * adapter,u8 cap)15821 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
15822 {
15823 	return GET_HAL_SPEC(adapter)->band_cap & cap;
15824 }
15825 
hal_chk_bw_cap(_adapter * adapter,u8 cap)15826 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
15827 {
15828 	return GET_HAL_SPEC(adapter)->bw_cap & cap;
15829 }
15830 
hal_chk_proto_cap(_adapter * adapter,u8 cap)15831 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
15832 {
15833 	return GET_HAL_SPEC(adapter)->proto_cap & cap;
15834 }
15835 
hal_chk_wl_func(_adapter * adapter,u8 func)15836 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
15837 {
15838 	return GET_HAL_SPEC(adapter)->wl_func & func;
15839 }
15840 
hal_is_band_support(_adapter * adapter,u8 band)15841 inline bool hal_is_band_support(_adapter *adapter, u8 band)
15842 {
15843 	return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
15844 }
15845 
hal_is_bw_support(_adapter * adapter,u8 bw)15846 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
15847 {
15848 	return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
15849 }
15850 
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)15851 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
15852 {
15853 	u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
15854 
15855 	if (mode == WIRELESS_11B)
15856 		if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15857 			return 1;
15858 
15859 	if (mode == WIRELESS_11G)
15860 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15861 			return 1;
15862 
15863 	if (mode == WIRELESS_11A)
15864 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15865 			return 1;
15866 
15867 	if (mode == WIRELESS_11_24N)
15868 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15869 			return 1;
15870 
15871 	if (mode == WIRELESS_11_5N)
15872 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15873 			return 1;
15874 
15875 	if (mode == WIRELESS_11AC)
15876 		if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15877 			return 1;
15878 
15879 	return 0;
15880 }
hal_is_mimo_support(_adapter * adapter)15881 inline bool hal_is_mimo_support(_adapter *adapter)
15882 {
15883 	if ((GET_HAL_TX_NSS(adapter) == 1) &&
15884 		(GET_HAL_RX_NSS(adapter) == 1))
15885 		return 0;
15886 	return 1;
15887 }
15888 
15889 /*
15890 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
15891 * @adapter:
15892 * @in_bw: starting bw, value of enum channel_width
15893 *
15894 * Returns: value of enum channel_width
15895 */
hal_largest_bw(_adapter * adapter,u8 in_bw)15896 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
15897 {
15898 	for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
15899 		if (hal_is_bw_support(adapter, in_bw))
15900 			break;
15901 	}
15902 
15903 	if (!hal_is_bw_support(adapter, in_bw))
15904 		rtw_warn_on(1);
15905 
15906 	return in_bw;
15907 }
15908 
15909 #ifndef CONFIG_HAS_TX_BEACON_PAUSE
ResumeTxBeacon(_adapter * padapter)15910 void ResumeTxBeacon(_adapter *padapter)
15911 {
15912 	RTW_DBG("ResumeTxBeacon\n");
15913 	#ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE
15914 	rtw_write8(padapter, REG_TXPAUSE,
15915 		rtw_read8(padapter, REG_TXPAUSE) & (~BIT6));
15916 	#else
15917 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15918 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
15919 	#endif
15920 
15921 #ifdef RTW_HALMAC
15922 	/* Add this for driver using HALMAC because driver doesn't have setup time init by self */
15923 	/* TBTT setup time */
15924 	rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
15925 #endif
15926 
15927 	/* TBTT hold time: 0x540[19:8] */
15928 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
15929 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15930 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
15931 }
15932 
StopTxBeacon(_adapter * padapter)15933 void StopTxBeacon(_adapter *padapter)
15934 {
15935 	RTW_DBG("StopTxBeacon\n");
15936 	#ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE
15937 	rtw_write8(padapter, REG_TXPAUSE,
15938 	rtw_read8(padapter, REG_TXPAUSE) | BIT6);
15939 	#else
15940 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15941 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
15942 	#endif
15943 
15944 	/* TBTT hold time: 0x540[19:8] */
15945 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
15946 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15947 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
15948 }
15949 #endif /* CONFIG_HAS_TX_BEACON_PAUSE */
15950 
15951 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
15952 
15953 #ifdef CONFIG_CLIENT_PORT_CFG
15954 const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
15955 	CLT_PORT0,
15956 	CLT_PORT1,
15957 	CLT_PORT2,
15958 	CLT_PORT3
15959 };
15960 
rtw_clt_port_init(struct clt_port_t * cltp)15961 void rtw_clt_port_init(struct clt_port_t  *cltp)
15962 {
15963 	cltp->bmp = 0;
15964 	cltp->num = 0;
15965 	_rtw_spinlock_init(&cltp->lock);
15966 }
rtw_clt_port_deinit(struct clt_port_t * cltp)15967 void rtw_clt_port_deinit(struct clt_port_t *cltp)
15968 {
15969 	_rtw_spinlock_free(&cltp->lock);
15970 }
_hw_client_port_alloc(_adapter * adapter)15971 static void _hw_client_port_alloc(_adapter *adapter)
15972 {
15973 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15974 	struct clt_port_t  *cltp = &dvobj->clt_port;
15975 	_irqL irql;
15976 	int i;
15977 
15978 	#if 0
15979 	if (cltp->num > MAX_CLIENT_PORT_NUM) {
15980 		RTW_ERR(ADPT_FMT" cann't  alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
15981 		rtw_warn_on(1);
15982 		return;
15983 	}
15984 	#endif
15985 
15986 	if (adapter->client_id !=  MAX_CLIENT_PORT_NUM) {
15987 		RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
15988 			ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
15989 		return;
15990 	}
15991 	_enter_critical_bh(&cltp->lock, &irql);
15992 	for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
15993 		if (!(cltp->bmp & BIT(i)))
15994 			break;
15995 	}
15996 
15997 	if (i < MAX_CLIENT_PORT_NUM) {
15998 		adapter->client_id = i;
15999 		cltp->bmp |= BIT(i);
16000 		adapter->client_port = _clt_port_id[i];
16001 	}
16002 	cltp->num++;
16003 	_exit_critical_bh(&cltp->lock, &irql);
16004 	RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
16005 		__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
16006 }
_hw_client_port_free(_adapter * adapter)16007 static void _hw_client_port_free(_adapter *adapter)
16008 {
16009 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
16010 	struct clt_port_t  *cltp = &dvobj->clt_port;
16011 	_irqL irql;
16012 
16013 	#if 0
16014 	if (adapter->client_id >=  MAX_CLIENT_PORT_NUM) {
16015 		RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
16016 		/*rtw_warn_on(1);*/
16017 	}
16018 	#endif
16019 
16020 	RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
16021 		__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
16022 
16023 	_enter_critical_bh(&cltp->lock, &irql);
16024 	if (adapter->client_id !=  MAX_CLIENT_PORT_NUM) {
16025 		cltp->bmp &= ~ BIT(adapter->client_id);
16026 		adapter->client_id = MAX_CLIENT_PORT_NUM;
16027 		adapter->client_port = CLT_PORT_INVALID;
16028 	}
16029 	cltp->num--;
16030 	if (cltp->num < 0)
16031 		cltp->num = 0;
16032 	_exit_critical_bh(&cltp->lock, &irql);
16033 }
rtw_hw_client_port_allocate(_adapter * adapter)16034 void rtw_hw_client_port_allocate(_adapter *adapter)
16035 {
16036 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16037 
16038 	if (hal_spec->port_num != 5)
16039 		return;
16040 
16041 	_hw_client_port_alloc(adapter);
16042 }
rtw_hw_client_port_release(_adapter * adapter)16043 void rtw_hw_client_port_release(_adapter *adapter)
16044 {
16045 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16046 
16047 	if (hal_spec->port_num != 5)
16048 		return;
16049 
16050 	_hw_client_port_free(adapter);
16051 }
16052 #endif /*CONFIG_CLIENT_PORT_CFG*/
16053 
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)16054 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
16055 {
16056 	RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
16057 
16058 	rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
16059 
16060 	/* set net_type */
16061 	Set_MSR(Adapter, mode);
16062 
16063 	if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
16064 		if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
16065 			StopTxBeacon(Adapter);
16066 	} else if (mode == _HW_STATE_ADHOC_)
16067 		ResumeTxBeacon(Adapter);
16068 	else if (mode == _HW_STATE_AP_)
16069 		/* enable rx ps-poll */
16070 		rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
16071 
16072 	/* enable rx data frame */
16073 	rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
16074 
16075 #ifdef CONFIG_CLIENT_PORT_CFG
16076 	if (mode == _HW_STATE_STATION_)
16077 		rtw_hw_client_port_allocate(Adapter);
16078 	else
16079 		rtw_hw_client_port_release(Adapter);
16080 #endif
16081 #if defined(CONFIG_RTL8192F)
16082 		rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
16083 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
16084 #endif
16085 }
16086 #endif
16087 
16088 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)16089 u8	rtw_hal_antdiv_before_linked(_adapter *padapter)
16090 {
16091 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16092 	u8 cur_ant, change_ant;
16093 
16094 	if (!pHalData->AntDivCfg)
16095 		return _FALSE;
16096 
16097 	if (pHalData->sw_antdiv_bl_state == 0) {
16098 		pHalData->sw_antdiv_bl_state = 1;
16099 
16100 		rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
16101 		change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
16102 
16103 		return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
16104 	}
16105 
16106 	pHalData->sw_antdiv_bl_state = 0;
16107 	return _FALSE;
16108 }
16109 
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)16110 void	rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
16111 {
16112 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16113 
16114 	if (pHalData->AntDivCfg) {
16115 		/*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
16116 		/*select optimum_antenna for before linked =>For antenna diversity*/
16117 		if (dst->Rssi >=  src->Rssi) {/*keep org parameter*/
16118 			src->Rssi = dst->Rssi;
16119 			src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
16120 		}
16121 	}
16122 }
16123 #endif
16124 
16125 #ifdef CONFIG_PROC_DEBUG
16126 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)16127 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
16128 {
16129 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
16130 	struct phy_spec_t *phy_spec = &pHalData->phy_spec;
16131 
16132 	RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
16133 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
16134 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
16135 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index	[15:8]*/
16136 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index	[7:0]*/
16137 
16138 	RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
16139 	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]*/
16140 	/*VHT STBC Rx [23:16]
16141 	0 = not support
16142 	1 = support for 1 spatial stream
16143 	2 = support for 1 or 2 spatial streams
16144 	3 = support for 1 or 2 or 3 spatial streams
16145 	4 = support for 1 or 2 or 3 or 4 spatial streams*/
16146 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
16147 	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]*/
16148 	/*HT STBC Rx [7:0]
16149 	0 = not support
16150 	1 = support for 1 spatial stream
16151 	2 = support for 1 or 2 spatial streams
16152 	3 = support for 1 or 2 or 3 spatial streams*/
16153 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
16154 
16155 	RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
16156 	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]*/
16157 	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]*/
16158 	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]*/
16159 	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]*/
16160 	#ifdef CONFIG_BEAMFORMING
16161 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
16162 	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]*/
16163 	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]*/
16164 	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]*/
16165 	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]*/
16166 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF)  ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
16167 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
16168 
16169 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
16170 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
16171 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
16172 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
16173 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
16174 	#endif
16175 }
16176 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)16177 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
16178 {
16179 	u8 phy_cap = _FALSE;
16180 
16181 	/* STBC */
16182 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
16183 	RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16184 
16185 	phy_cap = _FALSE;
16186 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
16187 	RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16188 
16189 	/* LDPC support */
16190 	phy_cap = _FALSE;
16191 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
16192 	RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16193 
16194 	phy_cap = _FALSE;
16195 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
16196 	RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16197 
16198 	#ifdef CONFIG_BEAMFORMING
16199 	phy_cap = _FALSE;
16200 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
16201 	RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16202 
16203 	phy_cap = _FALSE;
16204 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
16205 	RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16206 
16207 	phy_cap = _FALSE;
16208 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
16209 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16210 
16211 	phy_cap = _FALSE;
16212 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
16213 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16214 	#endif
16215 }
16216 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)16217 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
16218 {
16219 	RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
16220 #ifdef CONFIG_PHY_CAPABILITY_QUERY
16221 	rtw_dump_phy_cap_by_phydmapi(sel, adapter);
16222 #else
16223 	rtw_dump_phy_cap_by_hal(sel, adapter);
16224 #endif
16225 }
16226 #endif
16227 
translate_dbm_to_percentage(s16 signal)16228 inline s16 translate_dbm_to_percentage(s16 signal)
16229 {
16230 	if ((signal <= -100) || (signal >= 20))
16231 		return	0;
16232 	else if (signal >= 0)
16233 		return	100;
16234 	else
16235 		return 100 + signal;
16236 }
16237 
16238 #ifdef CONFIG_SWTIMER_BASED_TXBCN
16239 #ifdef CONFIG_BCN_RECOVERY
16240 #define REG_CPU_MGQ_INFO	0x041C
16241 #define BIT_BCN_POLL			BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)16242 u8 rtw_ap_bcn_recovery(_adapter *padapter)
16243 {
16244 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
16245 
16246 	if (hal_data->issue_bcn_fail >= 2) {
16247 		RTW_ERR("%s ISSUE BCN Fail\n", __func__);
16248 		rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
16249 		hal_data->issue_bcn_fail = 0;
16250 	}
16251 	return _SUCCESS;
16252 }
16253 #endif /*CONFIG_BCN_RECOVERY*/
16254 
16255 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)16256 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
16257 {
16258 	u32 start_time = rtw_get_current_time();
16259 	u8 bcn_queue_empty = _FALSE;
16260 
16261 	do {
16262 		if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
16263 			bcn_queue_empty = _TRUE;
16264 			break;
16265 		}
16266 	} while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
16267 
16268 	if (bcn_queue_empty == _FALSE)
16269 		RTW_ERR("%s BCN queue not empty\n", __func__);
16270 
16271 	return bcn_queue_empty;
16272 }
16273 #endif /*CONFIG_BCN_XMIT_PROTECT*/
16274 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
16275 
16276 /**
16277  * rtw_hal_get_trx_path() - Get RF path related information
16278  * @d:		struct dvobj_priv*
16279  * @type:	RF type, nTnR
16280  * @tx:		Tx path
16281  * @rx:		Rx path
16282  *
16283  * Get RF type, TX path and RX path information.
16284  */
rtw_hal_get_trx_path(struct dvobj_priv * d,enum rf_type * type,enum bb_path * tx,enum bb_path * rx)16285 void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
16286 			 enum bb_path *tx, enum bb_path *rx)
16287 {
16288 	struct _ADAPTER *a = dvobj_get_primary_adapter(d);
16289 	enum rf_type t = GET_HAL_RFPATH(a);
16290 
16291 	if (type)
16292 		*type = t;
16293 
16294 	if (tx || rx) {
16295 		u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
16296 		u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
16297 
16298 		if (!tx_bmp && !rx_bmp)
16299 			rf_type_to_default_trx_bmp(t, tx, rx);
16300 		else {
16301 			if (tx)
16302 				*tx = GET_HAL_TX_PATH_BMP(a);
16303 			if (rx)
16304 				*rx = GET_HAL_RX_PATH_BMP(a);
16305 		}
16306 	}
16307 }
16308 
16309 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
rtw_hal_switch_chnl_and_set_bw_offload(_adapter * adapter,u8 central_ch,u8 pri_ch_idx,u8 bw)16310 void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
16311 {
16312 	u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
16313 	PHAL_DATA_TYPE hal;
16314 	struct submit_ctx *chsw_sctx;
16315 
16316 	hal = GET_HAL_DATA(adapter);
16317 	chsw_sctx = &hal->chsw_sctx;
16318 
16319 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
16320 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
16321 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
16322 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_IQK_UPDATE_EN(h2c, 1);
16323 
16324 	rtw_sctx_init(chsw_sctx, 10);
16325 	rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
16326 	rtw_sctx_wait(chsw_sctx, __func__);
16327 }
16328 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
16329 
phy_get_capable_tx_num(_adapter * adapter,enum MGN_RATE rate)16330 u8 phy_get_capable_tx_num(_adapter *adapter, enum MGN_RATE rate)
16331 {
16332 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16333 	u8 tx_num = 0;
16334 
16335 	if (IS_1T_RATE(rate))
16336 		tx_num = hal_data->txpath_cap_num_nss[0];
16337 	else if (IS_2T_RATE(rate))
16338 		tx_num = hal_data->txpath_cap_num_nss[1];
16339 	else if (IS_3T_RATE(rate))
16340 		tx_num = hal_data->txpath_cap_num_nss[2];
16341 	else if (IS_4T_RATE(rate))
16342 		tx_num = hal_data->txpath_cap_num_nss[3];
16343 	else
16344 		rtw_warn_on(1);
16345 
16346 	return tx_num == 0 ? RF_1TX : tx_num - 1;
16347 }
16348 
phy_get_current_tx_num(_adapter * adapter,enum MGN_RATE rate)16349 u8 phy_get_current_tx_num(_adapter *adapter, enum MGN_RATE rate)
16350 {
16351 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16352 	u8 tx_num = 0;
16353 
16354 	if (IS_1T_RATE(rate))
16355 		tx_num = hal_data->txpath_num_nss[0];
16356 	else if (IS_2T_RATE(rate))
16357 		tx_num = hal_data->txpath_num_nss[1];
16358 	else if (IS_3T_RATE(rate))
16359 		tx_num = hal_data->txpath_num_nss[2];
16360 	else if (IS_4T_RATE(rate))
16361 		tx_num = hal_data->txpath_num_nss[3];
16362 	else
16363 		rtw_warn_on(1);
16364 
16365 	return tx_num == 0 ? RF_1TX : tx_num - 1;
16366 }
16367 
16368 #ifdef CONFIG_RTL8812A
rtw_hal_set_8812a_vendor_ie(_adapter * padapter,u8 * pframe,uint * frlen)16369 u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
16370 	int vender_len = 7;
16371 	unsigned char	vendor_info[vender_len];
16372 	unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
16373 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
16374 
16375 	if( !IS_HARDWARE_TYPE_8812(padapter) )
16376 		return pframe;
16377 
16378 	_rtw_memset(vendor_info,0,vender_len);
16379 	_rtw_memcpy(vendor_info, REALTEK_OUI, 3);
16380 	vendor_info[4] =2;
16381 	if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
16382 		vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
16383 	else
16384 		vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
16385 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
16386 
16387 	return pframe;
16388 }
16389 #endif /*CONFIG_RTL8812A*/
16390 
rtw_enter_protsel(struct protsel * protsel,u32 sel)16391 static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
16392 {
16393 	int refcnt;
16394 
16395 	_enter_critical_mutex(&protsel->mutex, NULL);
16396 
16397 	refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
16398 
16399 	WARN_ON(refcnt > 1 && protsel->sel != sel);
16400 
16401 	protsel->sel = sel;
16402 
16403 	_exit_critical_mutex(&protsel->mutex, NULL);
16404 }
16405 
rtw_leave_protsel(struct protsel * protsel)16406 static inline void rtw_leave_protsel(struct protsel *protsel)
16407 {
16408 	int refcnt;
16409 
16410 	_enter_critical_mutex(&protsel->mutex, NULL);
16411 
16412 	refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
16413 
16414 	_exit_critical_mutex(&protsel->mutex, NULL);
16415 
16416 	WARN_ON(refcnt < 0);
16417 }
16418 
rtw_assert_protsel(struct protsel * protsel)16419 static inline bool rtw_assert_protsel(struct protsel *protsel)
16420 {
16421 	int refcnt = ATOMIC_READ(&protsel->refcnt);
16422 
16423 	if (refcnt > 0)
16424 		return true;
16425 
16426 	return false;
16427 }
16428 
16429 #ifdef CONFIG_PROTSEL_PORT
rtw_enter_protsel_port(_adapter * padapter,u8 port_sel)16430 void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
16431 {
16432 	u8 val8;
16433 
16434 	rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
16435 
16436 	val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
16437 	val8 &= ~BIT_MASK_PORT_CTRL_SEL;
16438 	val8 |= BIT_PORT_CTRL_SEL(port_sel);
16439 	rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
16440 }
16441 
rtw_assert_protsel_port(_adapter * padapter,u32 addr,u8 len)16442 bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
16443 {
16444 	if (!padapter->bup)	/* don't assert before IF up */
16445 		return true;
16446 
16447 	return rtw_assert_protsel(&padapter->dvobj->protsel_port);
16448 }
16449 
rtw_leave_protsel_port(_adapter * padapter)16450 void rtw_leave_protsel_port(_adapter *padapter)
16451 {
16452 	rtw_leave_protsel(&padapter->dvobj->protsel_port);
16453 }
16454 #endif
16455 
16456 #ifdef CONFIG_PROTSEL_ATIMDTIM
rtw_enter_protsel_atimdtim(_adapter * padapter,u8 port_sel)16457 void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
16458 {
16459 	/* 0~15 is for port 0 MBSSID setting
16460 	 * 16 is for port 1 setting
16461 	 * 17 is for port 2 setting
16462 	 * 18 is for port 3 setting
16463 	 * 19 is for port 4 setting
16464 	 */
16465 	u8 val8;
16466 
16467 	if (port_sel >= 1 && port_sel <= 4)
16468 		port_sel += 15;
16469 
16470 	rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
16471 
16472 	val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
16473 	val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
16474 	val8 |= BIT_ATIM_DTIM_SEL(port_sel);
16475 	rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
16476 }
16477 
rtw_assert_protsel_atimdtim(_adapter * padapter,u32 addr,u8 len)16478 bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
16479 {
16480 	return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
16481 }
16482 
rtw_leave_protsel_atimdtim(_adapter * padapter)16483 void rtw_leave_protsel_atimdtim(_adapter *padapter)
16484 {
16485 	rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
16486 }
16487 #endif
16488 
16489 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_enter_protsel_macsleep(_adapter * padapter,u8 sel)16490 void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
16491 {
16492 	u32 val32;
16493 
16494 	rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
16495 
16496 	val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
16497 	val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
16498 	val32 |= BIT_MACID_SLEEP_SEL(sel);
16499 	rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
16500 }
16501 
rtw_assert_protsel_macsleep(_adapter * padapter,u32 addr,u8 len)16502 bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
16503 {
16504 	return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
16505 }
16506 
rtw_leave_protsel_macsleep(_adapter * padapter)16507 void rtw_leave_protsel_macsleep(_adapter *padapter)
16508 {
16509 	rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
16510 }
16511 #endif
16512 
rtw_hal_bcn_early_rpt_c2h_handler(_adapter * padapter)16513 void rtw_hal_bcn_early_rpt_c2h_handler(_adapter *padapter)
16514 {
16515 
16516 	if(0)
16517 		RTW_INFO("Recv Bcn Early report!!\n");
16518 
16519 #ifdef CONFIG_TDLS
16520 #ifdef CONFIG_TDLS_CH_SW
16521 	if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
16522 		rtw_tdls_ch_sw_back_to_base_chnl(padapter);
16523 #endif
16524 #endif
16525 }
16526