xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8723ds/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) || (psta->wireless_mode & WIRELESS_11_5N))
2014 		w_set |= WIRELESS_HT;
2015 
2016 	if (psta->wireless_mode & WIRELESS_11AC)
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 	#ifdef CONFIG_RTL8192F
3096 	rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x640);/*unit:32us*/
3097 	#else/*not CONFIG_RTL8192F*/
3098 	rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3099 	#endif
3100 	#endif
3101 
3102 	/*reset TSF*/
3103 	rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
3104 
3105 	/*enable BCN0 Function for if1*/
3106 	/*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
3107 	#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3108 	rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
3109 	#else
3110 	rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3111 	#endif
3112 	#ifdef CONFIG_BCN_XMIT_PROTECT
3113 	rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
3114 	#endif
3115 
3116 	if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
3117 		rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
3118 
3119 	/* Enable HW seq for BCN
3120 	 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT  */
3121 	#ifdef CONFIG_RTL8822B
3122 	if (IS_HARDWARE_TYPE_8822B(adapter))
3123 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3124 	#endif
3125 
3126 	#ifdef CONFIG_RTL8822C
3127 	if (IS_HARDWARE_TYPE_8822C(adapter))
3128 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3129 	#endif
3130 }
3131 #endif
3132 
3133 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3134 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3135 {
3136 
3137 #if 0 /*TODO - modify for more flexible*/
3138 	u8 idx = 0;
3139 
3140 	if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
3141 	    (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
3142 		for (idx = 0; idx < 6; idx++)
3143 			rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
3144 	}  else {
3145 		/*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
3146 		u8 entry_id;
3147 
3148 		if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
3149 		    (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
3150 			entry_id = 0;
3151 			if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
3152 				RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
3153 				write_mbssid_cam(adapter, entry_id, val);
3154 			}
3155 		} else {
3156 			entry_id = rtw_mbid_camid_alloc(adapter, val);
3157 			if (entry_id != INVALID_CAM_ID)
3158 				write_mbssid_cam(adapter, entry_id, val);
3159 		}
3160 	}
3161 #else
3162 	{
3163 		/*
3164 			MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
3165 		*/
3166 		u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
3167 
3168 
3169 		if (entry_id != INVALID_CAM_ID) {
3170 			write_mbssid_cam(adapter, entry_id, mac_addr);
3171 			RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
3172 				ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
3173 		}
3174 	}
3175 #endif
3176 }
3177 
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3178 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3179 {
3180 	u8 idx = 0;
3181 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3182 	u8 entry_id;
3183 
3184 	if (!mac_addr) {
3185 		rtw_warn_on(1);
3186 		return;
3187 	}
3188 
3189 
3190 	entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
3191 
3192 	if (entry_id != INVALID_CAM_ID)
3193 		write_mbssid_cam(adapter, entry_id, mac_addr);
3194 }
3195 
3196 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)3197 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
3198 {
3199 	if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
3200 		return adapter_to_dvobj(adapter)->inter_bcn_space;
3201 	else
3202 		return bcn_interval;
3203 }
3204 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
3205 
3206 #else
3207 
3208 #ifndef RTW_HALMAC
_get_macaddr_reg(enum _hw_port hwport)3209 static u32 _get_macaddr_reg(enum _hw_port hwport)
3210 {
3211 	u32 reg_macaddr = REG_MACID;
3212 
3213 	#ifdef CONFIG_CONCURRENT_MODE
3214 	if (hwport == HW_PORT1)
3215 		reg_macaddr = REG_MACID1;
3216 	#if defined(CONFIG_RTL8814A)
3217 	else if (hwport == HW_PORT2)
3218 		reg_macaddr = REG_MACID2;
3219 	else if (hwport == HW_PORT3)
3220 		reg_macaddr = REG_MACID3;
3221 	else if (hwport == HW_PORT4)
3222 		reg_macaddr = REG_MACID4;
3223 	#endif /*CONFIG_RTL8814A*/
3224 	#endif /*CONFIG_CONCURRENT_MODE*/
3225 
3226 	return reg_macaddr;
3227 }
3228 #endif /*!RTW_HALMAC*/
3229 
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * mac_addr)3230 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)
3231 {
3232 	enum _hw_port hwport;
3233 
3234 	if (mac_addr == NULL)
3235 		return;
3236 	hwport = get_hw_port(adapter);
3237 
3238 	RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
3239 		 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3240 
3241 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3242 	rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3243 #else /* !RTW_HALMAC */
3244 	{
3245 		u8 idx = 0;
3246 		u32 reg_macaddr = _get_macaddr_reg(hwport);
3247 
3248 		for (idx = 0; idx < ETH_ALEN; idx++)
3249 			rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);
3250 	}
3251 #endif /* !RTW_HALMAC */
3252 }
3253 
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)3254 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
3255 {
3256 	enum _hw_port hwport;
3257 
3258 	if (mac_addr == NULL)
3259 		return;
3260 	hwport = get_hw_port(adapter);
3261 
3262 	_rtw_memset(mac_addr, 0, ETH_ALEN);
3263 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3264 	rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3265 #else /* !RTW_HALMAC */
3266 	{
3267 		u8 idx = 0;
3268 		u32 reg_macaddr = _get_macaddr_reg(hwport);
3269 
3270 		for (idx = 0; idx < ETH_ALEN; idx++)
3271 			mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));
3272 	}
3273 #endif /* !RTW_HALMAC */
3274 
3275 	RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
3276 		 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3277 }
3278 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
3279 
3280 #ifndef RTW_HALMAC
_get_bssid_reg(enum _hw_port hw_port)3281 static u32 _get_bssid_reg(enum _hw_port hw_port)
3282 {
3283 	u32 reg_bssid = REG_BSSID;
3284 
3285 	#ifdef CONFIG_CONCURRENT_MODE
3286 	if (hw_port == HW_PORT1)
3287 		reg_bssid = REG_BSSID1;
3288 	#if defined(CONFIG_RTL8814A)
3289 	else if (hw_port == HW_PORT2)
3290 		reg_bssid = REG_BSSID2;
3291 	else if (hw_port == HW_PORT3)
3292 		reg_bssid = REG_BSSID3;
3293 	else if (hw_port == HW_PORT4)
3294 		reg_bssid = REG_BSSID4;
3295 	#endif /*CONFIG_RTL8814A*/
3296 	#endif /*CONFIG_CONCURRENT_MODE*/
3297 
3298 	return reg_bssid;
3299 }
3300 #endif /*!RTW_HALMAC*/
rtw_hal_set_bssid(_adapter * adapter,u8 * val)3301 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
3302 {
3303 	enum _hw_port hw_port = rtw_hal_get_port(adapter);
3304 #ifdef RTW_HALMAC
3305 
3306 	rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
3307 #else /* !RTW_HALMAC */
3308 	u8 idx = 0;
3309 	u32 reg_bssid = _get_bssid_reg(hw_port);
3310 
3311 	for (idx = 0 ; idx < ETH_ALEN; idx++)
3312 		rtw_write8(adapter, (reg_bssid + idx), val[idx]);
3313 #endif /* !RTW_HALMAC */
3314 
3315 	RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
3316 		__func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
3317 }
3318 
3319 #ifndef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_tsf_update(_adapter * adapter,u8 en)3320 static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
3321 {
3322 	u32 addr = 0;
3323 	u8 val8;
3324 
3325 	rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
3326 	if (addr) {
3327 		rtw_enter_protsel_port(adapter, get_hw_port(adapter));
3328 		val8 = rtw_read8(adapter, addr);
3329 		if (en && (val8 & DIS_TSF_UDT)) {
3330 			rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
3331 			#ifdef DBG_TSF_UPDATE
3332 			RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3333 			#endif
3334 		}
3335 		if (!en && !(val8 & DIS_TSF_UDT)) {
3336 			rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
3337 			#ifdef DBG_TSF_UPDATE
3338 			RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3339 			#endif
3340 		}
3341 		rtw_leave_protsel_port(adapter);
3342 	} else {
3343 		RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
3344 			, adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
3345 		rtw_warn_on(1);
3346 	}
3347 }
3348 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_set_hw_update_tsf(PADAPTER padapter)3349 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
3350 {
3351 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3352 
3353 #else
3354 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3355 
3356 	if (!pmlmeext->en_hw_update_tsf)
3357 		return;
3358 
3359 	/* check RCR */
3360 	if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
3361 		return;
3362 
3363 	if (pmlmeext->tsf_update_required) {
3364 		pmlmeext->tsf_update_pause_stime = 0;
3365 		rtw_hal_set_tsf_update(padapter, 1);
3366 	}
3367 
3368 	pmlmeext->en_hw_update_tsf = 0;
3369 #endif
3370 }
3371 
rtw_iface_enable_tsf_update(_adapter * adapter)3372 void rtw_iface_enable_tsf_update(_adapter *adapter)
3373 {
3374 	adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3375 	adapter->mlmeextpriv.tsf_update_required = 1;
3376 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3377 
3378 #else
3379 	rtw_hal_set_tsf_update(adapter, 1);
3380 #endif
3381 }
3382 
rtw_iface_disable_tsf_update(_adapter * adapter)3383 void rtw_iface_disable_tsf_update(_adapter *adapter)
3384 {
3385 	adapter->mlmeextpriv.tsf_update_required = 0;
3386 	adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3387 	adapter->mlmeextpriv.en_hw_update_tsf = 0;
3388 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3389 
3390 #else
3391 	rtw_hal_set_tsf_update(adapter, 0);
3392 #endif
3393 }
3394 
rtw_hal_tsf_update_pause(_adapter * adapter)3395 static void rtw_hal_tsf_update_pause(_adapter *adapter)
3396 {
3397 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3398 
3399 #else
3400 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3401 	_adapter *iface;
3402 	int i;
3403 
3404 	for (i = 0; i < dvobj->iface_nums; i++) {
3405 		iface = dvobj->padapters[i];
3406 		if (!iface)
3407 			continue;
3408 
3409 		rtw_hal_set_tsf_update(iface, 0);
3410 		if (iface->mlmeextpriv.tsf_update_required) {
3411 			iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
3412 			if (!iface->mlmeextpriv.tsf_update_pause_stime)
3413 				iface->mlmeextpriv.tsf_update_pause_stime++;
3414 		}
3415 		iface->mlmeextpriv.en_hw_update_tsf = 0;
3416 	}
3417 #endif
3418 }
3419 
rtw_hal_tsf_update_restore(_adapter * adapter)3420 static void rtw_hal_tsf_update_restore(_adapter *adapter)
3421 {
3422 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3423 
3424 #else
3425 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3426 	_adapter *iface;
3427 	int i;
3428 
3429 	for (i = 0; i < dvobj->iface_nums; i++) {
3430 		iface = dvobj->padapters[i];
3431 		if (!iface)
3432 			continue;
3433 
3434 		if (iface->mlmeextpriv.tsf_update_required) {
3435 			/* enable HW TSF update when recive beacon*/
3436 			iface->mlmeextpriv.en_hw_update_tsf = 1;
3437 			#ifdef DBG_TSF_UPDATE
3438 			RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
3439 				, iface->hw_port, ADPT_ARG(iface));
3440 			#endif
3441 		}
3442 	}
3443 #endif
3444 }
3445 
rtw_hal_periodic_tsf_update_chk(_adapter * adapter)3446 void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
3447 {
3448 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3449 
3450 #else
3451 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3452 	_adapter *iface;
3453 	struct mlme_ext_priv *mlmeext;
3454 	int i;
3455 	u32 restore_ms = 0;
3456 
3457 	if (dvobj->periodic_tsf_update_etime) {
3458 		if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
3459 			/* end for restore status */
3460 			dvobj->periodic_tsf_update_etime = 0;
3461 			rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3462 		}
3463 		return;
3464 	}
3465 
3466 	if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
3467 		return;
3468 
3469 	/*
3470 	* all required ifaces can switch to restore status together
3471 	* loop all pause iface to get largest restore time required
3472 	*/
3473 	for (i = 0; i < dvobj->iface_nums; i++) {
3474 		iface = dvobj->padapters[i];
3475 		if (!iface)
3476 			continue;
3477 
3478 		mlmeext = &iface->mlmeextpriv;
3479 
3480 		if (mlmeext->tsf_update_required
3481 			&& mlmeext->tsf_update_pause_stime
3482 			&& rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
3483 				> mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
3484 		) {
3485 			if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
3486 				restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
3487 		}
3488 	}
3489 
3490 	if (!restore_ms)
3491 		return;
3492 
3493 	dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
3494 	if (!dvobj->periodic_tsf_update_etime)
3495 		dvobj->periodic_tsf_update_etime++;
3496 
3497 	rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3498 
3499 	/* set timer to end restore status */
3500 	_set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
3501 #endif
3502 }
3503 
rtw_hal_periodic_tsf_update_end_timer_hdl(void * ctx)3504 void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
3505 {
3506 	struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
3507 
3508 	if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
3509 		return;
3510 
3511 	rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
3512 }
3513 
hw_var_rcr_config(_adapter * adapter,u32 rcr)3514 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
3515 {
3516 	int err;
3517 
3518 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3519 	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;
3520 #endif
3521 	err = rtw_write32(adapter, REG_RCR, rcr);
3522 	if (err == _SUCCESS)
3523 		GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
3524 	return err;
3525 }
3526 
hw_var_rcr_get(_adapter * adapter,u32 * rcr)3527 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
3528 {
3529 	u32 v32;
3530 
3531 	v32 = rtw_read32(adapter, REG_RCR);
3532 	if (rcr)
3533 		*rcr = v32;
3534 	GET_HAL_DATA(adapter)->ReceiveConfig = v32;
3535 	return _SUCCESS;
3536 }
3537 
3538 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)3539 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
3540 {
3541 	PHAL_DATA_TYPE hal;
3542 	u32 rcr;
3543 
3544 	hal = GET_HAL_DATA(adapter);
3545 
3546 	rcr = hal->ReceiveConfig;
3547 	if ((rcr & check_bit) == check_bit)
3548 		return 1;
3549 
3550 	return 0;
3551 }
3552 
rtw_hal_rcr_add(_adapter * adapter,u32 add)3553 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
3554 {
3555 	PHAL_DATA_TYPE hal;
3556 	u32 rcr;
3557 	u8 ret = _SUCCESS;
3558 
3559 	hal = GET_HAL_DATA(adapter);
3560 
3561 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3562 	rcr |= add;
3563 	if (rcr != hal->ReceiveConfig)
3564 		ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3565 
3566 	return ret;
3567 }
3568 
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)3569 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
3570 {
3571 	PHAL_DATA_TYPE hal;
3572 	u32 rcr;
3573 	u8 ret = _SUCCESS;
3574 
3575 	hal = GET_HAL_DATA(adapter);
3576 
3577 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3578 	rcr &= ~clear;
3579 	if (rcr != hal->ReceiveConfig)
3580 		ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3581 
3582 	return ret;
3583 }
3584 
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)3585 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
3586 {
3587 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3588 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3589 	u32 rcr, rcr_new;
3590 #if !defined(CONFIG_MI_WITH_MBSSID_CAM) || defined(CONFIG_CLIENT_PORT_CFG) || defined(CONFIG_RTW_MULTI_AP)
3591 	struct mi_state mstate, mstate_s;
3592 #endif
3593 
3594 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3595 	rcr_new = rcr;
3596 
3597 #if !defined(CONFIG_MI_WITH_MBSSID_CAM) || defined(CONFIG_CLIENT_PORT_CFG) || defined(CONFIG_RTW_MULTI_AP)
3598 	rtw_mi_status_no_self(adapter, &mstate);
3599 	rtw_mi_status_no_others(adapter, &mstate_s);
3600 
3601 	/* only adjust parameters interested */
3602 	switch (self_action) {
3603 	case MLME_SCAN_ENTER:
3604 		mstate_s.scan_num = 1;
3605 		mstate_s.scan_enter_num = 1;
3606 		break;
3607 	case MLME_SCAN_DONE:
3608 		mstate_s.scan_enter_num = 0;
3609 		break;
3610 	case MLME_STA_CONNECTING:
3611 		mstate_s.lg_sta_num = 1;
3612 		mstate_s.ld_sta_num = 0;
3613 		break;
3614 	case MLME_STA_CONNECTED:
3615 		mstate_s.lg_sta_num = 0;
3616 		mstate_s.ld_sta_num = 1;
3617 		break;
3618 	case MLME_STA_DISCONNECTED:
3619 		mstate_s.lg_sta_num = 0;
3620 		mstate_s.ld_sta_num = 0;
3621 		break;
3622 #ifdef CONFIG_TDLS
3623 	case MLME_TDLS_LINKED:
3624 		mstate_s.ld_tdls_num = 1;
3625 		break;
3626 	case MLME_TDLS_NOLINK:
3627 		mstate_s.ld_tdls_num = 0;
3628 		break;
3629 #endif
3630 #ifdef CONFIG_AP_MODE
3631 	case MLME_AP_STARTED:
3632 		mstate_s.ap_num = 1;
3633 		break;
3634 	case MLME_AP_STOPPED:
3635 		mstate_s.ap_num = 0;
3636 		mstate_s.ld_ap_num = 0;
3637 		break;
3638 #endif
3639 #ifdef CONFIG_RTW_MESH
3640 	case MLME_MESH_STARTED:
3641 		mstate_s.mesh_num = 1;
3642 		break;
3643 	case MLME_MESH_STOPPED:
3644 		mstate_s.mesh_num = 0;
3645 		mstate_s.ld_mesh_num = 0;
3646 		break;
3647 #endif
3648 	case MLME_ACTION_NONE:
3649 	case MLME_ADHOC_STARTED:
3650 		/* caller without effect of decision */
3651 		break;
3652 	default:
3653 		rtw_warn_on(1);
3654 	};
3655 
3656 	rtw_mi_status_merge(&mstate, &mstate_s);
3657 #endif /* !defined(CONFIG_MI_WITH_MBSSID_CAM) || defined(CONFIG_CLIENT_PORT_CFG) || defined(CONFIG_RTW_MULTI_AP) */
3658 
3659 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
3660 	rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
3661 #else
3662 	if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
3663 		#ifdef CONFIG_FIND_BEST_CHANNEL
3664 		|| MSTATE_SCAN_ENTER_NUM(&mstate)
3665 		#endif
3666 		|| hal_data->in_cta_test
3667 	)
3668 		rcr_new &= ~RCR_CBSSID_DATA;
3669 	else
3670 		rcr_new |= RCR_CBSSID_DATA;
3671 
3672 	if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
3673 		rcr_new &= ~RCR_CBSSID_BCN;
3674 	else if (MSTATE_STA_LG_NUM(&mstate)
3675 		|| adapter_to_dvobj(adapter)->periodic_tsf_update_etime
3676 	)
3677 		rcr_new |= RCR_CBSSID_BCN;
3678 	else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
3679 		|| MSTATE_MESH_NUM(&mstate)
3680 	)
3681 		rcr_new &= ~RCR_CBSSID_BCN;
3682 	else
3683 		rcr_new |= RCR_CBSSID_BCN;
3684 
3685 	#ifdef CONFIG_CLIENT_PORT_CFG
3686 	if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
3687 		rcr_new &= ~RCR_CBSSID_BCN;
3688 	#endif
3689 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
3690 
3691 #ifdef CONFIG_RTW_MULTI_AP
3692 	if (MSTATE_AP_NUM(&mstate)
3693 		&& rtw_unassoc_sta_src_chk(adapter, UNASOC_STA_SRC_RX_NMY_UC)
3694 	) {
3695 		rcr_new |= RCR_AAP;
3696 	} else
3697 		rcr_new &= ~RCR_AAP;
3698 #endif
3699 
3700 	if (rcr == rcr_new)
3701 		return;
3702 
3703 	if (!hal_spec->rx_tsf_filter
3704 		&& (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
3705 		rtw_hal_tsf_update_pause(adapter);
3706 
3707 	rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
3708 
3709 	if (!hal_spec->rx_tsf_filter
3710 		&& !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
3711 		&& self_action != MLME_STA_CONNECTING)
3712 		rtw_hal_tsf_update_restore(adapter);
3713 }
3714 
rtw_hal_rcr_set_chk_bssid_act_non(_adapter * adapter)3715 void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter)
3716 {
3717 	rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3718 }
3719 
hw_var_set_rcr_am(_adapter * adapter,u8 enable)3720 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
3721 {
3722 	u32 rcr = RCR_AM;
3723 
3724 	if (enable)
3725 		rtw_hal_rcr_add(adapter, rcr);
3726 	else
3727 		rtw_hal_rcr_clear(adapter, rcr);
3728 }
3729 
hw_var_set_bcn_interval(_adapter * adapter,u16 interval)3730 static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
3731 {
3732 #ifdef CONFIG_SWTIMER_BASED_TXBCN
3733 	interval = rtw_hal_bcn_interval_adjust(adapter, interval);
3734 #endif
3735 
3736 #ifdef RTW_HALMAC
3737 	rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
3738 #else
3739 	rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
3740 #endif
3741 
3742 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3743 	{
3744 		struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
3745 		struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3746 
3747 		if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3748 			RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
3749 			rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
3750 		}
3751 	}
3752 #endif
3753 }
3754 
3755 #if CONFIG_TX_AC_LIFETIME
3756 const char *const _tx_aclt_conf_str[] = {
3757 	"DEFAULT",
3758 	"AP_M2U",
3759 	"MESH",
3760 	"INVALID",
3761 };
3762 
dump_tx_aclt_force_val(void * sel,struct dvobj_priv * dvobj)3763 void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)
3764 {
3765 #define TX_ACLT_FORCE_MSG_LEN 64
3766 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3767 	struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3768 	char buf[TX_ACLT_FORCE_MSG_LEN];
3769 	int cnt = 0;
3770 
3771 	RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3772 		, hal_spec->tx_aclt_unit_factor * 32
3773 		, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3774 
3775 	RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");
3776 	RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"
3777 		, conf->en
3778 		, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3779 		, conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3780 	);
3781 
3782 	cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");
3783 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3784 		goto exit;
3785 
3786 	if (conf->vo_vi)
3787 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);
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 
3794 	if (conf->be_bk)
3795 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);
3796 	else
3797 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "         AUTO");
3798 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3799 		goto exit;
3800 
3801 	RTW_PRINT_SEL(sel, "%s\n", buf);
3802 
3803 exit:
3804 	return;
3805 }
3806 
rtw_hal_set_tx_aclt_force_val(_adapter * adapter,struct tx_aclt_conf_t * input,u8 arg_num)3807 void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)
3808 {
3809 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3810 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3811 	struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3812 
3813 	if (arg_num >= 1) {
3814 		if (input->en == 0xFF)
3815 			conf->en = input->en;
3816 		else
3817 			conf->en = input->en & 0xF;
3818 	}
3819 	if (arg_num >= 2) {
3820 		conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3821 		if (conf->vo_vi > 0xFFFF)
3822 			conf->vo_vi = 0xFFFF;
3823 	}
3824 	if (arg_num >= 3) {
3825 		conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3826 		if (conf->be_bk > 0xFFFF)
3827 			conf->be_bk = 0xFFFF;
3828 	}
3829 }
3830 
dump_tx_aclt_confs(void * sel,struct dvobj_priv * dvobj)3831 void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)
3832 {
3833 #define TX_ACLT_CONF_MSG_LEN 32
3834 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3835 	struct tx_aclt_conf_t *conf;
3836 	char buf[TX_ACLT_CONF_MSG_LEN];
3837 	int cnt;
3838 	int i;
3839 
3840 	RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3841 		, hal_spec->tx_aclt_unit_factor * 32
3842 		, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3843 
3844 	RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"
3845 		, "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");
3846 
3847 	for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3848 		conf = &dvobj->tx_aclt_confs[i];
3849 		cnt = 0;
3850 
3851 		if (conf->vo_vi)
3852 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "     0x%04x", conf->vo_vi);
3853 		else
3854 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "        N/A");
3855 		if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
3856 			continue;
3857 
3858 		if (conf->be_bk)
3859 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "     0x%04x", conf->be_bk);
3860 		else
3861 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "        N/A");
3862 		if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
3863 			continue;
3864 
3865 		RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"
3866 			, tx_aclt_conf_str(i), i
3867 			, conf->en
3868 			, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3869 			, conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3870 			, buf
3871 		);
3872 	}
3873 }
3874 
rtw_hal_set_tx_aclt_conf(_adapter * adapter,u8 conf_idx,struct tx_aclt_conf_t * input,u8 arg_num)3875 void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)
3876 {
3877 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3878 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3879 	struct tx_aclt_conf_t *conf;
3880 
3881 	if (conf_idx >= TX_ACLT_CONF_NUM)
3882 		return;
3883 
3884 	conf = &dvobj->tx_aclt_confs[conf_idx];
3885 
3886 	if (arg_num >= 1) {
3887 		if (input->en != 0xFF)
3888 			conf->en = input->en & 0xF;
3889 	}
3890 	if (arg_num >= 2) {
3891 		conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3892 		if (conf->vo_vi > 0xFFFF)
3893 			conf->vo_vi = 0xFFFF;
3894 	}
3895 	if (arg_num >= 3) {
3896 		conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3897 		if (conf->be_bk > 0xFFFF)
3898 			conf->be_bk = 0xFFFF;
3899 	}
3900 }
3901 
rtw_hal_update_tx_aclt(_adapter * adapter)3902 void rtw_hal_update_tx_aclt(_adapter *adapter)
3903 {
3904 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3905 	struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);
3906 	u8 lt_en = 0, lt_en_ori;
3907 	u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;
3908 	u32 lt, lt_ori;
3909 	struct tx_aclt_conf_t *conf;
3910 	int i;
3911 #ifdef CONFIG_AP_MODE
3912 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
3913 	_adapter *iface;
3914 	u8 ap_m2u_num = 0;
3915 
3916 	for (i = 0; i < dvobj->iface_nums; i++) {
3917 		iface = dvobj->padapters[i];
3918 		if (!iface)
3919 			continue;
3920 
3921 		if (MLME_IS_AP(iface)
3922 			&& ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST)
3923 				|| (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST))
3924 		)
3925 			ap_m2u_num++;
3926 	}
3927 #endif
3928 #endif /* CONFIG_AP_MODE */
3929 
3930 	lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);
3931 	lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);
3932 
3933 	for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3934 		if (!(dvobj->tx_aclt_flags & BIT(i)))
3935 			continue;
3936 
3937 		conf = &dvobj->tx_aclt_confs[i];
3938 
3939 		if (i == TX_ACLT_CONF_DEFAULT) {
3940 			/* first and default status, assign directly */
3941 			lt_en = conf->en;
3942 			if (conf->vo_vi)
3943 				lt_vo_vi = conf->vo_vi;
3944 			if (conf->be_bk)
3945 				lt_be_bk = conf->be_bk;
3946 		}
3947 		#ifdef CONFIG_AP_MODE
3948 		#if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH)
3949 		else if (0
3950 			#if CONFIG_RTW_AP_DATA_BMC_TO_UC
3951 			|| (i == TX_ACLT_CONF_AP_M2U
3952 				&& ap_m2u_num
3953 				&& macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)
3954 			#endif
3955 			#ifdef CONFIG_RTW_MESH
3956 			|| (i == TX_ACLT_CONF_MESH
3957 				&& macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)
3958 			#endif
3959 		) {
3960 			/* long term status, OR en and MIN lifetime */
3961 			lt_en |= conf->en;
3962 			if (conf->vo_vi && lt_vo_vi > conf->vo_vi)
3963 				lt_vo_vi = conf->vo_vi;
3964 			if (conf->be_bk && lt_be_bk > conf->be_bk)
3965 				lt_be_bk = conf->be_bk;
3966 		}
3967 		#endif
3968 		#endif /* CONFIG_AP_MODE */
3969 	}
3970 
3971 	if (dvobj->tx_aclt_force_val.en != 0xFF)
3972 		lt_en = dvobj->tx_aclt_force_val.en;
3973 	if (dvobj->tx_aclt_force_val.vo_vi)
3974 		lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;
3975 	if (dvobj->tx_aclt_force_val.be_bk)
3976 		lt_be_bk = dvobj->tx_aclt_force_val.be_bk;
3977 
3978 	lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);
3979 	lt = (lt_be_bk << 16) | lt_vo_vi;
3980 
3981 	if (0)
3982 		RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);
3983 
3984 	if (lt_en != lt_en_ori)
3985 		rtw_write8(adapter, REG_LIFETIME_EN, lt_en);
3986 	if (lt != lt_ori)
3987 		rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);
3988 }
3989 #endif /* CONFIG_TX_AC_LIFETIME */
3990 
hw_var_port_switch(_adapter * adapter)3991 void hw_var_port_switch(_adapter *adapter)
3992 {
3993 #ifdef CONFIG_CONCURRENT_MODE
3994 #ifdef CONFIG_RUNTIME_PORT_SWITCH
3995 	/*
3996 	0x102: MSR
3997 	0x550: REG_BCN_CTRL
3998 	0x551: REG_BCN_CTRL_1
3999 	0x55A: REG_ATIMWND
4000 	0x560: REG_TSFTR
4001 	0x568: REG_TSFTR1
4002 	0x570: REG_ATIMWND_1
4003 	0x610: REG_MACID
4004 	0x618: REG_BSSID
4005 	0x700: REG_MACID1
4006 	0x708: REG_BSSID1
4007 	*/
4008 
4009 	int i;
4010 	u8 msr;
4011 	u8 bcn_ctrl;
4012 	u8 bcn_ctrl_1;
4013 	u8 atimwnd[2];
4014 	u8 atimwnd_1[2];
4015 	u8 tsftr[8];
4016 	u8 tsftr_1[8];
4017 	u8 macid[6];
4018 	u8 bssid[6];
4019 	u8 macid_1[6];
4020 	u8 bssid_1[6];
4021 #if defined(CONFIG_RTL8192F)
4022 	u16 wlan_act_mask_ctrl = 0;
4023 	u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
4024 #endif
4025 
4026 	u8 hw_port;
4027 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4028 	_adapter *iface = NULL;
4029 
4030 	msr = rtw_read8(adapter, MSR);
4031 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4032 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4033 #if defined(CONFIG_RTL8192F)
4034 	wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4035 #endif
4036 
4037 	for (i = 0; i < 2; i++)
4038 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4039 	for (i = 0; i < 2; i++)
4040 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4041 
4042 	for (i = 0; i < 8; i++)
4043 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4044 	for (i = 0; i < 8; i++)
4045 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4046 
4047 	for (i = 0; i < 6; i++)
4048 		macid[i] = rtw_read8(adapter, REG_MACID + i);
4049 
4050 	for (i = 0; i < 6; i++)
4051 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4052 
4053 	for (i = 0; i < 6; i++)
4054 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4055 
4056 	for (i = 0; i < 6; i++)
4057 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4058 
4059 #ifdef DBG_RUNTIME_PORT_SWITCH
4060 	RTW_INFO(FUNC_ADPT_FMT" before switch\n"
4061 		 "msr:0x%02x\n"
4062 		 "bcn_ctrl:0x%02x\n"
4063 		 "bcn_ctrl_1:0x%02x\n"
4064 #if defined(CONFIG_RTL8192F)
4065 		 "wlan_act_mask_ctrl:0x%02x\n"
4066 #endif
4067 		 "atimwnd:0x%04x\n"
4068 		 "atimwnd_1:0x%04x\n"
4069 		 "tsftr:%llu\n"
4070 		 "tsftr1:%llu\n"
4071 		 "macid:"MAC_FMT"\n"
4072 		 "bssid:"MAC_FMT"\n"
4073 		 "macid_1:"MAC_FMT"\n"
4074 		 "bssid_1:"MAC_FMT"\n"
4075 		 , FUNC_ADPT_ARG(adapter)
4076 		 , msr
4077 		 , bcn_ctrl
4078 		 , bcn_ctrl_1
4079 #if defined(CONFIG_RTL8192F)
4080 		 , wlan_act_mask_ctrl
4081 #endif
4082 		 , *((u16 *)atimwnd)
4083 		 , *((u16 *)atimwnd_1)
4084 		 , *((u64 *)tsftr)
4085 		 , *((u64 *)tsftr_1)
4086 		 , MAC_ARG(macid)
4087 		 , MAC_ARG(bssid)
4088 		 , MAC_ARG(macid_1)
4089 		 , MAC_ARG(bssid_1)
4090 		);
4091 #endif /* DBG_RUNTIME_PORT_SWITCH */
4092 
4093 	/* disable bcn function, disable update TSF */
4094 	rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4095 	rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4096 
4097 #if defined(CONFIG_RTL8192F)
4098 	rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
4099 #endif
4100 
4101 	/* switch msr */
4102 	msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
4103 	rtw_write8(adapter, MSR, msr);
4104 
4105 	/* write port0 */
4106 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
4107 	for (i = 0; i < 2; i++)
4108 		rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
4109 	for (i = 0; i < 8; i++)
4110 		rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
4111 	for (i = 0; i < 6; i++)
4112 		rtw_write8(adapter, REG_MACID + i, macid_1[i]);
4113 	for (i = 0; i < 6; i++)
4114 		rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
4115 
4116 	/* write port1 */
4117 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
4118 	for (i = 0; i < 2; i++)
4119 		rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
4120 	for (i = 0; i < 8; i++)
4121 		rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
4122 	for (i = 0; i < 6; i++)
4123 		rtw_write8(adapter, REG_MACID1 + i, macid[i]);
4124 	for (i = 0; i < 6; i++)
4125 		rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
4126 
4127 	/* write bcn ctl */
4128 #ifdef CONFIG_BT_COEXIST
4129 	/* always enable port0 beacon function for PSTDMA */
4130 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
4131 	    || IS_HARDWARE_TYPE_8723D(adapter))
4132 		bcn_ctrl_1 |= EN_BCN_FUNCTION;
4133 	/* always disable port1 beacon function for PSTDMA */
4134 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
4135 		bcn_ctrl &= ~EN_BCN_FUNCTION;
4136 #endif
4137 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
4138 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
4139 
4140 #if defined(CONFIG_RTL8192F)
4141 	/* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
4142 	if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
4143 		!= (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
4144 		wlan_act_mask_ctrl ^= en_port_mask;
4145 	rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
4146 #endif
4147 
4148 	if (adapter->iface_id == IFACE_ID0)
4149 		iface = dvobj->padapters[IFACE_ID1];
4150 	else if (adapter->iface_id == IFACE_ID1)
4151 		iface = dvobj->padapters[IFACE_ID0];
4152 
4153 
4154 	if (adapter->hw_port == HW_PORT0) {
4155 		adapter->hw_port = HW_PORT1;
4156 		iface->hw_port = HW_PORT0;
4157 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4158 			  ADPT_ARG(iface), ADPT_ARG(adapter));
4159 	} else {
4160 		adapter->hw_port = HW_PORT0;
4161 		iface->hw_port = HW_PORT1;
4162 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4163 			  ADPT_ARG(adapter), ADPT_ARG(iface));
4164 	}
4165 
4166 #ifdef DBG_RUNTIME_PORT_SWITCH
4167 	msr = rtw_read8(adapter, MSR);
4168 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4169 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4170 #if defined(CONFIG_RTL8192F)
4171 	wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4172 #endif
4173 
4174 	for (i = 0; i < 2; i++)
4175 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4176 	for (i = 0; i < 2; i++)
4177 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4178 
4179 	for (i = 0; i < 8; i++)
4180 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4181 	for (i = 0; i < 8; i++)
4182 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4183 
4184 	for (i = 0; i < 6; i++)
4185 		macid[i] = rtw_read8(adapter, REG_MACID + i);
4186 
4187 	for (i = 0; i < 6; i++)
4188 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4189 
4190 	for (i = 0; i < 6; i++)
4191 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4192 
4193 	for (i = 0; i < 6; i++)
4194 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4195 
4196 	RTW_INFO(FUNC_ADPT_FMT" after switch\n"
4197 		 "msr:0x%02x\n"
4198 		 "bcn_ctrl:0x%02x\n"
4199 		 "bcn_ctrl_1:0x%02x\n"
4200 #if defined(CONFIG_RTL8192F)
4201 		 "wlan_act_mask_ctrl:0x%02x\n"
4202 #endif
4203 		 "atimwnd:%u\n"
4204 		 "atimwnd_1:%u\n"
4205 		 "tsftr:%llu\n"
4206 		 "tsftr1:%llu\n"
4207 		 "macid:"MAC_FMT"\n"
4208 		 "bssid:"MAC_FMT"\n"
4209 		 "macid_1:"MAC_FMT"\n"
4210 		 "bssid_1:"MAC_FMT"\n"
4211 		 , FUNC_ADPT_ARG(adapter)
4212 		 , msr
4213 		 , bcn_ctrl
4214 		 , bcn_ctrl_1
4215 #if defined(CONFIG_RTL8192F)
4216 		 , wlan_act_mask_ctrl
4217 #endif
4218 		 , *((u16 *)atimwnd)
4219 		 , *((u16 *)atimwnd_1)
4220 		 , *((u64 *)tsftr)
4221 		 , *((u64 *)tsftr_1)
4222 		 , MAC_ARG(macid)
4223 		 , MAC_ARG(bssid)
4224 		 , MAC_ARG(macid_1)
4225 		 , MAC_ARG(bssid_1)
4226 		);
4227 #endif /* DBG_RUNTIME_PORT_SWITCH */
4228 
4229 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
4230 #endif /* CONFIG_CONCURRENT_MODE */
4231 }
4232 
4233 const char *const _h2c_msr_role_str[] = {
4234 	"RSVD",
4235 	"STA",
4236 	"AP",
4237 	"GC",
4238 	"GO",
4239 	"TDLS",
4240 	"ADHOC",
4241 	"MESH",
4242 	"INVALID",
4243 };
4244 
4245 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)4246 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
4247 {
4248 	s32 ret = _SUCCESS;
4249 	u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
4250 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4251 	u8 port_id = rtw_hal_get_port(adapter);
4252 
4253 	if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
4254 		return ret;
4255 
4256 	SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
4257 	SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
4258 
4259 	RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
4260 	RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
4261 		__func__, ADPT_ARG(adapter), port_id, mac_id);
4262 
4263 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
4264 	dvobj->dft.port_id = port_id;
4265 	dvobj->dft.mac_id = mac_id;
4266 
4267 	return ret;
4268 }
rtw_set_default_port_id(_adapter * adapter)4269 s32 rtw_set_default_port_id(_adapter *adapter)
4270 {
4271 	s32 ret = _SUCCESS;
4272 	struct sta_info		*psta;
4273 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4274 
4275 	if (is_client_associated_to_ap(adapter)) {
4276 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
4277 		if (psta)
4278 			ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
4279 	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
4280 
4281 	} else {
4282 	}
4283 
4284 	return ret;
4285 }
rtw_set_ps_rsvd_page(_adapter * adapter)4286 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
4287 {
4288 	s32 ret = _SUCCESS;
4289 	u16 media_status_rpt = RT_MEDIA_CONNECT;
4290 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4291 
4292 	if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
4293 		return ret;
4294 
4295 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
4296 			  (u8 *)&media_status_rpt);
4297 
4298 	return ret;
4299 }
4300 
4301 #if 0
4302 _adapter * _rtw_search_dp_iface(_adapter *adapter)
4303 {
4304 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4305 	_adapter *iface;
4306 	_adapter *target_iface = NULL;
4307 	int i;
4308 	u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
4309 	u8 p2p_go_num = 0, p2p_gc_num = 0;
4310 	_adapter *sta_ifs[8];
4311 	_adapter *ap_ifs[8];
4312 	_adapter *mesh_ifs[8];
4313 	_adapter *gc_ifs[8];
4314 	_adapter *go_ifs[8];
4315 
4316 	for (i = 0; i < dvobj->iface_nums; i++) {
4317 		iface = dvobj->padapters[i];
4318 
4319 		if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
4320 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4321 				sta_ifs[sta_num++] = iface;
4322 
4323 				#ifdef CONFIG_TDLS
4324 				if (iface->tdlsinfo.link_established == _TRUE)
4325 					tdls_num++;
4326 				#endif
4327 				#ifdef CONFIG_P2P
4328 				if (MLME_IS_GC(iface))
4329 					gc_ifs[p2p_gc_num++] = iface;
4330 				#endif
4331 			}
4332 #ifdef CONFIG_AP_MODE
4333 		} else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
4334 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4335 				ap_ifs[ap_num++] = iface;
4336 				#ifdef CONFIG_P2P
4337 				if (MLME_IS_GO(iface))
4338 					go_ifs[p2p_go_num++] = iface;
4339 				#endif
4340 			}
4341 #endif
4342 		} else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
4343 			&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4344 		) {
4345 			adhoc_num++;
4346 
4347 #ifdef CONFIG_RTW_MESH
4348 		} else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
4349 			&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4350 		) {
4351 			mesh_ifs[mesh_num++] = iface;
4352 #endif
4353 		}
4354 	}
4355 
4356 	if (p2p_gc_num) {
4357 		target_iface = gc_ifs[0];
4358 	}
4359 	else if (sta_num) {
4360 		if(sta_num == 1) {
4361 			target_iface = sta_ifs[0];
4362 		} else if (sta_num >= 2) {
4363 			/*TODO get target_iface by timestamp*/
4364 			target_iface = sta_ifs[0];
4365 		}
4366 	} else if (ap_num) {
4367 		target_iface = ap_ifs[0];
4368 	}
4369 
4370 	RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
4371 	RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
4372 	RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
4373 	RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
4374 	RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
4375 	RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
4376 	RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
4377 
4378 	if (target_iface)
4379 		RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
4380 			__func__, ADPT_ARG(target_iface));
4381 	else
4382 		RTW_INFO("%s => target_iface NULL\n", __func__);
4383 
4384 	return target_iface;
4385 }
4386 
4387 void rtw_search_default_port(_adapter *adapter)
4388 {
4389 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4390 	_adapter *adp_iface = NULL;
4391 #ifdef CONFIG_WOWLAN
4392 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
4393 
4394 	if (pwrpriv->wowlan_mode == _TRUE) {
4395 		adp_iface = adapter;
4396 		goto exit;
4397 	}
4398 #endif
4399 	adp_iface = _rtw_search_dp_iface(adapter);
4400 
4401 exit :
4402 	if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
4403 		rtw_set_default_port_id(adp_iface);
4404 	else
4405 		rtw_hal_set_default_port_id_cmd(adapter, 0);
4406 
4407 	if (1) {
4408 		_adapter *tmp_adp;
4409 
4410 		tmp_adp = (adp_iface) ? adp_iface : adapter;
4411 
4412 		RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
4413 			__func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
4414 	}
4415 }
4416 #endif
4417 #endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
4418 
4419 #ifdef CONFIG_P2P_PS
4420 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)4421 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
4422 {
4423 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4424 	struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4425 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
4426 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4427 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
4428 	struct sta_priv		*pstapriv = &adapter->stapriv;
4429 	struct sta_info		*psta;
4430 	HAL_P2P_PS_PARA p2p_ps_para;
4431 	int status = -1;
4432 	u8 i;
4433 	u8 hw_port = rtw_hal_get_port(adapter);
4434 
4435 	_rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
4436 	_rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
4437 
4438 	(&p2p_ps_para)->p2p_port_id = hw_port;
4439 	(&p2p_ps_para)->p2p_group = 0;
4440 	psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4441 	if (psta) {
4442 		(&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
4443 	} else {
4444 		if (p2p_ps_state != P2P_PS_DISABLE) {
4445 			RTW_ERR("%s , psta was NULL\n", __func__);
4446 			return;
4447 		}
4448 	}
4449 
4450 
4451 	switch (p2p_ps_state) {
4452 	case P2P_PS_DISABLE:
4453 		RTW_INFO("P2P_PS_DISABLE\n");
4454 		_rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
4455 		break;
4456 
4457 	case P2P_PS_ENABLE:
4458 		RTW_INFO("P2P_PS_ENABLE\n");
4459 		/* update CTWindow value. */
4460 		if (pwdinfo->ctwindow > 0) {
4461 			(&p2p_ps_para)->ctwindow_en = 1;
4462 			(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4463 			/*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
4464 		}
4465 
4466 
4467 		if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
4468 			(&p2p_ps_para)->offload_en = 1;
4469 			if (pwdinfo->role == P2P_ROLE_GO) {
4470 				(&p2p_ps_para)->role = 1;
4471 				(&p2p_ps_para)->all_sta_sleep = 0;
4472 			} else
4473 				(&p2p_ps_para)->role = 0;
4474 
4475 			(&p2p_ps_para)->discovery = 0;
4476 		}
4477 		/* hw only support 2 set of NoA */
4478 		for (i = 0; i < pwdinfo->noa_num; i++) {
4479 			/* To control the register setting for which NOA */
4480 			(&p2p_ps_para)->noa_sel = i;
4481 			(&p2p_ps_para)->noa_en = 1;
4482 			(&p2p_ps_para)->disable_close_rf = 0;
4483 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
4484 #ifdef CONFIG_CONCURRENT_MODE
4485 			if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))
4486 #endif /* CONFIG_CONCURRENT_MODE */
4487 				(&p2p_ps_para)->disable_close_rf = 1;
4488 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
4489 			/* config P2P NoA Descriptor Register */
4490 			/* config NOA duration */
4491 			(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
4492 			/* config NOA interval */
4493 			(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
4494 			/* config NOA start time */
4495 			(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
4496 			/* config NOA count */
4497 			(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
4498 			/*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
4499 				(&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
4500 				(&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
4501 			status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4502 			if (status == -1)
4503 				RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4504 		}
4505 
4506 		break;
4507 
4508 	case P2P_PS_SCAN:
4509 		/*This feature FW not ready 20161116 YiWei*/
4510 		return;
4511 		/*
4512 		RTW_INFO("P2P_PS_SCAN\n");
4513 		(&p2p_ps_para)->discovery = 1;
4514 		(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4515 		(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4516 		(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4517 		(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4518 		(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4519 		*/
4520 		break;
4521 
4522 	case P2P_PS_SCAN_DONE:
4523 		/*This feature FW not ready 20161116 YiWei*/
4524 		return;
4525 		/*
4526 		RTW_INFO("P2P_PS_SCAN_DONE\n");
4527 		(&p2p_ps_para)->discovery = 0;
4528 		pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
4529 		(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4530 		(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4531 		(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4532 		(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4533 		(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4534 		*/
4535 		break;
4536 
4537 	default:
4538 		break;
4539 	}
4540 
4541 	if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
4542 		status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4543 		if (status == -1)
4544 			RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4545 	}
4546 	_rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
4547 
4548 }
4549 #endif /* RTW_HALMAC */
4550 #endif /* CONFIG_P2P */
4551 
4552 #if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR)
_rtw_hal_dtp_macid_set(_adapter * padapter,u8 opmode,u8 mac_id)4553 static void _rtw_hal_dtp_macid_set(
4554 	_adapter *padapter, u8 opmode, u8 mac_id)
4555 {
4556 	struct macid_ctl_t *macid_ctl = &(padapter->dvobj->macid_ctl);
4557 	struct sta_info *psta;
4558 	u8 h2c_cmd[H2C_FW_CRC5_SEARCH_LEN] = {0};
4559 	u8 mac_addr[ETH_ALEN] = {0};
4560 
4561 	if (opmode) {
4562 		psta = macid_ctl->sta[mac_id];
4563 		if (psta)
4564 			_rtw_memcpy(mac_addr, psta->cmn.mac_addr, ETH_ALEN);
4565 
4566 		if (rtw_check_invalid_mac_address(mac_addr, _FALSE))
4567 			return;
4568 	}
4569 	/* else DON'T CARE H2C_FW_CRC5_SEARCH mac addr in disconnected case */
4570 
4571 	if (rtw_get_chip_type(padapter) == RTL8822C) {
4572 		SET_H2CCMD_FW_CRC5_SEARCH_EN(h2c_cmd, opmode);
4573 		SET_H2CCMD_FW_CRC5_SEARCH_MACID(h2c_cmd, mac_id);
4574 		SET_H2CCMD_FW_CRC5_SEARCH_MAC(&h2c_cmd[1], mac_addr);
4575 		if (rtw_hal_fill_h2c_cmd(padapter, H2C_FW_CRC5_SEARCH,
4576 						H2C_FW_CRC5_SEARCH_LEN, h2c_cmd) != _SUCCESS)
4577 			RTW_WARN("%s : set h2c - 0x%02x fail!\n", __func__, H2C_FW_CRC5_SEARCH);
4578 	}
4579 }
4580 
rtw_hal_dtp_macid_set(_adapter * padapter,u8 opmode,bool macid_ind,u8 mac_id,u8 macid_end)4581 static void rtw_hal_dtp_macid_set(_adapter *padapter, u8 opmode,
4582 	bool macid_ind, u8 mac_id, u8 macid_end)
4583 {
4584 	int i;
4585 
4586 	if (macid_ind == 0) {
4587 		_rtw_hal_dtp_macid_set(padapter, opmode, mac_id);
4588 	} else {
4589 		for (i = mac_id; i <= macid_end; i++)
4590 			_rtw_hal_dtp_macid_set(padapter, opmode, i);
4591 	}
4592 }
4593 #endif
4594 
4595 /*
4596 * rtw_hal_set_FwMediaStatusRpt_cmd -
4597 *
4598 * @adapter:
4599 * @opmode:  0:disconnect, 1:connect
4600 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
4601 * @miracast_sink: 0:source. 1:sink
4602 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
4603 * @macid:
4604 * @macid_ind:  0:update Media Status to macid.  1:update Media Status from macid to macid_end
4605 * @macid_end:
4606 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)4607 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)
4608 {
4609 	struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4610 	u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
4611 	int i;
4612 	s32 ret;
4613 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4614 	u8 hw_port = rtw_hal_get_port(adapter);
4615 #endif
4616 	u8 op_num_change_bmp = 0;
4617 
4618 #if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR)
4619 	rtw_hal_dtp_macid_set(adapter, opmode, macid_ind, macid, macid_end);
4620 #endif
4621 
4622 	SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
4623 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
4624 	SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
4625 	SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
4626 	SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
4627 	SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
4628 	SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
4629 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4630 	SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
4631 #endif
4632 	RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
4633 
4634 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
4635 	if (ret != _SUCCESS)
4636 		goto exit;
4637 
4638 #if defined(CONFIG_RTL8188E)
4639 	if (rtw_get_chip_type(adapter) == RTL8188E) {
4640 		HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4641 
4642 		/* 8188E FW doesn't set macid no link, driver does it by self */
4643 		if (opmode)
4644 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
4645 		else
4646 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
4647 
4648 		/* for 8188E RA */
4649 #if (RATE_ADAPTIVE_SUPPORT == 1)
4650 		if (hal_data->fw_ractrl == _FALSE) {
4651 			u8 max_macid;
4652 
4653 			max_macid = rtw_search_max_mac_id(adapter);
4654 			rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
4655 		}
4656 #endif
4657 	}
4658 #endif
4659 
4660 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
4661 	/* TODO: this should move to IOT issue area */
4662 	if (rtw_get_chip_type(adapter) == RTL8812
4663 		|| rtw_get_chip_type(adapter) == RTL8821
4664 	) {
4665 		if (MLME_IS_STA(adapter))
4666 			Hal_PatchwithJaguar_8812(adapter, opmode);
4667 	}
4668 #endif
4669 
4670 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
4671 	if (macid_ind == 0)
4672 		macid_end = macid;
4673 
4674 	for (i = macid; macid <= macid_end; macid++) {
4675 		op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
4676 		if (!opmode) {
4677 			rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
4678 			rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
4679 			rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
4680 			rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
4681 		}
4682 	}
4683 
4684 #if CONFIG_TX_AC_LIFETIME
4685 	if (op_num_change_bmp)
4686 		rtw_hal_update_tx_aclt(adapter);
4687 #endif
4688 
4689 	if (!opmode)
4690 		rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
4691 
4692 exit:
4693 	return ret;
4694 }
4695 
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)4696 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
4697 {
4698 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
4699 }
4700 
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)4701 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
4702 {
4703 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
4704 }
4705 
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4706 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4707 {
4708 	u8	u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
4709 	u8	ret = 0;
4710 
4711 	RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
4712 		 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
4713 		 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
4714 		 rsvdpageloc->LocBTQosNull);
4715 
4716 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
4717 	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
4718 	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
4719 	SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
4720 	SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
4721 
4722 	ret = rtw_hal_fill_h2c_cmd(padapter,
4723 				   H2C_RSVD_PAGE,
4724 				   H2C_RSVDPAGE_LOC_LEN,
4725 				   u1H2CRsvdPageParm);
4726 
4727 }
4728 
4729 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)4730 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
4731 {
4732 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4733 
4734 	if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)
4735 		|| IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)
4736 		|| IS_8822C_SERIES(pHalData->version_id))
4737 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4738 	/*
4739 	* Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
4740 	* It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
4741 	* and implement HAL function.
4742 	* TODO: GPIO_8 multi function?
4743 	*/
4744 
4745 	if ((index == 13 || index == 14)
4746 		#if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
4747 		/* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
4748 		&& (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
4749 		#endif
4750 	)
4751 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4752 }
4753 
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)4754 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
4755 {
4756 #if defined(CONFIG_RTL8192F)
4757 	rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval));
4758 #else
4759 	if (index <= 7) {
4760 		/* config GPIO mode */
4761 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4762 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4763 
4764 		/* config GPIO Sel */
4765 		/* 0: input */
4766 		/* 1: output */
4767 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4768 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
4769 
4770 		/* set output value */
4771 		if (outputval) {
4772 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4773 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
4774 		} else {
4775 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4776 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
4777 		}
4778 	} else if (index <= 15) {
4779 		/* 88C Series: */
4780 		/* index: 11~8 transform to 3~0 */
4781 		/* 8723 Series: */
4782 		/* index: 12~8 transform to 4~0 */
4783 
4784 		index -= 8;
4785 
4786 		/* config GPIO mode */
4787 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4788 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4789 
4790 		/* config GPIO Sel */
4791 		/* 0: input */
4792 		/* 1: output */
4793 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4794 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
4795 
4796 		/* set output value */
4797 		if (outputval) {
4798 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4799 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
4800 		} else {
4801 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4802 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
4803 		}
4804 	} else {
4805 		RTW_INFO("%s: invalid GPIO%d=%d\n",
4806 			 __FUNCTION__, index, outputval);
4807 	}
4808 #endif
4809 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)4810 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
4811 {
4812 #if defined(CONFIG_RTL8192F)
4813 	rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));
4814 #else
4815 	if (index <= 7) {
4816 		/* config GPIO mode */
4817 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4818 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4819 
4820 		/* config GPIO Sel */
4821 		/* 0: input */
4822 		/* 1: output */
4823 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4824 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
4825 
4826 	} else if (index <= 15) {
4827 		/* 88C Series: */
4828 		/* index: 11~8 transform to 3~0 */
4829 		/* 8723 Series: */
4830 		/* index: 12~8 transform to 4~0 */
4831 
4832 		index -= 8;
4833 
4834 		/* config GPIO mode */
4835 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4836 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4837 
4838 		/* config GPIO Sel */
4839 		/* 0: input */
4840 		/* 1: output */
4841 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4842 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
4843 	} else
4844 		RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
4845 #endif
4846 }
4847 
4848 #endif
4849 
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4850 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4851 {
4852 	struct	pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
4853 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
4854 	u8 ret = 0;
4855 #ifdef CONFIG_WOWLAN
4856 	u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
4857 
4858 	RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
4859 		 __func__, rsvdpageloc->LocRemoteCtrlInfo,
4860 		 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
4861 		 rsvdpageloc->LocNDPInfo);
4862 	RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
4863 		 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
4864 		 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
4865 
4866 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
4867 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
4868 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
4869 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
4870 							rsvdpageloc->LocNbrAdv);
4871 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
4872 						      rsvdpageloc->LocNDPInfo);
4873 #ifdef CONFIG_GTK_OL
4874 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
4875 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
4876 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
4877 #endif /* CONFIG_GTK_OL */
4878 		ret = rtw_hal_fill_h2c_cmd(padapter,
4879 					   H2C_AOAC_RSVD_PAGE,
4880 					   H2C_AOAC_RSVDPAGE_LOC_LEN,
4881 					   u1H2CAoacRsvdPageParm);
4882 
4883 		RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
4884 		_rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
4885 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
4886 					 rsvdpageloc->LocAOACReport);
4887 		ret = rtw_hal_fill_h2c_cmd(padapter,
4888 				   H2C_AOAC_RSVDPAGE3,
4889 				   H2C_AOAC_RSVDPAGE_LOC_LEN,
4890 				   u1H2CAoacRsvdPageParm);
4891 		pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
4892 	}
4893 #ifdef CONFIG_PNO_SUPPORT
4894 	else {
4895 
4896 		if (!pwrpriv->wowlan_in_resume) {
4897 			RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
4898 			_rtw_memset(&u1H2CAoacRsvdPageParm, 0,
4899 				    sizeof(u1H2CAoacRsvdPageParm));
4900 			SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
4901 						      rsvdpageloc->LocPNOInfo);
4902 			ret = rtw_hal_fill_h2c_cmd(padapter,
4903 						   H2C_AOAC_RSVDPAGE3,
4904 						   H2C_AOAC_RSVDPAGE_LOC_LEN,
4905 						   u1H2CAoacRsvdPageParm);
4906 		}
4907 	}
4908 #endif /* CONFIG_PNO_SUPPORT */
4909 #endif /* CONFIG_WOWLAN */
4910 }
4911 
4912 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4913 void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4914 {
4915 	struct	hal_ops *pHalFunc = &padapter->hal_func;
4916 	u8	u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
4917 	u8	ret = 0;
4918 
4919 
4920 	RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
4921 
4922 	SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
4923 	SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
4924 	ret = rtw_hal_fill_h2c_cmd(padapter,
4925 				   H2C_FW_DBG_MSG_PKT,
4926 				   H2C_FW_DBG_MSG_PKT_LEN,
4927 				   u1H2C_fw_dbg_msg_pkt_parm);
4928 
4929 }
4930 #endif /*DBG_FW_DEBUG_MSG_PKT*/
4931 
4932 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)4933 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
4934 	u32 page_num, u8 *buffer, u32 buffer_size)
4935 {
4936 	u32 addr = 0, size = 0, count = 0;
4937 	u32 page_size = 0, data_low = 0, data_high = 0;
4938 	u16 txbndy = 0, offset = 0;
4939 	u8 i = 0;
4940 	bool rst = _FALSE;
4941 
4942 #ifdef DBG_LA_MODE
4943 	struct registry_priv *registry_par = &adapter->registrypriv;
4944 
4945 	if(registry_par->la_mode_en == 1) {
4946 		RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
4947 		return rst;
4948 	}
4949 #endif
4950 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
4951 
4952 	addr = page_offset * page_size;
4953 	size = page_num * page_size;
4954 
4955 	if (buffer_size < size) {
4956 		RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
4957 			__func__, buffer_size, size);
4958 		return rst;
4959 	}
4960 #ifdef RTW_HALMAC
4961 	if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
4962 		rst = _FALSE;
4963 	else
4964 		rst = _TRUE;
4965 #else
4966 	txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
4967 
4968 	offset = (txbndy + page_offset) * page_size / 8;
4969 	count = (buffer_size / 8) + 1;
4970 
4971 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
4972 
4973 	for (i = 0 ; i < count ; i++) {
4974 		rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
4975 		data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
4976 		data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
4977 		_rtw_memcpy(buffer + (i * 8),
4978 			&data_low, sizeof(data_low));
4979 		_rtw_memcpy(buffer + ((i * 8) + 4),
4980 			&data_high, sizeof(data_high));
4981 	}
4982 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
4983 	rst = _TRUE;
4984 #endif /*RTW_HALMAC*/
4985 
4986 #ifdef DBG_GET_RSVD_PAGE
4987 	RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
4988 		 __func__, page_offset, page_num, addr, size);
4989 	RTW_INFO_DUMP("\n", buffer, size);
4990 	RTW_INFO(" ==================================================\n");
4991 #endif
4992 	return rst;
4993 }
4994 
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)4995 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
4996 {
4997 #if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG)
4998 	u32 page_size = 0;
4999 	u8 *buffer = NULL;
5000 	u32 buf_size = 0;
5001 
5002 	if (page_num == 0)
5003 		return;
5004 
5005 	RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
5006 	RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
5007 
5008 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5009 	if (page_size) {
5010 		buf_size = page_size * page_num;
5011 		buffer = rtw_zvmalloc(buf_size);
5012 
5013 		if (buffer) {
5014 			rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
5015 			RTW_DUMP_SEL(sel, buffer, buf_size);
5016 			rtw_vmfree(buffer, buf_size);
5017 		} else
5018 			RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
5019 	} else
5020 			RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
5021 
5022 	RTW_PRINT_SEL(sel, "==========================\n");
5023 #endif
5024 }
5025 
5026 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)5027 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
5028 {
5029 	u8 *buffer = NULL;
5030 	u32 buff_size = 0;
5031 	static const char * const fifo_sel_str[] = {
5032 		"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
5033 	};
5034 
5035 	if (fifo_sel > 5) {
5036 		RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
5037 		return;
5038 	}
5039 
5040 	RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
5041 	RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
5042 
5043 	if (fifo_size) {
5044 		buff_size = RND4(fifo_size);
5045 		buffer = rtw_zvmalloc(buff_size);
5046 		if (buffer == NULL)
5047 			buff_size = 0;
5048 	}
5049 
5050 	rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
5051 
5052 	if (buffer) {
5053 		RTW_DUMP_SEL(sel, buffer, fifo_size);
5054 		rtw_vmfree(buffer, buff_size);
5055 	}
5056 
5057 	RTW_PRINT_SEL(sel, "==========================\n");
5058 }
5059 #endif
5060 
5061 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)5062 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
5063 {
5064 	RTW_INFO("%s: Set 0x690=0x00\n", __func__);
5065 	rtw_write8(adapter, REG_WOW_CTRL,
5066 		   (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
5067 	RTW_PRINT("%s: Release RXDMA\n", __func__);
5068 	rtw_write32(adapter, REG_RXPKT_NUM,
5069 		    (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
5070 }
5071 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)5072 static void rtw_hal_disable_tx_report(_adapter *adapter)
5073 {
5074 	rtw_write8(adapter, REG_TX_RPT_CTRL,
5075 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
5076 	RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5077 }
5078 
rtw_hal_enable_tx_report(_adapter * adapter)5079 static void rtw_hal_enable_tx_report(_adapter *adapter)
5080 {
5081 	rtw_write8(adapter, REG_TX_RPT_CTRL,
5082 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
5083 	RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5084 }
5085 #endif
rtw_hal_release_rx_dma(_adapter * adapter)5086 static void rtw_hal_release_rx_dma(_adapter *adapter)
5087 {
5088 	u32 val32 = 0;
5089 
5090 	val32 = rtw_read32(adapter, REG_RXPKT_NUM);
5091 
5092 	rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
5093 
5094 	RTW_INFO("%s, [0x%04x]: 0x%08x\n",
5095 		 __func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));
5096 }
5097 
rtw_hal_pause_rx_dma(_adapter * adapter)5098 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
5099 {
5100 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
5101 	u8 ret = 0;
5102 	s8 trycnt = 100;
5103 	u32 tmp = 0;
5104 	int res = 0;
5105 	/* RX DMA stop */
5106 	RTW_PRINT("Pause DMA\n");
5107 	rtw_write32(adapter, REG_RXPKT_NUM,
5108 		    (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
5109 	do {
5110 		if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
5111 #ifdef CONFIG_USB_HCI
5112 			/* stop interface before leave */
5113 			if (_TRUE == hal->usb_intf_start) {
5114 				rtw_intf_stop(adapter);
5115 				RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
5116 				RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
5117 			}
5118 #endif /* CONFIG_USB_HCI */
5119 
5120 			RTW_PRINT("RX_DMA_IDLE is true\n");
5121 			ret = _SUCCESS;
5122 			break;
5123 		}
5124 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5125 		else {
5126 			res = RecvOnePkt(adapter);
5127 			RTW_PRINT("RecvOnePkt Result: %d\n", res);
5128 		}
5129 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
5130 
5131 #ifdef CONFIG_USB_HCI
5132 		else {
5133 			/* to avoid interface start repeatedly  */
5134 			if (_FALSE == hal->usb_intf_start)
5135 				rtw_intf_start(adapter);
5136 		}
5137 #endif /* CONFIG_USB_HCI */
5138 	} while (trycnt--);
5139 
5140 	if (trycnt < 0) {
5141 		tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
5142 
5143 		RTW_PRINT("Stop RX DMA failed......\n");
5144 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
5145 		RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
5146 			  __func__, rtw_read16(adapter, REG_RXPKTNUM));
5147 #else
5148 		RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
5149 			  __func__, ((tmp & 0xFF00) >> 8));
5150 #endif
5151 		if (tmp & BIT(3))
5152 			RTW_PRINT("%s, RX DMA has req\n",
5153 				  __func__);
5154 		else
5155 			RTW_PRINT("%s, RX DMA no req\n",
5156 				  __func__);
5157 		ret = _FAIL;
5158 	}
5159 
5160 	return ret;
5161 }
5162 
5163 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5164 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)5165 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
5166 {
5167 	u8 ret = 0;
5168 	int res = 0;
5169 	u32 tmp = 0;
5170 #ifdef CONFIG_GPIO_WAKEUP
5171 	return _SUCCESS;
5172 #else
5173 	RTW_PRINT("%s\n", __func__);
5174 
5175 	res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5176 	if (!res)
5177 		RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
5178 	else
5179 		RTW_INFO("sdio_local_read fail\n");
5180 
5181 	tmp = SDIO_HIMR_CPWM2_MSK;
5182 
5183 	res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5184 
5185 	if (!res) {
5186 		res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5187 		RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
5188 		ret = _SUCCESS;
5189 	} else {
5190 		RTW_INFO("sdio_local_write fail\n");
5191 		ret = _FAIL;
5192 	}
5193 	return ret;
5194 #endif /* CONFIG_CPIO_WAKEUP */
5195 }
5196 #endif
5197 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
5198 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
5199 
5200 #ifdef CONFIG_WOWLAN
5201 /*
5202  * rtw_hal_check_wow_ctrl
5203  * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
5204  *									If 0x1C7 == 0 (for 3081), WOW enable successful.
5205  *		     _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
5206  *									If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
5207  */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)5208 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
5209 {
5210 	u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
5211 	u8 mstatus = 0;
5212 	u8 reason = 0xFF;
5213 	u8 trycnt = 25;
5214 	u8 res = _FALSE;
5215 
5216 	if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
5217 		if (chk_type) {
5218 			reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5219 			RTW_INFO("%s reason:0x%02x\n", __func__, reason);
5220 
5221 			while (reason && trycnt > 1) {
5222 				reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5223 				RTW_PRINT("Loop index: %d :0x%02x\n",
5224 					  trycnt, reason);
5225 				trycnt--;
5226 				rtw_msleep_os(20);
5227 			}
5228 			if (!reason)
5229 				res = _TRUE;
5230 			else
5231 				res = _FALSE;
5232 		} else {
5233 			/* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
5234 			fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
5235 			rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
5236 			RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
5237 
5238 			while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
5239 				rtw_msleep_os(20);
5240 				fe1_imr = rtw_read32(adapter, REG_FE1IMR);
5241 				rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
5242 				RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
5243 					  trycnt, fe1_imr, rxpkt_num);
5244 				trycnt--;
5245 			}
5246 
5247 			if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
5248 				res = _FALSE;
5249 			else
5250 				res = _TRUE;
5251 		}
5252 	} else {
5253 		mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5254 		RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
5255 
5256 
5257 		if (chk_type) {
5258 			while (!(mstatus & BIT1) && trycnt > 1) {
5259 				mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5260 				RTW_PRINT("Loop index: %d :0x%02x\n",
5261 					  trycnt, mstatus);
5262 				trycnt--;
5263 				rtw_msleep_os(20);
5264 			}
5265 			if (mstatus & BIT1)
5266 				res = _TRUE;
5267 			else
5268 				res = _FALSE;
5269 		} else {
5270 			while (mstatus & BIT1 && trycnt > 1) {
5271 				mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5272 				RTW_PRINT("Loop index: %d :0x%02x\n",
5273 					  trycnt, mstatus);
5274 				trycnt--;
5275 				rtw_msleep_os(20);
5276 			}
5277 
5278 			if (mstatus & BIT1)
5279 				res = _FALSE;
5280 			else
5281 				res = _TRUE;
5282 		}
5283 	}
5284 
5285 	RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
5286 		  __func__, chk_type, res, (25 - trycnt));
5287 	return res;
5288 }
5289 
5290 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)5291 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
5292 {
5293 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5294 	u8 res = 0, count = 0;
5295 	u8 ret = _FALSE;
5296 
5297 	if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
5298 		res = rtw_read8(adapter, REG_PNO_STATUS);
5299 		while (!(res & BIT(7)) && count < 25) {
5300 			RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
5301 				 count, res);
5302 			res = rtw_read8(adapter, REG_PNO_STATUS);
5303 			count++;
5304 			rtw_msleep_os(2);
5305 		}
5306 		if (res & BIT(7))
5307 			ret = _TRUE;
5308 		else
5309 			ret = _FALSE;
5310 		RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
5311 	}
5312 	return ret;
5313 }
5314 #endif
5315 
rtw_hal_backup_rate(_adapter * adapter)5316 static void rtw_hal_backup_rate(_adapter *adapter)
5317 {
5318 	RTW_INFO("%s\n", __func__);
5319 	/* backup data rate to register 0x8b for wowlan FW */
5320 	rtw_write8(adapter, 0x8d, 1);
5321 	rtw_write8(adapter, 0x8c, 0);
5322 	rtw_write8(adapter, 0x8f, 0x40);
5323 	rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
5324 }
5325 
5326 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)5327 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
5328 {
5329 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5330 	int cam_id, index = 0;
5331 	u8 *addr = NULL;
5332 
5333 	if (!MLME_IS_STA(adapter))
5334 		return;
5335 
5336 	addr = get_bssid(pmlmepriv);
5337 
5338 	if (addr == NULL) {
5339 		RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
5340 		return;
5341 	}
5342 
5343 	rtw_clean_dk_section(adapter);
5344 
5345 	do {
5346 		cam_id = rtw_camid_search(adapter, addr, index, 1);
5347 
5348 		if (cam_id == -1)
5349 			RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
5350 		else
5351 			rtw_sec_cam_swap(adapter, cam_id, index);
5352 
5353 		index++;
5354 	} while (index < 4);
5355 
5356 	rtw_write8(adapter, REG_SECCFG, 0xcc);
5357 }
5358 
rtw_hal_update_gtk_offload_info(_adapter * adapter)5359 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
5360 {
5361 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5362 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5363 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5364 	struct security_priv *psecuritypriv = &adapter->securitypriv;
5365 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5366 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
5367 	_irqL irqL;
5368 	u8 get_key[16];
5369 	u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
5370 	u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
5371 
5372 	if (!MLME_IS_STA(adapter))
5373 		return;
5374 
5375 	_rtw_memset(get_key, 0, sizeof(get_key));
5376 	_rtw_memcpy(&replay_count,
5377 		paoac_rpt->replay_counter_eapol_key, 8);
5378 
5379 	/*read gtk key index*/
5380 	gtk_id = paoac_rpt->key_index;
5381 	aoac_rpt_ver = paoac_rpt->version_info;
5382 
5383 	if (aoac_rpt_ver == 0) {
5384 		/* initial verison */
5385 		if (gtk_id == 5)
5386 			has_rekey = _FALSE;
5387 		else
5388 			has_rekey = _TRUE;
5389 	} else if (aoac_rpt_ver >= 1) {
5390 		/* Add krack patch */
5391 		if (gtk_id == 5)
5392 			RTW_WARN("%s FW check iv fail\n", __func__);
5393 
5394 		if (aoac_rpt_ver == 1)
5395 			RTW_WARN("%s aoac report version should be update to v2\n", __func__);
5396 
5397 		/* Fix key id mismatch */
5398 		if (aoac_rpt_ver == 2)
5399 			has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
5400 	}
5401 
5402 	if (has_rekey == _FALSE) {
5403 		RTW_INFO("%s no rekey event happened.\n", __func__);
5404 	} else if (has_rekey == _TRUE) {
5405 		RTW_INFO("%s update security key.\n", __func__);
5406 		/*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
5407 		rtw_sec_read_cam_ent(adapter, gtk_id,
5408 				     NULL, NULL, get_key);
5409 		rtw_clean_hw_dk_cam(adapter);
5410 
5411 		if (_rtw_camid_is_gk(adapter, gtk_id)) {
5412 			_enter_critical_bh(&cam_ctl->lock, &irqL);
5413 			_rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
5414 				    get_key, 16);
5415 			_exit_critical_bh(&cam_ctl->lock, &irqL);
5416 		} else {
5417 			struct setkey_parm parm_gtk;
5418 
5419 			parm_gtk.algorithm = paoac_rpt->security_type;
5420 			parm_gtk.keyid = gtk_id;
5421 			_rtw_memcpy(parm_gtk.key, get_key, 16);
5422 			setkey_hdl(adapter, (u8 *)&parm_gtk);
5423 		}
5424 
5425 		/*update key into related sw variable and sec-cam cache*/
5426 		psecuritypriv->dot118021XGrpKeyid = gtk_id;
5427 		_rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
5428 				get_key, 16);
5429 		/* update SW TKIP TX/RX MIC value */
5430 		if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
5431 			offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
5432 			_rtw_memcpy(
5433 				&psecuritypriv->dot118021XGrptxmickey[gtk_id],
5434 				&(paoac_rpt->group_key[offset]),
5435 				RTW_TKIP_MIC_LEN);
5436 
5437 			offset = RTW_KEK_LEN;
5438 			_rtw_memcpy(
5439 				&psecuritypriv->dot118021XGrprxmickey[gtk_id],
5440 				&(paoac_rpt->group_key[offset]),
5441 				RTW_TKIP_MIC_LEN);
5442 		}
5443 		RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
5444 			KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
5445 	}
5446 
5447 	/* Update broadcast RX IV */
5448 	if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
5449 		sz = sizeof(psecuritypriv->iv_seq[0]);
5450 		for (i = 0 ; i < 4 ; i++) {
5451 			_rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
5452 			tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
5453 			pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
5454 			_rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
5455 		}
5456 	}
5457 
5458 	rtw_clean_dk_section(adapter);
5459 
5460 	rtw_write8(adapter, REG_SECCFG, 0x0c);
5461 
5462 	#ifdef CONFIG_GTK_OL_DBG
5463 	/* if (gtk_keyindex != 5) */
5464 	dump_sec_cam(RTW_DBGDUMP, adapter);
5465 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
5466 	#endif
5467 }
5468 #endif /*CONFIG_GTK_OL*/
5469 
rtw_dump_aoac_rpt(_adapter * adapter)5470 static void rtw_dump_aoac_rpt(_adapter *adapter)
5471 {
5472 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5473 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5474 	int i = 0;
5475 
5476 	RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
5477 	RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
5478 		paoac_rpt->replay_counter_eapol_key, 8);
5479 	RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
5480 	RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
5481 	RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
5482 	RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
5483 		 paoac_rpt->wow_pattern_idx);
5484 	RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
5485 	RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
5486 	RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
5487 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
5488 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
5489 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
5490 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
5491 }
5492 
rtw_hal_get_aoac_rpt(_adapter * adapter)5493 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
5494 {
5495 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5496 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5497 	u32 page_offset = 0, page_number = 0;
5498 	u32 page_size = 0, buf_size = 0;
5499 	u8 *buffer = NULL;
5500 	u8 i = 0, tmp = 0;
5501 	int ret = -1;
5502 
5503 	/* read aoac report from rsvd page */
5504 	page_offset = pwrctl->wowlan_aoac_rpt_loc;
5505 	page_number = 1;
5506 
5507 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5508 	buf_size = page_size * page_number;
5509 
5510 	buffer = rtw_zvmalloc(buf_size);
5511 
5512 	if (buffer == NULL) {
5513 		RTW_ERR("%s buffer allocate failed size(%d)\n",
5514 			__func__, buf_size);
5515 		return;
5516 	}
5517 
5518 	RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
5519 
5520 	ret = rtw_hal_get_rsvd_page(adapter, page_offset,
5521 		page_number, buffer, buf_size);
5522 
5523 	if (ret == _FALSE) {
5524 		RTW_ERR("%s get aoac report failed\n", __func__);
5525 		rtw_warn_on(1);
5526 		goto _exit;
5527 	}
5528 
5529 	_rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
5530 	_rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
5531 
5532 	for (i = 0 ; i < 4 ; i++) {
5533 		tmp = paoac_rpt->replay_counter_eapol_key[i];
5534 		paoac_rpt->replay_counter_eapol_key[i] =
5535 			paoac_rpt->replay_counter_eapol_key[7 - i];
5536 		paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
5537 	}
5538 
5539 	rtw_dump_aoac_rpt(adapter);
5540 
5541 _exit:
5542 	if (buffer)
5543 		rtw_vmfree(buffer, buf_size);
5544 }
5545 
rtw_hal_update_tx_iv(_adapter * adapter)5546 static void rtw_hal_update_tx_iv(_adapter *adapter)
5547 {
5548 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5549 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5550 	struct sta_info	*psta;
5551 	struct mlme_ext_priv	*pmlmeext = &(adapter->mlmeextpriv);
5552 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5553 	struct security_priv	*psecpriv = &adapter->securitypriv;
5554 
5555 	u16 val16 = 0;
5556 	u32 val32 = 0;
5557 	u64 txiv = 0;
5558 	u8 *pval = NULL;
5559 
5560 	psta = rtw_get_stainfo(&adapter->stapriv,
5561 			       get_my_bssid(&pmlmeinfo->network));
5562 
5563 	/* Update TX iv data. */
5564 	pval = (u8 *)&paoac_rpt->iv;
5565 
5566 	if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
5567 		val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
5568 			((u16)(paoac_rpt->iv[0]) << 8);
5569 		val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5570 			((u32)(paoac_rpt->iv[5]) << 8) +
5571 			((u32)(paoac_rpt->iv[6]) << 16) +
5572 			((u32)(paoac_rpt->iv[7]) << 24);
5573 	} else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
5574 		val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
5575 			((u16)(paoac_rpt->iv[1]) << 8);
5576 		val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5577 			((u32)(paoac_rpt->iv[5]) << 8) +
5578 			((u32)(paoac_rpt->iv[6]) << 16) +
5579 			((u32)(paoac_rpt->iv[7]) << 24);
5580 	}
5581 
5582 	if (psta) {
5583 		txiv = val16 + ((u64)val32 << 16);
5584 		if (txiv != 0)
5585 			psta->dot11txpn.val = txiv;
5586 	}
5587 }
5588 
rtw_hal_update_sw_security_info(_adapter * adapter)5589 static void rtw_hal_update_sw_security_info(_adapter *adapter)
5590 {
5591 	struct security_priv *psecpriv = &adapter->securitypriv;
5592 	u8 sz = sizeof (psecpriv->iv_seq);
5593 
5594 	rtw_hal_update_tx_iv(adapter);
5595 #ifdef CONFIG_GTK_OL
5596 	if (psecpriv->binstallKCK_KEK == _TRUE &&
5597 		(psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5598 		rtw_hal_update_gtk_offload_info(adapter);
5599 #else
5600 	_rtw_memset(psecpriv->iv_seq, 0, sz);
5601 #endif
5602 }
5603 #ifdef CONFIG_CUSTOM_PULSE
rtw_hal_set_gpio_custom_cmd(_adapter * adapter,u8 enable)5604 static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable)
5605 {
5606 	u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0};
5607 	u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1;
5608 	u8 ret = _FAIL;
5609 
5610 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5611 
5612 	if(enable) {
5613 		SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid);
5614 		SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason);
5615 		SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason);
5616 
5617 		ret = rtw_hal_fill_h2c_cmd(adapter,
5618 						H2C_GPIO_CUSTOM,
5619 						H2C_GPIO_CUSTOM_LEN,
5620 						H2CGpioCustomParm);
5621 		RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM,
5622 		H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]);
5623 	}
5624 
5625 	return ret;
5626 }
5627 #endif /* CONFIG_CUSTOM_PULSE */
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)5628 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
5629 {
5630 	u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
5631 	u8 adopt = 1, check_period = 5;
5632 	u8 ret = _FAIL;
5633 	u8 hw_port = rtw_hal_get_port(adapter);
5634 
5635 	SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
5636 	SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
5637 	SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
5638 	SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
5639 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5640 	SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
5641 	RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5642 #else
5643 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5644 #endif
5645 	ret = rtw_hal_fill_h2c_cmd(adapter,
5646 				   H2C_KEEP_ALIVE,
5647 				   H2C_KEEP_ALIVE_CTRL_LEN,
5648 				   u1H2CKeepAliveParm);
5649 
5650 	return ret;
5651 }
5652 
5653 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter,u8 enable)5654 static u8 rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter, u8 enable)
5655 {
5656 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5657 	u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_PATTERN_LEN] = {0};
5658 	u8 ret = _FAIL;
5659 	int i;
5660 
5661 	/* If keep alive pattern is set, FW will use pattern for keep alive action */
5662 	if(enable == 0 || (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_disable)) {
5663 		SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _FALSE);
5664 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE);
5665 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5666 		return ret;
5667 	}
5668 	/*step1:set keep alive period*/
5669 	SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_LOW_BIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_period & 0x00FF);
5670 	SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_HI_BIT(u1H2CKeepAliveParm, ((pwrctl->wowlan_keep_alive_period & 0xFF00)>> 8));
5671 
5672 	if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_tx) {
5673 		SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5674 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE);
5675 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5676 		SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5677 		goto exit;
5678 	}
5679 	if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx) {
5680 		SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5681 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE);
5682 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5683 		SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5684 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index);
5685 		SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval);
5686 		SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter);
5687 		goto exit;
5688 	}
5689 	if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx_with_ack) {
5690 		SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5691 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE);
5692 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _TRUE);
5693 		SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5694 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index);
5695 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_wake_pattern_index);
5696 		SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval);
5697 		SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter);
5698 		goto exit;
5699 	}
5700 exit:
5701 	for(i=0; i<H2C_KEEP_ALIVE_PATTERN_LEN; i++) {
5702 		RTW_INFO("u1H2CKeepAliveParm[%d]= x%0x\n", i, u1H2CKeepAliveParm[i]);
5703 	}
5704 	ret = rtw_hal_fill_h2c_cmd(adapter,
5705 				   H2C_UDP_KEEPALIVE,
5706 				   H2C_KEEP_ALIVE_PATTERN_LEN,
5707 				   u1H2CKeepAliveParm);
5708 
5709 	return ret;
5710 }
5711 #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
5712 
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)5713 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
5714 {
5715 	u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
5716 	u8 adopt = 1, check_period = 100, trypkt_num = 5;
5717 	u8 ret = _FAIL;
5718 	struct registry_priv *pregistry = &adapter->registrypriv;
5719 	u8 hw_port = rtw_hal_get_port(adapter);
5720 
5721 	SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
5722 	SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
5723 	if (!(pregistry->wakeup_event & BIT(2)))
5724 		SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt);
5725 	SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
5726 	SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
5727 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5728 	SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
5729 	RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5730 #else
5731 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5732 #endif
5733 
5734 	ret = rtw_hal_fill_h2c_cmd(adapter,
5735 				   H2C_DISCON_DECISION,
5736 				   H2C_DISCON_DECISION_LEN,
5737 				   u1H2CDisconDecisionParm);
5738 	return ret;
5739 }
5740 
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)5741 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
5742 {
5743 	struct registry_priv  *registry_par = &adapter->registrypriv;
5744 	struct security_priv *psecpriv = &adapter->securitypriv;
5745 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5746 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
5747 
5748 	u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
5749 	u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;
5750 	u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
5751 	u8 sdio_wakeup_enable = 1;
5752 	u8 gpio_high_active = 0;
5753 	u8 magic_pkt = 0;
5754 	u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
5755 	u8 ret = _FAIL;
5756 #ifdef CONFIG_DIS_UPHY
5757 	u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
5758 #endif /* CONFIG_DIS_UPHY */
5759 
5760 #ifdef CONFIG_GPIO_WAKEUP
5761 	gpio_high_active = ppwrpriv->is_high_active;
5762 	gpionum = ppwrpriv->wowlan_gpio_index;
5763 	sdio_wakeup_enable = 0;
5764 #endif /* CONFIG_GPIO_WAKEUP */
5765 
5766 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
5767 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5768 		no_wake = 1;
5769 
5770 	if (!ppwrpriv->wowlan_pno_enable &&
5771 		registry_par->wakeup_event & BIT(0) && !no_wake)
5772 		magic_pkt = enable;
5773 
5774 	if (registry_par->wakeup_event & BIT(2) && !no_wake)
5775 		discont_wake = enable;
5776 
5777 	RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5778 		 enable, change_unit);
5779 
5780 	/* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5781 	if (enable && change_unit) {
5782 		gpio_dur = 0x40;
5783 		gpio_unit = 1;
5784 		gpio_pulse_en = 1;
5785 	}
5786 
5787 #ifdef CONFIG_PLATFORM_ARM_RK3188
5788 	if (enable) {
5789 		gpio_pulse_en = 1;
5790 		gpio_pulse_cnt = 0x04;
5791 	}
5792 #endif
5793 
5794 	SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5795 	if(!no_wake)
5796 		SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5797 	SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5798 	SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5799 	SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5800 	SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5801 
5802 #ifdef CONFIG_GTK_OL
5803 	if (psecpriv->binstallKCK_KEK == _TRUE &&
5804 		(psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5805 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5806 	else
5807 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5808 #else
5809 	SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5810 #endif
5811 	SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5812 	SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5813 	SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5814 
5815 	SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5816 	SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5817 
5818 	SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5819 	SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5820 
5821 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5822 	if (enable)
5823 		SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5824 #endif
5825 
5826 #ifdef CONFIG_DIS_UPHY
5827 	if (enable) {
5828 		dis_uphy = 1;
5829 		/* time unit: 0 -> ms, 1 -> 256 ms*/
5830 		dis_uphy_unit = 1;
5831 		dis_uphy_time = 0x4;
5832 	}
5833 
5834 	SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5835 	SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5836 	SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5837 	if (ppwrpriv->hst2dev_high_active == 1)
5838 		SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5839 #ifdef CONFIG_RTW_ONE_PIN_GPIO
5840 	SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5841 	SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5842 	SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5843 #else
5844 	SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5845 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
5846 #endif /* CONFIG_DIS_UPHY */
5847 
5848 
5849 	ret = rtw_hal_fill_h2c_cmd(adapter,
5850 				   H2C_WOWLAN,
5851 				   H2C_WOWLAN_LEN,
5852 				   u1H2CWoWlanCtrlParm);
5853 	return ret;
5854 }
5855 
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)5856 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5857 {
5858 	struct security_priv *psecuritypriv = &(adapter->securitypriv);
5859 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5860 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
5861 	u8 arp_en = pregistrypriv->wakeup_event & BIT(3);
5862 	u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5863 	u8 ret = _FAIL, count = 0, no_wake = 0;
5864 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
5865 
5866 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
5867 
5868 	if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5869 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5870 		no_wake = 1;
5871 	if(no_wake) {
5872 		SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5873 			u1H2CRemoteWakeCtrlParm, enable);
5874 	} else {
5875 		if (!ppwrpriv->wowlan_pno_enable) {
5876 			SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5877 				u1H2CRemoteWakeCtrlParm, enable);
5878 			if (arp_en)
5879 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5880 					u1H2CRemoteWakeCtrlParm, 1);
5881 			else
5882 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5883 					u1H2CRemoteWakeCtrlParm, 0);
5884 	#ifdef CONFIG_GTK_OL
5885 			if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5886 				(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) {
5887 				SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5888 					u1H2CRemoteWakeCtrlParm, 1);
5889 			} else {
5890 				RTW_INFO("no kck kek\n");
5891 				SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5892 					u1H2CRemoteWakeCtrlParm, 0);
5893 			}
5894 	#endif /* CONFIG_GTK_OL */
5895 
5896 	#ifdef CONFIG_IPV6
5897 			if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5898 				RTW_INFO("enable NS offload\n");
5899 				SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5900 					u1H2CRemoteWakeCtrlParm, enable);
5901 			}
5902 
5903 			/*
5904 			 * filter NetBios name service pkt to avoid being waked-up
5905 			 * by this kind of unicast pkt this exceptional modification
5906 			 * is used for match competitor's behavior
5907 			 */
5908 
5909 			SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5910 				u1H2CRemoteWakeCtrlParm, enable);
5911 	#endif /*CONFIG_IPV6*/
5912 #if 0 /* replaced by WOWLAN pattern match */
5913 	#ifdef CONFIG_RTL8192F
5914 			if (IS_HARDWARE_TYPE_8192F(adapter)){
5915 				SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
5916 					u1H2CRemoteWakeCtrlParm, enable);
5917 			}
5918 	#endif /* CONFIG_RTL8192F */
5919 #endif
5920 			if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
5921 				(psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
5922 				(psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
5923 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5924 					u1H2CRemoteWakeCtrlParm, 0);
5925 			} else { /* WEP etc. */
5926 				if (arp_en)
5927 					SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5928 						u1H2CRemoteWakeCtrlParm, 1);
5929 			}
5930 
5931 			if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
5932 #ifdef CONFIG_GTK_OL
5933 				if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))
5934 					SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5935 						u1H2CRemoteWakeCtrlParm, enable);
5936 #endif /* CONFIG_GTK_OL */
5937 				if (IS_HARDWARE_TYPE_8188E(adapter) ||
5938 				    IS_HARDWARE_TYPE_8812(adapter)) {
5939 					SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5940 						u1H2CRemoteWakeCtrlParm, 0);
5941 					if (arp_en)
5942 						SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5943 							u1H2CRemoteWakeCtrlParm, 1);
5944 				}
5945 			}
5946 
5947 			SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
5948 				u1H2CRemoteWakeCtrlParm, 1);
5949 		}
5950 	#ifdef CONFIG_PNO_SUPPORT
5951 		else {
5952 			SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5953 				u1H2CRemoteWakeCtrlParm, enable);
5954 			SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
5955 				u1H2CRemoteWakeCtrlParm, enable);
5956 		}
5957 	#endif
5958 
5959 	#ifdef CONFIG_P2P_WOWLAN
5960 		if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
5961 			RTW_INFO("P2P OFFLOAD ENABLE\n");
5962 			SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
5963 		} else {
5964 			RTW_INFO("P2P OFFLOAD DISABLE\n");
5965 			SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
5966 		}
5967 	#endif /* CONFIG_P2P_WOWLAN */
5968 	}
5969 
5970 
5971 	ret = rtw_hal_fill_h2c_cmd(adapter,
5972 				   H2C_REMOTE_WAKE_CTRL,
5973 				   H2C_REMOTE_WAKE_CTRL_LEN,
5974 				   u1H2CRemoteWakeCtrlParm);
5975 	return ret;
5976 }
5977 
5978 #ifdef CONFIG_WAR_OFFLOAD
rtw_hal_set_war_offload_ctrl_cmd(_adapter * adapter,u8 enable)5979 static u8 rtw_hal_set_war_offload_ctrl_cmd(_adapter *adapter, u8 enable)
5980 {
5981 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5982 	u8 u1H2CWarOffloadParm[H2C_WAR_OFFLOAD_LEN] = {0};
5983 	u8 ret = _FAIL;
5984 
5985 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
5986 
5987 	if (_TRUE == ppwrpriv->wowlan_war_offload_mode) {
5988 		SET_H2CCMD_WAR_CFG_EN(u1H2CWarOffloadParm, enable);
5989 		SET_H2CCMD_WAR_CFG_ARP_RSP_EN(u1H2CWarOffloadParm, 1);
5990 
5991 #ifdef CONFIG_OFFLOAD_MDNS_V4
5992 		if (WAR_MDNS_V4_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
5993 			SET_H2CCMD_WAR_CFG_MDNSV4_RSP_EN(u1H2CWarOffloadParm, 1);
5994 		}
5995 		if (WAR_MDNS_V4_WAKEUP_EN& ppwrpriv->wowlan_war_offload_ctrl) {
5996 			SET_H2CCMD_WAR_CFG_MDNSV4_WAKE_EN(u1H2CWarOffloadParm, 1);
5997 		}
5998 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
5999 
6000 #ifdef CONFIG_OFFLOAD_MDNS_V6
6001 		if (WAR_MDNS_V6_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
6002 			SET_H2CCMD_WAR_CFG_MDNSV6_RSP_EN(u1H2CWarOffloadParm, 1);
6003 		}
6004 		if (WAR_MDNS_V6_WAKEUP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
6005 			SET_H2CCMD_WAR_CFG_MDNSV6_WAKE_EN(u1H2CWarOffloadParm, 1);
6006 		}
6007 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
6008 
6009 	}
6010 
6011 	ret = rtw_hal_fill_h2c_cmd(adapter,
6012 					H2C_WAR_OFFLOAD,
6013 					H2C_WAR_OFFLOAD_LEN,
6014 					u1H2CWarOffloadParm);
6015 	return ret;
6016 }
6017 
rtw_hal_set_war_offload_parm(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)6018 static u8 rtw_hal_set_war_offload_parm(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
6019 {
6020 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6021 	u8 u1H2CWarOfldParm[H2C_WAROFLD_RSVDPAGE1_LEN] = {0};
6022 	u8 ret = _FAIL;
6023 
6024 	SET_H2CCMD_WAROFLD_RSVDPAGE1_LOC_PARM(u1H2CWarOfldParm, rsvdpageloc->LocIpParm);
6025 	RTW_INFO("%s(): LocIpParm = %d\n", __func__, rsvdpageloc->LocIpParm);
6026 
6027 
6028 	ret = rtw_hal_fill_h2c_cmd(adapter,
6029 					H2C_WAROFLD_RSVDPAGE1,
6030 					H2C_WAROFLD_RSVDPAGE1_LEN,
6031 					u1H2CWarOfldParm);
6032 
6033 	return ret;
6034 }
6035 #endif /* CONFIG_WAR_OFFLOAD */
6036 
6037 
6038 
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)6039 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
6040 {
6041 	u8 ret = _FAIL;
6042 	u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
6043 
6044 	RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
6045 		 __func__, group_alg, pairwise_alg);
6046 	SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
6047 			pairwise_alg);
6048 	SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
6049 			group_alg);
6050 
6051 	ret = rtw_hal_fill_h2c_cmd(adapter,
6052 				   H2C_AOAC_GLOBAL_INFO,
6053 				   H2C_AOAC_GLOBAL_INFO_LEN,
6054 				   u1H2CAOACGlobalInfoParm);
6055 
6056 	return ret;
6057 }
6058 
6059 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)6060 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
6061 		PRSVDPAGE_LOC rsvdpageloc, u8 enable)
6062 {
6063 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6064 	u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
6065 	u8 res = 0, count = 0, ret = _FAIL;
6066 
6067 	RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
6068 		 __func__, rsvdpageloc->LocProbePacket,
6069 		 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
6070 
6071 	SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6072 	SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6073 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6074 					       rsvdpageloc->LocScanInfo);
6075 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6076 			rsvdpageloc->LocProbePacket);
6077 	/*
6078 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6079 				rsvdpageloc->LocSSIDInfo);
6080 	*/
6081 	ret = rtw_hal_fill_h2c_cmd(adapter,
6082 				   H2C_D0_SCAN_OFFLOAD_INFO,
6083 				   H2C_SCAN_OFFLOAD_CTRL_LEN,
6084 				   u1H2CScanOffloadInfoParm);
6085 	return ret;
6086 }
6087 #endif /* CONFIG_PNO_SUPPORT */
6088 
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)6089 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6090 {
6091 	struct security_priv *psecpriv = &padapter->securitypriv;
6092 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6093 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
6094 	struct registry_priv *pregistry = &padapter->registrypriv;
6095 	u8	pkt_type = 0, no_wake = 0;
6096 
6097 	if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6098 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
6099 		no_wake = 1;
6100 
6101 	RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6102 
6103 	rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6104 
6105 	if (enable) {
6106 		if(!no_wake)
6107 			rtw_hal_set_global_info_cmd(padapter,
6108 					    psecpriv->dot118021XGrpPrivacy,
6109 					    psecpriv->dot11PrivacyAlgrthm);
6110 
6111 		if (!(ppwrpriv->wowlan_pno_enable)) {
6112 			if (!no_wake)
6113 				rtw_hal_set_disconnect_decision_cmd(padapter,
6114 								    enable);
6115 #ifdef CONFIG_ARP_KEEP_ALIVE
6116 			if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6117 			    (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6118 				pkt_type = 0;
6119 			else
6120 				pkt_type = 1;
6121 #else
6122 			pkt_type = 0;
6123 #endif /* CONFIG_ARP_KEEP_ALIVE */
6124 			if(!no_wake) {
6125 				#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
6126 				rtw_hal_set_keep_alive_pattern_cmd(padapter,enable);
6127 				#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
6128 				rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6129                         }
6130 		}
6131 #ifdef CONFIG_PNO_SUPPORT
6132 		rtw_hal_check_pno_enabled(padapter);
6133 #endif /* CONFIG_PNO_SUPPORT */
6134 #ifdef CONFIG_WAR_OFFLOAD
6135 		rtw_hal_set_war_offload_ctrl_cmd(padapter, enable);
6136 #endif /* CONFIG_WAR_OFFLOAD */
6137 
6138 	} else {
6139 #if 0
6140 		{
6141 			u32 PageSize = 0;
6142 			rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
6143 			dump_TX_FIFO(padapter, 4, PageSize);
6144 		}
6145 #endif
6146 	}
6147 #ifdef CONFIG_CUSTOM_PULSE
6148 	rtw_hal_set_gpio_custom_cmd(padapter, enable);
6149 #endif /* CONFIG_CUSTOM_PULSE */
6150 	rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6151 	RTW_PRINT("-%s()-\n", __func__);
6152 }
6153 #endif /* CONFIG_WOWLAN */
6154 
6155 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)6156 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
6157 {
6158 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6159 
6160 	u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
6161 	u8 gpionum = 0, gpio_dur = 0;
6162 	u8 gpio_pulse = enable;
6163 	u8 sdio_wakeup_enable = 1;
6164 	u8 gpio_high_active = 0;
6165 	u8 ret = _FAIL;
6166 
6167 #ifdef CONFIG_GPIO_WAKEUP
6168 	gpio_high_active = ppwrpriv->is_high_active;
6169 	gpionum = ppwrpriv->wowlan_gpio_index;
6170 	sdio_wakeup_enable = 0;
6171 #endif /*CONFIG_GPIO_WAKEUP*/
6172 
6173 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
6174 
6175 	SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
6176 					  gpionum);
6177 	SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
6178 					 gpio_pulse);
6179 	SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
6180 						gpio_high_active);
6181 	SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
6182 				       enable);
6183 	SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
6184 					     gpio_dur);
6185 
6186 	ret = rtw_hal_fill_h2c_cmd(adapter,
6187 				   H2C_AP_WOW_GPIO_CTRL,
6188 				   H2C_AP_WOW_GPIO_CTRL_LEN,
6189 				   u1H2CAPWoWlanCtrlParm);
6190 
6191 	return ret;
6192 }
6193 
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)6194 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6195 {
6196 	u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
6197 	u8 ret = _FAIL;
6198 
6199 	RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
6200 
6201 	SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
6202 
6203 	ret = rtw_hal_fill_h2c_cmd(adapter,
6204 				   H2C_AP_OFFLOAD,
6205 				   H2C_AP_OFFLOAD_LEN,
6206 				   u1H2CAPOffloadCtrlParm);
6207 
6208 	return ret;
6209 }
6210 
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)6211 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
6212 {
6213 	u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
6214 	u8 ret = _FAIL;
6215 
6216 	RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
6217 
6218 	SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
6219 #ifndef CONFIG_USB_HCI
6220 	SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
6221 #endif /*CONFIG_USB_HCI*/
6222 	SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
6223 
6224 	if (enable)
6225 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
6226 	else
6227 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
6228 
6229 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
6230 				   H2C_AP_PS_LEN, ap_ps_parm);
6231 
6232 	return ret;
6233 }
6234 
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)6235 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
6236 		PRSVDPAGE_LOC rsvdpageloc)
6237 {
6238 	struct hal_ops *pHalFunc = &padapter->hal_func;
6239 	u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
6240 	u8 ret = _FAIL, header = 0;
6241 
6242 	if (pHalFunc->fill_h2c_cmd == NULL) {
6243 		RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
6244 		return;
6245 	}
6246 
6247 	header = rtw_read8(padapter, REG_BCNQ_BDNY);
6248 
6249 	RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
6250 		 rsvdpageloc->LocApOffloadBCN,
6251 		 rsvdpageloc->LocProbeRsp,
6252 		 header);
6253 
6254 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
6255 				      rsvdpageloc->LocApOffloadBCN + header);
6256 
6257 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
6258 				   H2C_BCN_RSVDPAGE_LEN, rsvdparm);
6259 
6260 	if (ret == _FAIL)
6261 		RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
6262 
6263 	rtw_msleep_os(10);
6264 
6265 	_rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
6266 
6267 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
6268 			rsvdpageloc->LocProbeRsp + header);
6269 
6270 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
6271 				   H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
6272 
6273 	if (ret == _FAIL)
6274 		RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
6275 
6276 	rtw_msleep_os(10);
6277 }
6278 
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)6279 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
6280 {
6281 	rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
6282 	rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
6283 	rtw_hal_set_ap_ps_cmd(padapter, enable);
6284 }
6285 
rtw_hal_ap_wow_enable(_adapter * padapter)6286 static void rtw_hal_ap_wow_enable(_adapter *padapter)
6287 {
6288 	struct security_priv *psecuritypriv = &padapter->securitypriv;
6289 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6290 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6291 	struct sta_info *psta = NULL;
6292 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6293 #ifdef DBG_CHECK_FW_PS_STATE
6294 	struct dvobj_priv *psdpriv = padapter->dvobj;
6295 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6296 #endif /*DBG_CHECK_FW_PS_STATE*/
6297 	int res;
6298 	u16 media_status_rpt;
6299 #ifdef CONFIG_GPIO_WAKEUP
6300 	u8 val8 = 0;
6301 #endif
6302 
6303 	RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
6304 #ifdef DBG_CHECK_FW_PS_STATE
6305 	if (rtw_fw_ps_state(padapter) == _FAIL) {
6306 		pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
6307 		RTW_PRINT("wowlan enable no leave 32k\n");
6308 	}
6309 #endif /*DBG_CHECK_FW_PS_STATE*/
6310 
6311 	/* 1. Download WOWLAN FW*/
6312 	rtw_hal_fw_dl(padapter, _TRUE);
6313 
6314 	media_status_rpt = RT_MEDIA_CONNECT;
6315 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6316 			  (u8 *)&media_status_rpt);
6317 
6318 	issue_beacon(padapter, 0);
6319 
6320 	rtw_msleep_os(2);
6321 	#if defined(CONFIG_RTL8188E)
6322 	if (IS_HARDWARE_TYPE_8188E(padapter))
6323 		rtw_hal_disable_tx_report(padapter);
6324 	#endif
6325 	/* RX DMA stop */
6326 	res = rtw_hal_pause_rx_dma(padapter);
6327 	if (res == _FAIL)
6328 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
6329 
6330 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6331 	/* Enable CPWM2 only. */
6332 	res = rtw_hal_enable_cpwm2(padapter);
6333 	if (res == _FAIL)
6334 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6335 #endif
6336 
6337 #ifdef CONFIG_GPIO_WAKEUP
6338 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6339 	rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6340 	rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6341 #else
6342 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6343 	if (pwrctrlpriv->is_high_active == 0)
6344 		rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6345 	else
6346 		rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index,
6347 			GPIO_OUTPUT_LOW);
6348 #else
6349 	val8 = (pwrpriv->is_high_active == 0) ? 1 : 0;
6350 	rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8);
6351 	rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6352 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n",
6353 		 __func__, pwrpriv->wowlan_gpio_index,
6354 		 pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW",
6355 		 pwrpriv->is_high_active ? "HIGI" : "LOW");
6356 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
6357 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6358 #endif /* CONFIG_GPIO_WAKEUP */
6359 
6360 	/* 5. Set Enable WOWLAN H2C command. */
6361 	RTW_PRINT("Set Enable AP WOWLan cmd\n");
6362 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
6363 
6364 	rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
6365 #ifdef CONFIG_USB_HCI
6366 	rtw_mi_intf_stop(padapter);
6367 #endif
6368 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
6369 	/* Invoid SE0 reset signal during suspending*/
6370 	rtw_write8(padapter, REG_RSV_CTRL, 0x20);
6371 	if (IS_8188F(pHalData->version_id) == FALSE
6372 		&& IS_8188GTV(pHalData->version_id) == FALSE)
6373 		rtw_write8(padapter, REG_RSV_CTRL, 0x60);
6374 #endif
6375 }
6376 
rtw_hal_ap_wow_disable(_adapter * padapter)6377 static void rtw_hal_ap_wow_disable(_adapter *padapter)
6378 {
6379 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6380 #ifdef DBG_CHECK_FW_PS_STATE
6381 	struct dvobj_priv *psdpriv = padapter->dvobj;
6382 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6383 #endif /*DBG_CHECK_FW_PS_STATE*/
6384 	u16 media_status_rpt;
6385 
6386 	RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
6387 	/* 1. Read wakeup reason*/
6388 	pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
6389 
6390 	RTW_PRINT("wakeup_reason: 0x%02x\n",
6391 		  pwrctl->wowlan_wake_reason);
6392 
6393 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
6394 
6395 	rtw_msleep_os(2);
6396 #ifdef DBG_CHECK_FW_PS_STATE
6397 	if (rtw_fw_ps_state(padapter) == _FAIL) {
6398 		pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
6399 		RTW_PRINT("wowlan enable no leave 32k\n");
6400 	}
6401 #endif /*DBG_CHECK_FW_PS_STATE*/
6402 
6403 	#if defined(CONFIG_RTL8188E)
6404 	if (IS_HARDWARE_TYPE_8188E(padapter))
6405 		rtw_hal_enable_tx_report(padapter);
6406 	#endif
6407 
6408 	rtw_hal_force_enable_rxdma(padapter);
6409 
6410 	rtw_hal_fw_dl(padapter, _FALSE);
6411 
6412 #ifdef CONFIG_GPIO_WAKEUP
6413 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6414 	rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6415 #else
6416 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6417 	if (pwrctl->is_high_active == 0)
6418 		rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6419 	else
6420 		rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index
6421 			, GPIO_OUTPUT_LOW);
6422 #else
6423 	rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index,
6424 		pwrctl->wowlan_gpio_output_state);
6425 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n",
6426 		 __func__, pwrctl->wowlan_gpio_index,
6427 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
6428 		 pwrctl->is_high_active ? "HIGI" : "LOW");
6429 #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
6430 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6431 #endif /* CONFIG_GPIO_WAKEUP */
6432 	media_status_rpt = RT_MEDIA_CONNECT;
6433 
6434 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6435 			  (u8 *)&media_status_rpt);
6436 
6437 	issue_beacon(padapter, 0);
6438 }
6439 #endif /*CONFIG_AP_WOWLAN*/
6440 
6441 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)6442 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6443 {
6444 	u8 *ssid_ie;
6445 	sint ssid_len_ori;
6446 	int len_diff = 0;
6447 
6448 	ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
6449 
6450 	/* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
6451 
6452 	if (ssid_ie && ssid_len_ori > 0) {
6453 		switch (hidden_ssid_mode) {
6454 		case 1: {
6455 			u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6456 			u32 remain_len = 0;
6457 
6458 			remain_len = ies_len - (next_ie - ies);
6459 
6460 			ssid_ie[1] = 0;
6461 			_rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
6462 			len_diff -= ssid_len_ori;
6463 
6464 			break;
6465 		}
6466 		case 2:
6467 			_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6468 			break;
6469 		default:
6470 			break;
6471 		}
6472 	}
6473 
6474 	return len_diff;
6475 }
6476 
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)6477 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
6478 {
6479 	/* struct xmit_frame	*pmgntframe; */
6480 	/* struct pkt_attrib	*pattrib; */
6481 	/* unsigned char	*pframe; */
6482 	struct rtw_ieee80211_hdr *pwlanhdr;
6483 	unsigned short *fctrl;
6484 	unsigned int	rate_len;
6485 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
6486 	u32	pktlen;
6487 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6488 	/*	_irqL irqL;
6489 	 *	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6490 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6491 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6492 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6493 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6494 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
6495 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6496 #ifdef CONFIG_P2P
6497 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6498 #endif /* CONFIG_P2P */
6499 
6500 	/* for debug */
6501 	u8 *dbgbuf = pframe;
6502 	u8 dbgbufLen = 0, index = 0;
6503 
6504 	RTW_INFO("%s\n", __FUNCTION__);
6505 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6506 	/*	_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6507 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6508 
6509 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6510 
6511 
6512 	fctrl = &(pwlanhdr->frame_ctl);
6513 	*(fctrl) = 0;
6514 
6515 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6516 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6517 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6518 
6519 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6520 	/* pmlmeext->mgnt_seq++; */
6521 	set_frame_sub_type(pframe, WIFI_BEACON);
6522 
6523 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6524 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6525 
6526 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6527 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6528 #ifdef CONFIG_P2P
6529 		/* for P2P : Primary Device Type & Device Name */
6530 		u32 wpsielen = 0, insert_len = 0;
6531 		u8 *wpsie = NULL;
6532 		wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
6533 
6534 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
6535 			uint wps_offset, remainder_ielen;
6536 			u8 *premainder_ie, *pframe_wscie;
6537 
6538 			wps_offset = (uint)(wpsie - cur_network->IEs);
6539 
6540 			premainder_ie = wpsie + wpsielen;
6541 
6542 			remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6543 
6544 #ifdef CONFIG_IOCTL_CFG80211
6545 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6546 				if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
6547 					_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
6548 					pframe += wps_offset;
6549 					pktlen += wps_offset;
6550 
6551 					_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6552 					pframe += pmlmepriv->wps_beacon_ie_len;
6553 					pktlen += pmlmepriv->wps_beacon_ie_len;
6554 
6555 					/* copy remainder_ie to pframe */
6556 					_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6557 					pframe += remainder_ielen;
6558 					pktlen += remainder_ielen;
6559 				} else {
6560 					_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6561 					pframe += cur_network->IELength;
6562 					pktlen += cur_network->IELength;
6563 				}
6564 			} else
6565 #endif /* CONFIG_IOCTL_CFG80211 */
6566 			{
6567 				pframe_wscie = pframe + wps_offset;
6568 				_rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
6569 				pframe += (wps_offset + wpsielen);
6570 				pktlen += (wps_offset + wpsielen);
6571 
6572 				/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6573 				/*	Primary Device Type */
6574 				/*	Type: */
6575 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6576 				insert_len += 2;
6577 
6578 				/*	Length: */
6579 				*(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
6580 				insert_len += 2;
6581 
6582 				/*	Value: */
6583 				/*	Category ID */
6584 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6585 				insert_len += 2;
6586 
6587 				/*	OUI */
6588 				*(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
6589 				insert_len += 4;
6590 
6591 				/*	Sub Category ID */
6592 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6593 				insert_len += 2;
6594 
6595 
6596 				/*	Device Name */
6597 				/*	Type: */
6598 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6599 				insert_len += 2;
6600 
6601 				/*	Length: */
6602 				*(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
6603 				insert_len += 2;
6604 
6605 				/*	Value: */
6606 				_rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
6607 				insert_len += pwdinfo->device_name_len;
6608 
6609 
6610 				/* update wsc ie length */
6611 				*(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
6612 
6613 				/* pframe move to end */
6614 				pframe += insert_len;
6615 				pktlen += insert_len;
6616 
6617 				/* copy remainder_ie to pframe */
6618 				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6619 				pframe += remainder_ielen;
6620 				pktlen += remainder_ielen;
6621 			}
6622 		} else
6623 #endif /* CONFIG_P2P */
6624 		{
6625 			int len_diff;
6626 			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6627 			len_diff = update_hidden_ssid(
6628 					   pframe + _BEACON_IE_OFFSET_
6629 				   , cur_network->IELength - _BEACON_IE_OFFSET_
6630 					   , pmlmeinfo->hidden_ssid_mode
6631 				   );
6632 			pframe += (cur_network->IELength + len_diff);
6633 			pktlen += (cur_network->IELength + len_diff);
6634 		}
6635 #if 0
6636 		{
6637 			u8 *wps_ie;
6638 			uint wps_ielen;
6639 			u8 sr = 0;
6640 			wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
6641 				pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
6642 			if (wps_ie && wps_ielen > 0)
6643 				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6644 			if (sr != 0)
6645 				set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6646 			else
6647 				_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6648 		}
6649 #endif
6650 #ifdef CONFIG_P2P
6651 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6652 			u32 len;
6653 #ifdef CONFIG_IOCTL_CFG80211
6654 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6655 				len = pmlmepriv->p2p_beacon_ie_len;
6656 				if (pmlmepriv->p2p_beacon_ie && len > 0)
6657 					_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6658 			} else
6659 #endif /* CONFIG_IOCTL_CFG80211 */
6660 			{
6661 				len = build_beacon_p2p_ie(pwdinfo, pframe);
6662 			}
6663 
6664 			pframe += len;
6665 			pktlen += len;
6666 
6667 			#ifdef CONFIG_WFD
6668 			len = rtw_append_beacon_wfd_ie(padapter, pframe);
6669 			pframe += len;
6670 			pktlen += len;
6671 			#endif
6672 
6673 		}
6674 #endif /* CONFIG_P2P */
6675 
6676 		goto _issue_bcn;
6677 
6678 	}
6679 
6680 	/* below for ad-hoc mode */
6681 
6682 	/* timestamp will be inserted by hardware */
6683 	pframe += 8;
6684 	pktlen += 8;
6685 
6686 	/* beacon interval: 2 bytes */
6687 
6688 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6689 
6690 	pframe += 2;
6691 	pktlen += 2;
6692 
6693 	/* capability info: 2 bytes */
6694 
6695 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6696 
6697 	pframe += 2;
6698 	pktlen += 2;
6699 
6700 	/* SSID */
6701 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6702 
6703 	/* supported rates... */
6704 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6705 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6706 
6707 	/* DS parameter set */
6708 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6709 
6710 	/* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6711 	{
6712 		u8 erpinfo = 0;
6713 		u32 ATIMWindow;
6714 		/* IBSS Parameter Set... */
6715 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
6716 		ATIMWindow = 0;
6717 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6718 
6719 		/* ERP IE */
6720 		pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
6721 	}
6722 
6723 
6724 	/* EXTERNDED SUPPORTED RATE */
6725 	if (rate_len > 8)
6726 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6727 
6728 
6729 	/* todo:HT for adhoc */
6730 
6731 _issue_bcn:
6732 
6733 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6734 	/*	pmlmepriv->update_bcn = _FALSE;
6735 	 *
6736 	 *	_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6737 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6738 
6739 	*pLength = pktlen;
6740 #if 0
6741 	/* printf dbg msg */
6742 	dbgbufLen = pktlen;
6743 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6744 
6745 	for (index = 0; index < dbgbufLen; index++)
6746 		printk("%x ", *(dbgbuf + index));
6747 
6748 	printk("\n");
6749 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6750 
6751 #endif
6752 }
6753 
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6754 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6755 {
6756 	/* struct xmit_frame			*pmgntframe; */
6757 	/* struct pkt_attrib			*pattrib; */
6758 	/* unsigned char					*pframe; */
6759 	struct rtw_ieee80211_hdr	*pwlanhdr;
6760 	unsigned short				*fctrl;
6761 	unsigned char					*mac;
6762 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
6763 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6764 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6765 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6766 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
6767 	u16					beacon_interval = 100;
6768 	u16					capInfo = 0;
6769 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6770 	u8					wpsie[255] = { 0x00 };
6771 	u32					wpsielen = 0, p2pielen = 0;
6772 	u32					pktlen;
6773 #ifdef CONFIG_WFD
6774 	u32					wfdielen = 0;
6775 #endif
6776 
6777 	/* for debug */
6778 	u8 *dbgbuf = pframe;
6779 	u8 dbgbufLen = 0, index = 0;
6780 
6781 	RTW_INFO("%s\n", __FUNCTION__);
6782 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6783 
6784 	mac = adapter_mac_addr(padapter);
6785 
6786 	fctrl = &(pwlanhdr->frame_ctl);
6787 	*(fctrl) = 0;
6788 
6789 	/* DA filled by FW */
6790 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6791 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6792 
6793 	/*	Use the device address for BSSID field.	 */
6794 	_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6795 
6796 	SetSeqNum(pwlanhdr, 0);
6797 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
6798 
6799 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6800 	pframe += pktlen;
6801 
6802 
6803 	/* timestamp will be inserted by hardware */
6804 	pframe += 8;
6805 	pktlen += 8;
6806 
6807 	/* beacon interval: 2 bytes */
6808 	_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6809 	pframe += 2;
6810 	pktlen += 2;
6811 
6812 	/*	capability info: 2 bytes */
6813 	/*	ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6814 	capInfo |= cap_ShortPremble;
6815 	capInfo |= cap_ShortSlot;
6816 
6817 	_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6818 	pframe += 2;
6819 	pktlen += 2;
6820 
6821 
6822 	/* SSID */
6823 	pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
6824 
6825 	/* supported rates... */
6826 	/*	Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6827 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
6828 
6829 	/* DS parameter set */
6830 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
6831 
6832 #ifdef CONFIG_IOCTL_CFG80211
6833 	if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6834 		if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6835 			/* WPS IE */
6836 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6837 			pktlen += pmlmepriv->wps_probe_resp_ie_len;
6838 			pframe += pmlmepriv->wps_probe_resp_ie_len;
6839 
6840 			/* P2P IE */
6841 			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6842 			pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6843 			pframe += pmlmepriv->p2p_probe_resp_ie_len;
6844 		}
6845 	} else
6846 #endif /* CONFIG_IOCTL_CFG80211		 */
6847 	{
6848 
6849 		/*	Todo: WPS IE */
6850 		/*	Noted by Albert 20100907 */
6851 		/*	According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6852 
6853 		wpsielen = 0;
6854 		/*	WPS OUI */
6855 		*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6856 		wpsielen += 4;
6857 
6858 		/*	WPS version */
6859 		/*	Type: */
6860 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6861 		wpsielen += 2;
6862 
6863 		/*	Length: */
6864 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6865 		wpsielen += 2;
6866 
6867 		/*	Value: */
6868 		wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
6869 
6870 		/*	WiFi Simple Config State */
6871 		/*	Type: */
6872 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6873 		wpsielen += 2;
6874 
6875 		/*	Length: */
6876 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6877 		wpsielen += 2;
6878 
6879 		/*	Value: */
6880 		wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;	/*	Not Configured. */
6881 
6882 		/*	Response Type */
6883 		/*	Type: */
6884 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6885 		wpsielen += 2;
6886 
6887 		/*	Length: */
6888 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6889 		wpsielen += 2;
6890 
6891 		/*	Value: */
6892 		wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6893 
6894 		/*	UUID-E */
6895 		/*	Type: */
6896 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6897 		wpsielen += 2;
6898 
6899 		/*	Length: */
6900 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6901 		wpsielen += 2;
6902 
6903 		/*	Value: */
6904 		if (pwdinfo->external_uuid == 0) {
6905 			_rtw_memset(wpsie + wpsielen, 0x0, 16);
6906 			_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6907 		} else
6908 			_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6909 		wpsielen += 0x10;
6910 
6911 		/*	Manufacturer */
6912 		/*	Type: */
6913 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6914 		wpsielen += 2;
6915 
6916 		/*	Length: */
6917 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6918 		wpsielen += 2;
6919 
6920 		/*	Value: */
6921 		_rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6922 		wpsielen += 7;
6923 
6924 		/*	Model Name */
6925 		/*	Type: */
6926 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
6927 		wpsielen += 2;
6928 
6929 		/*	Length: */
6930 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
6931 		wpsielen += 2;
6932 
6933 		/*	Value: */
6934 		_rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6935 		wpsielen += 6;
6936 
6937 		/*	Model Number */
6938 		/*	Type: */
6939 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6940 		wpsielen += 2;
6941 
6942 		/*	Length: */
6943 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6944 		wpsielen += 2;
6945 
6946 		/*	Value: */
6947 		wpsie[wpsielen++] = 0x31;		/*	character 1 */
6948 
6949 		/*	Serial Number */
6950 		/*	Type: */
6951 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6952 		wpsielen += 2;
6953 
6954 		/*	Length: */
6955 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6956 		wpsielen += 2;
6957 
6958 		/*	Value: */
6959 		_rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6960 		wpsielen += ETH_ALEN;
6961 
6962 		/*	Primary Device Type */
6963 		/*	Type: */
6964 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6965 		wpsielen += 2;
6966 
6967 		/*	Length: */
6968 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6969 		wpsielen += 2;
6970 
6971 		/*	Value: */
6972 		/*	Category ID */
6973 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6974 		wpsielen += 2;
6975 
6976 		/*	OUI */
6977 		*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6978 		wpsielen += 4;
6979 
6980 		/*	Sub Category ID */
6981 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6982 		wpsielen += 2;
6983 
6984 		/*	Device Name */
6985 		/*	Type: */
6986 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6987 		wpsielen += 2;
6988 
6989 		/*	Length: */
6990 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
6991 		wpsielen += 2;
6992 
6993 		/*	Value: */
6994 		_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
6995 		wpsielen += pwdinfo->device_name_len;
6996 
6997 		/*	Config Method */
6998 		/*	Type: */
6999 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
7000 		wpsielen += 2;
7001 
7002 		/*	Length: */
7003 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7004 		wpsielen += 2;
7005 
7006 		/*	Value: */
7007 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7008 		wpsielen += 2;
7009 
7010 
7011 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7012 
7013 
7014 		p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
7015 		pframe += p2pielen;
7016 		pktlen += p2pielen;
7017 	}
7018 
7019 #ifdef CONFIG_WFD
7020 	wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
7021 	pframe += wfdielen;
7022 	pktlen += wfdielen;
7023 #endif
7024 
7025 	*pLength = pktlen;
7026 
7027 #if 0
7028 	/* printf dbg msg */
7029 	dbgbufLen = pktlen;
7030 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7031 
7032 	for (index = 0; index < dbgbufLen; index++)
7033 		printk("%x ", *(dbgbuf + index));
7034 
7035 	printk("\n");
7036 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7037 #endif
7038 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7039 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7040 {
7041 	struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7042 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7043 	u8			action = P2P_PUB_ACTION_ACTION;
7044 	u32			p2poui = cpu_to_be32(P2POUI);
7045 	u8			oui_subtype = P2P_GO_NEGO_RESP;
7046 	u8			wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
7047 	u8			p2pielen = 0, i;
7048 	uint			wpsielen = 0;
7049 	u16			wps_devicepassword_id = 0x0000;
7050 	uint			wps_devicepassword_id_len = 0;
7051 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
7052 	u16			len_channellist_attr = 0;
7053 	u32			pktlen;
7054 	u8			dialogToken = 0;
7055 
7056 	/* struct xmit_frame			*pmgntframe; */
7057 	/* struct pkt_attrib			*pattrib; */
7058 	/* unsigned char					*pframe; */
7059 	struct rtw_ieee80211_hdr	*pwlanhdr;
7060 	unsigned short				*fctrl;
7061 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7062 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7063 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7064 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7065 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
7066 
7067 #ifdef CONFIG_WFD
7068 	u32					wfdielen = 0;
7069 #endif
7070 
7071 	/* for debug */
7072 	u8 *dbgbuf = pframe;
7073 	u8 dbgbufLen = 0, index = 0;
7074 
7075 	RTW_INFO("%s\n", __FUNCTION__);
7076 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7077 
7078 	fctrl = &(pwlanhdr->frame_ctl);
7079 	*(fctrl) = 0;
7080 
7081 	/* RA, filled by FW */
7082 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7083 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7084 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7085 
7086 	SetSeqNum(pwlanhdr, 0);
7087 	set_frame_sub_type(pframe, WIFI_ACTION);
7088 
7089 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7090 	pframe += pktlen;
7091 
7092 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7093 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7094 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7095 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7096 
7097 	/* dialog token, filled by FW */
7098 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7099 
7100 	_rtw_memset(wpsie, 0x00, 255);
7101 	wpsielen = 0;
7102 
7103 	/*	WPS Section */
7104 	wpsielen = 0;
7105 	/*	WPS OUI */
7106 	*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7107 	wpsielen += 4;
7108 
7109 	/*	WPS version */
7110 	/*	Type: */
7111 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7112 	wpsielen += 2;
7113 
7114 	/*	Length: */
7115 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7116 	wpsielen += 2;
7117 
7118 	/*	Value: */
7119 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
7120 
7121 	/*	Device Password ID */
7122 	/*	Type: */
7123 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
7124 	wpsielen += 2;
7125 
7126 	/*	Length: */
7127 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7128 	wpsielen += 2;
7129 
7130 	/*	Value: */
7131 	if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
7132 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
7133 	else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
7134 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
7135 	else
7136 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
7137 	wpsielen += 2;
7138 
7139 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7140 
7141 
7142 	/*	P2P IE Section. */
7143 
7144 	/*	P2P OUI */
7145 	p2pielen = 0;
7146 	p2pie[p2pielen++] = 0x50;
7147 	p2pie[p2pielen++] = 0x6F;
7148 	p2pie[p2pielen++] = 0x9A;
7149 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
7150 
7151 	/*	Commented by Albert 20100908 */
7152 	/*	According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
7153 	/*	1. Status */
7154 	/*	2. P2P Capability */
7155 	/*	3. Group Owner Intent */
7156 	/*	4. Configuration Timeout */
7157 	/*	5. Operating Channel */
7158 	/*	6. Intended P2P Interface Address */
7159 	/*	7. Channel List */
7160 	/*	8. Device Info */
7161 	/*	9. Group ID	( Only GO ) */
7162 
7163 
7164 	/*	ToDo: */
7165 
7166 	/*	P2P Status */
7167 	/*	Type: */
7168 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
7169 
7170 	/*	Length: */
7171 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7172 	p2pielen += 2;
7173 
7174 	/*	Value, filled by FW */
7175 	p2pie[p2pielen++] = 1;
7176 
7177 	/*	P2P Capability */
7178 	/*	Type: */
7179 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
7180 
7181 	/*	Length: */
7182 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7183 	p2pielen += 2;
7184 
7185 	/*	Value: */
7186 	/*	Device Capability Bitmap, 1 byte */
7187 
7188 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
7189 		/*	Commented by Albert 2011/03/08 */
7190 		/*	According to the P2P specification */
7191 		/*	if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
7192 		p2pie[p2pielen++] = 0;
7193 	} else {
7194 		/*	Be group owner or meet the error case */
7195 		p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
7196 	}
7197 
7198 	/*	Group Capability Bitmap, 1 byte */
7199 	if (pwdinfo->persistent_supported)
7200 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
7201 	else
7202 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
7203 
7204 	/*	Group Owner Intent */
7205 	/*	Type: */
7206 	p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
7207 
7208 	/*	Length: */
7209 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7210 	p2pielen += 2;
7211 
7212 	/*	Value: */
7213 	if (pwdinfo->peer_intent & 0x01) {
7214 		/*	Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
7215 		p2pie[p2pielen++] = (pwdinfo->intent << 1);
7216 	} else {
7217 		/*	Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
7218 		p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
7219 	}
7220 
7221 
7222 	/*	Configuration Timeout */
7223 	/*	Type: */
7224 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7225 
7226 	/*	Length: */
7227 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7228 	p2pielen += 2;
7229 
7230 	/*	Value: */
7231 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
7232 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
7233 
7234 	/*	Operating Channel */
7235 	/*	Type: */
7236 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7237 
7238 	/*	Length: */
7239 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7240 	p2pielen += 2;
7241 
7242 	/*	Value: */
7243 	/*	Country String */
7244 	p2pie[p2pielen++] = 'X';
7245 	p2pie[p2pielen++] = 'X';
7246 
7247 	/*	The third byte should be set to 0x04. */
7248 	/*	Described in the "Operating Channel Attribute" section. */
7249 	p2pie[p2pielen++] = 0x04;
7250 
7251 	/*	Operating Class */
7252 	if (pwdinfo->operating_channel <= 14) {
7253 		/*	Operating Class */
7254 		p2pie[p2pielen++] = 0x51;
7255 	} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
7256 		/*	Operating Class */
7257 		p2pie[p2pielen++] = 0x73;
7258 	} else {
7259 		/*	Operating Class */
7260 		p2pie[p2pielen++] = 0x7c;
7261 	}
7262 
7263 	/*	Channel Number */
7264 	p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
7265 
7266 	/*	Intended P2P Interface Address	 */
7267 	/*	Type: */
7268 	p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
7269 
7270 	/*	Length: */
7271 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7272 	p2pielen += 2;
7273 
7274 	/*	Value: */
7275 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7276 	p2pielen += ETH_ALEN;
7277 
7278 	/*	Channel List */
7279 	/*	Type: */
7280 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7281 
7282 	/* Country String(3) */
7283 	/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7284 	/* + number of channels in all classes */
7285 	len_channellist_attr = 3
7286 		       + (1 + 1) * (u16)ch_list->reg_classes
7287 		       + get_reg_classes_full_count(ch_list);
7288 
7289 #ifdef CONFIG_CONCURRENT_MODE
7290 	if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7291 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7292 	else
7293 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7294 
7295 #else
7296 
7297 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7298 
7299 #endif
7300 	p2pielen += 2;
7301 
7302 	/*	Value: */
7303 	/*	Country String */
7304 	p2pie[p2pielen++] = 'X';
7305 	p2pie[p2pielen++] = 'X';
7306 
7307 	/*	The third byte should be set to 0x04. */
7308 	/*	Described in the "Operating Channel Attribute" section. */
7309 	p2pie[p2pielen++] = 0x04;
7310 
7311 	/*	Channel Entry List */
7312 
7313 #ifdef CONFIG_CONCURRENT_MODE
7314 	if (rtw_mi_check_status(padapter, MI_LINKED)) {
7315 		u8 union_ch = rtw_mi_get_union_chan(padapter);
7316 
7317 		/*	Operating Class */
7318 		if (union_ch > 14) {
7319 			if (union_ch >= 149)
7320 				p2pie[p2pielen++] = 0x7c;
7321 			else
7322 				p2pie[p2pielen++] = 0x73;
7323 		} else
7324 			p2pie[p2pielen++] = 0x51;
7325 
7326 
7327 		/*	Number of Channels */
7328 		/*	Just support 1 channel and this channel is AP's channel */
7329 		p2pie[p2pielen++] = 1;
7330 
7331 		/*	Channel List */
7332 		p2pie[p2pielen++] = union_ch;
7333 	} else
7334 #endif /* CONFIG_CONCURRENT_MODE */
7335 	{
7336 		int i, j;
7337 		for (j = 0; j < ch_list->reg_classes; j++) {
7338 			/*	Operating Class */
7339 			p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7340 
7341 			/*	Number of Channels */
7342 			p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7343 
7344 			/*	Channel List */
7345 			for (i = 0; i < ch_list->reg_class[j].channels; i++)
7346 				p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7347 		}
7348 	}
7349 
7350 	/*	Device Info */
7351 	/*	Type: */
7352 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7353 
7354 	/*	Length: */
7355 	/*	21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
7356 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7357 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
7358 	p2pielen += 2;
7359 
7360 	/*	Value: */
7361 	/*	P2P Device Address */
7362 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7363 	p2pielen += ETH_ALEN;
7364 
7365 	/*	Config Method */
7366 	/*	This field should be big endian. Noted by P2P specification. */
7367 
7368 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7369 
7370 	p2pielen += 2;
7371 
7372 	/*	Primary Device Type */
7373 	/*	Category ID */
7374 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7375 	p2pielen += 2;
7376 
7377 	/*	OUI */
7378 	*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
7379 	p2pielen += 4;
7380 
7381 	/*	Sub Category ID */
7382 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7383 	p2pielen += 2;
7384 
7385 	/*	Number of Secondary Device Types */
7386 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
7387 
7388 	/*	Device Name */
7389 	/*	Type: */
7390 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7391 	p2pielen += 2;
7392 
7393 	/*	Length: */
7394 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
7395 	p2pielen += 2;
7396 
7397 	/*	Value: */
7398 	_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
7399 	p2pielen += pwdinfo->device_name_len;
7400 
7401 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7402 		/*	Group ID Attribute */
7403 		/*	Type: */
7404 		p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
7405 
7406 		/*	Length: */
7407 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
7408 		p2pielen += 2;
7409 
7410 		/*	Value: */
7411 		/*	p2P Device Address */
7412 		_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
7413 		p2pielen += ETH_ALEN;
7414 
7415 		/*	SSID */
7416 		_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
7417 		p2pielen += pwdinfo->nego_ssidlen;
7418 
7419 	}
7420 
7421 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7422 
7423 #ifdef CONFIG_WFD
7424 	wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
7425 	pframe += wfdielen;
7426 	pktlen += wfdielen;
7427 #endif
7428 
7429 	*pLength = pktlen;
7430 #if 0
7431 	/* printf dbg msg */
7432 	dbgbufLen = pktlen;
7433 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7434 
7435 	for (index = 0; index < dbgbufLen; index++)
7436 		printk("%x ", *(dbgbuf + index));
7437 
7438 	printk("\n");
7439 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7440 #endif
7441 }
7442 
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7443 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7444 {
7445 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7446 	u8			action = P2P_PUB_ACTION_ACTION;
7447 	u32			p2poui = cpu_to_be32(P2POUI);
7448 	u8			oui_subtype = P2P_INVIT_RESP;
7449 	u8			p2pie[255] = { 0x00 };
7450 	u8			p2pielen = 0, i;
7451 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
7452 	u16			len_channellist_attr = 0;
7453 	u32			pktlen;
7454 	u8			dialogToken = 0;
7455 #ifdef CONFIG_WFD
7456 	u32					wfdielen = 0;
7457 #endif
7458 
7459 	/* struct xmit_frame			*pmgntframe; */
7460 	/* struct pkt_attrib			*pattrib; */
7461 	/* unsigned char					*pframe; */
7462 	struct rtw_ieee80211_hdr	*pwlanhdr;
7463 	unsigned short				*fctrl;
7464 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7465 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7466 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7467 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7468 
7469 	/* for debug */
7470 	u8 *dbgbuf = pframe;
7471 	u8 dbgbufLen = 0, index = 0;
7472 
7473 
7474 	RTW_INFO("%s\n", __FUNCTION__);
7475 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7476 
7477 	fctrl = &(pwlanhdr->frame_ctl);
7478 	*(fctrl) = 0;
7479 
7480 	/* RA fill by FW */
7481 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7482 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7483 
7484 	/* BSSID fill by FW */
7485 	_rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
7486 
7487 	SetSeqNum(pwlanhdr, 0);
7488 	set_frame_sub_type(pframe, WIFI_ACTION);
7489 
7490 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7491 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7492 
7493 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7494 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7495 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7496 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7497 
7498 	/* dialog token, filled by FW */
7499 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7500 
7501 	/*	P2P IE Section. */
7502 
7503 	/*	P2P OUI */
7504 	p2pielen = 0;
7505 	p2pie[p2pielen++] = 0x50;
7506 	p2pie[p2pielen++] = 0x6F;
7507 	p2pie[p2pielen++] = 0x9A;
7508 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
7509 
7510 	/*	Commented by Albert 20101005 */
7511 	/*	According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
7512 	/*	1. Status */
7513 	/*	2. Configuration Timeout */
7514 	/*	3. Operating Channel	( Only GO ) */
7515 	/*	4. P2P Group BSSID	( Only GO ) */
7516 	/*	5. Channel List */
7517 
7518 	/*	P2P Status */
7519 	/*	Type: */
7520 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
7521 
7522 	/*	Length: */
7523 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7524 	p2pielen += 2;
7525 
7526 	/*	Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
7527 	p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7528 
7529 	/*	Configuration Timeout */
7530 	/*	Type: */
7531 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7532 
7533 	/*	Length: */
7534 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7535 	p2pielen += 2;
7536 
7537 	/*	Value: */
7538 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
7539 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
7540 
7541 	/* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
7542 #if 0
7543 	if (status_code == P2P_STATUS_SUCCESS) {
7544 		struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7545 
7546 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7547 			/*	The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
7548 			/*	In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
7549 			/*	First one is operating channel attribute. */
7550 			/*	Second one is P2P Group BSSID attribute. */
7551 
7552 			/*	Operating Channel */
7553 			/*	Type: */
7554 			p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7555 
7556 			/*	Length: */
7557 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7558 			p2pielen += 2;
7559 
7560 			/*	Value: */
7561 			/*	Country String */
7562 			p2pie[p2pielen++] = 'X';
7563 			p2pie[p2pielen++] = 'X';
7564 
7565 			/*	The third byte should be set to 0x04. */
7566 			/*	Described in the "Operating Channel Attribute" section. */
7567 			p2pie[p2pielen++] = 0x04;
7568 
7569 			/*	Operating Class */
7570 			p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
7571 
7572 			/*	Channel Number */
7573 			p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
7574 
7575 
7576 			/*	P2P Group BSSID */
7577 			/*	Type: */
7578 			p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
7579 
7580 			/*	Length: */
7581 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7582 			p2pielen += 2;
7583 
7584 			/*	Value: */
7585 			/*	P2P Device Address for GO */
7586 			_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7587 			p2pielen += ETH_ALEN;
7588 
7589 		}
7590 
7591 		/*	Channel List */
7592 		/*	Type: */
7593 		p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7594 
7595 		/*	Length: */
7596 		/* Country String(3) */
7597 		/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7598 		/* + number of channels in all classes */
7599 		len_channellist_attr = 3
7600 			+ (1 + 1) * (u16)ch_list->reg_classes
7601 			+ get_reg_classes_full_count(ch_list);
7602 
7603 #ifdef CONFIG_CONCURRENT_MODE
7604 		if (rtw_mi_check_status(padapter, MI_LINKED))
7605 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7606 		else
7607 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7608 
7609 #else
7610 
7611 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7612 
7613 #endif
7614 		p2pielen += 2;
7615 
7616 		/*	Value: */
7617 		/*	Country String */
7618 		p2pie[p2pielen++] = 'X';
7619 		p2pie[p2pielen++] = 'X';
7620 
7621 		/*	The third byte should be set to 0x04. */
7622 		/*	Described in the "Operating Channel Attribute" section. */
7623 		p2pie[p2pielen++] = 0x04;
7624 
7625 		/*	Channel Entry List */
7626 #ifdef CONFIG_CONCURRENT_MODE
7627 		if (rtw_mi_check_status(padapter, MI_LINKED)) {
7628 			u8 union_ch = rtw_mi_get_union_chan(padapter);
7629 
7630 			/*	Operating Class */
7631 			if (union_ch > 14) {
7632 				if (union_ch >= 149)
7633 					p2pie[p2pielen++] = 0x7c;
7634 				else
7635 					p2pie[p2pielen++] = 0x73;
7636 
7637 			} else
7638 				p2pie[p2pielen++] = 0x51;
7639 
7640 
7641 			/*	Number of Channels */
7642 			/*	Just support 1 channel and this channel is AP's channel */
7643 			p2pie[p2pielen++] = 1;
7644 
7645 			/*	Channel List */
7646 			p2pie[p2pielen++] = union_ch;
7647 		} else
7648 #endif /* CONFIG_CONCURRENT_MODE */
7649 		{
7650 			int i, j;
7651 			for (j = 0; j < ch_list->reg_classes; j++) {
7652 				/*	Operating Class */
7653 				p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7654 
7655 				/*	Number of Channels */
7656 				p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7657 
7658 				/*	Channel List */
7659 				for (i = 0; i < ch_list->reg_class[j].channels; i++)
7660 					p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7661 			}
7662 		}
7663 	}
7664 #endif
7665 
7666 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7667 
7668 #ifdef CONFIG_WFD
7669 	wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
7670 	pframe += wfdielen;
7671 	pktlen += wfdielen;
7672 #endif
7673 
7674 	*pLength = pktlen;
7675 
7676 #if 0
7677 	/* printf dbg msg */
7678 	dbgbufLen = pktlen;
7679 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7680 
7681 	for (index = 0; index < dbgbufLen; index++)
7682 		printk("%x ", *(dbgbuf + index));
7683 
7684 	printk("\n");
7685 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7686 #endif
7687 }
7688 
7689 
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7690 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7691 {
7692 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7693 	u8			action = P2P_PUB_ACTION_ACTION;
7694 	u8			dialogToken = 0;
7695 	u32			p2poui = cpu_to_be32(P2POUI);
7696 	u8			oui_subtype = P2P_PROVISION_DISC_RESP;
7697 	u8			wpsie[100] = { 0x00 };
7698 	u8			wpsielen = 0;
7699 	u32			pktlen;
7700 #ifdef CONFIG_WFD
7701 	u32					wfdielen = 0;
7702 #endif
7703 
7704 	/* struct xmit_frame			*pmgntframe; */
7705 	/* struct pkt_attrib			*pattrib; */
7706 	/* unsigned char					*pframe; */
7707 	struct rtw_ieee80211_hdr	*pwlanhdr;
7708 	unsigned short				*fctrl;
7709 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7710 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7711 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7712 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7713 
7714 	/* for debug */
7715 	u8 *dbgbuf = pframe;
7716 	u8 dbgbufLen = 0, index = 0;
7717 
7718 	RTW_INFO("%s\n", __FUNCTION__);
7719 
7720 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7721 
7722 	fctrl = &(pwlanhdr->frame_ctl);
7723 	*(fctrl) = 0;
7724 
7725 	/* RA filled by FW */
7726 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7727 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7728 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7729 
7730 	SetSeqNum(pwlanhdr, 0);
7731 	set_frame_sub_type(pframe, WIFI_ACTION);
7732 
7733 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7734 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7735 
7736 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7737 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7738 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7739 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7740 	/* dialog token, filled by FW */
7741 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7742 
7743 	wpsielen = 0;
7744 	/*	WPS OUI */
7745 	/* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
7746 	RTW_PUT_BE32(wpsie, WPSOUI);
7747 	wpsielen += 4;
7748 
7749 #if 0
7750 	/*	WPS version */
7751 	/*	Type: */
7752 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7753 	wpsielen += 2;
7754 
7755 	/*	Length: */
7756 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7757 	wpsielen += 2;
7758 
7759 	/*	Value: */
7760 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
7761 #endif
7762 
7763 	/*	Config Method */
7764 	/*	Type: */
7765 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
7766 	RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
7767 	wpsielen += 2;
7768 
7769 	/*	Length: */
7770 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
7771 	RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
7772 	wpsielen += 2;
7773 
7774 	/*	Value: filled by FW, default value is PBC */
7775 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
7776 	RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
7777 	wpsielen += 2;
7778 
7779 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7780 
7781 #ifdef CONFIG_WFD
7782 	wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
7783 	pframe += wfdielen;
7784 	pktlen += wfdielen;
7785 #endif
7786 
7787 	*pLength = pktlen;
7788 
7789 	/* printf dbg msg */
7790 #if 0
7791 	dbgbufLen = pktlen;
7792 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT  ProvisionDis Rsp\n");
7793 
7794 	for (index = 0; index < dbgbufLen; index++)
7795 		printk("%x ", *(dbgbuf + index));
7796 
7797 	printk("\n");
7798 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7799 #endif
7800 }
7801 
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)7802 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
7803 {
7804 	u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
7805 	struct hal_ops *pHalFunc = &adapter->hal_func;
7806 	u8 ret = _FAIL;
7807 
7808 	RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
7809 		 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
7810 		 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
7811 		 rsvdpageloc->LocPDRsp);
7812 
7813 	SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
7814 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
7815 	SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
7816 	SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
7817 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
7818 
7819 	/* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
7820 	ret = rtw_hal_fill_h2c_cmd(adapter,
7821 				   H2C_P2P_OFFLOAD_RSVD_PAGE,
7822 				   H2C_P2PRSVDPAGE_LOC_LEN,
7823 				   u1H2CP2PRsvdPageParm);
7824 
7825 	return ret;
7826 }
7827 
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)7828 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
7829 {
7830 
7831 	u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
7832 	struct wifidirect_info	*pwdinfo = &(adapter->wdinfo);
7833 	struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
7834 	struct hal_ops *pHalFunc = &adapter->hal_func;
7835 	u8 ret = _FAIL;
7836 
7837 	_rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
7838 	RTW_INFO("%s\n", __func__);
7839 	switch (pwdinfo->role) {
7840 	case P2P_ROLE_DEVICE:
7841 		RTW_INFO("P2P_ROLE_DEVICE\n");
7842 		p2p_wowlan_offload->role = 0;
7843 		break;
7844 	case P2P_ROLE_CLIENT:
7845 		RTW_INFO("P2P_ROLE_CLIENT\n");
7846 		p2p_wowlan_offload->role = 1;
7847 		break;
7848 	case P2P_ROLE_GO:
7849 		RTW_INFO("P2P_ROLE_GO\n");
7850 		p2p_wowlan_offload->role = 2;
7851 		break;
7852 	default:
7853 		RTW_INFO("P2P_ROLE_DISABLE\n");
7854 		break;
7855 	}
7856 	p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
7857 	p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
7858 	offload_cmd = (u8 *)p2p_wowlan_offload;
7859 	RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
7860 
7861 	ret = rtw_hal_fill_h2c_cmd(adapter,
7862 				   H2C_P2P_OFFLOAD,
7863 				   H2C_P2P_OFFLOAD_LEN,
7864 				   offload_cmd);
7865 	return ret;
7866 
7867 	/* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
7868 }
7869 #endif /* CONFIG_P2P_WOWLAN */
7870 
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)7871 void rtw_hal_construct_beacon(_adapter *padapter,
7872 				     u8 *pframe, u32 *pLength)
7873 {
7874 	struct rtw_ieee80211_hdr	*pwlanhdr;
7875 	u16					*fctrl;
7876 	u32					pktlen;
7877 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7878 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7879 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
7880 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7881 
7882 
7883 	/* RTW_INFO("%s\n", __FUNCTION__); */
7884 
7885 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7886 
7887 	fctrl = &(pwlanhdr->frame_ctl);
7888 	*(fctrl) = 0;
7889 
7890 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7891 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7892 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7893 
7894 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7895 	/* pmlmeext->mgnt_seq++; */
7896 	set_frame_sub_type(pframe, WIFI_BEACON);
7897 
7898 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7899 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7900 
7901 	/* timestamp will be inserted by hardware */
7902 	pframe += 8;
7903 	pktlen += 8;
7904 
7905 	/* beacon interval: 2 bytes */
7906 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7907 
7908 	pframe += 2;
7909 	pktlen += 2;
7910 
7911 #if 0
7912 	/* capability info: 2 bytes */
7913 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7914 
7915 	pframe += 2;
7916 	pktlen += 2;
7917 
7918 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7919 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7920 		pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
7921 		_rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
7922 
7923 		goto _ConstructBeacon;
7924 	}
7925 
7926 	/* below for ad-hoc mode */
7927 
7928 	/* SSID */
7929 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
7930 
7931 	/* supported rates... */
7932 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7933 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
7934 
7935 	/* DS parameter set */
7936 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
7937 
7938 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
7939 		u32 ATIMWindow;
7940 		/* IBSS Parameter Set... */
7941 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
7942 		ATIMWindow = 0;
7943 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
7944 	}
7945 
7946 
7947 	/* todo: ERP IE */
7948 
7949 
7950 	/* EXTERNDED SUPPORTED RATE */
7951 	if (rate_len > 8)
7952 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
7953 
7954 	/* todo:HT for adhoc */
7955 
7956 _ConstructBeacon:
7957 #endif
7958 
7959 	if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
7960 		RTW_ERR("beacon frame too large ,len(%d,%d)\n",
7961 			(pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
7962 		rtw_warn_on(1);
7963 		return;
7964 	}
7965 
7966 	*pLength = pktlen;
7967 
7968 	/* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
7969 
7970 }
7971 
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)7972 static void rtw_hal_construct_PSPoll(_adapter *padapter,
7973 				     u8 *pframe, u32 *pLength)
7974 {
7975 	struct rtw_ieee80211_hdr	*pwlanhdr;
7976 	u16					*fctrl;
7977 	u32					pktlen;
7978 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7979 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7980 
7981 	/* RTW_INFO("%s\n", __FUNCTION__); */
7982 
7983 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7984 
7985 	/* Frame control. */
7986 	fctrl = &(pwlanhdr->frame_ctl);
7987 	*(fctrl) = 0;
7988 	SetPwrMgt(fctrl);
7989 	set_frame_sub_type(pframe, WIFI_PSPOLL);
7990 
7991 	/* AID. */
7992 	set_duration(pframe, (pmlmeinfo->aid | 0xc000));
7993 
7994 	/* BSSID. */
7995 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7996 
7997 	/* TA. */
7998 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7999 
8000 	*pLength = 16;
8001 }
8002 
8003 
8004 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_construct_fw_dbg_msg_pkt(PADAPTER padapter,u8 * pframe,u32 * plength)8005 void rtw_hal_construct_fw_dbg_msg_pkt(
8006 	PADAPTER padapter,
8007 	u8		*pframe,
8008 	u32		*plength)
8009 {
8010 	struct rtw_ieee80211_hdr	*pwlanhdr;
8011 	u16						*fctrl;
8012 	u32						pktlen;
8013 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
8014 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
8015 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8016 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8017 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8018 
8019 
8020 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8021 
8022 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8023 
8024 	fctrl = &pwlanhdr->frame_ctl;
8025 	*(fctrl) = 0;
8026 
8027 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8028 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8029 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8030 
8031 	SetSeqNum(pwlanhdr, 0);
8032 
8033 	set_frame_sub_type(pframe, WIFI_DATA);
8034 
8035 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8036 
8037 	*plength = pktlen;
8038 }
8039 #endif /*DBG_FW_DEBUG_MSG_PKT*/
8040 
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)8041 void rtw_hal_construct_NullFunctionData(
8042 	PADAPTER padapter,
8043 	u8		*pframe,
8044 	u32		*pLength,
8045 	u8		bQoS,
8046 	u8		AC,
8047 	u8		bEosp,
8048 	u8		bForcePowerSave)
8049 {
8050 	struct rtw_ieee80211_hdr	*pwlanhdr;
8051 	u16						*fctrl;
8052 	u32						pktlen;
8053 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
8054 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
8055 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8056 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8057 	u8 *sta_addr = NULL;
8058 	u8 bssid[ETH_ALEN] = {0};
8059 
8060 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8061 
8062 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8063 
8064 	fctrl = &pwlanhdr->frame_ctl;
8065 	*(fctrl) = 0;
8066 	if (bForcePowerSave)
8067 		SetPwrMgt(fctrl);
8068 
8069 	sta_addr = get_my_bssid(&pmlmeinfo->network);
8070 	if (NULL == sta_addr) {
8071 		_rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
8072 		sta_addr = bssid;
8073 	}
8074 
8075 	switch (cur_network->network.InfrastructureMode) {
8076 	case Ndis802_11Infrastructure:
8077 		SetToDs(fctrl);
8078 		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8079 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8080 		_rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
8081 		break;
8082 	case Ndis802_11APMode:
8083 		SetFrDs(fctrl);
8084 		_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8085 		_rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8086 		_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8087 		break;
8088 	case Ndis802_11IBSS:
8089 	default:
8090 		_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8091 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8092 		_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8093 		break;
8094 	}
8095 
8096 	SetSeqNum(pwlanhdr, 0);
8097 	set_duration(pwlanhdr, 0);
8098 
8099 	if (bQoS == _TRUE) {
8100 		struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
8101 
8102 		set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
8103 
8104 		pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
8105 		SetPriority(&pwlanqoshdr->qc, AC);
8106 		SetEOSP(&pwlanqoshdr->qc, bEosp);
8107 
8108 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8109 	} else {
8110 		set_frame_sub_type(pframe, WIFI_DATA_NULL);
8111 
8112 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8113 	}
8114 
8115 	*pLength = pktlen;
8116 }
8117 
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,BOOLEAN bHideSSID)8118 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
8119 				BOOLEAN bHideSSID)
8120 {
8121 	struct rtw_ieee80211_hdr	*pwlanhdr;
8122 	u16					*fctrl;
8123 	u8					*mac, *bssid, *sta_addr;
8124 	u32					pktlen;
8125 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8126 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8127 	WLAN_BSSID_EX  *cur_network = &(pmlmeinfo->network);
8128 
8129 	/*RTW_INFO("%s\n", __FUNCTION__);*/
8130 
8131 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8132 
8133 	mac = adapter_mac_addr(padapter);
8134 	bssid = cur_network->MacAddress;
8135 	sta_addr = get_my_bssid(&pmlmeinfo->network);
8136 
8137 	fctrl = &(pwlanhdr->frame_ctl);
8138 	*(fctrl) = 0;
8139 	_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8140 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8141 	_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8142 
8143 	SetSeqNum(pwlanhdr, 0);
8144 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
8145 
8146 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8147 	pframe += pktlen;
8148 
8149 	if (cur_network->IELength > MAX_IE_SZ)
8150 		return;
8151 
8152 	_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8153 	pframe += cur_network->IELength;
8154 	pktlen += cur_network->IELength;
8155 
8156 	*pLength = pktlen;
8157 }
8158 
8159 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)8160 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
8161 				    u8 *pframe, u32 offset)
8162 {
8163 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8164 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8165 	struct rtw_ieee80211_hdr	*pwlanhdr;
8166 	struct mic_data	micdata;
8167 	struct sta_info	*psta = NULL;
8168 	int res = 0;
8169 
8170 	u8	*payload = (u8 *)(pframe + offset);
8171 
8172 	u8	mic[8];
8173 	u8	priority[4] = {0x0};
8174 	u8	null_key[16] = {0x0};
8175 
8176 	RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
8177 
8178 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8179 
8180 	psta = rtw_get_stainfo(&padapter->stapriv,
8181 			get_my_bssid(&(pmlmeinfo->network)));
8182 	if (psta != NULL) {
8183 		res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
8184 				  null_key, 16);
8185 		if (res == _TRUE)
8186 			RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
8187 		rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
8188 	}
8189 
8190 	rtw_secmicappend(&micdata, pwlanhdr->addr3, 6);  /* DA */
8191 
8192 	rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
8193 
8194 	priority[0] = 0;
8195 
8196 	rtw_secmicappend(&micdata, &priority[0], 4);
8197 
8198 	rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
8199 
8200 	rtw_secgetmic(&micdata, &(mic[0]));
8201 
8202 	payload += 36;
8203 
8204 	_rtw_memcpy(payload, &(mic[0]), 8);
8205 }
8206 /*
8207  * Description:
8208  *	Construct the ARP response packet to support ARP offload.
8209  *   */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8210 static void rtw_hal_construct_ARPRsp(
8211 	PADAPTER padapter,
8212 	u8			*pframe,
8213 	u32			*pLength,
8214 	u8			*pIPAddress
8215 )
8216 {
8217 	struct rtw_ieee80211_hdr	*pwlanhdr;
8218 	u16	*fctrl;
8219 	u32	pktlen;
8220 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8221 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8222 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8223 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8224 	static u8	ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
8225 	u8	*pARPRspPkt = pframe;
8226 	/* for TKIP Cal MIC */
8227 	u8	*payload = pframe;
8228 	u8	EncryptionHeadOverhead = 0, arp_offset = 0;
8229 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8230 
8231 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8232 
8233 	fctrl = &pwlanhdr->frame_ctl;
8234 	*(fctrl) = 0;
8235 
8236 	/* ------------------------------------------------------------------------- */
8237 	/* MAC Header. */
8238 	/* ------------------------------------------------------------------------- */
8239 	SetFrameType(fctrl, WIFI_DATA);
8240 	/* set_frame_sub_type(fctrl, 0); */
8241 	SetToDs(fctrl);
8242 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8243 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8244 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8245 
8246 	SetSeqNum(pwlanhdr, 0);
8247 	set_duration(pwlanhdr, 0);
8248 	/* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
8249 	/* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
8250 	/* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
8251 	/* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
8252 	/* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
8253 	/* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
8254 
8255 	/* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
8256 	/* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
8257 #ifdef CONFIG_WAPI_SUPPORT
8258 	*pLength = sMacHdrLng;
8259 #else
8260 	*pLength = 24;
8261 #endif
8262 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8263 	case _WEP40_:
8264 	case _WEP104_:
8265 		EncryptionHeadOverhead = 4;
8266 		break;
8267 	case _TKIP_:
8268 		EncryptionHeadOverhead = 8;
8269 		break;
8270 	case _AES_:
8271 		EncryptionHeadOverhead = 8;
8272 		break;
8273 #ifdef CONFIG_WAPI_SUPPORT
8274 	case _SMS4_:
8275 		EncryptionHeadOverhead = 18;
8276 		break;
8277 #endif
8278 	default:
8279 		EncryptionHeadOverhead = 0;
8280 	}
8281 
8282 	if (EncryptionHeadOverhead > 0) {
8283 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8284 		*pLength += EncryptionHeadOverhead;
8285 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8286 		SetPrivacy(fctrl);
8287 	}
8288 
8289 	/* ------------------------------------------------------------------------- */
8290 	/* Frame Body. */
8291 	/* ------------------------------------------------------------------------- */
8292 	arp_offset = *pLength;
8293 	pARPRspPkt = (u8 *)(pframe + arp_offset);
8294 	payload = pARPRspPkt; /* Get Payload pointer */
8295 	/* LLC header */
8296 	_rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
8297 	*pLength += 8;
8298 
8299 	/* ARP element */
8300 	pARPRspPkt += 8;
8301 	SET_ARP_HTYPE(pARPRspPkt, 1);
8302 	SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP);	/* IP protocol */
8303 	SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
8304 	SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
8305 	SET_ARP_OPER(pARPRspPkt, 2);	/* ARP response */
8306 	SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
8307 	SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
8308 #ifdef CONFIG_ARP_KEEP_ALIVE
8309 	if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
8310 		SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
8311 		SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
8312 	} else
8313 #endif
8314 	{
8315 		SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
8316 				    get_my_bssid(&(pmlmeinfo->network)));
8317 		SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
8318 					   pIPAddress);
8319 		RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
8320 			 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
8321 		RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
8322 			 IP_ARG(pIPAddress));
8323 	}
8324 
8325 	*pLength += 28;
8326 
8327 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8328 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8329 		    IS_HARDWARE_TYPE_8812(padapter)) {
8330 			rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
8331 		}
8332 		*pLength += 8;
8333 	}
8334 }
8335 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
8336 /*
8337  * Description:
8338  *	Construct the Keep Alive packet to support specific Keep Alive packet.
8339  *   */
rtw_hal_construct_keepalive(PADAPTER padapter,u8 * pframe,u32 * pLength)8340 static void rtw_hal_construct_keepalive(	PADAPTER padapter,
8341 	u8			*pframe,
8342 	u32			*pLength
8343 ){
8344 	struct rtw_ieee80211_hdr	*pwlanhdr;
8345 	u16	*fctrl;
8346 	u32	pktlen;
8347 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8348 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8349 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8350 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8351 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
8352 	static u8	LLCHeader[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
8353 	u8	*pKeepAlivePkt = pframe;
8354 	/* for TKIP Cal MIC */
8355 	u8	*payload = pframe;
8356 	u8	EncryptionHeadOverhead = 0, frame_offset = 0;
8357 	int i;
8358 
8359 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8360 
8361 	fctrl = &pwlanhdr->frame_ctl;
8362 	*(fctrl) = 0;
8363 
8364 	RTW_INFO("%s======>\n", __func__);
8365 
8366 
8367 	/* ------------------------------------------------------------------------- */
8368 	/* MAC Header. */
8369 	/* ------------------------------------------------------------------------- */
8370 	SetFrameType(fctrl, WIFI_DATA);
8371 	/* set_frame_sub_type(fctrl, 0); */
8372 	SetToDs(fctrl);
8373 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8374 	_rtw_memcpy(pwlanhdr->addr2, pwrpriv->keep_alive_pattern+6, ETH_ALEN);
8375 	_rtw_memcpy(pwlanhdr->addr3,pwrpriv->keep_alive_pattern, ETH_ALEN);
8376 
8377 	SetSeqNum(pwlanhdr, 0);
8378 	set_duration(pwlanhdr, 0);
8379 
8380 #ifdef CONFIG_WAPI_SUPPORT
8381 	*pLength = sMacHdrLng;
8382 #else
8383 	*pLength = 24;
8384 #endif
8385 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8386 	case _WEP40_:
8387 	case _WEP104_:
8388 		EncryptionHeadOverhead = 4;
8389 		break;
8390 	case _TKIP_:
8391 		EncryptionHeadOverhead = 8;
8392 		break;
8393 	case _AES_:
8394 		EncryptionHeadOverhead = 8;
8395 		break;
8396 #ifdef CONFIG_WAPI_SUPPORT
8397 	case _SMS4_:
8398 		EncryptionHeadOverhead = 18;
8399 		break;
8400 #endif
8401 	default:
8402 		EncryptionHeadOverhead = 0;
8403 	}
8404 
8405 	if (EncryptionHeadOverhead > 0) {
8406 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8407 		*pLength += EncryptionHeadOverhead;
8408 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8409 		SetPrivacy(fctrl);
8410 	}
8411 
8412 	/* ------------------------------------------------------------------------- */
8413 	/* Frame Body. */
8414 	/* ------------------------------------------------------------------------- */
8415 	frame_offset = *pLength;
8416 	pKeepAlivePkt = (u8 *)(pframe + frame_offset);
8417 	payload = pKeepAlivePkt; /* Get Payload pointer */
8418 	/* LLC header */
8419 	_rtw_memcpy(pKeepAlivePkt, LLCHeader, 6);
8420 	*pLength += 6;
8421 
8422 	/*From  protocol type*/
8423 	pKeepAlivePkt+=6;
8424 
8425 	_rtw_memcpy(pKeepAlivePkt,pwrpriv->keep_alive_pattern+12,pwrpriv->keep_alive_pattern_len-12);
8426 
8427 	*pLength+=pwrpriv->keep_alive_pattern_len-12;
8428 
8429 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8430 		*pLength += 8;
8431 	}
8432 
8433 	/* for debug
8434 	for (i=0; i< (*pLength) ;i++) {
8435 		RTW_INFO("KA_Pkt[0x%x]=x%0x", i,pKeepAlivePkt[i]);
8436 		if((i%8) == 7)
8437 			RTW_INFO("\n");
8438 	}
8439 	*/
8440 
8441 	RTW_INFO("%s <======\n", __func__);
8442 }
8443 
8444 #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
8445 
8446 #ifdef CONFIG_IPV6
8447 /*
8448  * Description: Neighbor Discovery Offload.
8449  */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)8450 static void rtw_hal_construct_na_message(_adapter *padapter,
8451 				     u8 *pframe, u32 *pLength)
8452 {
8453 	struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8454 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8455 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8456 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
8457 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8458 
8459 	u32 pktlen = 0;
8460 	u16 *fctrl = NULL;
8461 
8462 	u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8463 	u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8464 	u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8465 	u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8466 	u8 val8 = 0;
8467 
8468 	u8 *p_na_msg = pframe;
8469 	/* for TKIP Cal MIC */
8470 	u8 *payload = pframe;
8471 	u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8472 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8473 
8474 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8475 
8476 	fctrl = &pwlanhdr->frame_ctl;
8477 	*(fctrl) = 0;
8478 
8479 	/* ------------------------------------------------------------------------- */
8480 	/* MAC Header. */
8481 	/* ------------------------------------------------------------------------- */
8482 	SetFrameType(fctrl, WIFI_DATA);
8483 	SetToDs(fctrl);
8484 	_rtw_memcpy(pwlanhdr->addr1,
8485 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8486 	_rtw_memcpy(pwlanhdr->addr2,
8487 		    adapter_mac_addr(padapter), ETH_ALEN);
8488 	_rtw_memcpy(pwlanhdr->addr3,
8489 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8490 
8491 	SetSeqNum(pwlanhdr, 0);
8492 	set_duration(pwlanhdr, 0);
8493 
8494 #ifdef CONFIG_WAPI_SUPPORT
8495 	*pLength = sMacHdrLng;
8496 #else
8497 	*pLength = 24;
8498 #endif
8499 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8500 	case _WEP40_:
8501 	case _WEP104_:
8502 		EncryptionHeadOverhead = 4;
8503 		break;
8504 	case _TKIP_:
8505 		EncryptionHeadOverhead = 8;
8506 		break;
8507 	case _AES_:
8508 		EncryptionHeadOverhead = 8;
8509 		break;
8510 #ifdef CONFIG_WAPI_SUPPORT
8511 	case _SMS4_:
8512 		EncryptionHeadOverhead = 18;
8513 		break;
8514 #endif
8515 	default:
8516 		EncryptionHeadOverhead = 0;
8517 	}
8518 
8519 	if (EncryptionHeadOverhead > 0) {
8520 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8521 		*pLength += EncryptionHeadOverhead;
8522 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8523 		SetPrivacy(fctrl);
8524 	}
8525 
8526 	/* ------------------------------------------------------------------------- */
8527 	/* Frame Body. */
8528 	/* ------------------------------------------------------------------------- */
8529 	na_msg_offset = *pLength;
8530 	p_na_msg = (u8 *)(pframe + na_msg_offset);
8531 	payload = p_na_msg; /* Get Payload pointer */
8532 
8533 	/* LLC header */
8534 	val8 = sizeof(ns_hdr);
8535 	_rtw_memcpy(p_na_msg, ns_hdr, val8);
8536 	*pLength += val8;
8537 	p_na_msg += val8;
8538 
8539 	/* IPv6 Header */
8540 	/* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8541 	val8 = sizeof(ipv6_info);
8542 	_rtw_memcpy(p_na_msg, ipv6_info, val8);
8543 	*pLength += val8;
8544 	p_na_msg += val8;
8545 
8546 	/* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8547 	val8 = sizeof(ipv6_contx);
8548 	_rtw_memcpy(p_na_msg, ipv6_contx, val8);
8549 	*pLength += val8;
8550 	p_na_msg += val8;
8551 
8552 	/* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8553 	_rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8554 	*pLength += 32;
8555 	p_na_msg += 32;
8556 
8557 	/* ICMPv6 */
8558 	/* 1. Type : 0x88 (NA)
8559 	 * 2. Code : 0x00
8560 	 * 3. ChechSum : 0x00 0x00 (RSvd)
8561 	 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8562 	 */
8563 	val8 = sizeof(icmpv6_hdr);
8564 	_rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8565 	*pLength += val8;
8566 	p_na_msg += val8;
8567 
8568 	/* TA: 16 bytes*/
8569 	_rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8570 	*pLength += 16;
8571 	p_na_msg += 16;
8572 
8573 	/* ICMPv6 Target Link Layer Address */
8574 	p_na_msg[0] = 0x02; /* type */
8575 	p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8576 	*pLength += 2;
8577 	p_na_msg += 2;
8578 
8579 	_rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8580 	*pLength += 6;
8581 	p_na_msg += 6;
8582 
8583 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8584 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8585 		    IS_HARDWARE_TYPE_8812(padapter)) {
8586 			rtw_hal_append_tkip_mic(padapter, pframe,
8587 						na_msg_offset);
8588 		}
8589 		*pLength += 8;
8590 	}
8591 }
8592 /*
8593  * Description: Neighbor Discovery Protocol Information.
8594  */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)8595 static void rtw_hal_construct_ndp_info(_adapter *padapter,
8596 				     u8 *pframe, u32 *pLength)
8597 {
8598 	struct mlme_ext_priv *pmlmeext = NULL;
8599 	struct mlme_ext_info *pmlmeinfo = NULL;
8600 	struct rtw_ndp_info ndp_info;
8601 	u8	*pndp_info = pframe;
8602 	u8	len = sizeof(struct rtw_ndp_info);
8603 
8604 	RTW_INFO("%s: len: %d\n", __func__, len);
8605 
8606 	pmlmeext =  &padapter->mlmeextpriv;
8607 	pmlmeinfo = &pmlmeext->mlmext_info;
8608 
8609 	_rtw_memset(pframe, 0, len);
8610 	_rtw_memset(&ndp_info, 0, len);
8611 
8612 	ndp_info.enable = 1;
8613 	ndp_info.check_remote_ip = 0;
8614 	ndp_info.num_of_target_ip = 1;
8615 
8616 	_rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8617 		    ETH_ALEN);
8618 	_rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8619 		    RTW_IPv6_ADDR_LEN);
8620 
8621 	_rtw_memcpy(pndp_info, &ndp_info, len);
8622 }
8623 #endif /* CONFIG_IPV6 */
8624 
8625 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)8626 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8627 				       u32 *pLength, pno_ssid_t *ssid)
8628 {
8629 	struct rtw_ieee80211_hdr	*pwlanhdr;
8630 	u16				*fctrl;
8631 	u32				pktlen;
8632 	unsigned char			*mac;
8633 	unsigned char			bssrate[NumRates];
8634 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
8635 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8636 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8637 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8638 	int	bssrate_len = 0;
8639 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8640 
8641 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8642 	mac = adapter_mac_addr(padapter);
8643 
8644 	fctrl = &(pwlanhdr->frame_ctl);
8645 	*(fctrl) = 0;
8646 
8647 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8648 	_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8649 
8650 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8651 
8652 	SetSeqNum(pwlanhdr, 0);
8653 	set_frame_sub_type(pframe, WIFI_PROBEREQ);
8654 
8655 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8656 	pframe += pktlen;
8657 
8658 	if (ssid == NULL)
8659 		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8660 	else {
8661 		/* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8662 		pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8663 	}
8664 
8665 	get_rate_set(padapter, bssrate, &bssrate_len);
8666 
8667 	if (bssrate_len > 8) {
8668 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8669 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8670 	} else
8671 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8672 
8673 	*pLength = pktlen;
8674 }
8675 
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)8676 static void rtw_hal_construct_PNO_info(_adapter *padapter,
8677 				       u8 *pframe, u32 *pLength)
8678 {
8679 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8680 	int i;
8681 
8682 	u8	*pPnoInfoPkt = pframe;
8683 	pPnoInfoPkt = (u8 *)(pframe + *pLength);
8684 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8685 
8686 	pPnoInfoPkt += 1;
8687 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8688 
8689 	pPnoInfoPkt += 3;
8690 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8691 
8692 	pPnoInfoPkt += 4;
8693 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8694 
8695 	pPnoInfoPkt += 4;
8696 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8697 
8698 	pPnoInfoPkt += 4;
8699 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8700 
8701 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8702 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8703 
8704 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8705 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8706 
8707 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8708 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8709 
8710 	pPnoInfoPkt += MAX_HIDDEN_AP;
8711 
8712 	/*
8713 	SSID is located at 128th Byte in NLO info Page
8714 	*/
8715 
8716 	*pLength += 128;
8717 	pPnoInfoPkt = pframe + 128;
8718 
8719 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8720 		_rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8721 			    pwrctl->pnlo_info->ssid_length[i]);
8722 		*pLength += WLAN_SSID_MAXLEN;
8723 		pPnoInfoPkt += WLAN_SSID_MAXLEN;
8724 	}
8725 }
8726 
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)8727 static void rtw_hal_construct_ssid_list(_adapter *padapter,
8728 					u8 *pframe, u32 *pLength)
8729 {
8730 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8731 	u8 *pSSIDListPkt = pframe;
8732 	int i;
8733 
8734 	pSSIDListPkt = (u8 *)(pframe + *pLength);
8735 
8736 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8737 		_rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8738 			    pwrctl->pnlo_info->ssid_length[i]);
8739 
8740 		*pLength += WLAN_SSID_MAXLEN;
8741 		pSSIDListPkt += WLAN_SSID_MAXLEN;
8742 	}
8743 }
8744 
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)8745 static void rtw_hal_construct_scan_info(_adapter *padapter,
8746 					u8 *pframe, u32 *pLength)
8747 {
8748 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8749 	u8 *pScanInfoPkt = pframe;
8750 	int i;
8751 
8752 	pScanInfoPkt = (u8 *)(pframe + *pLength);
8753 
8754 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8755 
8756 	*pLength += 1;
8757 	pScanInfoPkt += 1;
8758 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8759 
8760 
8761 	*pLength += 1;
8762 	pScanInfoPkt += 1;
8763 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8764 
8765 
8766 	*pLength += 1;
8767 	pScanInfoPkt += 1;
8768 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8769 
8770 	*pLength += 1;
8771 	pScanInfoPkt += 1;
8772 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8773 
8774 	*pLength += 1;
8775 	pScanInfoPkt += 1;
8776 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8777 
8778 	*pLength += 1;
8779 	pScanInfoPkt += 1;
8780 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8781 
8782 	*pLength += 1;
8783 	pScanInfoPkt += 1;
8784 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8785 
8786 	*pLength += 1;
8787 	pScanInfoPkt += 1;
8788 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8789 
8790 	*pLength += 8;
8791 	pScanInfoPkt += 8;
8792 
8793 	for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8794 		_rtw_memcpy(pScanInfoPkt,
8795 			    &pwrctl->pscan_info->ssid_channel_info[i], 4);
8796 		*pLength += 4;
8797 		pScanInfoPkt += 4;
8798 	}
8799 }
8800 #endif /* CONFIG_PNO_SUPPORT */
8801 
8802 #ifdef CONFIG_WAR_OFFLOAD
8803 #ifdef CONFIG_OFFLOAD_MDNS_V4
8804 
8805 /*
8806  * Description:
8807  *	Construct the MDNS V4 response packet to support MDNS offload.
8808  *
8809  */
rtw_hal_construct_mdns_rsp_v4(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8810 static void rtw_hal_construct_mdns_rsp_v4(
8811 	PADAPTER 	padapter,
8812 	u8			*pframe,
8813 	u32			*pLength,
8814 	u8			*pIPAddress
8815 )
8816 {
8817 	struct rtw_ieee80211_hdr	*pwlanhdr;
8818 	u16	*fctrl;
8819 	u32	pktlen;
8820 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8821 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
8822 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8823 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8824 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8825 	static u8	ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00};
8826 	u8	mulicast_ipv4_addr[4] = {0xe0, 0x00, 0x00, 0xfb};
8827 	u8	mulicast_mac_addr_for_mdns[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb};
8828 	u8	*pMdnsRspPkt = pframe;
8829 	/* for TKIP Cal MIC */
8830 	u8	EncryptionHeadOverhead = 0, mdns_offset = 0;
8831 
8832 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
8833 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
8834 
8835 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8836 
8837 	fctrl = &pwlanhdr->frame_ctl;
8838 	*(fctrl) = 0;
8839 
8840 	/* ------------------------------------------------------------------------- */
8841 	/* MAC Header. */
8842 	/* ------------------------------------------------------------------------- */
8843 	SetFrameType(fctrl, WIFI_DATA);
8844 	/* set_frame_sub_type(fctrl, 0); */
8845 	SetToDs(fctrl);
8846 	//_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8847 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8848 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8849 	_rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN );
8850 
8851 	SetSeqNum(pwlanhdr, 0);
8852 	set_duration(pwlanhdr, 0);
8853 
8854 #ifdef CONFIG_WAPI_SUPPORT
8855 	*pLength = sMacHdrLng;
8856 #else
8857 	*pLength = 24;
8858 #endif
8859 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8860 	case _WEP40_:
8861 	case _WEP104_:
8862 		EncryptionHeadOverhead = 4;
8863 		break;
8864 	case _TKIP_:
8865 		EncryptionHeadOverhead = 8;
8866 		break;
8867 	case _AES_:
8868 		EncryptionHeadOverhead = 8;
8869 		break;
8870 #ifdef CONFIG_WAPI_SUPPORT
8871 	case _SMS4_:
8872 		EncryptionHeadOverhead = 18;
8873 		break;
8874 #endif
8875 	default:
8876 		EncryptionHeadOverhead = 0;
8877 	}
8878 
8879 	if (EncryptionHeadOverhead > 0) {
8880 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8881 		*pLength += EncryptionHeadOverhead;
8882 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8883 		SetPrivacy(fctrl);
8884 	}
8885 
8886 	/* ------------------------------------------------------------------------- */
8887 	/* Frame Body. */
8888 	/* ------------------------------------------------------------------------- */
8889 	mdns_offset = *pLength;
8890 	pMdnsRspPkt = (u8 *)(pframe + mdns_offset);
8891 	/* LLC header */
8892 	_rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8);
8893 	*pLength += 8;
8894 
8895 	/* IP element */
8896 	pMdnsRspPkt += 8;
8897 	SET_IPHDR_VERSION(pMdnsRspPkt, 0x45);
8898 	SET_IPHDR_DSCP(pMdnsRspPkt, 0);
8899 	SET_IPHDR_TOTAL_LEN(pMdnsRspPkt, 0);  // filled by fw
8900 	SET_IPHDR_IDENTIFIER(pMdnsRspPkt, 0);  // filled by fw
8901 	SET_IPHDR_FLAGS(pMdnsRspPkt, 0x40);
8902 	SET_IPHDR_FRAG_OFFSET(pMdnsRspPkt, 0);
8903 	SET_IPHDR_TTL(pMdnsRspPkt, 0x40);
8904 	SET_IPHDR_PROTOCOL(pMdnsRspPkt, 0x11);  // ICMP-UDP
8905 	SET_IPHDR_HDR_CHECKSUM(pMdnsRspPkt, 0);  // filled by fw
8906 	SET_IPHDR_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress);
8907 	SET_IPHDR_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv4_addr);  // filled by fw
8908 
8909 	*pLength += 20;
8910 
8911 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8912 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8913 			IS_HARDWARE_TYPE_8812(padapter)) {
8914 			rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset);
8915 		}
8916 		*pLength += 8;
8917 	}
8918 
8919 	/* UDP element */
8920 	pMdnsRspPkt += 20;
8921 	SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // MDNS
8922 	SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // MDNS
8923 	SET_UDP_LEN(pMdnsRspPkt, 0);      //  filled by fw
8924 	SET_UDP_CHECKSUM(pMdnsRspPkt, 0);     // filled by fw
8925 	*pLength += 8;
8926 
8927 	/* MDNS Header */
8928 	pMdnsRspPkt += 8;
8929 	SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84);
8930 	*pLength += 12;
8931 
8932 }
8933 
8934 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
8935 
8936 #ifdef CONFIG_OFFLOAD_MDNS_V6
8937 
8938 /*
8939  * Description:
8940  *	Construct the MDNS response V6 packet to support MDNS offload.
8941  *
8942  */
rtw_hal_construct_mdns_rsp_v6(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8943 static void rtw_hal_construct_mdns_rsp_v6(
8944 	PADAPTER 	padapter,
8945 	u8			*pframe,
8946 	u32			*pLength,
8947 	u8			*pIPAddress
8948 )
8949 {
8950 	struct rtw_ieee80211_hdr        *pwlanhdr;
8951 	u16     *fctrl;
8952 	u32     pktlen;
8953 	struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
8954 	struct wlan_network     *cur_network = &pmlmepriv->cur_network;
8955 	struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
8956 	struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
8957 	struct security_priv    *psecuritypriv = &padapter->securitypriv;
8958 	static u8       ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8959 	u8	mulicast_ipv6_addr[16] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
8960 	u8	mulicast_mac_addr_for_mdns[6] = {0x33, 0x33, 0x00, 0x00, 0x00, 0xfb}; /* could be revise by fw */
8961 	u8      *pMdnsRspPkt = pframe;
8962 	/* for TKIP Cal MIC */
8963 	u8      EncryptionHeadOverhead = 0, mdns_offset = 0;
8964 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8965 
8966 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
8967 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
8968 
8969 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8970 
8971 	fctrl = &pwlanhdr->frame_ctl;
8972 	*(fctrl) = 0;
8973 
8974 	/* ------------------------------------------------------------------------- */
8975 	/* MAC Header. */
8976 	/* ------------------------------------------------------------------------- */
8977 	SetFrameType(fctrl, WIFI_DATA);
8978 	/* set_frame_sub_type(fctrl, 0); */
8979 	SetToDs(fctrl);
8980 	//_rtw_memcpy(pwlanhdr->addr1, mulicast_mac_addr_for_mdns, ETH_ALEN);
8981 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8982 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8983 	//_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8984 	_rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN);
8985 
8986 	SetSeqNum(pwlanhdr, 0);
8987 	set_duration(pwlanhdr, 0);
8988 
8989 #ifdef CONFIG_WAPI_SUPPORT
8990 	*pLength = sMacHdrLng;
8991 #else
8992 	*pLength = 24;
8993 #endif
8994 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8995 	case _WEP40_:
8996 	case _WEP104_:
8997 		EncryptionHeadOverhead = 4;
8998 		break;
8999 	case _TKIP_:
9000 		EncryptionHeadOverhead = 8;
9001 		break;
9002 	case _AES_:
9003 		EncryptionHeadOverhead = 8;
9004 		break;
9005 #ifdef CONFIG_WAPI_SUPPORT
9006 	case _SMS4_:
9007 		EncryptionHeadOverhead = 18;
9008 		break;
9009 #endif
9010 	default:
9011 		EncryptionHeadOverhead = 0;
9012 	}
9013 
9014 	if (EncryptionHeadOverhead > 0) {
9015 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
9016 		*pLength += EncryptionHeadOverhead;
9017 		SetPrivacy(fctrl);
9018 	}
9019 
9020 	/* ------------------------------------------------------------------------- */
9021 	/* Frame Body. */
9022 	/* ------------------------------------------------------------------------- */
9023 	mdns_offset = *pLength;
9024 	pMdnsRspPkt = (u8 *)(pframe + mdns_offset);
9025 	/* LLC header */
9026 	_rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8);
9027 	*pLength += 8;
9028 
9029 	/* ICMP element */
9030 	pMdnsRspPkt += 8;
9031 	SET_IPHDRV6_VERSION(pMdnsRspPkt, 0x06);
9032 	SET_IPHDRV6_PAYLOAD_LENGTH(pMdnsRspPkt, 0); // filled by fw
9033 	SET_IPHDRV6_NEXT_HEADER(pMdnsRspPkt, 0x3A);
9034 	SET_IPHDRV6_HOP_LIMIT(pMdnsRspPkt, 0xFF);
9035 	SET_IPHDRV6_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress);  // filled by fw
9036 	SET_IPHDRV6_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv6_addr);  // filled by fw
9037 
9038 	*pLength += 40;
9039 
9040 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
9041 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
9042 			IS_HARDWARE_TYPE_8812(padapter)) {
9043 				rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset);
9044 		}
9045 		*pLength += 8;
9046 	}
9047 
9048 	/* UDP element */
9049 	pMdnsRspPkt += 40;
9050 	SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // SNMP
9051 	SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // SNMP
9052 	SET_UDP_LEN(pMdnsRspPkt, 0);      //  filled by fw
9053 	SET_UDP_CHECKSUM(pMdnsRspPkt, 0);     // filled by fw
9054 	*pLength += 8;
9055 
9056 	/* MDNS Header */
9057 	pMdnsRspPkt += 8;
9058 	SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84);
9059 	*pLength += 12;
9060 
9061 }
9062 
9063 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
9064 #endif
9065 
9066 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)9067 static void rtw_hal_construct_GTKRsp(
9068 	PADAPTER	padapter,
9069 	u8		*pframe,
9070 	u32		*pLength
9071 )
9072 {
9073 	struct rtw_ieee80211_hdr	*pwlanhdr;
9074 	u16	*fctrl;
9075 	u32	pktlen;
9076 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
9077 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
9078 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9079 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9080 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
9081 	static u8	LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
9082 	static u8	GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
9083 	u8	*pGTKRspPkt = pframe;
9084 	u8	EncryptionHeadOverhead = 0;
9085 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
9086 
9087 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9088 
9089 	fctrl = &pwlanhdr->frame_ctl;
9090 	*(fctrl) = 0;
9091 
9092 	/* ------------------------------------------------------------------------- */
9093 	/* MAC Header. */
9094 	/* ------------------------------------------------------------------------- */
9095 	SetFrameType(fctrl, WIFI_DATA);
9096 	/* set_frame_sub_type(fctrl, 0); */
9097 	SetToDs(fctrl);
9098 
9099 	_rtw_memcpy(pwlanhdr->addr1,
9100 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9101 
9102 	_rtw_memcpy(pwlanhdr->addr2,
9103 		    adapter_mac_addr(padapter), ETH_ALEN);
9104 
9105 	_rtw_memcpy(pwlanhdr->addr3,
9106 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9107 
9108 	SetSeqNum(pwlanhdr, 0);
9109 	set_duration(pwlanhdr, 0);
9110 
9111 #ifdef CONFIG_WAPI_SUPPORT
9112 	*pLength = sMacHdrLng;
9113 #else
9114 	*pLength = 24;
9115 #endif /* CONFIG_WAPI_SUPPORT */
9116 
9117 	/* ------------------------------------------------------------------------- */
9118 	/* Security Header: leave space for it if necessary. */
9119 	/* ------------------------------------------------------------------------- */
9120 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
9121 	case _WEP40_:
9122 	case _WEP104_:
9123 		EncryptionHeadOverhead = 4;
9124 		break;
9125 	case _TKIP_:
9126 		EncryptionHeadOverhead = 8;
9127 		break;
9128 	case _AES_:
9129 		EncryptionHeadOverhead = 8;
9130 		break;
9131 #ifdef CONFIG_WAPI_SUPPORT
9132 	case _SMS4_:
9133 		EncryptionHeadOverhead = 18;
9134 		break;
9135 #endif /* CONFIG_WAPI_SUPPORT */
9136 	default:
9137 		EncryptionHeadOverhead = 0;
9138 	}
9139 
9140 	if (EncryptionHeadOverhead > 0) {
9141 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
9142 		*pLength += EncryptionHeadOverhead;
9143 		/* SET_80211_HDR_WEP(pGTKRspPkt, 1);  */ /* Suggested by CCW. */
9144 		/* GTK's privacy bit is done by FW */
9145 		/* SetPrivacy(fctrl); */
9146 	}
9147 	/* ------------------------------------------------------------------------- */
9148 	/* Frame Body. */
9149 	/* ------------------------------------------------------------------------- */
9150 	pGTKRspPkt = (u8 *)(pframe + *pLength);
9151 	/* LLC header */
9152 	_rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
9153 	*pLength += 8;
9154 
9155 	/* GTK element */
9156 	pGTKRspPkt += 8;
9157 
9158 	/* GTK frame body after LLC, part 1 */
9159 	/* TKIP key_length = 32, AES key_length = 16 */
9160 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
9161 		GTKbody_a[8] = 0x20;
9162 
9163 	/* GTK frame body after LLC, part 1 */
9164 	_rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
9165 	*pLength += 11;
9166 	pGTKRspPkt += 11;
9167 	/* GTK frame body after LLC, part 2 */
9168 	_rtw_memset(&(pframe[*pLength]), 0, 88);
9169 	*pLength += 88;
9170 	pGTKRspPkt += 88;
9171 
9172 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
9173 		*pLength += 8;
9174 }
9175 #endif /* CONFIG_GTK_OL */
9176 
9177 #define PN_2_CCMPH(ch,key_id)	((ch) & 0x000000000000ffff) \
9178 				| (((ch) & 0x0000ffffffff0000) << 16) \
9179 				| (((key_id) << 30)) \
9180 				| BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)9181 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
9182 						  u8 *pframe, u32 *pLength)
9183 {
9184 	struct mlme_priv   *pmlmepriv = &adapter->mlmepriv;
9185 	struct sta_priv *pstapriv = &adapter->stapriv;
9186 	struct security_priv *psecuritypriv = &adapter->securitypriv;
9187 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
9188 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9189 	struct sta_info *psta;
9190 	struct stainfo_rxcache *prxcache;
9191 	u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
9192 	size_t sz = 0, total = 0;
9193 	u64 ccmp_hdr = 0, tmp_key = 0;
9194 
9195 	psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
9196 
9197 	if (psta == NULL) {
9198 		rtw_warn_on(1);
9199 		return;
9200 	}
9201 
9202 	prxcache = &psta->sta_recvpriv.rxcache;
9203 	sz = sizeof(cur_dot11rxiv);
9204 
9205 	/* 3 SEC IV * 1 page */
9206 	rtw_get_sec_iv(adapter, cur_dot11rxiv,
9207 		       get_my_bssid(&pmlmeinfo->network));
9208 
9209 	_rtw_memcpy(pframe, cur_dot11rxiv, sz);
9210 	*pLength += sz;
9211 	pframe += sz;
9212 
9213 	_rtw_memset(&cur_dot11rxiv, 0, sz);
9214 
9215 	if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
9216 		id = psecuritypriv->dot118021XGrpKeyid;
9217 		tid_id = prxcache->last_tid;
9218 		REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
9219 		REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
9220 		REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
9221 		REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
9222 		_rtw_memcpy(pframe, cur_dot11rxiv, sz);
9223 		*pLength += sz;
9224 		pframe += sz;
9225 
9226 		_rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
9227 		*pLength += sz;
9228 		pframe += sz;
9229 
9230 		total = sizeof(psecuritypriv->iv_seq);
9231 		total /= sizeof(psecuritypriv->iv_seq[0]);
9232 
9233 		for (i = 0 ; i < total ; i ++) {
9234 			ccmp_hdr =
9235 				le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
9236 			_rtw_memset(&cur_dot11rxiv, 0, sz);
9237 			if (ccmp_hdr != 0) {
9238 				tmp_key = i;
9239 				ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
9240 				*(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
9241 				_rtw_memcpy(pframe, cur_dot11rxiv, sz);
9242 			}
9243 			*pLength += sz;
9244 			pframe += sz;
9245 		}
9246 	}
9247 }
9248 
rtw_hal_gate_bb(_adapter * adapter,bool stop)9249 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9250 {
9251 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9252 	u8 i = 0, val8 = 0, empty = _FAIL;
9253 
9254 	if (stop) {
9255 		/* checking TX queue status */
9256 		for (i = 0 ; i < 5 ; i++) {
9257 			rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9258 			if (empty) {
9259 				break;
9260 			} else {
9261 				RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9262 					 __func__, i);
9263 				rtw_mdelay_os(10);
9264 			}
9265 		}
9266 
9267 		if (val8 == 5)
9268 			RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9269 
9270 		/* Pause TX*/
9271 		pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9272 		rtw_write8(adapter, REG_TXPAUSE, 0xff);
9273 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9274 		val8 &= ~BIT(0);
9275 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9276 		RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9277 			 __func__,
9278 			 rtw_read8(adapter, REG_SYS_FUNC_EN),
9279 			 pwrpriv->wowlan_txpause_status);
9280 	} else {
9281 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9282 		val8 |= BIT(0);
9283 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9284 		RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9285 			 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9286 			 pwrpriv->wowlan_txpause_status);
9287 		/* release TX*/
9288 		rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9289 	}
9290 }
9291 
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)9292 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9293 {
9294 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9295 	 u8 *pattern;
9296 	 u8 len = 0;
9297 	 u8 *mask;
9298 
9299 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
9300 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9301 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9302 	u8 multicast_addr1[2] = {0x33, 0x33};
9303 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9304 	u8 mask_len = 0;
9305 	u8 mac_addr[ETH_ALEN] = {0};
9306 	u16 count = 0;
9307 	int i;
9308 
9309 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9310 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9311 			 __func__, MAX_WKFM_CAM_NUM);
9312 		return _FAIL;
9313 	}
9314 
9315 	pattern = pwrctl->patterns[idx].content;
9316 	len = pwrctl->patterns[idx].len;
9317 	mask = pwrctl->patterns[idx].mask;
9318 
9319 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9320 	_rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9321 
9322 	mask_len = DIV_ROUND_UP(len, 8);
9323 
9324 	/* 1. setup A1 table */
9325 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9326 		pwow_pattern->type = PATTERN_BROADCAST;
9327 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
9328 		pwow_pattern->type = PATTERN_MULTICAST;
9329 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
9330 		pwow_pattern->type = PATTERN_MULTICAST;
9331 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9332 		pwow_pattern->type = PATTERN_UNICAST;
9333 	else
9334 		pwow_pattern->type = PATTERN_INVALID;
9335 
9336 	/* translate mask from os to mask for hw */
9337 
9338 	/******************************************************************************
9339 	 * pattern from OS uses 'ethenet frame', like this:
9340 
9341 		|    6   |    6   |   2  |     20    |  Variable  |  4  |
9342 		|--------+--------+------+-----------+------------+-----|
9343 		|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
9344 		|   DA   |   SA   | Type |
9345 
9346 	 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9347 
9348 		|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
9349 		|-------------------+--------+------+-----------+------------+-----|
9350 		| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
9351 				    | Others | Tpye |
9352 
9353 	 * Therefore, we need translate mask_from_OS to mask_to_hw.
9354 	 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9355 	 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9356 	 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9357 	 ******************************************************************************/
9358 	/* Shift 6 bits */
9359 	for (i = 0; i < mask_len - 1; i++) {
9360 		mask_hw[i] = mask[i] >> 6;
9361 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9362 	}
9363 
9364 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
9365 	/* Set bit 0-5 to zero */
9366 	mask_hw[0] &= 0xC0;
9367 
9368 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9369 		pwow_pattern->mask[i] = mask_hw[i * 4];
9370 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9371 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9372 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9373 	}
9374 
9375 	/* To get the wake up pattern from the mask.
9376 	 * We do not count first 12 bits which means
9377 	 * DA[6] and SA[6] in the pattern to match HW design. */
9378 	count = 0;
9379 	for (i = 12; i < len; i++) {
9380 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
9381 			content[count] = pattern[i];
9382 			count++;
9383 		}
9384 	}
9385 
9386 	pwow_pattern->crc = rtw_calc_crc(content, count);
9387 
9388 	if (pwow_pattern->crc != 0) {
9389 		if (pwow_pattern->type == PATTERN_INVALID)
9390 			pwow_pattern->type = PATTERN_VALID;
9391 	}
9392 
9393 	return _SUCCESS;
9394 }
9395 
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)9396 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
9397 {
9398 	int j;
9399 
9400 	RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
9401 	RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
9402 	RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
9403 	for (j = 0; j < 4; j++)
9404 		RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
9405 }
9406 /*bit definition of pattern match format*/
9407 #define WOW_VALID_BIT	BIT31
9408 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
9409 #define WOW_BC_BIT		BIT26
9410 #define WOW_MC_BIT		BIT25
9411 #define WOW_UC_BIT		BIT24
9412 #else
9413 #define WOW_BC_BIT		BIT18
9414 #define WOW_UC_BIT		BIT17
9415 #define WOW_MC_BIT		BIT16
9416 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
9417 
9418 #ifndef CONFIG_WOW_PATTERN_HW_CAM
9419 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_hal_reset_mac_rx(_adapter * adapter)9420 static void rtw_hal_reset_mac_rx(_adapter *adapter)
9421 {
9422 	u8 val8 = 0;
9423 	/* Set REG_CR bit1, bit3, bit7 to 0*/
9424 	val8 = rtw_read8(adapter, REG_CR);
9425 	val8 &= 0x75;
9426 	rtw_write8(adapter, REG_CR, val8);
9427 	val8 = rtw_read8(adapter, REG_CR);
9428 	/* Set REG_CR bit1, bit3, bit7 to 1*/
9429 	val8 |= 0x8a;
9430 	rtw_write8(adapter, REG_CR, val8);
9431 	RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
9432 }
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)9433 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
9434 {
9435 	u8 val8 = 0;
9436 	u16 rxff_bndy = 0;
9437 	u32 rx_dma_buff_sz = 0;
9438 
9439 	val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
9440 	if (val8 != 0)
9441 		RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
9442 			 __func__, (REG_FIFOPAGE + 3));
9443 
9444 	rtw_hal_reset_mac_rx(adapter);
9445 
9446 	if (wow_mode) {
9447 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9448 				    (u8 *)&rx_dma_buff_sz);
9449 		rxff_bndy = rx_dma_buff_sz - 1;
9450 
9451 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9452 		RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
9453 			 REG_TRXFF_BNDY + 2,
9454 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9455 	} else {
9456 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
9457 				    (u8 *)&rx_dma_buff_sz);
9458 		rxff_bndy = rx_dma_buff_sz - 1;
9459 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9460 		RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
9461 			 REG_TRXFF_BNDY + 2,
9462 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9463 	}
9464 }
9465 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO*/
9466 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9467 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9468 {
9469 	u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9470 	u16 offset, rx_buf_ptr = 0;
9471 	u16 cam_start_offset = 0;
9472 	u16 ctrl_l = 0, ctrl_h = 0;
9473 	u8 count = 0, tmp = 0;
9474 	int i = 0;
9475 	bool res = _TRUE;
9476 
9477 	if (idx > MAX_WKFM_CAM_NUM) {
9478 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9479 			 __func__);
9480 		return _FALSE;
9481 	}
9482 
9483 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9484 			    (u8 *)&rx_dma_buff_sz);
9485 
9486 	if (rx_dma_buff_sz == 0) {
9487 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9488 		return _FALSE;
9489 	}
9490 
9491 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9492 
9493 	if (page_sz == 0) {
9494 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9495 		return _FALSE;
9496 	}
9497 
9498 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9499 	cam_start_offset = offset * page_sz;
9500 
9501 	ctrl_l = 0x0;
9502 	ctrl_h = 0x0;
9503 
9504 	/* Enable RX packet buffer access */
9505 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9506 
9507 	/* Read the WKFM CAM */
9508 	for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9509 		/*
9510 		 * Set Rx packet buffer offset.
9511 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9512 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9513 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9514 		 * * Index: The index of the wake up frame mask
9515 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9516 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9517 		 */
9518 		rx_buf_ptr =
9519 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9520 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9521 
9522 		rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9523 		data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9524 		data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9525 
9526 		RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9527 
9528 		count = 0;
9529 
9530 		do {
9531 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9532 			rtw_udelay_os(2);
9533 			count++;
9534 		} while (!tmp && count < 100);
9535 
9536 		if (count >= 100) {
9537 			RTW_INFO("%s count:%d\n", __func__, count);
9538 			res = _FALSE;
9539 		}
9540 	}
9541 
9542 	/* Disable RX packet buffer access */
9543 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9544 		   DISABLE_TRXPKT_BUF_ACCESS);
9545 	return res;
9546 }
9547 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9548 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9549 			     struct  rtl_wow_pattern *context)
9550 {
9551 	u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
9552 	u16 offset, rx_buf_ptr = 0;
9553 	u16 cam_start_offset = 0;
9554 	u16 ctrl_l = 0, ctrl_h = 0;
9555 	u8 count = 0, tmp = 0;
9556 	int res = 0, i = 0;
9557 
9558 	if (idx > MAX_WKFM_CAM_NUM) {
9559 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9560 			 __func__);
9561 		return _FALSE;
9562 	}
9563 
9564 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9565 			    (u8 *)&rx_dma_buff_sz);
9566 
9567 	if (rx_dma_buff_sz == 0) {
9568 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9569 		return _FALSE;
9570 	}
9571 
9572 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9573 
9574 	if (page_sz == 0) {
9575 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9576 		return _FALSE;
9577 	}
9578 
9579 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9580 
9581 	cam_start_offset = offset * page_sz;
9582 
9583 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
9584 		ctrl_l = 0x0001;
9585 		ctrl_h = 0x0001;
9586 	} else {
9587 		ctrl_l = 0x0f01;
9588 		ctrl_h = 0xf001;
9589 	}
9590 
9591 	/* Enable RX packet buffer access */
9592 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9593 
9594 	/* Write the WKFM CAM */
9595 	for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
9596 		/*
9597 		 * Set Rx packet buffer offset.
9598 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9599 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9600 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9601 		 * * Index: The index of the wake up frame mask
9602 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9603 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9604 		 */
9605 		rx_buf_ptr =
9606 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
9607 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9608 
9609 		if (i == 0) {
9610 			if (context->type == PATTERN_VALID)
9611 				data = WOW_VALID_BIT;
9612 			else if (context->type == PATTERN_BROADCAST)
9613 				data = WOW_VALID_BIT | WOW_BC_BIT;
9614 			else if (context->type == PATTERN_MULTICAST)
9615 				data = WOW_VALID_BIT | WOW_MC_BIT;
9616 			else if (context->type == PATTERN_UNICAST)
9617 				data = WOW_VALID_BIT | WOW_UC_BIT;
9618 
9619 			if (context->crc != 0)
9620 				data |= context->crc;
9621 
9622 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9623 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9624 		} else if (i == 1) {
9625 			data = 0;
9626 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9627 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9628 		} else if (i == 2 || i == 4) {
9629 			data = context->mask[i - 2];
9630 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9631 			/* write to RX packet buffer*/
9632 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9633 		} else if (i == 3 || i == 5) {
9634 			data = context->mask[i - 2];
9635 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9636 			/* write to RX packet buffer*/
9637 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9638 		}
9639 
9640 		count = 0;
9641 		do {
9642 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9643 			rtw_udelay_os(2);
9644 			count++;
9645 		} while (tmp && count < 100);
9646 
9647 		if (count >= 100)
9648 			res = _FALSE;
9649 		else
9650 			res = _TRUE;
9651 	}
9652 
9653 	/* Disable RX packet buffer access */
9654 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9655 		   DISABLE_TRXPKT_BUF_ACCESS);
9656 
9657 	return res;
9658 }
rtw_fill_pattern(_adapter * adapter)9659 void rtw_fill_pattern(_adapter *adapter)
9660 {
9661 	int i = 0, total = 0, index;
9662 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9663 	struct rtl_wow_pattern wow_pattern;
9664 
9665 	total = pwrpriv->wowlan_pattern_idx;
9666 
9667 	if (total > MAX_WKFM_CAM_NUM)
9668 		total = MAX_WKFM_CAM_NUM;
9669 
9670 	for (i = 0 ; i < total ; i++) {
9671 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
9672 
9673 			index = i;
9674 			if (!pwrpriv->bInSuspend)
9675 				index += 2;
9676 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
9677 			if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
9678 				RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
9679 		}
9680 
9681 	}
9682 	rtw_write8(adapter, REG_WKFMCAM_NUM, total);
9683 
9684 }
9685 #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9686 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9687 {
9688 	u32 data_l = 0, data_h = 0, page_sz = 0;
9689 	u16 tx_page_start, tx_buf_ptr = 0;
9690 	u16 cam_start_offset = 0;
9691 	u16 ctrl_l = 0, ctrl_h = 0;
9692 	u8 count = 0, tmp = 0, last_entry = 0;
9693 	int i = 0;
9694 	bool res = _TRUE;
9695 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9696 	u32 buffer[WKFMCAM_ADDR_NUM];
9697 
9698 
9699 	if (idx > MAX_WKFM_CAM_NUM) {
9700 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9701 			 __func__);
9702 		return _FALSE;
9703 	}
9704 
9705 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9706 	if (page_sz == 0) {
9707 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9708 		return _FALSE;
9709 	}
9710 
9711 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9712 	if (last_entry == 0) {
9713 		RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9714 		return _FALSE;
9715 	}
9716 
9717 
9718 	if(_rtw_wow_chk_cap(adapter, WOW_CAP_HALMAC_ACCESS_PATTERN_IN_TXFIFO)) {
9719 		/* 8723F cannot indirect access tx fifo
9720 		 * rtw_halmac_dump_fifo(dvobj, fifo_sel, fifo_addr, buf_sz, buf)
9721 		 */
9722 		#ifdef RTW_HALMAC
9723 		rtw_halmac_dump_fifo(adapter_to_dvobj(adapter),
9724 		2,
9725 		(pwrctl->pattern_rsvd_page_loc * page_sz) + (idx * WKFMCAM_ADDR_NUM * 4),
9726 		WKFMCAM_ADDR_NUM*4, (u8*)buffer);
9727 		#endif
9728 
9729 		for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9730 			RTW_INFO("[%d]: %08x %08x\n", i, *(buffer + i*2), *(buffer + i*2 + 1));
9731 		}
9732 	} else {
9733 		/* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9734 		tx_page_start = last_entry - 1;
9735 		cam_start_offset = tx_page_start * page_sz / 8;
9736 		ctrl_l = 0x0;
9737 		ctrl_h = 0x0;
9738 
9739 		/* Enable TX packet buffer access */
9740 		rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9741 
9742 		/* Read the WKFM CAM */
9743 		for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9744 			/*
9745 			 * Set Tx packet buffer offset.
9746 			 * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer.
9747 			 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9748 			 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9749 			 * * Index: The index of the wake up frame mask
9750 			 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9751 			 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9752 			 */
9753 			tx_buf_ptr =
9754 				(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9755 			rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr);
9756 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9757 			data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9758 			data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9759 
9760 			RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9761 
9762 			count = 0;
9763 
9764 			do {
9765 				tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9766 				rtw_udelay_os(2);
9767 				count++;
9768 			} while (!tmp && count < 100);
9769 
9770 			if (count >= 100) {
9771 				RTW_INFO("%s count:%d\n", __func__, count);
9772 				res = _FALSE;
9773 			}
9774 		}
9775 
9776 		/* Disable RX packet buffer access */
9777 		rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9778 			   DISABLE_TRXPKT_BUF_ACCESS);
9779 	}
9780 
9781 	return res;
9782 }
9783 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9784 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9785 			     struct  rtl_wow_pattern *context)
9786 {
9787 	u32 tx_page_start = 0, page_sz = 0;
9788 	u16 tx_buf_ptr = 0;
9789 	u16 cam_start_offset = 0;
9790 	u32 data_l = 0, data_h = 0;
9791 	u8 count = 0, tmp = 0, last_entry = 0;
9792 	int res = 0, i = 0;
9793 
9794 	if (idx > MAX_WKFM_CAM_NUM) {
9795 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9796 			 __func__);
9797 		return _FALSE;
9798 	}
9799 
9800 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9801 	if (page_sz == 0) {
9802 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9803 		return _FALSE;
9804 	}
9805 
9806 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9807 	if (last_entry == 0) {
9808 		RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9809 		return _FALSE;
9810 	}
9811 
9812 	/* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9813 	tx_page_start = last_entry - 1;
9814 	cam_start_offset = tx_page_start * page_sz / 8;
9815 
9816 	/* Write the PATTERN location to BIT_TXBUF_WKCAM_OFFSET */
9817 	rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET, cam_start_offset & 0xFF);
9818 	rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET + 1, (cam_start_offset >> 8) & 0xFF);
9819 	/* Enable TX packet buffer access */
9820 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9821 
9822 	/* Write the WKFM CAM */
9823 	for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9824 		/*
9825 		 * Set Tx packet buffer offset.
9826 		 * TxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9827 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9828 		 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9829 		 * * Index: The index of the wake up frame mask
9830 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9831 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9832 		 */
9833 		tx_buf_ptr = cam_start_offset + ((idx * WKFMCAM_SIZE + i * 8) >> 3);
9834 
9835 		if (i == 0) {
9836 			if (context->type == PATTERN_VALID)
9837 				data_l = WOW_VALID_BIT;
9838 			else if (context->type == PATTERN_BROADCAST)
9839 				data_l = WOW_VALID_BIT | WOW_BC_BIT;
9840 			else if (context->type == PATTERN_MULTICAST)
9841 				data_l = WOW_VALID_BIT | WOW_MC_BIT;
9842 			else if (context->type == PATTERN_UNICAST)
9843 				data_l = WOW_VALID_BIT | WOW_UC_BIT;
9844 
9845 			if (context->crc != 0)
9846 				data_l |= context->crc;
9847 
9848 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9849 		} else {
9850 			data_l = context->mask[i * 2 - 2];
9851 			data_h = context->mask[i * 2 - 1];
9852 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9853 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h);
9854 		}
9855 
9856 		rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0x1FFF) | BIT23 | (0xff <<24));
9857 		count = 0;
9858 		do {
9859 			tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9860 			rtw_udelay_os(2);
9861 			count++;
9862 		} while (tmp && count < 100);
9863 
9864 		if (count >= 100) {
9865 			res = _FALSE;
9866 			RTW_INFO("%s write failed\n", __func__);
9867 		} else {
9868 			res = _TRUE;
9869 			RTW_INFO("%s write OK\n", __func__);
9870 		}
9871 	}
9872 
9873 	/* Disable TX packet buffer access */
9874 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
9875 	return res;
9876 }
rtw_write_to_frame_mask_buf(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context,char * pattern_info,u32 * ppattern_info_len)9877 bool rtw_write_to_frame_mask_buf(_adapter *adapter, u8 idx,
9878 			     struct  rtl_wow_pattern *context, char *pattern_info, u32 *ppattern_info_len)
9879 {
9880 
9881 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9882 	u32 page_sz = 0;
9883 	int res = _FALSE, i = 0;
9884 	u32 tmp_pattern_buf[6] = {0};
9885 
9886 	if (pattern_info == NULL) {
9887 		RTW_ERR("[Error]: %s, pattern info is NULL\n", __func__);
9888 	}
9889 	if (idx > MAX_WKFM_CAM_NUM) {
9890 		RTW_ERR("[Error]: %s, pattern index is out of range\n",
9891 			 __func__);
9892 		return _FALSE;
9893 	}
9894 
9895 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9896 	if (page_sz == 0) {
9897 		RTW_ERR("[Error]: %s, page_sz is 0!!\n", __func__);
9898 		return _FALSE;
9899 	}
9900 
9901 	/* Fill WKFM */
9902 	for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9903 		if (i == 0) {
9904 			if (context->type == PATTERN_VALID)
9905 				tmp_pattern_buf[0] = WOW_VALID_BIT;
9906 			else if (context->type == PATTERN_BROADCAST)
9907 				tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_BC_BIT;
9908 			else if (context->type == PATTERN_MULTICAST)
9909 				tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_MC_BIT;
9910 			else if (context->type == PATTERN_UNICAST)
9911 				tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_UC_BIT;
9912 
9913 			if (context->crc != 0)
9914 				tmp_pattern_buf[0] |= context->crc;
9915 			/* pattern[1] is reserved in pattern format, dont care. */
9916 
9917 		} else {
9918 			tmp_pattern_buf[i * 2] = context->mask[i * 2 - 2];
9919 			tmp_pattern_buf[i * 2 + 1] = context->mask[i * 2 - 1];
9920 		}
9921 	}
9922 
9923 
9924 	/* put pattern to pattern_buf */
9925 	_rtw_memcpy((pattern_info + idx * WKFMCAM_SIZE) , tmp_pattern_buf, WKFMCAM_SIZE);
9926 	*ppattern_info_len += WKFMCAM_SIZE;
9927 	#ifdef CONFIG_WOW_PATTERN_IN_TXFIFO_DBG
9928 	RTW_INFO("\nidx : %u pattern_info_len : %u\n", idx, *ppattern_info_len);
9929 	RTW_INFO_DUMP("", (pattern_info + idx * WKFMCAM_SIZE), WKFMCAM_SIZE);
9930 	#endif
9931 	res = _TRUE;
9932 
9933 
9934 	return res;
9935 }
9936 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
9937 
rtw_clean_pattern(_adapter * adapter)9938 void rtw_clean_pattern(_adapter *adapter)
9939 {
9940 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9941 	struct rtl_wow_pattern zero_pattern;
9942 	int i = 0;
9943 
9944 	_rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
9945 
9946 	zero_pattern.type = PATTERN_INVALID;
9947 	/* pattern in tx fifo do not need clear to zero*/
9948 
9949 	rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
9950 }
9951 #if 0
9952 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
9953 			       u8 len, u8 *mask, u8 idx)
9954 {
9955 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9956 	struct mlme_ext_priv *pmlmeext = NULL;
9957 	struct mlme_ext_info *pmlmeinfo = NULL;
9958 	struct rtl_wow_pattern wow_pattern;
9959 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
9960 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9961 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9962 	u8 multicast_addr1[2] = {0x33, 0x33};
9963 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9964 	u8 res = _FALSE, index = 0, mask_len = 0;
9965 	u8 mac_addr[ETH_ALEN] = {0};
9966 	u16 count = 0;
9967 	int i, j;
9968 
9969 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9970 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9971 			 __func__, MAX_WKFM_CAM_NUM);
9972 		return _FALSE;
9973 	}
9974 
9975 	pmlmeext = &adapter->mlmeextpriv;
9976 	pmlmeinfo = &pmlmeext->mlmext_info;
9977 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9978 	_rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
9979 
9980 	mask_len = DIV_ROUND_UP(len, 8);
9981 
9982 	/* 1. setup A1 table */
9983 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9984 		wow_pattern.type = PATTERN_BROADCAST;
9985 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
9986 		wow_pattern.type = PATTERN_MULTICAST;
9987 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
9988 		wow_pattern.type = PATTERN_MULTICAST;
9989 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9990 		wow_pattern.type = PATTERN_UNICAST;
9991 	else
9992 		wow_pattern.type = PATTERN_INVALID;
9993 
9994 	/* translate mask from os to mask for hw */
9995 
9996 /******************************************************************************
9997  * pattern from OS uses 'ethenet frame', like this:
9998 
9999 	|    6   |    6   |   2  |     20    |  Variable  |  4  |
10000 	|--------+--------+------+-----------+------------+-----|
10001 	|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
10002 	|   DA   |   SA   | Type |
10003 
10004  * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
10005 
10006 	|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
10007 	|-------------------+--------+------+-----------+------------+-----|
10008 	| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
10009 			    | Others | Tpye |
10010 
10011  * Therefore, we need translate mask_from_OS to mask_to_hw.
10012  * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
10013  * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
10014  * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
10015  ******************************************************************************/
10016 	/* Shift 6 bits */
10017 	for (i = 0; i < mask_len - 1; i++) {
10018 		mask_hw[i] = mask[i] >> 6;
10019 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
10020 	}
10021 
10022 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
10023 	/* Set bit 0-5 to zero */
10024 	mask_hw[0] &= 0xC0;
10025 
10026 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
10027 		wow_pattern.mask[i] = mask_hw[i * 4];
10028 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
10029 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
10030 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
10031 	}
10032 
10033 	/* To get the wake up pattern from the mask.
10034 	 * We do not count first 12 bits which means
10035 	 * DA[6] and SA[6] in the pattern to match HW design. */
10036 	count = 0;
10037 	for (i = 12; i < len; i++) {
10038 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
10039 			content[count] = pattern[i];
10040 			count++;
10041 		}
10042 	}
10043 
10044 	wow_pattern.crc = rtw_calc_crc(content, count);
10045 
10046 	if (wow_pattern.crc != 0) {
10047 		if (wow_pattern.type == PATTERN_INVALID)
10048 			wow_pattern.type = PATTERN_VALID;
10049 	}
10050 
10051 	index = idx;
10052 
10053 	if (!pwrctl->bInSuspend)
10054 		index += 2;
10055 
10056 	/* write pattern */
10057 	res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
10058 
10059 	if (res == _FALSE)
10060 		RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
10061 			 __func__, idx);
10062 
10063 	return res;
10064 }
10065 #endif
10066 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
10067 
10068 #define WOW_CAM_ACCESS_TIMEOUT_MS	200
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)10069 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
10070 {
10071 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10072 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10073 
10074 	u32 rdata = 0;
10075 	u32 cnt = 0;
10076 	systime start = 0;
10077 	u8 timeout = 0;
10078 	u8 rst = _FALSE;
10079 
10080 	_enter_critical_mutex(mutex, NULL);
10081 
10082 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
10083 
10084 	start = rtw_get_current_time();
10085 	while (1) {
10086 		if (rtw_is_surprise_removed(adapter))
10087 			break;
10088 
10089 		cnt++;
10090 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10091 			rst = _SUCCESS;
10092 			break;
10093 		}
10094 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10095 			timeout = 1;
10096 			break;
10097 		}
10098 	}
10099 
10100 	rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
10101 
10102 	_exit_critical_mutex(mutex, NULL);
10103 
10104 	/*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
10105 
10106 	if (timeout)
10107 		RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
10108 
10109 	return rdata;
10110 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10111 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
10112 {
10113 	int i;
10114 	u32 rdata;
10115 
10116 	_rtw_memset(context, 0, sizeof(struct  rtl_wow_pattern));
10117 
10118 	for (i = 4; i >= 0; i--) {
10119 		rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
10120 
10121 		switch (i) {
10122 		case 4:
10123 			if (rdata & WOW_BC_BIT)
10124 				context->type = PATTERN_BROADCAST;
10125 			else if (rdata & WOW_MC_BIT)
10126 				context->type = PATTERN_MULTICAST;
10127 			else if (rdata & WOW_UC_BIT)
10128 				context->type = PATTERN_UNICAST;
10129 			else
10130 				context->type = PATTERN_INVALID;
10131 
10132 			context->crc = rdata & 0xFFFF;
10133 			break;
10134 		default:
10135 			_rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
10136 			break;
10137 		}
10138 	}
10139 }
10140 
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)10141 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
10142 {
10143 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10144 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10145 	u32 cnt = 0;
10146 	systime start = 0, end = 0;
10147 	u8 timeout = 0;
10148 
10149 	/*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
10150 	_enter_critical_mutex(mutex, NULL);
10151 
10152 	rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
10153 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
10154 
10155 	start = rtw_get_current_time();
10156 	while (1) {
10157 		if (rtw_is_surprise_removed(adapter))
10158 			break;
10159 
10160 		cnt++;
10161 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
10162 			break;
10163 
10164 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10165 			timeout = 1;
10166 			break;
10167 		}
10168 	}
10169 	end = rtw_get_current_time();
10170 
10171 	_exit_critical_mutex(mutex, NULL);
10172 
10173 	if (timeout) {
10174 		RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
10175 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
10176 	}
10177 }
10178 
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10179 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
10180 {
10181 	int j;
10182 	u8 addr;
10183 	u32 wdata = 0;
10184 
10185 	for (j = 4; j >= 0; j--) {
10186 		switch (j) {
10187 		case 4:
10188 			wdata = context->crc;
10189 
10190 			if (PATTERN_BROADCAST == context->type)
10191 				wdata |= WOW_BC_BIT;
10192 			if (PATTERN_MULTICAST == context->type)
10193 				wdata |= WOW_MC_BIT;
10194 			if (PATTERN_UNICAST == context->type)
10195 				wdata |= WOW_UC_BIT;
10196 			if (PATTERN_INVALID != context->type)
10197 				wdata |= WOW_VALID_BIT;
10198 			break;
10199 		default:
10200 			wdata = context->mask[j];
10201 			break;
10202 		}
10203 
10204 		addr = (id << 3) + j;
10205 
10206 		_rtw_wow_pattern_write_cam(adapter, addr, wdata);
10207 	}
10208 }
10209 
_rtw_wow_pattern_clean_cam(_adapter * adapter)10210 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
10211 {
10212 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10213 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10214 	u32 cnt = 0;
10215 	systime start = 0;
10216 	u8 timeout = 0;
10217 	u8 rst = _FAIL;
10218 
10219 	_enter_critical_mutex(mutex, NULL);
10220 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
10221 
10222 	start = rtw_get_current_time();
10223 	while (1) {
10224 		if (rtw_is_surprise_removed(adapter))
10225 			break;
10226 
10227 		cnt++;
10228 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10229 			rst = _SUCCESS;
10230 			break;
10231 		}
10232 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10233 			timeout = 1;
10234 			break;
10235 		}
10236 	}
10237 	_exit_critical_mutex(mutex, NULL);
10238 
10239 	if (timeout)
10240 		RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
10241 
10242 	return rst;
10243 }
10244 
rtw_clean_pattern(_adapter * adapter)10245 void rtw_clean_pattern(_adapter *adapter)
10246 {
10247 	if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
10248 		RTW_ERR("rtw_clean_pattern failed\n");
10249 }
rtw_fill_pattern(_adapter * adapter)10250 void rtw_fill_pattern(_adapter *adapter)
10251 {
10252 	int i = 0, total = 0;
10253 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10254 	struct rtl_wow_pattern wow_pattern;
10255 
10256 	total = pwrpriv->wowlan_pattern_idx;
10257 
10258 	if (total > MAX_WKFM_CAM_NUM)
10259 		total = MAX_WKFM_CAM_NUM;
10260 
10261 	for (i = 0 ; i < total ; i++) {
10262 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10263 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10264 			rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
10265 		}
10266 	}
10267 }
10268 
10269 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)10270 void rtw_wow_pattern_cam_dump(_adapter *adapter)
10271 {
10272 
10273 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10274 	int i = 0, total = 0;
10275 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10276 	total = pwrpriv->wowlan_pattern_idx;
10277 
10278 	if (total > MAX_WKFM_CAM_NUM)
10279 		total = MAX_WKFM_CAM_NUM;
10280 
10281 	for (i = 0 ; i < total; i++) {
10282 		RTW_INFO("=======[%d]=======\n", i);
10283 		rtw_read_from_frame_mask(adapter, i);
10284 	}
10285 #else
10286 	struct  rtl_wow_pattern context;
10287 	int i;
10288 
10289 	for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10290 		rtw_wow_pattern_read_cam_ent(adapter, i, &context);
10291 		rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
10292 	}
10293 
10294 #endif
10295 }
10296 
10297 
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)10298 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
10299 {
10300 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10301 
10302 	switch (mode) {
10303 	case 0:
10304 		rtw_clean_pattern(adapter);
10305 		RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
10306 		break;
10307 	case 1:
10308 		#if defined(CONFIG_WOW_PATTERN_IN_TXFIFO)
10309 		RTW_INFO("%s Patterns have been downloaded in rsvd pages\n", __func__);
10310 		#else
10311 		rtw_set_default_pattern(adapter);
10312 		rtw_fill_pattern(adapter);
10313 		RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
10314 		#endif
10315 		break;
10316 	case 2:
10317 		rtw_clean_pattern(adapter);
10318 		rtw_wow_pattern_sw_reset(adapter);
10319 		RTW_INFO("%s: clean patterns\n", __func__);
10320 		break;
10321 	default:
10322 		RTW_INFO("%s: unknown mode\n", __func__);
10323 		break;
10324 	}
10325 }
10326 
rtw_hal_wow_enable(_adapter * adapter)10327 static void rtw_hal_wow_enable(_adapter *adapter)
10328 {
10329 	struct registry_priv  *registry_par = &adapter->registrypriv;
10330 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10331 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10332 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10333 	struct sta_info *psta = NULL;
10334 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
10335 	int res;
10336 	u16 media_status_rpt;
10337 	u8 no_wake = 0, i;
10338 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10339 	_adapter *iface;
10340 #ifdef CONFIG_GPIO_WAKEUP
10341 	u8 val8 = 0;
10342 #endif
10343 
10344 #ifdef CONFIG_LPS_PG
10345 	u8 lps_pg_hdl_id = 0;
10346 #endif
10347 
10348 
10349 
10350 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
10351 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
10352 		no_wake = 1;
10353 
10354 	RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
10355 	rtw_hal_gate_bb(adapter, _TRUE);
10356 
10357 	for (i = 0; i < dvobj->iface_nums; i++) {
10358 		iface = dvobj->padapters[i];
10359 		/* Start Usb TxDMA */
10360 		if(iface) {
10361 			RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface));
10362 			RTW_ENABLE_FUNC(iface, DF_TX_BIT);
10363 		}
10364 	}
10365 
10366 #ifdef CONFIG_GTK_OL
10367 	if (psecuritypriv->binstallKCK_KEK == _TRUE)
10368 		rtw_hal_fw_sync_cam_id(adapter);
10369 #endif
10370 	if (IS_HARDWARE_TYPE_8723B(adapter))
10371 		rtw_hal_backup_rate(adapter);
10372 
10373 	rtw_hal_fw_dl(adapter, _TRUE);
10374 	if(no_wake)
10375 		media_status_rpt = RT_MEDIA_DISCONNECT;
10376 	else
10377 		media_status_rpt = RT_MEDIA_CONNECT;
10378 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10379 			  (u8 *)&media_status_rpt);
10380 
10381 	/* RX DMA stop */
10382 	#if defined(CONFIG_RTL8188E)
10383 	if (IS_HARDWARE_TYPE_8188E(adapter))
10384 		rtw_hal_disable_tx_report(adapter);
10385 	#endif
10386 
10387 	res = rtw_hal_pause_rx_dma(adapter);
10388 	if (res == _FAIL)
10389 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
10390 
10391 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
10392 	/* Reconfig RX_FF Boundary */
10393 	#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10394 	rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
10395 	#endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10396 	#endif
10397 
10398 	/* redownload wow pattern */
10399 	if(!no_wake)
10400 		rtw_hal_dl_pattern(adapter, 1);
10401 
10402 	if (!pwrctl->wowlan_pno_enable) {
10403 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10404 
10405 		if (psta != NULL) {
10406 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10407 			adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10408 			adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10409 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10410 			#endif
10411 			if(!no_wake)
10412 				rtw_sta_media_status_rpt(adapter, psta, 1);
10413 		}
10414 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10415 		else {
10416 			if(registry_par->suspend_type == FW_IPS_WRC) {
10417 				adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10418 				adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10419 				rtw_hal_set_default_port_id_cmd(adapter, 0);
10420 			}
10421 		}
10422 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10423 	}
10424 
10425 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10426 	/* Enable CPWM2 only. */
10427 	res = rtw_hal_enable_cpwm2(adapter);
10428 	if (res == _FAIL)
10429 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
10430 #endif
10431 #ifdef CONFIG_GPIO_WAKEUP
10432 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10433 	rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10434 	rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10435 #else
10436 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10437 	if (pwrctl->is_high_active == 0)
10438 		rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10439 	else
10440 		rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10441 			GPIO_OUTPUT_LOW);
10442 #else
10443 	val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10444 	rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8);
10445 	rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10446 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n",
10447 		 __func__, pwrctl->wowlan_gpio_index,
10448 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10449 		 pwrctl->is_high_active ? "HIGI" : "LOW");
10450 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10451 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10452 #endif /* CONFIG_GPIO_WAKEUP */
10453 	/* Set WOWLAN H2C command. */
10454 	RTW_PRINT("Set WOWLan cmd\n");
10455 	rtw_hal_set_fw_wow_related_cmd(adapter, 1);
10456 
10457 	res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
10458 
10459 	if (res == _FALSE)
10460 		RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
10461 
10462 	pwrctl->wowlan_wake_reason =
10463 		rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10464 
10465 	RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
10466 		  pwrctl->wowlan_wake_reason);
10467 #ifdef CONFIG_GTK_OL_DBG
10468 	dump_sec_cam(RTW_DBGDUMP, adapter);
10469 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
10470 #endif
10471 
10472 #ifdef CONFIG_LPS_PG
10473 	if (pwrctl->lps_level == LPS_PG) {
10474 		lps_pg_hdl_id = LPS_PG_INFO_CFG;
10475 		rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
10476 	}
10477 #endif
10478 
10479 #ifdef CONFIG_USB_HCI
10480 	/* free adapter's resource */
10481 	rtw_mi_intf_stop(adapter);
10482 
10483 #endif
10484 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
10485 	/* Invoid SE0 reset signal during suspending*/
10486 	rtw_write8(adapter, REG_RSV_CTRL, 0x20);
10487 	if (IS_8188F(pHalData->version_id) == FALSE
10488 		&& IS_8188GTV(pHalData->version_id) == FALSE)
10489 		rtw_write8(adapter, REG_RSV_CTRL, 0x60);
10490 #endif
10491 
10492 	rtw_hal_gate_bb(adapter, _FALSE);
10493 }
10494 
10495 #define DBG_WAKEUP_REASON
10496 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)10497 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
10498 {
10499 	RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
10500 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)10501 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
10502 {
10503 	if (RX_PAIRWISEKEY == reason)
10504 		_dbg_wake_up_reason_string(adapter, "Rx pairwise key");
10505 	else if (RX_GTK == reason)
10506 		_dbg_wake_up_reason_string(adapter, "Rx GTK");
10507 	else if (RX_FOURWAY_HANDSHAKE == reason)
10508 		_dbg_wake_up_reason_string(adapter, "Rx four way handshake");
10509 	else if (RX_DISASSOC == reason)
10510 		_dbg_wake_up_reason_string(adapter, "Rx disassoc");
10511 	else if (RX_DEAUTH == reason)
10512 		_dbg_wake_up_reason_string(adapter, "Rx deauth");
10513 	else if (RX_ARP_REQUEST == reason)
10514 		_dbg_wake_up_reason_string(adapter, "Rx ARP request");
10515 	else if (FW_DECISION_DISCONNECT == reason)
10516 		_dbg_wake_up_reason_string(adapter, "FW detect disconnect");
10517 	else if (RX_MAGIC_PKT == reason)
10518 		_dbg_wake_up_reason_string(adapter, "Rx magic packet");
10519 	else if (RX_UNICAST_PKT == reason)
10520 		_dbg_wake_up_reason_string(adapter, "Rx unicast packet");
10521 	else if (RX_PATTERN_PKT == reason)
10522 		_dbg_wake_up_reason_string(adapter, "Rx pattern packet");
10523 	else if (RTD3_SSID_MATCH == reason)
10524 		_dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
10525 	else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
10526 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
10527 	else if (RX_REALWOW_V2_ACK_LOST == reason)
10528 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
10529 	else if (ENABLE_FAIL_DMA_IDLE == reason)
10530 		_dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
10531 	else if (ENABLE_FAIL_DMA_PAUSE == reason)
10532 		_dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
10533 	else if (AP_OFFLOAD_WAKEUP == reason)
10534 		_dbg_wake_up_reason_string(adapter, "AP offload wakeup");
10535 	else if (CLK_32K_UNLOCK == reason)
10536 		_dbg_wake_up_reason_string(adapter, "clk 32k unlock");
10537 	else if (RTIME_FAIL_DMA_IDLE == reason)
10538 		_dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
10539 	else if (CLK_32K_LOCK == reason)
10540 		_dbg_wake_up_reason_string(adapter, "clk 32k lock");
10541 	#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10542 	else if (WOW_KEEPALIVE_ACK_TIMEOUT == reason)
10543 		_dbg_wake_up_reason_string(adapter, "rx keep alive ack timeout");
10544 	else if (WOW_KEEPALIVE_WAKE == reason)
10545 		_dbg_wake_up_reason_string(adapter, "rx keep alive wake pattern");
10546 	#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
10547 	else
10548 		_dbg_wake_up_reason_string(adapter, "unknown reasoen");
10549 }
10550 #endif
10551 
rtw_hal_wow_disable(_adapter * adapter)10552 static void rtw_hal_wow_disable(_adapter *adapter)
10553 {
10554 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10555 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10556 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10557 	struct sta_info *psta = NULL;
10558 	struct registry_priv  *registry_par = &adapter->registrypriv;
10559 	int res;
10560 	u16 media_status_rpt;
10561 
10562 	RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
10563 
10564 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
10565 		RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
10566 		return;
10567 	}
10568 
10569 	if (!pwrctl->wowlan_pno_enable) {
10570 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10571 		if (psta != NULL)
10572 			rtw_sta_media_status_rpt(adapter, psta, 0);
10573 		else
10574 			RTW_INFO("%s: psta is null\n", __func__);
10575 	}
10576 
10577 	if (0) {
10578 		RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
10579 		RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
10580 		RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
10581 		RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
10582 	}
10583 
10584 	pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10585 
10586 	RTW_PRINT("wakeup_reason: 0x%02x\n",
10587 		  pwrctl->wowlan_wake_reason);
10588 	#ifdef DBG_WAKEUP_REASON
10589 	_dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
10590 	#endif
10591 
10592 	rtw_hal_set_fw_wow_related_cmd(adapter, 0);
10593 
10594 	res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
10595 
10596 	#if defined(CONFIG_RTL8188E)
10597 	if (IS_HARDWARE_TYPE_8188E(adapter))
10598 		rtw_hal_enable_tx_report(adapter);
10599 	#endif
10600 
10601 	if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10602 		(pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
10603 		(pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
10604 		rtw_hal_get_aoac_rpt(adapter);
10605 		rtw_hal_update_sw_security_info(adapter);
10606 	}
10607 
10608 	if (res == _FALSE) {
10609 		RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
10610 		rtw_hal_force_enable_rxdma(adapter);
10611 	}
10612 
10613 	rtw_hal_gate_bb(adapter, _TRUE);
10614 
10615 	res = rtw_hal_pause_rx_dma(adapter);
10616 	if (res == _FAIL)
10617 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
10618 
10619 	/* clean HW pattern match */
10620 	rtw_hal_dl_pattern(adapter, 0);
10621 
10622 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
10623 	/* config RXFF boundary to original */
10624 	#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10625 	rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
10626 	#endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10627 	#endif
10628 	rtw_hal_release_rx_dma(adapter);
10629 
10630 	rtw_hal_fw_dl(adapter, _FALSE);
10631 
10632 #ifdef CONFIG_GPIO_WAKEUP
10633 
10634 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10635 	rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10636 #else
10637 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10638 	if (pwrctl->is_high_active == 0)
10639 		rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10640 	else
10641 		rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10642 			GPIO_OUTPUT_LOW);
10643 #else
10644 	rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index
10645 		, pwrctl->wowlan_gpio_output_state);
10646 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n",
10647 		 __func__, pwrctl->wowlan_gpio_index,
10648 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10649 		 pwrctl->is_high_active ? "HIGI" : "LOW");
10650 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10651 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10652 #endif /* CONFIG_GPIO_WAKEUP */
10653 	if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10654 	    (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
10655 	    (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10656 	    (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
10657 
10658 		media_status_rpt = RT_MEDIA_CONNECT;
10659 		rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10660 				  (u8 *)&media_status_rpt);
10661 
10662 		if (psta != NULL) {
10663 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10664 			adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10665 			adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10666 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10667 			#endif
10668 			rtw_sta_media_status_rpt(adapter, psta, 1);
10669 		}
10670 	}
10671 	rtw_hal_gate_bb(adapter, _FALSE);
10672 }
10673 #if defined(CONFIG_WOW_PATTERN_IN_TXFIFO)
rtw_hal_construct_pattern_info(PADAPTER padapter,u8 * pframe,u32 * pLength)10674 static void rtw_hal_construct_pattern_info(
10675 	PADAPTER	padapter,
10676 	u8		*pframe,
10677 	u32		*pLength
10678 )
10679 {
10680 
10681 	u32 pattern_info_len = 0;
10682 	int i = 0, total = 0, index;
10683 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
10684 	struct rtl_wow_pattern wow_pattern;
10685 	u32 page_sz = 0;
10686 
10687 	total = pwrpriv->wowlan_pattern_idx;
10688 
10689 	if (total > MAX_WKFM_CAM_NUM)
10690 		total = MAX_WKFM_CAM_NUM;
10691 
10692 	/* Generate default pattern */
10693 	rtw_set_default_pattern(padapter);
10694 
10695 	/* Convert pattern to WKFM_CAM pattern */
10696 	for (i = 0 ; i < total ; i++) {
10697 		if (_SUCCESS == rtw_hal_wow_pattern_generate(padapter, i, &wow_pattern)) {
10698 
10699 			index = i;
10700 			if (!pwrpriv->bInSuspend)
10701 				index += 2;
10702 			#ifdef CONFIG_WOW_PATTERN_IN_TXFIFO_DBG
10703 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10704 			#endif
10705 
10706 			if (rtw_write_to_frame_mask_buf(padapter, index, &wow_pattern,
10707 				pframe, &pattern_info_len) == _FALSE)
10708 				RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
10709 		}
10710 	}
10711 	*pLength = pattern_info_len;
10712 
10713 
10714 }
10715 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
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)10716 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
10717 		  u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
10718 				  RSVDPAGE_LOC *rsvd_page_loc)
10719 {
10720 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10721 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10722 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10723 	struct mlme_ext_priv	*pmlmeext;
10724 	struct mlme_ext_info	*pmlmeinfo;
10725 	u32	ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
10726 	u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
10727 	u8 CurtPktPageNum = 0;
10728 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10729 	u32 keep_alive_len=0;
10730 	int i;
10731 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN */
10732 #ifdef CONFIG_WAR_OFFLOAD
10733 	u16 tmp_idx = 0;
10734 	u32	buf_len = 0;
10735 #endif
10736 
10737 #ifdef CONFIG_GTK_OL
10738 	struct sta_priv *pstapriv = &adapter->stapriv;
10739 	struct sta_info *psta;
10740 	struct security_priv *psecpriv = &adapter->securitypriv;
10741 	u8 kek[RTW_KEK_LEN];
10742 	u8 kck[RTW_KCK_LEN];
10743 #endif /* CONFIG_GTK_OL */
10744 #ifdef CONFIG_PNO_SUPPORT
10745 	int pno_index;
10746 	u8 ssid_num;
10747 #endif /* CONFIG_PNO_SUPPORT */
10748 #ifdef CONFIG_WOW_PATTERN_IN_TXFIFO
10749 	u32 PatternLen = 0;
10750 	u32 cam_start_offset = 0;
10751 	u32 reg_cam_start_offset_val = 0;
10752 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
10753 
10754 	pmlmeext = &adapter->mlmeextpriv;
10755 	pmlmeinfo = &pmlmeext->mlmext_info;
10756 
10757 	if (pwrctl->wowlan_pno_enable == _FALSE) {
10758 		/* ARP RSP * 1 page */
10759 
10760 		rsvd_page_loc->LocArpRsp = *page_num;
10761 
10762 		RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
10763 
10764 #ifdef CONFIG_WAR_OFFLOAD
10765 		if ((0 != pwrctl->wowlan_war_offload_ipv4.ip_addr[0]) &&
10766 			(_FALSE == _rtw_memcmp(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4))) {
10767 			_rtw_memcpy(pmlmeinfo->ip_addr, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4);
10768 			RTW_INFO("Update IP(%d.%d.%d.%d) to arp rsvd page\n",
10769 			pmlmeinfo->ip_addr[0], pmlmeinfo->ip_addr[1],
10770 			pmlmeinfo->ip_addr[2], pmlmeinfo->ip_addr[3]);
10771 		}
10772 #endif /* CONFIG_WAR_OFFLOAD */
10773 
10774 
10775 		rtw_hal_construct_ARPRsp(adapter, &pframe[index],
10776 					 &ARPLength, pmlmeinfo->ip_addr);
10777 
10778 		rtw_hal_fill_fake_txdesc(adapter,
10779 					 &pframe[index - tx_desc],
10780 					 ARPLength, _FALSE, _FALSE, _TRUE);
10781 
10782 		CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
10783 
10784 		*page_num += CurtPktPageNum;
10785 
10786 		index += (CurtPktPageNum * page_size);
10787 		RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
10788 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10789 		/* Keep Alive * ? page*/
10790 		if(pwrctl->keep_alive_pattern_len){
10791 			rsvd_page_loc->LocKeepAlive = *page_num;
10792 			pwrctl->keep_alive_pattern_loc = rsvd_page_loc->LocKeepAlive;
10793 			RTW_INFO("pwrctl->keep_alive_pattern_loc: %d\n", pwrctl->keep_alive_pattern_loc);
10794 			rtw_hal_construct_keepalive(adapter,&pframe[index],&keep_alive_len);
10795 			rtw_hal_fill_fake_txdesc(adapter,
10796 					 &pframe[index - tx_desc],
10797 					 keep_alive_len, _FALSE, _FALSE, _TRUE);
10798 			CurtPktPageNum = (u8)PageNum(tx_desc + keep_alive_len, page_size);
10799 			*page_num += CurtPktPageNum;
10800 			index += (CurtPktPageNum * page_size);
10801 			RSVD_PAGE_CFG("WOW-KeepAlive:", CurtPktPageNum, *page_num, 0);
10802 		}
10803 #endif /* CONFIG_WOW_KEEP_ALIVE_PATTERN*/
10804 
10805 #ifdef CONFIG_IPV6
10806 		/* 2 NS offload and NDP Info*/
10807 		if (pwrctl->wowlan_ns_offload_en == _TRUE) {
10808 			rsvd_page_loc->LocNbrAdv = *page_num;
10809 			RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
10810 			rtw_hal_construct_na_message(adapter,
10811 						     &pframe[index], &ns_len);
10812 			rtw_hal_fill_fake_txdesc(adapter,
10813 						 &pframe[index - tx_desc],
10814 						 ns_len, _FALSE,
10815 						 _FALSE, _TRUE);
10816 			CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
10817 						      page_size);
10818 			*page_num += CurtPktPageNum;
10819 			index += (CurtPktPageNum * page_size);
10820 			RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
10821 
10822 			rsvd_page_loc->LocNDPInfo = *page_num;
10823 			RTW_INFO("LocNDPInfo: %d\n",
10824 				 rsvd_page_loc->LocNDPInfo);
10825 
10826 			rtw_hal_construct_ndp_info(adapter,
10827 						   &pframe[index - tx_desc],
10828 						   &ns_len);
10829 			CurtPktPageNum =
10830 				(u8)PageNum(tx_desc + ns_len, page_size);
10831 			*page_num += CurtPktPageNum;
10832 			index += (CurtPktPageNum * page_size);
10833 			RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
10834 
10835 		}
10836 #endif /*CONFIG_IPV6*/
10837 		/* 3 Remote Control Info. * 1 page */
10838 		rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
10839 		RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
10840 		rtw_hal_construct_remote_control_info(adapter,
10841 						      &pframe[index - tx_desc],
10842 						      &rc_len);
10843 		CurtPktPageNum = (u8)PageNum(rc_len, page_size);
10844 		*page_num += CurtPktPageNum;
10845 		*total_pkt_len = index + rc_len;
10846 		RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
10847 #ifdef CONFIG_GTK_OL
10848 		index += (CurtPktPageNum * page_size);
10849 
10850 		/* if the ap staion info. exists, get the kek, kck from staion info. */
10851 		psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
10852 		if (psta == NULL) {
10853 			_rtw_memset(kek, 0, RTW_KEK_LEN);
10854 			_rtw_memset(kck, 0, RTW_KCK_LEN);
10855 			RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
10856 				 __func__);
10857 		} else {
10858 			_rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
10859 			_rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
10860 		}
10861 
10862 		/* 3 KEK, KCK */
10863 		rsvd_page_loc->LocGTKInfo = *page_num;
10864 		RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
10865 
10866 		if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
10867 			struct security_priv *psecpriv = NULL;
10868 
10869 			psecpriv = &adapter->securitypriv;
10870 			_rtw_memcpy(pframe + index - tx_desc,
10871 				    &psecpriv->dot11PrivacyAlgrthm, 1);
10872 			_rtw_memcpy(pframe + index - tx_desc + 1,
10873 				    &psecpriv->dot118021XGrpPrivacy, 1);
10874 			_rtw_memcpy(pframe + index - tx_desc + 2,
10875 				    kck, RTW_KCK_LEN);
10876 			_rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
10877 				    kek, RTW_KEK_LEN);
10878 			CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
10879 		} else {
10880 
10881 			_rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
10882 			_rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
10883 				    kek, RTW_KEK_LEN);
10884 			GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
10885 
10886 			if (psta != NULL &&
10887 				psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
10888 				_rtw_memcpy(pframe + index - tx_desc + 56,
10889 					&psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
10890 				GTKLength += RTW_TKIP_MIC_LEN;
10891 			}
10892 			CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
10893 		}
10894 #if 0
10895 		{
10896 			int i;
10897 			printk("\ntoFW KCK: ");
10898 			for (i = 0; i < 16; i++)
10899 				printk(" %02x ", kck[i]);
10900 			printk("\ntoFW KEK: ");
10901 			for (i = 0; i < 16; i++)
10902 				printk(" %02x ", kek[i]);
10903 			printk("\n");
10904 		}
10905 
10906 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
10907 			 __FUNCTION__, &pframe[index - tx_desc],
10908 			 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
10909 #endif
10910 
10911 		*page_num += CurtPktPageNum;
10912 
10913 		index += (CurtPktPageNum * page_size);
10914 		RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
10915 
10916 		/* 3 GTK Response */
10917 		rsvd_page_loc->LocGTKRsp = *page_num;
10918 		RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
10919 		rtw_hal_construct_GTKRsp(adapter, &pframe[index], &GTKLength);
10920 
10921 		rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10922 					 GTKLength, _FALSE, _FALSE, _TRUE);
10923 #if 0
10924 		{
10925 			int gj;
10926 			printk("123GTK pkt=>\n");
10927 			for (gj = 0; gj < GTKLength + tx_desc; gj++) {
10928 				printk(" %02x ", pframe[index - tx_desc + gj]);
10929 				if ((gj + 1) % 16 == 0)
10930 					printk("\n");
10931 			}
10932 			printk(" <=end\n");
10933 		}
10934 
10935 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
10936 			 __FUNCTION__, &pframe[index - tx_desc],
10937 			 (tx_desc + GTKLength));
10938 #endif
10939 
10940 		CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
10941 
10942 		*page_num += CurtPktPageNum;
10943 
10944 		index += (CurtPktPageNum * page_size);
10945 		RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
10946 
10947 		/* below page is empty for GTK extension memory */
10948 		/* 3(11) GTK EXT MEM */
10949 		rsvd_page_loc->LocGTKEXTMEM = *page_num;
10950 		RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
10951 		CurtPktPageNum = 2;
10952 
10953 		if (page_size >= 256)
10954 			CurtPktPageNum = 1;
10955 
10956 		*page_num += CurtPktPageNum;
10957 		/* extension memory for FW */
10958 		*total_pkt_len = index + (page_size * CurtPktPageNum);
10959 		RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
10960 #endif /* CONFIG_GTK_OL */
10961 
10962 		index += (CurtPktPageNum * page_size);
10963 
10964 #ifdef CONFIG_WAR_OFFLOAD
10965 		if(_TRUE == pwrctl->wowlan_war_offload_mode) {
10966 			u8 zero_ary[16] = {0x00};
10967 			u8 war_tmp_cnt = 0;
10968 
10969 			/* Reserve 2 page for Ip parameters */
10970 			/* First page
10971 			   | Byte 15 -----------Byte 0 |
10972 			   | IP-4 | IP-3 | IP-2 | IP-1 |
10973 			   | location of each feature | mac addr |
10974 			   | NetBIOS name			   |
10975 			   | location of each feature  |
10976 			Second page
10977 			   | IPv6 - 1				   |
10978 			   | IPv6 - 2				   |
10979 			   | IPv6 - 3				   |
10980 			   | IPv6 - 4				   |
10981 			   | IPv6 - 5				   |
10982 			   | IPv6 - 6				   |
10983 			   | IPv6 - 7				   |
10984 			   | IPv6 - 8				   |
10985 			*/
10986 
10987 			/* location of each feature : Byte 22 ~ Byte 31
10988 			 * Byte22 : location of SNMP RX
10989 			 * Byte23 : location of SNMP V4
10990 			 * Byte24 : location of SNMP V6
10991 			 * Byte25 : location of MDNS Param
10992 			 * Byte26 : location of MDNS V4
10993 			 * Byte27 : location of MDNS V6
10994 			 * Byte28 : location of SSDP pattern
10995 			 * Byte29 : location of WSD pattern
10996 			 * Byte30 : location of SLP pattern
10997 			 * Byte31 : location of LLMNR
10998 			 */
10999 
11000 			/* ipv4 : 4 */
11001 			if (0 == pwrctl->wowlan_war_offload_ipv4.ip_addr[0])
11002 				_rtw_memcpy(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4);
11003 			for(war_tmp_cnt=0; war_tmp_cnt<4 ;war_tmp_cnt++)
11004 				_rtw_memcpy(pframe + index - tx_desc + (war_tmp_cnt*4), &pwrctl->wowlan_war_offload_ipv4.ip_addr[war_tmp_cnt], 4);
11005 
11006 			if (is_zero_mac_addr(pwrctl->wowlan_war_offload_mac)) {
11007 				_rtw_memcpy(pwrctl->wowlan_war_offload_mac, adapter_mac_addr(adapter), 6);
11008 			}
11009 			_rtw_memcpy(pframe + index + 16 - tx_desc, pwrctl->wowlan_war_offload_mac, 6);
11010 
11011 
11012 			/* ipv6 : 8 */
11013 			if (_TRUE == _rtw_memcmp(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], zero_ary, RTW_IPv6_ADDR_LEN))
11014 				_rtw_memcpy(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], pmlmeinfo->ip6_addr, RTW_IPv6_ADDR_LEN);
11015 
11016 			for(war_tmp_cnt=0; war_tmp_cnt<8 ;war_tmp_cnt++)
11017 				_rtw_memcpy(pframe + index + page_size - tx_desc + (war_tmp_cnt*16), pwrctl->wowlan_war_offload_ipv6.ipv6_addr[war_tmp_cnt], 16);
11018 
11019 			rsvd_page_loc->LocIpParm = *page_num;
11020 
11021 			tmp_idx = index;
11022 			CurtPktPageNum = 2;
11023 			*page_num += CurtPktPageNum;
11024 			*total_pkt_len = index + (page_size * CurtPktPageNum);
11025 			index += (CurtPktPageNum * page_size);
11026 
11027 
11028 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
11029 			if ( (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) ||
11030 				 (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) ||
11031 				 (WAR_MDNS_V4_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl) ||
11032 				 (WAR_MDNS_V6_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl)) {
11033 
11034 				struct war_mdns_service_info *psinfo = pwrctl->wowlan_war_offload_mdns_service;
11035 				u8 txt_in_ptr[31]={ 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
11036 									 0x00, 0x13, 0x09, 0x74, 0x78, 0x74, 0x76, 0x65, 0x72, 0x73,
11037 									 0x3d, 0x31, 0x08, 0x71, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x3d, 0x31};
11038 				u16 mdns_offset = index - tx_desc;
11039 				u8 i = 0;
11040 
11041 				rsvd_page_loc->LocMdnsPara = *page_num;
11042 				RTW_INFO("LocMdnsPara : %d\n", rsvd_page_loc->LocMdnsPara);
11043 
11044 				/* 1. service info */
11045 				pframe[mdns_offset] = 0x01;  // TLV(T)
11046 				mdns_offset += 1;
11047 				_rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_service_info_num, 1);
11048 				mdns_offset += 1;
11049 
11050 				for(i=0; i<pwrctl->wowlan_war_offload_mdns_service_info_num ;i++)
11051 				{
11052 					u16 srv_rsp_len = 0;
11053 
11054 					// 1.1 : construct service name string
11055 					//	   : length of total service name string (service+transport+domain)
11056 					pframe[mdns_offset] = psinfo[i].service_len + psinfo[i].transport_len + psinfo[i].domain_len + 4;
11057 					mdns_offset += 1;
11058 
11059 					//	   :  service name
11060 					pframe[mdns_offset] = psinfo[i].service_len;
11061 					mdns_offset += 1;
11062 					_rtw_memcpy(pframe + mdns_offset, &psinfo[i].service, psinfo[i].service_len);
11063 					mdns_offset += psinfo[i].service_len;
11064 
11065 					//	   : transport name
11066 					pframe[mdns_offset] = psinfo[i].transport_len;
11067 					mdns_offset += 1;
11068 					_rtw_memcpy(pframe + mdns_offset, &psinfo[i].transport, psinfo[i].transport_len);
11069 					mdns_offset += psinfo[i].transport_len;
11070 
11071 					//	   : domain name
11072 					pframe[mdns_offset] = psinfo[i].domain_len;
11073 					mdns_offset += 1;
11074 					_rtw_memcpy(pframe + mdns_offset, &psinfo[i].domain, psinfo[i].domain_len);
11075 					mdns_offset += psinfo[i].domain_len;
11076 
11077 					//	   : delimiter
11078 					mdns_offset += 1;
11079 
11080 					// 1.2 : construct type srv rsp
11081 					pframe[mdns_offset] = psinfo[i].target_len + 19; // length
11082 					pframe[mdns_offset + 2] = 0x21; // rsp type (srv)
11083 					pframe[mdns_offset + 4] = 0x01; // cache flush + class
11084 					_rtw_memcpy(pframe + mdns_offset + 5, &psinfo[i].ttl, 4); // ttl
11085 					pframe[mdns_offset + 5] = (u8) ( (psinfo[i].ttl & 0xff000000) >> 24);	// ttl - byte0
11086 					pframe[mdns_offset + 6] = (u8) ( (psinfo[i].ttl & 0x00ff0000) >> 16);	// ttl - byte1
11087 					pframe[mdns_offset + 7] = (u8) ( (psinfo[i].ttl & 0x0000ff00) >> 8 );		// ttl - byte2
11088 					pframe[mdns_offset + 8] = (u8) (psinfo[i].ttl & 0x000000ff);			// ttl - byte3
11089 					pframe[mdns_offset + 10] = psinfo[i].target_len + 9;	  // data length
11090 					_rtw_memcpy(pframe + mdns_offset + 15, &psinfo[i].port, 2); // port
11091 					_rtw_memcpy(pframe + mdns_offset + 17, &psinfo[i].target_len, 1); // target len
11092 					_rtw_memcpy(pframe + mdns_offset + 18, &psinfo[i].target, psinfo[i].target_len); // target
11093 					pframe[mdns_offset + 18 + psinfo[i].target_len] = 0xc0; // message compresion, offset will be filled by fw.
11094 					mdns_offset += (1 + psinfo[i].target_len + 19);
11095 
11096 					// 1.3 : set the idx of txt rsp
11097 					pframe[mdns_offset] = psinfo[i].txt_rsp_idx;
11098 					mdns_offset += 1;
11099 				}
11100 
11101 				/* 2. machine name */
11102 				pframe[mdns_offset] = 0x02; // TLV(T)
11103 				mdns_offset += 1;
11104 				_rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_mnane_num, 1); // NUM
11105 				mdns_offset += 1;
11106 
11107 				for(i=0; i<pwrctl->wowlan_war_offload_mdns_mnane_num; i++)
11108 				{
11109 					pframe[mdns_offset] = pwrctl->wowlan_war_offload_mdns_mnane[i].name_len;
11110 					_rtw_memcpy(pframe + mdns_offset + 1, pwrctl->wowlan_war_offload_mdns_mnane[i].name,
11111 						pwrctl->wowlan_war_offload_mdns_mnane[i].name_len); // machine name
11112 					mdns_offset += (1+pwrctl->wowlan_war_offload_mdns_mnane[i].name_len);
11113 				}
11114 
11115 				/* 3. A rsp */
11116 				pframe[mdns_offset] = 0x03; // TLV(T)
11117 				pframe[mdns_offset + 1] = 14;	// TLV(L)
11118 				pframe[mdns_offset + 3] = 0x01; // rsp type (a)
11119 				pframe[mdns_offset + 5] = 0x01; // cache flush + class
11120 				pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec)
11121 				pframe[mdns_offset + 11] = 4;	// length of ipv4 addr.
11122 				_rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4);
11123 				mdns_offset += (2 + 14);
11124 
11125 				/* 4. AAAA rsp */
11126 				pframe[mdns_offset] = 0x04; // TLV(T)
11127 				pframe[mdns_offset + 1] = 26;	// TLV(L)
11128 				pframe[mdns_offset + 3] = 0x1c; // rsp type (aaaa)
11129 				pframe[mdns_offset + 5] = 0x01; // cache flush + class
11130 				pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec)
11131 				pframe[mdns_offset + 11] = 16;	// length of ipv6 addr.
11132 				_rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], 16);
11133 				mdns_offset += (2 + 26);
11134 
11135 				/* 5. PTR rsp */
11136 				pframe[mdns_offset] = 0x05; // TLV(T)
11137 				pframe[mdns_offset + 1] = 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // TLV(L)
11138 				pframe[mdns_offset + 3] = 0x0c; // rsp type (aaaa)
11139 				pframe[mdns_offset + 5] = 0x01; // cache flush + class
11140 				pframe[mdns_offset + 8] = 0x1c; // ttl
11141 				pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec)
11142 				pframe[mdns_offset + 11] = 3 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // data length
11143 				pframe[mdns_offset + 12] = pwrctl->wowlan_war_offload_mdns_domain_name_len; // domain name length
11144 				_rtw_memcpy(pframe + mdns_offset + 13, &pwrctl->wowlan_war_offload_mdns_domain_name,
11145 					pwrctl->wowlan_war_offload_mdns_domain_name_len);
11146 				pframe[mdns_offset + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len] = 0xc0; // message compression
11147 				mdns_offset += (2 + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len);
11148 
11149 				/* 6. TXT in PTR rsp */
11150 				pframe[mdns_offset] = 0x06; 		// TLV(T)
11151 				pframe[mdns_offset + 1] = 31;	// TLV(L)
11152 				_rtw_memcpy(pframe + mdns_offset + 2, &txt_in_ptr, 31);
11153 				mdns_offset += (2 + 31);
11154 
11155 				/* 7. TXT rsp */
11156 				pframe[mdns_offset] = 0x07; // TLV(T)
11157 				mdns_offset += 1;
11158 				_rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_txt_rsp_num, 1); // NUM
11159 				mdns_offset += 1;
11160 
11161 				for(i=0; i<pwrctl->wowlan_war_offload_mdns_txt_rsp_num; i++)
11162 				{
11163 					u16 txt_rsp_len = pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len;
11164 
11165 					if(pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len==0)
11166 					{
11167 						_rtw_memcpy(pframe + mdns_offset, &txt_rsp_len,  2);
11168 						mdns_offset += ( 2 + txt_rsp_len );
11169 						continue;
11170 					}
11171 
11172 					txt_rsp_len += 10;
11173 					_rtw_memcpy(pframe + mdns_offset, &txt_rsp_len,  2);
11174 					pframe[mdns_offset + 3] = 0x10; // rsp type (txt)
11175 					pframe[mdns_offset + 5] = 0x01; // cache flush + class
11176 					pframe[mdns_offset + 8] = 0x1c; // ttl
11177 					pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec)
11178 					pframe[mdns_offset + 10] = (u8) ((pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0xff00) >> 8);
11179 					pframe[mdns_offset + 11] = (u8) (pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0x00ff);
11180 						_rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt,
11181 							pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len);
11182 					mdns_offset  += ( 2 + txt_rsp_len );
11183 				}
11184 
11185 				CurtPktPageNum = (u8)PageNum(mdns_offset - index, page_size)+1;
11186 				*page_num += CurtPktPageNum;
11187 				*total_pkt_len = index + (page_size * CurtPktPageNum);
11188 				index += (CurtPktPageNum * page_size);
11189 			}
11190 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
11191 
11192 #ifdef CONFIG_OFFLOAD_MDNS_V4
11193 			if (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) {
11194 				rsvd_page_loc->LocMdnsv4 = *page_num;
11195 				RTW_INFO("LocMdnsv4: %d\n", rsvd_page_loc->LocMdnsv4);
11196 
11197 				rtw_hal_construct_mdns_rsp_v4(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr);
11198 				rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE);
11199 				CurtPktPageNum = 16;
11200 				*page_num += CurtPktPageNum;
11201 				index += (CurtPktPageNum * page_size);
11202 			}
11203 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
11204 
11205 #ifdef CONFIG_OFFLOAD_MDNS_V6
11206 			if (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) {
11207 				rsvd_page_loc->LocMdnsv6 = *page_num;
11208 				RTW_INFO("LocMdnsv6: %d\n", rsvd_page_loc->LocMdnsv6);
11209 
11210 				rtw_hal_construct_mdns_rsp_v6(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr);
11211 				rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE);
11212 				CurtPktPageNum = 16;
11213 				*page_num += CurtPktPageNum;
11214 				index += (CurtPktPageNum * page_size);
11215 			}
11216 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
11217 
11218 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
11219 			*(pframe+tmp_idx+25-tx_desc) = rsvd_page_loc->LocMdnsPara;
11220 			*(pframe+tmp_idx+26-tx_desc) = rsvd_page_loc->LocMdnsv4;
11221 			*(pframe+tmp_idx+27-tx_desc) = rsvd_page_loc->LocMdnsv6;
11222 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
11223 
11224 			}
11225 			//rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, rsvd_page_loc->LocIpParm, 46);
11226 #endif /* CONFIG_WAR_OFFLOAD */
11227 
11228 #if defined(CONFIG_WOW_PATTERN_IN_TXFIFO)
11229 		/* pattern_rsvd_page_loc will be used by rtw_read_from_frame_mask() */
11230 		pwrctl->pattern_rsvd_page_loc = *page_num;
11231 		RTW_INFO("LocPatternInfo: %d\n", pwrctl->pattern_rsvd_page_loc);
11232 		rtw_hal_construct_pattern_info(adapter,
11233 								&pframe[index - tx_desc],
11234 								&PatternLen);
11235 
11236 		/* Set cam_start_offset to REG_TXBUF_WKCAM_OFFSET
11237 		 * Cam address(TxBufer pointer) access 8 bytes at a time
11238 		 */
11239 
11240 		// Get rsvd page start page number + pattern located page
11241 		cam_start_offset = rtw_read8(adapter, REG_BCNQ_BDNY) + *page_num;
11242 		cam_start_offset *= page_size;
11243 		cam_start_offset /= 8;
11244 
11245 		reg_cam_start_offset_val = rtw_read32(adapter, REG_TXBUF_WKCAM_OFFSET);
11246 		reg_cam_start_offset_val &= ~(WKCAM_OFFSET_BIT_MASK << WKCAM_OFFSET_BIT_MASK_OFFSET);
11247 		reg_cam_start_offset_val |= (cam_start_offset << WKCAM_OFFSET_BIT_MASK_OFFSET);
11248 		rtw_write32(adapter, REG_TXBUF_WKCAM_OFFSET, reg_cam_start_offset_val);
11249 
11250 		/* Set pattern number to REG_WKFMCAM_NUM */
11251 		rtw_write8(adapter, REG_WKFMCAM_NUM, PatternLen / WKFMCAM_SIZE);
11252 
11253 		CurtPktPageNum = (u8)PageNum(PatternLen, page_size);
11254 		*page_num += CurtPktPageNum;
11255 		index += (CurtPktPageNum * page_size);
11256 		RSVD_PAGE_CFG("WOW-PatternInfo", CurtPktPageNum, *page_num, index);
11257 
11258 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
11259 
11260 		/*Reserve 1 page for AOAC report*/
11261 		rsvd_page_loc->LocAOACReport = *page_num;
11262 		RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
11263 		*page_num += 1;
11264 		*total_pkt_len = index + (page_size * 1);
11265 		RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
11266 
11267 
11268 	} else {
11269 #ifdef CONFIG_PNO_SUPPORT
11270 		if (pwrctl->wowlan_in_resume == _FALSE &&
11271 		    pwrctl->pno_inited == _TRUE) {
11272 
11273 			/* Broadcast Probe Request */
11274 			rsvd_page_loc->LocProbePacket = *page_num;
11275 
11276 			RTW_INFO("loc_probe_req: %d\n",
11277 				 rsvd_page_loc->LocProbePacket);
11278 
11279 			rtw_hal_construct_ProbeReq(
11280 				adapter,
11281 				&pframe[index],
11282 				&ProbeReqLength,
11283 				NULL);
11284 
11285 			rtw_hal_fill_fake_txdesc(adapter,
11286 						 &pframe[index - tx_desc],
11287 				 ProbeReqLength, _FALSE, _FALSE, _FALSE);
11288 
11289 			CurtPktPageNum =
11290 				(u8)PageNum(tx_desc + ProbeReqLength, page_size);
11291 
11292 			*page_num += CurtPktPageNum;
11293 
11294 			index += (CurtPktPageNum * page_size);
11295 			RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
11296 
11297 			/* Hidden SSID Probe Request */
11298 			ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
11299 
11300 			for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
11301 				pwrctl->pnlo_info->loc_probe_req[pno_index] =
11302 					*page_num;
11303 
11304 				rtw_hal_construct_ProbeReq(
11305 					adapter,
11306 					&pframe[index],
11307 					&ProbeReqLength,
11308 					&pwrctl->pno_ssid_list->node[pno_index]);
11309 
11310 				rtw_hal_fill_fake_txdesc(adapter,
11311 						 &pframe[index - tx_desc],
11312 					ProbeReqLength, _FALSE, _FALSE, _FALSE);
11313 
11314 				CurtPktPageNum =
11315 					(u8)PageNum(tx_desc + ProbeReqLength, page_size);
11316 
11317 				*page_num += CurtPktPageNum;
11318 
11319 				index += (CurtPktPageNum * page_size);
11320 				RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
11321 			}
11322 
11323 			/* PNO INFO Page */
11324 			rsvd_page_loc->LocPNOInfo = *page_num;
11325 			RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
11326 			rtw_hal_construct_PNO_info(adapter,
11327 						   &pframe[index - tx_desc],
11328 						   &PNOLength);
11329 
11330 			CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
11331 			*page_num += CurtPktPageNum;
11332 			index += (CurtPktPageNum * page_size);
11333 			RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
11334 
11335 			/* Scan Info Page */
11336 			rsvd_page_loc->LocScanInfo = *page_num;
11337 			RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
11338 			rtw_hal_construct_scan_info(adapter,
11339 						    &pframe[index - tx_desc],
11340 						    &ScanInfoLength);
11341 
11342 			CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
11343 			*page_num += CurtPktPageNum;
11344 			*total_pkt_len = index + ScanInfoLength;
11345 			index += (CurtPktPageNum * page_size);
11346 			RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
11347 		}
11348 #endif /* CONFIG_PNO_SUPPORT */
11349 	}
11350 }
11351 #endif /*CONFIG_WOWLAN*/
11352 
11353 #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)11354 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
11355 	      u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
11356 				      RSVDPAGE_LOC *rsvd_page_loc)
11357 {
11358 	u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
11359 	u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
11360 	u8 CurtPktPageNum = 0;
11361 
11362 	/* P2P Beacon */
11363 	rsvd_page_loc->LocP2PBeacon = *page_num;
11364 	rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
11365 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11366 				 P2PBCNLength, _FALSE, _FALSE, _FALSE);
11367 
11368 #if 0
11369 	RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
11370 		__FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
11371 #endif
11372 
11373 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
11374 
11375 	*page_num += CurtPktPageNum;
11376 
11377 	index += (CurtPktPageNum * page_size);
11378 	RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
11379 
11380 	/* P2P Probe rsp */
11381 	rsvd_page_loc->LocP2PProbeRsp = *page_num;
11382 	rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
11383 				      &P2PProbeRspLength);
11384 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11385 				 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
11386 
11387 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",  */
11388 	/*	__FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
11389 
11390 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
11391 
11392 	*page_num += CurtPktPageNum;
11393 
11394 	index += (CurtPktPageNum * page_size);
11395 	RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
11396 
11397 	/* P2P nego rsp */
11398 	rsvd_page_loc->LocNegoRsp = *page_num;
11399 	rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
11400 				     &P2PNegoRspLength);
11401 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11402 				 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
11403 
11404 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
11405 	/*	__FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
11406 
11407 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
11408 
11409 	*page_num += CurtPktPageNum;
11410 
11411 	index += (CurtPktPageNum * page_size);
11412 	RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
11413 
11414 	/* P2P invite rsp */
11415 	rsvd_page_loc->LocInviteRsp = *page_num;
11416 	rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
11417 				       &P2PInviteRspLength);
11418 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11419 				 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
11420 
11421 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
11422 	/* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
11423 
11424 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
11425 
11426 	*page_num += CurtPktPageNum;
11427 
11428 	index += (CurtPktPageNum * page_size);
11429 	RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
11430 
11431 	/* P2P provision discovery rsp */
11432 	rsvd_page_loc->LocPDRsp = *page_num;
11433 	rtw_hal_construct_P2PProvisionDisRsp(adapter,
11434 					     &pframe[index], &P2PPDRspLength);
11435 
11436 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11437 				 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
11438 
11439 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
11440 	/*	__FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
11441 
11442 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
11443 
11444 	*page_num += CurtPktPageNum;
11445 
11446 	*total_pkt_len = index + P2PPDRspLength;
11447 	RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
11448 
11449 	index += (CurtPktPageNum * page_size);
11450 
11451 
11452 }
11453 #endif /* CONFIG_P2P_WOWLAN */
11454 
11455 #ifdef CONFIG_LPS_PG
11456 #ifndef DBG_LPSPG_INFO_DUMP
11457 #define DBG_LPSPG_INFO_DUMP 1
11458 #endif
11459 
11460 #include "hal_halmac.h"
11461 
11462 #ifdef CONFIG_RTL8822C
rtw_lps_pg_set_dpk_info_rsvd_page(_adapter * adapter)11463 static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
11464 {
11465 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11466 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11467 	struct dm_struct *dm = adapter_to_phydm(adapter);
11468 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
11469 	u8 *info = NULL;
11470 	u32 info_len;
11471 	int ret = _FAIL;
11472 
11473 	/* get length */
11474 	halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
11475 	if (!info_len) {
11476 		RTW_ERR("get %s length fail\n", cache->name);
11477 		goto exit;
11478 	}
11479 
11480 	/* allocate buf */
11481 	info = rtw_zmalloc(info_len);
11482 	if (!info) {
11483 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11484 		goto exit;
11485 	}
11486 
11487 	/* get content */
11488 	halrf_dpk_info_rsvd_page(dm, info, NULL);
11489 
11490 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
11491 
11492 		#if (DBG_LPSPG_INFO_DUMP >= 1)
11493 		RTW_INFO_DUMP(cache->name, info, info_len);
11494 		#endif
11495 
11496 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11497 		ret = !ret ? _SUCCESS : _FAIL;
11498 		if (ret != _SUCCESS) {
11499 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11500 			goto free_mem;
11501 		}
11502 
11503 		#if (DBG_LPSPG_INFO_DUMP >= 2)
11504 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11505 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11506 		#endif
11507 	}
11508 
11509 free_mem:
11510 	rtw_mfree(info, info_len);
11511 
11512 exit:
11513 	return ret;
11514 }
11515 
rtw_lps_pg_set_iqk_info_rsvd_page(_adapter * adapter)11516 static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
11517 {
11518 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11519 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11520 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11521 	struct dm_struct *dm = adapter_to_phydm(adapter);
11522 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
11523 	u8 *info = NULL;
11524 	u32 info_len = 0;
11525 	int ret = _FAIL;
11526 
11527 	if (hal_data->RegIQKFWOffload) {
11528 		rsvd_page_cache_free_data(cache);
11529 		ret = _SUCCESS;
11530 		goto exit;
11531 	}
11532 
11533 	/* get length */
11534 	halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
11535 	if (!info_len) {
11536 		RTW_ERR("get %s length fail\n", cache->name);
11537 		goto exit;
11538 	}
11539 
11540 	/* allocate buf */
11541 	info = rtw_zmalloc(info_len);
11542 	if (!info) {
11543 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11544 		goto exit;
11545 	}
11546 
11547 	/* get content */
11548 	halrf_iqk_info_rsvd_page(dm, info, NULL);
11549 
11550 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
11551 
11552 		#if (DBG_LPSPG_INFO_DUMP >= 1)
11553 		RTW_INFO_DUMP(cache->name, info, info_len);
11554 		#endif
11555 
11556 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11557 		ret = !ret ? _SUCCESS : _FAIL;
11558 		if (ret != _SUCCESS) {
11559 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11560 			goto free_mem;
11561 		}
11562 
11563 		#if (DBG_LPSPG_INFO_DUMP >= 2)
11564 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11565 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11566 		#endif
11567 	}
11568 
11569 free_mem:
11570 	rtw_mfree(info, info_len);
11571 
11572 exit:
11573 	return ret;
11574 }
11575 #endif /* CONFIG_RTL8822C */
11576 
rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv * dvobj,_adapter * ld_sta_iface,u8 * buf,u32 * buf_size)11577 static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size)
11578 {
11579 #define LPS_PG_INFO_RSVD_LEN	16
11580 
11581 	if (buf) {
11582 		_adapter *adapter = dvobj_get_primary_adapter(dvobj);
11583 		struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11584 		struct sta_info *psta;
11585 #ifdef CONFIG_MBSSID_CAM
11586 		u8 cam_id = INVALID_CAM_ID;
11587 #endif
11588 		u8 *psec_cam_id = buf + 8;
11589 		u8 sec_cam_num = 0;
11590 		u8 drv_rsvdpage_num = 0;
11591 
11592 		if (ld_sta_iface) {
11593 			psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv));
11594 			if (!psta) {
11595 				RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
11596 				rtw_warn_on(1);
11597 				goto size_chk;
11598 			}
11599 			/*Byte 0 - used macid*/
11600 			LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
11601 			RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
11602 		}
11603 
11604 #ifdef CONFIG_MBSSID_CAM
11605 		/*Byte 1 - used BSSID CAM entry*/
11606 		cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
11607 		if (cam_id != INVALID_CAM_ID)
11608 			LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
11609 		RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
11610 #endif
11611 
11612 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
11613 		/*Btye 2 - Max used Pattern Match CAM entry*/
11614 		if (pwrpriv->wowlan_mode == _TRUE
11615 			&& ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11616 			LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
11617 			RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
11618 		}
11619 #endif
11620 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
11621 		/*Btye 3 - Max MU rate table Group ID*/
11622 		LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
11623 		RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
11624 #endif
11625 
11626 		/*Btye 8 ~15 - used Security CAM entry */
11627 		sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
11628 
11629 		/*Btye 4 - used Security CAM entry number*/
11630 		if (sec_cam_num < 8)
11631 			LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
11632 		RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
11633 
11634 		/*Btye 5 - Txbuf used page number for fw offload*/
11635 		if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
11636 			drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11637 		else
11638 			drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11639 		LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
11640 		RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
11641 	}
11642 
11643 size_chk:
11644 	if (buf_size)
11645 		*buf_size = LPS_PG_INFO_RSVD_LEN;
11646 }
11647 
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)11648 static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
11649 {
11650 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11651 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11652 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
11653 	u8 *info = NULL;
11654 	u32 info_len = 0;
11655 	int ret = _FAIL;
11656 
11657 	/* get length */
11658 	rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len);
11659 	if (!info_len) {
11660 		RTW_ERR("get %s length fail\n", cache->name);
11661 		goto exit;
11662 	}
11663 
11664 	/* allocate buf */
11665 	info = rtw_zmalloc(info_len);
11666 	if (!info) {
11667 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11668 		goto exit;
11669 	}
11670 
11671 	/* get content */
11672 	rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL);
11673 
11674 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
11675 
11676 		#if (DBG_LPSPG_INFO_DUMP >= 1)
11677 		RTW_INFO_DUMP(cache->name, info, info_len);
11678 		#endif
11679 
11680 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11681 		ret = !ret ? _SUCCESS : _FAIL;
11682 		if (ret != _SUCCESS) {
11683 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11684 			goto free_mem;
11685 		}
11686 
11687 		#if (DBG_LPSPG_INFO_DUMP >= 2)
11688 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11689 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11690 		#endif
11691 	}
11692 
11693 free_mem:
11694 	rtw_mfree(info, info_len);
11695 
11696 exit:
11697 	return ret;
11698 }
11699 
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)11700 static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
11701 	, u8 txdesc_size, u32 page_size, u8 *total_page_num
11702 	, bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num)
11703 {
11704 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11705 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
11706 	struct rsvd_page_cache_t *cache;
11707 	bool rsvd = 1;
11708 	u8 *pos;
11709 	u32 len;
11710 
11711 	if (is_wow_mode) {
11712 		/* lps_level will not change when enter wow_mode */
11713 		if (pwrctl->lps_level != LPS_PG)
11714 			rsvd = 0;
11715 	} else {
11716 		if (!only_get_page_num && !ld_sta_iface)
11717 			rsvd = 0;
11718 	}
11719 
11720 	pos = only_get_page_num ? NULL : frame + *index;
11721 
11722 #ifdef CONFIG_RTL8822C
11723 	if (IS_8822C_SERIES(hal_data->version_id)) {
11724 		/* LPSPG_DPK_INFO */
11725 		cache = &pwrctl->lpspg_dpk_info;
11726 		if (rsvd) {
11727 			if (pwrctl->lps_level != LPS_PG)
11728 				pos = NULL;
11729 			len = 0;
11730 			halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
11731 			#if (DBG_LPSPG_INFO_DUMP >= 1)
11732 			if (pos)
11733 				RTW_INFO_DUMP(cache->name, pos, len);
11734 			#endif
11735 			rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11736 			*total_page_num += cache->page_num;
11737 			*index += page_size * cache->page_num;
11738 			pos = only_get_page_num ? NULL : frame + *index;
11739 			RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11740 		} else
11741 			rsvd_page_cache_free(cache);
11742 
11743 		/* LPSPG_IQK_INFO */
11744 		cache = &pwrctl->lpspg_iqk_info;
11745 		if (rsvd
11746 			/* RegIQKFWOffload will not change when enter wow_mode */
11747 			&& !(is_wow_mode && hal_data->RegIQKFWOffload)
11748 		) {
11749 			if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
11750 				pos = NULL;
11751 			len = 0;
11752 			halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
11753 			#if (DBG_LPSPG_INFO_DUMP >= 1)
11754 			if (pos)
11755 				RTW_INFO_DUMP(cache->name, pos, len);
11756 			#endif
11757 			rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11758 			*total_page_num += cache->page_num;
11759 			*index += page_size * cache->page_num;
11760 			pos = only_get_page_num ? NULL : frame + *index;
11761 			RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11762 		} else
11763 			rsvd_page_cache_free(cache);
11764 	}
11765 #endif
11766 
11767 	/* LPSPG_INFO */
11768 	cache = &pwrctl->lpspg_info;
11769 	if (rsvd) {
11770 		if (pwrctl->lps_level != LPS_PG)
11771 			pos = NULL;
11772 		rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len);
11773 		#if (DBG_LPSPG_INFO_DUMP >= 1)
11774 		if (pos)
11775 			RTW_INFO_DUMP(cache->name, pos, len);
11776 		#endif
11777 		rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11778 		*total_page_num += cache->page_num;
11779 		*index += page_size * cache->page_num;
11780 		pos = only_get_page_num ? NULL : frame + *index;
11781 		RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11782 	} else
11783 		rsvd_page_cache_free(cache);
11784 }
11785 
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)11786 u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
11787 {
11788 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11789 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11790 
11791 	u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
11792 	u8 ret = _FAIL;
11793 
11794 	if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
11795 		SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1);	/*SecurityCAM_En*/
11796 
11797 #ifdef CONFIG_MBSSID_CAM
11798 	SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1);		/*BSSIDCAM_En*/
11799 #endif
11800 
11801 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
11802 	if (pwrpriv->wowlan_mode == _TRUE &&
11803 	    check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11804 
11805 		SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1);	/*PatternMatchCAM_En*/
11806 	}
11807 #endif
11808 
11809 #ifdef CONFIG_MACID_SEARCH
11810 	SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1);	/*MACIDSearch_En*/
11811 #endif
11812 
11813 #ifdef CONFIG_TX_SC
11814 	SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1);	/*TXSC_En*/
11815 #endif
11816 
11817 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
11818 	SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1);	/*MURateTable_En*/
11819 #endif
11820 
11821 	SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
11822 
11823 #ifdef CONFIG_RTL8822C
11824 	if (pwrpriv->bFwCurrentInPSMode == _FALSE) {
11825 		SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
11826 		if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11827 			SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
11828 	} else {
11829 		SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0);
11830 		if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11831 			SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0);
11832 	}
11833 #endif
11834 
11835 #if (DBG_LPSPG_INFO_DUMP >= 1)
11836 	RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
11837 #endif
11838 
11839 	ret = rtw_hal_fill_h2c_cmd(adapter,
11840 				   H2C_LPS_PG_INFO,
11841 				   H2C_LPS_PG_INFO_LEN,
11842 				   lpspg_info);
11843 	return ret;
11844 }
rtw_hal_set_lps_pg_info(_adapter * adapter)11845 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
11846 {
11847 	u8 ret = _FAIL;
11848 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11849 
11850 	if (pwrpriv->lpspg_info.loc == 0) {
11851 		RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
11852 		rtw_warn_on(1);
11853 		return ret;
11854 	}
11855 	#ifdef CONFIG_RTL8822C
11856 	rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
11857 	rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
11858 	#endif
11859 	rtw_hal_set_lps_pg_info_rsvd_page(adapter);
11860 
11861 	ret = rtw_hal_set_lps_pg_info_cmd(adapter);
11862 
11863 	return ret;
11864 }
11865 
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)11866 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
11867 {
11868 #if 0
11869 	if (sta->cmn.ra_info.rssi_level >= 4)
11870 		sta->lps_pg_rssi_lv = 3;	/*RSSI High - 1SS_VHT_MCS7*/
11871 	else if (sta->cmn.ra_info.rssi_level >=  2)
11872 		sta->lps_pg_rssi_lv = 2;	/*RSSI Middle - 1SS_VHT_MCS3*/
11873 	else
11874 		sta->lps_pg_rssi_lv = 1;	/*RSSI Lower - Lowest_rate*/
11875 #else
11876 	sta->lps_pg_rssi_lv = 0;
11877 #endif
11878 	RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
11879 		__func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
11880 }
11881 
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)11882 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
11883 {
11884 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
11885 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11886 	struct sta_priv *pstapriv = &adapter->stapriv;
11887 	struct sta_info *sta;
11888 
11889 	sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
11890 
11891 	switch (hdl_id) {
11892 	case LPS_PG_INFO_CFG:
11893 		rtw_hal_set_lps_pg_info(adapter);
11894 		break;
11895 	case LPS_PG_REDLEMEM:
11896 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11897 			break;
11898 
11899 		/*set xmit_block*/
11900 		rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11901 		if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
11902 			rtw_warn_on(1);
11903 		/*clearn xmit_block*/
11904 		rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11905 		break;
11906 	case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
11907 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11908 			break;
11909 
11910 		if (sta)
11911 			rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
11912 		break;
11913 	case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
11914 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11915 			break;
11916 
11917 		if (sta) {
11918 			rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
11919 			rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
11920 			sta->lps_pg_rssi_lv = 0;
11921 		}
11922 		break;
11923 
11924 	default:
11925 		break;
11926 	}
11927 }
11928 
11929 #endif /*CONFIG_LPS_PG*/
11930 
_rtw_mi_assoc_if_num(_adapter * adapter)11931 static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
11932 {
11933 	u8 mi_iface_num = 0;
11934 
11935 	if (0) {
11936 		RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
11937 		RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
11938 		RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11939 		RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
11940 		RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
11941 		/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
11942 		/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
11943 	}
11944 
11945 	mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
11946 		DEV_AP_NUM(adapter_to_dvobj(adapter)) +
11947 		DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11948 	return mi_iface_num;
11949 }
11950 #ifdef CONFIG_CONCURRENT_MODE
_rtw_search_sta_iface(_adapter * adapter)11951 static _adapter *_rtw_search_sta_iface(_adapter *adapter)
11952 {
11953 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11954 	_adapter *iface = NULL;
11955 	_adapter *sta_iface = NULL;
11956 	int i;
11957 
11958 	for (i = 0; i < dvobj->iface_nums; i++) {
11959 		iface = dvobj->padapters[i];
11960 		if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
11961 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11962 				sta_iface = iface;
11963 				break;
11964 			}
11965 		}
11966 	}
11967 	return sta_iface;
11968 }
11969 #if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
_rtw_search_ap_iface(_adapter * adapter)11970 static _adapter *_rtw_search_ap_iface(_adapter *adapter)
11971 {
11972 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11973 	_adapter *iface = NULL;
11974 	_adapter *ap_iface = NULL;
11975 	int i;
11976 
11977 	for (i = 0; i < dvobj->iface_nums; i++) {
11978 		iface = dvobj->padapters[i];
11979 		if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
11980 			ap_iface = iface;
11981 			break;
11982 		}
11983 	}
11984 	return ap_iface;
11985 }
11986 #endif/*CONFIG_AP_MODE*/
11987 #endif/*CONFIG_CONCURRENT_MODE*/
11988 
11989 #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
rtw_hal_set_pathb_phase(_adapter * adapter,u8 phase_idx)11990 void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
11991 {
11992 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(adapter);
11993 	struct PHY_DM_STRUCT		*pDM_Odm = &pHalData->odmpriv;
11994 
11995 	return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
11996 }
11997 #endif
11998 
11999 /*
12000  * Description: Fill the reserved packets that FW will use to RSVD page.
12001  *			Now we just send 4 types packet to rsvd page.
12002  *			(1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
12003  * Input:
12004  * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
12005  *		    so we need to set the packet length to total lengh.
12006  *	      TRUE: At the second time, we should send the first packet (default:beacon)
12007  *		    to Hw again and set the lengh in descriptor to the real beacon lengh.
12008  * page_num - The amount of reserved page which driver need.
12009  *	      If this is not NULL, this function doesn't real download reserved
12010  *	      page, but just count the number of reserved page.
12011  *
12012  * 2009.10.15 by tynli.
12013  * 2017.06.20 modified by Lucas.
12014  *
12015  * Page Size = 128: 8188e, 8723a/b, 8192c/d,
12016  * Page Size = 256: 8192e, 8821a
12017  * Page Size = 512: 8812a
12018  */
12019 
12020 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)12021 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
12022 {
12023 	PHAL_DATA_TYPE pHalData;
12024 	struct xmit_frame	*pcmdframe = NULL;
12025 	struct pkt_attrib	*pattrib;
12026 	struct xmit_priv	*pxmitpriv;
12027 	struct pwrctrl_priv *pwrctl;
12028 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12029 	u32	BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
12030 	u32	NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
12031 	u32	ProbeReqLength = 0, NullFunctionDataLength = 0;
12032 	u8	TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
12033 	u8	TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
12034 	u8	*ReservedPagePacket;
12035 	u16	BufIndex = 0;
12036 	u32	TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
12037 	RSVDPAGE_LOC	RsvdPageLoc;
12038 	struct registry_priv  *registry_par = &adapter->registrypriv;
12039 
12040 #ifdef DBG_FW_DEBUG_MSG_PKT
12041 	u32	fw_dbg_msg_pkt_len = 0;
12042 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12043 
12044 #ifdef DBG_CONFIG_ERROR_DETECT
12045 	struct sreset_priv *psrtpriv;
12046 #endif /* DBG_CONFIG_ERROR_DETECT */
12047 
12048 #ifdef CONFIG_MCC_MODE
12049 	u8 dl_mcc_page = _FAIL;
12050 #endif /* CONFIG_MCC_MODE */
12051 	u8 nr_assoc_if;
12052 
12053 	_adapter *sta_iface = NULL;
12054 	_adapter *ap_iface = NULL;
12055 
12056 	bool is_wow_mode = _FALSE;
12057 
12058 	pHalData = GET_HAL_DATA(adapter);
12059 #ifdef DBG_CONFIG_ERROR_DETECT
12060 	psrtpriv = &pHalData->srestpriv;
12061 #endif
12062 	pxmitpriv = &adapter->xmitpriv;
12063 	pwrctl = adapter_to_pwrctl(adapter);
12064 
12065 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
12066 
12067 	if (PageSize == 0) {
12068 		RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
12069 		return;
12070 	}
12071 	nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
12072 
12073 	if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
12074 		pwrctl->wowlan_ap_mode == _TRUE ||
12075 		pwrctl->wowlan_p2p_mode == _TRUE)
12076 		is_wow_mode = _TRUE;
12077 
12078 	/*page_num for init time to get rsvd page number*/
12079 	/* Prepare ReservedPagePacket */
12080 	if (page_num) {
12081 		ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
12082 		if (!ReservedPagePacket) {
12083 			RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
12084 			*page_num = 0xFF;
12085 			return;
12086 		}
12087 		RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm  ==>\n",
12088 			FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
12089 
12090 	} else {
12091 		if (is_wow_mode)
12092 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
12093 		else
12094 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
12095 
12096 		RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
12097 			FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
12098 
12099 		MaxRsvdPageBufSize = RsvdPageNum * PageSize;
12100 		if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
12101 			RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
12102 				 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
12103 			rtw_warn_on(1);
12104 			return;
12105 		}
12106 
12107 		pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
12108 		if (pcmdframe == NULL) {
12109 			RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
12110 			return;
12111 		}
12112 
12113 		ReservedPagePacket = pcmdframe->buf_addr;
12114 	}
12115 
12116 	_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
12117 
12118 	BufIndex = TxDescOffset;
12119 
12120 	/*======== beacon content =======*/
12121 	rtw_hal_construct_beacon(adapter,
12122 				 &ReservedPagePacket[BufIndex], &BeaconLength);
12123 
12124 	/*
12125 	* When we count the first page size, we need to reserve description size for the RSVD
12126 	* packet, it will be filled in front of the packet in TXPKTBUF.
12127 	*/
12128 	BeaconLength = MAX_BEACON_LEN - TxDescLen;
12129 	CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
12130 
12131 #if defined(CONFIG_FW_HANDLE_TXBCN) || defined(CONFIG_PORT_BASED_TXBCN)
12132 	CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
12133 #endif
12134 	TotalPageNum += CurtPktPageNum;
12135 
12136 	BufIndex += (CurtPktPageNum * PageSize);
12137 
12138 	RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12139 
12140 	/*======== probe response content ========*/
12141 	if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
12142 		#ifdef CONFIG_CONCURRENT_MODE
12143 		if (nr_assoc_if >= 2)
12144 			RTW_ERR("Not support > 2 net-interface in WOW\n");
12145 		#endif
12146 		/* (4) probe response*/
12147 		RsvdPageLoc.LocProbeRsp = TotalPageNum;
12148 		rtw_hal_construct_ProbeRsp(
12149 			adapter, &ReservedPagePacket[BufIndex],
12150 			&ProbeRspLength,
12151 			_FALSE);
12152 		rtw_hal_fill_fake_txdesc(adapter,
12153 				 &ReservedPagePacket[BufIndex - TxDescLen],
12154 				 ProbeRspLength, _FALSE, _FALSE, _FALSE);
12155 
12156 		CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
12157 		TotalPageNum += CurtPktPageNum;
12158 		TotalPacketLen = BufIndex + ProbeRspLength;
12159 		BufIndex += (CurtPktPageNum * PageSize);
12160 		RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12161 		goto download_page;
12162 	}
12163 
12164 	/*======== ps-poll content * 1 page ========*/
12165 	sta_iface = adapter;
12166 	#ifdef CONFIG_CONCURRENT_MODE
12167 	if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
12168 		sta_iface = _rtw_search_sta_iface(adapter);
12169 		RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
12170 	}
12171 	#endif
12172 
12173 	if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12174 		RsvdPageLoc.LocPsPoll = TotalPageNum;
12175 		RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
12176 		rtw_hal_construct_PSPoll(sta_iface,
12177 					 &ReservedPagePacket[BufIndex], &PSPollLength);
12178 		rtw_hal_fill_fake_txdesc(sta_iface,
12179 					 &ReservedPagePacket[BufIndex - TxDescLen],
12180 					 PSPollLength, _TRUE, _FALSE, _FALSE);
12181 
12182 		CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
12183 
12184 		TotalPageNum += CurtPktPageNum;
12185 
12186 		BufIndex += (CurtPktPageNum * PageSize);
12187 		RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12188 	}
12189 
12190 #ifdef CONFIG_MCC_MODE
12191 	/*======== MCC * n page ======== */
12192 	if (MCC_EN(adapter)) {/*Normal mode*/
12193 		dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
12194 				&BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
12195 	} else {
12196 		dl_mcc_page = _FAIL;
12197 	}
12198 
12199 	if (dl_mcc_page == _FAIL)
12200 #endif /* CONFIG_MCC_MODE */
12201 	{	/*======== null data * 1 page ======== */
12202 		if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12203 			RsvdPageLoc.LocNullData = TotalPageNum;
12204 			RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
12205 			rtw_hal_construct_NullFunctionData(
12206 				sta_iface,
12207 				&ReservedPagePacket[BufIndex],
12208 				&NullDataLength,
12209 				_FALSE, 0, 0, _FALSE);
12210 			rtw_hal_fill_fake_txdesc(sta_iface,
12211 				 &ReservedPagePacket[BufIndex - TxDescLen],
12212 				 NullDataLength, _FALSE, _FALSE, _FALSE);
12213 
12214 			CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
12215 
12216 			TotalPageNum += CurtPktPageNum;
12217 
12218 			BufIndex += (CurtPktPageNum * PageSize);
12219 			RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12220 		}
12221 	}
12222 
12223 	/*======== Qos null data * 1 page ======== */
12224 	if (pwrctl->wowlan_mode == _FALSE ||
12225 		pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
12226 		if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12227 			RsvdPageLoc.LocQosNull = TotalPageNum;
12228 			RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
12229 			rtw_hal_construct_NullFunctionData(sta_iface,
12230 						&ReservedPagePacket[BufIndex],
12231 						&QosNullLength,
12232 						_TRUE, 0, 0, _FALSE);
12233 			rtw_hal_fill_fake_txdesc(sta_iface,
12234 					 &ReservedPagePacket[BufIndex - TxDescLen],
12235 					 QosNullLength, _FALSE, _FALSE, _FALSE);
12236 
12237 			CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
12238 						     PageSize);
12239 
12240 			TotalPageNum += CurtPktPageNum;
12241 
12242 			BufIndex += (CurtPktPageNum * PageSize);
12243 			RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12244 		}
12245 	}
12246 
12247 #ifdef CONFIG_BT_COEXIST
12248 	/*======== BT Qos null data * 1 page ======== */
12249 	if (pwrctl->wowlan_mode == _FALSE ||
12250 		pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
12251 
12252 		ap_iface = adapter;
12253 		#if defined (CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
12254 		if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) {	/*DEV_AP_STARTING_NUM*/
12255 			ap_iface = _rtw_search_ap_iface(adapter);
12256 			RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
12257 		}
12258 		#endif
12259 
12260 		if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
12261 			RsvdPageLoc.LocBTQosNull = TotalPageNum;
12262 
12263 			RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
12264 
12265 			rtw_hal_construct_NullFunctionData(ap_iface,
12266 						&ReservedPagePacket[BufIndex],
12267 						&BTQosNullLength,
12268 						_TRUE, 0, 0, _FALSE);
12269 
12270 			rtw_hal_fill_fake_txdesc(ap_iface,
12271 					&ReservedPagePacket[BufIndex - TxDescLen],
12272 					BTQosNullLength, _FALSE, _TRUE, _FALSE);
12273 
12274 			CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
12275 							 PageSize);
12276 
12277 			TotalPageNum += CurtPktPageNum;
12278 			BufIndex += (CurtPktPageNum * PageSize);
12279 
12280 			RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12281 		}
12282 	}
12283 #endif /* CONFIG_BT_COEXIT */
12284 
12285 	TotalPacketLen = BufIndex;
12286 
12287 #ifdef DBG_FW_DEBUG_MSG_PKT
12288 		/*======== FW DEBUG MSG * n page ======== */
12289 		RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
12290 		RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
12291 		rtw_hal_construct_fw_dbg_msg_pkt(
12292 			adapter,
12293 			&ReservedPagePacket[BufIndex],
12294 			&fw_dbg_msg_pkt_len);
12295 
12296 		rtw_hal_fill_fake_txdesc(adapter,
12297 				 &ReservedPagePacket[BufIndex - TxDescLen],
12298 				 fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
12299 
12300 		CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
12301 
12302 		if (CurtPktPageNum < 2)
12303 			CurtPktPageNum = 2; /*Need at least 2 rsvd page*/
12304 		TotalPageNum += CurtPktPageNum;
12305 
12306 		TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
12307 		BufIndex += (CurtPktPageNum * PageSize);
12308 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12309 
12310 #ifdef CONFIG_LPS_PG
12311 	rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
12312 		, TxDescLen, PageSize, &TotalPageNum, is_wow_mode
12313 		, (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL
12314 		, page_num ? 1 : 0
12315 	);
12316 	TotalPacketLen = BufIndex;
12317 #endif
12318 
12319 #ifdef CONFIG_WOWLAN
12320 	/*======== WOW * n page ======== */
12321 	if (pwrctl->wowlan_mode == _TRUE &&
12322 		pwrctl->wowlan_in_resume == _FALSE &&
12323 		check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {/*WOW mode*/
12324 		rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
12325 					     BufIndex, TxDescLen, PageSize,
12326 			     &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
12327 #ifdef CONFIG_WAR_OFFLOAD
12328 		rtw_hal_set_war_offload_parm(adapter, &RsvdPageLoc);
12329 #endif /* CONFIG_WAR_OFFLOAD */
12330 	}
12331 #endif /* CONFIG_WOWLAN */
12332 
12333 #ifdef CONFIG_P2P_WOWLAN
12334 	/*======== P2P WOW * n page ======== */
12335 	if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
12336 		rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
12337 						 BufIndex, TxDescLen, PageSize,
12338 				 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
12339 	}
12340 #endif /* CONFIG_P2P_WOWLAN */
12341 
12342 	/*Note:  BufIndex already add a TxDescOffset offset in first Beacon page
12343 	* The "TotalPacketLen" is calculate by BufIndex.
12344 	* We need to decrease TxDescOffset before doing length check. by yiwei
12345 	*/
12346 	TotalPacketLen = TotalPacketLen - TxDescOffset;
12347 
12348 download_page:
12349 	if (page_num) {
12350 		*page_num = TotalPageNum;
12351 		rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
12352 		ReservedPagePacket = NULL;
12353 		RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
12354 			FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
12355 		return;
12356 	}
12357 
12358 	/* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
12359 	RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
12360 		 __func__, TotalPageNum, TotalPacketLen);
12361 
12362 	if (TotalPacketLen > MaxRsvdPageBufSize) {
12363 		RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
12364 			 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
12365 		rtw_warn_on(1);
12366 		goto error;
12367 	} else {
12368 		/* update attribute */
12369 		pattrib = &pcmdframe->attrib;
12370 		update_mgntframe_attrib(adapter, pattrib);
12371 		pattrib->qsel = QSLT_BEACON;
12372 		pattrib->pktlen = TotalPacketLen;
12373 		pattrib->last_txcmdsz = TotalPacketLen;
12374 #ifdef CONFIG_PCI_HCI
12375 		dump_mgntframe(adapter, pcmdframe);
12376 #else
12377 		dump_mgntframe_and_wait(adapter, pcmdframe, 100);
12378 #endif
12379 	}
12380 
12381 	RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
12382 		 __func__, TotalPacketLen, TotalPageNum);
12383 #ifdef DBG_DUMP_SET_RSVD_PAGE
12384 	RTW_INFO(" ==================================================\n");
12385 	RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
12386 	RTW_INFO(" ==================================================\n");
12387 #endif
12388 
12389 
12390 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
12391 		|| MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
12392 		rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
12393 #ifdef DBG_FW_DEBUG_MSG_PKT
12394 		rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
12395 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12396 #ifdef CONFIG_WOWLAN
12397 		if (pwrctl->wowlan_mode == _TRUE &&
12398 			pwrctl->wowlan_in_resume == _FALSE)
12399 			rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
12400 #endif /* CONFIG_WOWLAN */
12401 #ifdef CONFIG_AP_WOWLAN
12402 		if (pwrctl->wowlan_ap_mode == _TRUE)
12403 			rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
12404 #endif /* CONFIG_AP_WOWLAN */
12405 	} else if (pwrctl->wowlan_pno_enable) {
12406 #ifdef CONFIG_PNO_SUPPORT
12407 		rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
12408 		if (pwrctl->wowlan_in_resume)
12409 			rtw_hal_set_scan_offload_info_cmd(adapter,
12410 							  &RsvdPageLoc, 0);
12411 		else
12412 			rtw_hal_set_scan_offload_info_cmd(adapter,
12413 							  &RsvdPageLoc, 1);
12414 #endif /* CONFIG_PNO_SUPPORT */
12415 	}
12416 
12417 #ifdef CONFIG_P2P_WOWLAN
12418 	if (_TRUE == pwrctl->wowlan_p2p_mode)
12419 		rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
12420 #endif /* CONFIG_P2P_WOWLAN */
12421 
12422 	return;
12423 error:
12424 	rtw_free_xmitframe(pxmitpriv, pcmdframe);
12425 }
12426 
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)12427 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
12428 {
12429 #ifdef CONFIG_AP_MODE
12430 	if (finished)
12431 		rtw_mi_tx_beacon_hdl(adapter);
12432 	else
12433 #endif
12434 		_rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
12435 }
12436 
rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER * adapter,u8 enable)12437 static u8 rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER *adapter, u8 enable)
12438 {
12439 	u8	u1H2CSetPwrMode[H2C_PWRMODE_LEN] = {0};
12440 	u8	ret = _FAIL;
12441 
12442 #ifdef CONFIG_TDLS
12443 #ifdef CONFIG_TDLS_CH_SW
12444 	if (ATOMIC_READ(&adapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12445 	{
12446 		SET_H2CCMD_PWRMODE_PARM_RLBM(u1H2CSetPwrMode, 1);
12447 		SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, 0);
12448 	}
12449 #endif
12450 #endif
12451 
12452 	SET_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, 0);
12453 	SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CSetPwrMode, 0x0C);
12454 	SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_C2H_RPT(u1H2CSetPwrMode, enable);
12455 
12456 	ret = rtw_hal_fill_h2c_cmd(adapter,
12457 					H2C_SET_PWR_MODE,
12458 					H2C_PWRMODE_LEN,
12459 					u1H2CSetPwrMode);
12460 
12461 	RTW_PRINT("-%s()-\n", __func__);
12462 
12463 	return ret;
12464 }
12465 
12466 /**
12467  * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
12468  * @adapter:	struct _ADAPTER*
12469  *
12470  * Caculate needed reserved page number.
12471  * In different state would get different number, for example normal mode and
12472  * WOW mode would need different reserved page size.
12473  *
12474  * Return the number of reserved page which driver need.
12475  */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)12476 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
12477 {
12478 	u8 num = 0;
12479 
12480 
12481 	_rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
12482 
12483 	return num;
12484 }
12485 
12486 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
hw_var_set_bcn_func(_adapter * adapter,u8 enable)12487 static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
12488 {
12489 	u32 bcn_ctrl_reg;
12490 
12491 #ifdef CONFIG_CONCURRENT_MODE
12492 	if (adapter->hw_port == HW_PORT1)
12493 		bcn_ctrl_reg = REG_BCN_CTRL_1;
12494 	else
12495 #endif
12496 		bcn_ctrl_reg = REG_BCN_CTRL;
12497 
12498 	if (enable)
12499 		rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
12500 	else {
12501 		u8 val8;
12502 
12503 		val8 = rtw_read8(adapter, bcn_ctrl_reg);
12504 		val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
12505 
12506 #ifdef CONFIG_BT_COEXIST
12507 		if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
12508 			/* Always enable port0 beacon function for PSTDMA */
12509 			if (REG_BCN_CTRL == bcn_ctrl_reg)
12510 				val8 |= EN_BCN_FUNCTION;
12511 		}
12512 #endif
12513 
12514 		rtw_write8(adapter, bcn_ctrl_reg, val8);
12515 	}
12516 
12517 #ifdef CONFIG_RTL8192F
12518 	if (IS_HARDWARE_TYPE_8192F(adapter)) {
12519 		u16 val16, val16_ori;
12520 
12521 		val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
12522 
12523 		#ifdef CONFIG_CONCURRENT_MODE
12524 		if (adapter->hw_port == HW_PORT1) {
12525 			if (enable)
12526 				val16 |= EN_PORT_1_FUNCTION;
12527 			else
12528 				val16 &= ~EN_PORT_1_FUNCTION;
12529 		} else
12530 		#endif
12531 		{
12532 			if (enable)
12533 				val16 |= EN_PORT_0_FUNCTION;
12534 			else
12535 				val16 &= ~EN_PORT_0_FUNCTION;
12536 
12537 			#ifdef CONFIG_BT_COEXIST
12538 			if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
12539 				val16 |= EN_PORT_0_FUNCTION;
12540 			#endif
12541 		}
12542 
12543 		if (val16 != val16_ori)
12544 			rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1,  val16);
12545 	}
12546 #endif
12547 }
12548 #endif
12549 
12550 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
hw_var_set_mlme_disconnect(_adapter * adapter)12551 static void hw_var_set_mlme_disconnect(_adapter *adapter)
12552 {
12553 	u8 val8;
12554 
12555 	/* reject all data frames */
12556 #ifdef CONFIG_CONCURRENT_MODE
12557 	if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
12558 #endif
12559 		rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
12560 
12561 #ifdef CONFIG_CONCURRENT_MODE
12562 	if (adapter->hw_port == HW_PORT1) {
12563 		/* reset TSF1 */
12564 		rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
12565 
12566 		/* disable update TSF1 */
12567 		rtw_iface_disable_tsf_update(adapter);
12568 
12569 		if (!IS_HARDWARE_TYPE_8723D(adapter)
12570 			&& !IS_HARDWARE_TYPE_8192F(adapter)
12571 			&& !IS_HARDWARE_TYPE_8710B(adapter)
12572 		) {
12573 			/* disable Port1's beacon function */
12574 			val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
12575 			val8 &= ~EN_BCN_FUNCTION;
12576 			rtw_write8(adapter, REG_BCN_CTRL_1, val8);
12577 		}
12578 	} else
12579 #endif
12580 	{
12581 		/* reset TSF */
12582 		rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
12583 
12584 		/* disable update TSF */
12585 		rtw_iface_disable_tsf_update(adapter);
12586 	}
12587 }
12588 #endif
12589 
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 enable)12590 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
12591 {
12592 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12593 	u16 value_rxfltmap2;
12594 
12595 #ifdef DBG_IFACE_STATUS
12596 	DBG_IFACE_STATUS_DUMP(adapter);
12597 #endif
12598 
12599 #ifdef CONFIG_FIND_BEST_CHANNEL
12600 	/* Receive all data frames */
12601 	value_rxfltmap2 = 0xFFFF;
12602 #else
12603 	/* not to receive data frame */
12604 	value_rxfltmap2 = 0;
12605 #endif
12606 
12607 	if (enable) { /* under sitesurvey */
12608 		/*
12609 		* 1. configure REG_RXFLTMAP2
12610 		* 2. disable TSF update &  buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
12611 		* 3. config RCR to receive different BSSID BCN or probe rsp
12612 		*/
12613 		rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
12614 
12615 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
12616 
12617 		/* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
12618 		#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
12619 		hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
12620 		hal_data->RegRRSR &= 0x000FFFFF;
12621 		#endif
12622 
12623 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
12624 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
12625 			/* set 718[1:0]=2'b00 to avoid BF scan hang */
12626 			hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
12627 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
12628 		}
12629 		#endif
12630 
12631 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12632 			StopTxBeacon(adapter);
12633 	} else { /* sitesurvey done */
12634 		/*
12635 		* 1. enable rx data frame
12636 		* 2. config RCR not to receive different BSSID BCN or probe rsp
12637 		* 3. doesn't enable TSF update &  buddy TSF right now to avoid HW conflict
12638 		*	 so, we enable TSF update when rx first BCN after sitesurvey done
12639 		*/
12640 		if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) {
12641 			/* enable to rx data frame */
12642 			rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12643 		}
12644 
12645 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
12646 
12647 		/* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
12648 		#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
12649 			rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
12650 		#endif
12651 
12652 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
12653 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
12654 			/* Restore orignal 0x718 setting*/
12655 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
12656 		}
12657 		#endif
12658 
12659 		#ifdef CONFIG_AP_MODE
12660 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12661 			ResumeTxBeacon(adapter);
12662 			rtw_mi_tx_beacon_hdl(adapter);
12663 		}
12664 		#endif
12665 	}
12666 }
12667 
12668 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
hw_var_set_mlme_join(_adapter * adapter,u8 type)12669 static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
12670 {
12671 	u8 val8;
12672 	u16 val16;
12673 	u32 val32;
12674 	u8 RetryLimit = RL_VAL_STA;
12675 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12676 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12677 
12678 #ifdef CONFIG_CONCURRENT_MODE
12679 	if (type == 0) {
12680 		/* prepare to join */
12681 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12682 			StopTxBeacon(adapter);
12683 
12684 		/* enable to rx data frame.Accept all data frame */
12685 		rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12686 
12687 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
12688 			RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
12689 		else /* Ad-hoc Mode */
12690 			RetryLimit = RL_VAL_AP;
12691 
12692 		rtw_iface_enable_tsf_update(adapter);
12693 
12694 	} else if (type == 1) {
12695 		/* joinbss_event call back when join res < 0 */
12696 		if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
12697 			rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
12698 
12699 		rtw_iface_disable_tsf_update(adapter);
12700 
12701 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12702 			ResumeTxBeacon(adapter);
12703 
12704 			/* reset TSF 1/2 after ResumeTxBeacon */
12705 			rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
12706 		}
12707 
12708 	} else if (type == 2) {
12709 		/* sta add event call back */
12710 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
12711 			/* fixed beacon issue for 8191su........... */
12712 			rtw_write8(adapter, 0x542 , 0x02);
12713 			RetryLimit = RL_VAL_AP;
12714 		}
12715 
12716 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12717 			ResumeTxBeacon(adapter);
12718 
12719 			/* reset TSF 1/2 after ResumeTxBeacon */
12720 			rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
12721 		}
12722 	}
12723 
12724 	val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
12725 	rtw_write16(adapter, REG_RETRY_LIMIT, val16);
12726 #else /* !CONFIG_CONCURRENT_MODE */
12727 	if (type == 0) { /* prepare to join */
12728 		/* enable to rx data frame.Accept all data frame */
12729 		rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12730 
12731 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
12732 			RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
12733 		else /* Ad-hoc Mode */
12734 			RetryLimit = RL_VAL_AP;
12735 
12736 		rtw_iface_enable_tsf_update(adapter);
12737 
12738 	} else if (type == 1) { /* joinbss_event call back when join res < 0 */
12739 		rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
12740 
12741 		rtw_iface_disable_tsf_update(adapter);
12742 
12743 	} else if (type == 2) { /* sta add event call back */
12744 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
12745 			RetryLimit = RL_VAL_AP;
12746 	}
12747 
12748 	val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
12749 	rtw_write16(adapter, REG_RETRY_LIMIT, val16);
12750 #endif /* !CONFIG_CONCURRENT_MODE */
12751 }
12752 #endif
12753 
12754 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)12755 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
12756 {
12757 	u8 buf[2];
12758 	int ret;
12759 
12760 	if (reset_port == HW_PORT0) {
12761 		buf[0] = 0x1;
12762 		buf[1] = 0;
12763 	} else {
12764 		buf[0] = 0x0;
12765 		buf[1] = 0x1;
12766 	}
12767 
12768 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
12769 
12770 	return ret;
12771 }
12772 
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)12773 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
12774 {
12775 	u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
12776 	u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
12777 				REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
12778 	int ret;
12779 
12780 	/* site survey will cause reset tsf fail */
12781 	rtw_mi_buddy_scan_abort(adapter, _FALSE);
12782 	reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
12783 	ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
12784 	if (ret != _SUCCESS)
12785 		return ret;
12786 
12787 	while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
12788 		rtw_msleep_os(100);
12789 		loop_cnt++;
12790 		reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
12791 	}
12792 
12793 	return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
12794 }
12795 #endif /* CONFIG_TSF_RESET_OFFLOAD */
12796 
12797 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12798 #ifdef CONFIG_HW_P0_TSF_SYNC
12799 #ifdef CONFIG_CONCURRENT_MODE
hw_port0_tsf_sync_sel(_adapter * adapter,u8 benable,u8 hw_port,u16 tr_offset)12800 static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
12801 {
12802 	u8 val8;
12803 	u8 client_id = 0;
12804 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12805 
12806 #ifdef CONFIG_MCC_MODE
12807 	if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
12808 		RTW_INFO("[MCC] do not set HW TSF sync\n");
12809 		return;
12810 	}
12811 #endif
12812 	/* check if port0 is already synced */
12813 	if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
12814 		RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
12815 			FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
12816 		return;
12817 	}
12818 
12819 	/* check if port0 already disable sync */
12820 	if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
12821 		RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
12822 		return;
12823 	}
12824 
12825 	/* check if port0 sync to port0 */
12826 	if (benable && hw_port == HW_PORT0) {
12827 		RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
12828 		rtw_warn_on(1);
12829 		return;
12830 	}
12831 
12832 	/*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
12833 	/*	Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
12834 		Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
12835 
12836 	val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
12837 
12838 	if (benable) {
12839 		/*Disable Port0's beacon function*/
12840 		rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
12841 
12842 		/*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
12843 		if (tr_offset)
12844 			rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
12845 
12846 		/*reg 0x577[6]=1*/	/*auto sync by tbtt*/
12847 		rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
12848 
12849 		if (HW_PORT1 == hw_port)
12850 			client_id = 0;
12851 		else if (HW_PORT2 == hw_port)
12852 			client_id = 1;
12853 		else if (HW_PORT3 == hw_port)
12854 			client_id = 2;
12855 		else if (HW_PORT4 == hw_port)
12856 			client_id = 3;
12857 
12858 		val8 &= 0x8F;
12859 		val8 |= (BIT(6) | (client_id << 4));
12860 
12861 		dvobj->p0_tsf.sync_port = hw_port;
12862 		dvobj->p0_tsf.offset = tr_offset;
12863 		rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12864 
12865 		/*Enable Port0's beacon function*/
12866 		rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)  | BIT_EN_BCN_FUNCTION);
12867 		RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
12868 	} else {
12869 		val8 &= ~BIT(6);
12870 
12871 		dvobj->p0_tsf.sync_port = MAX_HW_PORT;
12872 		dvobj->p0_tsf.offset = 0;
12873 		rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12874 		RTW_INFO("%s P0 TSF sync disable\n", __func__);
12875 	}
12876 }
_search_ld_sta(_adapter * adapter,u8 include_self)12877 static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
12878 {
12879 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12880 	u8 i;
12881 	_adapter *iface = NULL;
12882 
12883 	if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
12884 		RTW_ERR("STA_LD_NUM == 0\n");
12885 		rtw_warn_on(1);
12886 	}
12887 
12888 	for (i = 0; i < dvobj->iface_nums; i++) {
12889 		iface = dvobj->padapters[i];
12890 		if (!iface)
12891 			continue;
12892 		if (include_self == _FALSE && adapter == iface)
12893 			continue;
12894 		if (is_client_associated_to_ap(iface))
12895 			break;
12896 	}
12897 	if (iface)
12898 		RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
12899 	return iface;
12900 }
12901 #endif /*CONFIG_CONCURRENT_MODE*/
12902 /*Correct port0's TSF*/
12903 /*#define DBG_P0_TSF_SYNC*/
hw_var_set_correct_tsf(PADAPTER adapter,u8 mlme_state)12904 void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
12905 {
12906 #ifdef CONFIG_CONCURRENT_MODE
12907 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12908 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12909 	_adapter *sta_if = NULL;
12910 	u8 hw_port;
12911 
12912 	RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
12913 	#ifdef DBG_P0_TSF_SYNC
12914 	RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
12915 	RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
12916 	RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
12917 	if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12918 		RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
12919 	else
12920 		RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12921 	RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12922 	#endif
12923 	switch (mlme_state) {
12924 		case MLME_STA_CONNECTED :
12925 			{
12926 				hw_port = rtw_hal_get_port(adapter);
12927 
12928 				if (!MLME_IS_STA(adapter)) {
12929 					RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12930 					rtw_warn_on(1);
12931 				}
12932 
12933 				if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
12934 					RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
12935 					rtw_warn_on(1);
12936 					hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12937 				}
12938 
12939 				if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12940 					(rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
12941 					hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12942 					#ifdef DBG_P0_TSF_SYNC
12943 					RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
12944 					#endif
12945 				}
12946 			}
12947 			break;
12948 		case MLME_STA_DISCONNECTED :
12949 			{
12950 				hw_port = rtw_hal_get_port(adapter);
12951 
12952 				if (!MLME_IS_STA(adapter)) {
12953 					RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12954 					rtw_warn_on(1);
12955 				}
12956 
12957 				if (dvobj->p0_tsf.sync_port == hw_port) {
12958 					if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
12959 						/* search next appropriate sta*/
12960 						sta_if = _search_ld_sta(adapter, _FALSE);
12961 						if (sta_if) {
12962 							hw_port = rtw_hal_get_port(sta_if);
12963 							hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12964 							#ifdef DBG_P0_TSF_SYNC
12965 							RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
12966 							#endif
12967 						}
12968 					} else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
12969 						hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12970 						#ifdef DBG_P0_TSF_SYNC
12971 						RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
12972 						#endif
12973 					}
12974 				}
12975 			}
12976 			break;
12977 #ifdef CONFIG_AP_MODE
12978 		case MLME_AP_STARTED :
12979 		case MLME_MESH_STARTED :
12980 			{
12981 				if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12982 					RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12983 					rtw_warn_on(1);
12984 				}
12985 
12986 				if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12987 					rtw_mi_get_assoced_sta_num(adapter)) {
12988 					/* get port of sta */
12989 					sta_if = _search_ld_sta(adapter, _FALSE);
12990 					if (sta_if) {
12991 						hw_port = rtw_hal_get_port(sta_if);
12992 						hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12993 						#ifdef DBG_P0_TSF_SYNC
12994 						RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
12995 						#endif
12996 					}
12997 				}
12998 			}
12999 			break;
13000 		case MLME_AP_STOPPED :
13001 		case MLME_MESH_STOPPED :
13002 			{
13003 				if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
13004 					RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
13005 					rtw_warn_on(1);
13006 				}
13007 				/*stop ap mode*/
13008 				if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
13009 					(dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
13010 					hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
13011 					#ifdef DBG_P0_TSF_SYNC
13012 					RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
13013 					#endif
13014 				}
13015 			}
13016 			break;
13017 #endif /* CONFIG_AP_MODE */
13018 		default :
13019 			RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
13020 			break;
13021 	}
13022 
13023 	/*#ifdef DBG_P0_TSF_SYNC*/
13024 	#if 1
13025 	if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
13026 		RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
13027 	else
13028 		RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
13029 	RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
13030 	#endif
13031 #endif /*CONFIG_CONCURRENT_MODE*/
13032 }
13033 
13034 #else /*! CONFIG_HW_P0_TSF_SYNC*/
13035 
13036 #ifdef CONFIG_MI_WITH_MBSSID_CAM
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)13037 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
13038 {
13039 	/*do nothing*/
13040 }
13041 #else /* !CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)13042 static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
13043 {
13044 	if (hw_port == HW_PORT0) {
13045 		/*disable related TSF function*/
13046 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
13047 #if defined(CONFIG_RTL8192F)
13048 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13049 					REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
13050 #endif
13051 
13052 		rtw_write32(padapter, REG_TSFTR, tsf);
13053 		rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
13054 
13055 		/*enable related TSF function*/
13056 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
13057 #if defined(CONFIG_RTL8192F)
13058 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13059 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
13060 #endif
13061 	} else if (hw_port == HW_PORT1) {
13062 		/*disable related TSF function*/
13063 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
13064 #if defined(CONFIG_RTL8192F)
13065 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13066 					REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
13067 #endif
13068 
13069 		rtw_write32(padapter, REG_TSFTR1, tsf);
13070 		rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
13071 
13072 		/*enable related TSF function*/
13073 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
13074 #if defined(CONFIG_RTL8192F)
13075 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13076 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
13077 #endif
13078 	} else
13079 		RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
13080 }
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)13081 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
13082 {
13083 	u64 tsf;
13084 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
13085 	struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
13086 
13087 	tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
13088 
13089 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
13090 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
13091 		StopTxBeacon(adapter);
13092 
13093 	rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
13094 
13095 #ifdef CONFIG_CONCURRENT_MODE
13096 	/* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
13097 	if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
13098 		&& (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
13099 	) {
13100 		struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
13101 		int i;
13102 		_adapter *iface;
13103 
13104 		for (i = 0; i < dvobj->iface_nums; i++) {
13105 			iface = dvobj->padapters[i];
13106 			if (!iface)
13107 				continue;
13108 			if (iface == adapter)
13109 				continue;
13110 
13111 			#ifdef CONFIG_AP_MODE
13112 			if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
13113 				&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
13114 			) {
13115 				rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
13116 				#ifdef CONFIG_TSF_RESET_OFFLOAD
13117 				if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
13118 					RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
13119 						, __func__, ADPT_ARG(iface), iface->hw_port);
13120 				#endif	/* CONFIG_TSF_RESET_OFFLOAD*/
13121 				#ifdef CONFIG_TSF_SYNC
13122 				if(iface->hw_port == HW_PORT0)
13123 					rtw_write8(iface, REG_DUAL_TSF_RST, rtw_read8(iface, REG_DUAL_TSF_RST) | BIT(2));
13124 				else if(iface->hw_port == HW_PORT1)
13125 					rtw_write8(iface, REG_DUAL_TSF_RST, rtw_read8(iface, REG_DUAL_TSF_RST) | BIT(3));
13126 				#endif
13127 			}
13128 			#endif /* CONFIG_AP_MODE */
13129 		}
13130 	}
13131 #endif /* CONFIG_CONCURRENT_MODE */
13132 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
13133 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
13134 		ResumeTxBeacon(adapter);
13135 }
13136 #endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
13137 #endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
13138 #endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
13139 
rtw_hal_get_tsftr_by_port(_adapter * adapter,u8 port)13140 u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
13141 {
13142 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
13143 	u64 tsftr = 0;
13144 
13145 	if (port >= hal_spec->port_num) {
13146 		RTW_ERR("%s invalid port(%d) \n", __func__, port);
13147 		goto exit;
13148 	}
13149 
13150 	switch (rtw_get_chip_type(adapter)) {
13151 #if defined(CONFIG_RTL8814B)
13152 	case RTL8814B:
13153 	{
13154 		u8 val8;
13155 
13156 		/* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
13157 		val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
13158 		val8 &= ~0x70;
13159 		val8 |= port << 4;
13160 		rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
13161 
13162 		tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
13163 		tsftr = tsftr << 32;
13164 		tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
13165 
13166 		break;
13167 	}
13168 #endif
13169 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
13170 	case RTL8814A:
13171 	case RTL8822B:
13172 	case RTL8821C:
13173 	case RTL8822C:
13174 	{
13175 		u8 val8;
13176 
13177 		/* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
13178 		val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
13179 		val8 &= 0x8F;
13180 		val8 |= port << 4;
13181 		rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
13182 
13183 		tsftr = rtw_read32(adapter, REG_TSFTR + 4);
13184 		tsftr = tsftr << 32;
13185 		tsftr |= rtw_read32(adapter, REG_TSFTR);
13186 
13187 		break;
13188 	}
13189 #endif
13190 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
13191 		|| defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
13192 		|| defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
13193 		|| defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
13194 		|| defined(CONFIG_RTL8710B)
13195 	case RTL8188E:
13196 	case RTL8188F:
13197 	case RTL8188GTV:
13198 	case RTL8192E:
13199 	case RTL8192F:
13200 	case RTL8723B:
13201 	case RTL8703B:
13202 	case RTL8723D:
13203 	case RTL8812:
13204 	case RTL8821:
13205 	case RTL8710B:
13206 	{
13207 		u32 addr;
13208 
13209 		if (port == HW_PORT0)
13210 			addr = REG_TSFTR;
13211 		else if (port == HW_PORT1)
13212 			addr = REG_TSFTR1;
13213 		else {
13214 			RTW_ERR("%s unknown port(%d) \n", __func__, port);
13215 			goto exit;
13216 		}
13217 
13218 		tsftr = rtw_read32(adapter, addr + 4);
13219 		tsftr = tsftr << 32;
13220 		tsftr |= rtw_read32(adapter, addr);
13221 
13222 		break;
13223 	}
13224 #endif
13225 	default:
13226 		RTW_ERR("%s unknow chip type\n", __func__);
13227 	}
13228 
13229 exit:
13230 	return tsftr;
13231 }
13232 
13233 #ifdef CONFIG_TDLS
13234 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)13235 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
13236 {
13237 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
13238 	u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
13239 
13240 
13241 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
13242 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
13243 	switch (bwmode) {
13244 	case CHANNEL_WIDTH_40:
13245 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
13246 		break;
13247 	case CHANNEL_WIDTH_80:
13248 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
13249 		break;
13250 	case CHANNEL_WIDTH_20:
13251 	default:
13252 		break;
13253 	}
13254 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
13255 
13256 	return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
13257 }
13258 #endif
13259 #endif
13260 
13261 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)13262 void rtw_hal_update_uapsd_tid(_adapter *adapter)
13263 {
13264 	struct mlme_priv		*pmlmepriv = &adapter->mlmepriv;
13265 	struct qos_priv		*pqospriv = &pmlmepriv->qospriv;
13266 
13267 	/* write complement of pqospriv->uapsd_tid to mac register 0x693 because
13268 	    it's designed  for "0" represents "enable" and "1" represents "disable" */
13269 	rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
13270 }
13271 #endif /* CONFIG_WMMPS_STA */
13272 
13273 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
13274 /* 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)13275 s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
13276 {
13277 	u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
13278 	u8 hw_port = rtw_hal_get_port(adapter);
13279 
13280 	SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
13281 	RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
13282 	return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
13283 }
13284 #endif
13285 
13286 #define LPS_ACTIVE_TIMEOUT	50 /*number of times*/
rtw_lps_state_chk(_adapter * adapter,u8 ps_mode)13287 void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
13288 {
13289 	struct pwrctrl_priv 		*pwrpriv = adapter_to_pwrctl(adapter);
13290 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
13291 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13292 	struct sta_priv		*pstapriv = &adapter->stapriv;
13293 	struct sta_info		*psta = NULL;
13294 	u8 ps_ready = _FALSE;
13295 	s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
13296 
13297 	if (ps_mode == PS_MODE_ACTIVE) {
13298 #ifdef CONFIG_LPS_ACK
13299 		if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
13300 			if (pwrpriv->lps_ack_status > 0) {
13301 				psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
13302 				if (psta != NULL) {
13303 					if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
13304 						RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
13305 				}
13306 			}
13307 		} else {
13308 			RTW_WARN("LPS sctx query timeout, operation abort!!\n");
13309 			return;
13310 		}
13311 		pwrpriv->lps_ack_status = -1;
13312 #else
13313 		do {
13314 			if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
13315 				ps_ready = _TRUE;
13316 				break;
13317 			}
13318 			rtw_msleep_os(1);
13319 		} while (leave_wait_count--);
13320 
13321 		if (ps_ready == _FALSE) {
13322 			RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
13323 			return;
13324 		}
13325 #endif /* CONFIG_LPS_ACK */
13326 		}
13327 	}
13328 
rtw_var_set_basic_rate(PADAPTER padapter,u8 * val)13329 void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
13330 
13331 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
13332 	struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
13333 	u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
13334 	u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
13335 	u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
13336 	#if CONFIG_IEEE80211_BAND_5GHZ
13337 	u16 rrsr_5g_force_mask = (RRSR_6M);
13338 	u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
13339 	#endif
13340 	u32 temp_RRSR;
13341 
13342 	HalSetBrateCfg(padapter, val, &BrateCfg);
13343 	input_b = BrateCfg;
13344 
13345 	/* apply force and allow mask */
13346 	#if CONFIG_IEEE80211_BAND_5GHZ
13347 	if (pHalData->current_band_type != BAND_ON_2_4G) {
13348 		BrateCfg |= rrsr_5g_force_mask;
13349 		BrateCfg &= rrsr_5g_allow_mask;
13350 	} else
13351 	#endif
13352 	{ /* 2.4G */
13353 		BrateCfg |= rrsr_2g_force_mask;
13354 		BrateCfg &= rrsr_2g_allow_mask;
13355 	}
13356 	masked = BrateCfg;
13357 
13358 #ifdef CONFIG_CMCC_TEST
13359 	BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
13360 	BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
13361 #endif
13362 
13363 	/* IOT consideration */
13364 	if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
13365 		/* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
13366 		if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
13367 			BrateCfg |= RRSR_6M;
13368 	}
13369 		ioted = BrateCfg;
13370 
13371 #ifdef CONFIG_NARROWBAND_SUPPORTING
13372 	if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
13373 		|| (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
13374 		BrateCfg &= ~RRSR_CCK_RATES;
13375 		BrateCfg |= RRSR_6M;
13376 	}
13377 #endif
13378 	pHalData->BasicRateSet = BrateCfg;
13379 
13380 	RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
13381 
13382 	/* Set RRSR rate table. */
13383 		temp_RRSR = rtw_read32(padapter, REG_RRSR);
13384 		temp_RRSR &=0xFFFF0000;
13385 		temp_RRSR |=BrateCfg;
13386 		rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
13387 
13388 	rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
13389 
13390 	#if defined(CONFIG_RTL8188E)
13391 	rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
13392 	#endif
13393 }
13394 
SetHwReg(_adapter * adapter,u8 variable,u8 * val)13395 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
13396 {
13397 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13398 	u8 ret = _SUCCESS;
13399 
13400 	switch (variable) {
13401 	case HW_VAR_MEDIA_STATUS: {
13402 		u8 net_type = *((u8 *)val);
13403 
13404 		rtw_hal_set_msr(adapter, net_type);
13405 	}
13406 	break;
13407 	case HW_VAR_DO_IQK:
13408 		if (*val)
13409 			hal_data->bNeedIQK = _TRUE;
13410 		else
13411 			hal_data->bNeedIQK = _FALSE;
13412 		break;
13413 	case HW_VAR_MAC_ADDR:
13414 #ifdef CONFIG_MI_WITH_MBSSID_CAM
13415 		rtw_hal_set_macaddr_mbid(adapter, val);
13416 #else
13417 		rtw_hal_set_macaddr_port(adapter, val);
13418 #endif
13419 		break;
13420 	case HW_VAR_BSSID:
13421 		rtw_hal_set_bssid(adapter, val);
13422 		break;
13423 	case HW_VAR_RCR:
13424 		ret = hw_var_rcr_config(adapter, *((u32 *)val));
13425 		break;
13426 	case HW_VAR_ON_RCR_AM:
13427 		hw_var_set_rcr_am(adapter, 1);
13428 		break;
13429 	case HW_VAR_OFF_RCR_AM:
13430 		hw_var_set_rcr_am(adapter, 0);
13431 		break;
13432 	case HW_VAR_BEACON_INTERVAL:
13433 		hw_var_set_bcn_interval(adapter, *(u16 *)val);
13434 		break;
13435 #ifdef CONFIG_MBSSID_CAM
13436 	case HW_VAR_MBSSID_CAM_WRITE: {
13437 		u32	cmd = 0;
13438 		u32	*cam_val = (u32 *)val;
13439 
13440 		rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
13441 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
13442 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
13443 	}
13444 		break;
13445 	case HW_VAR_MBSSID_CAM_CLEAR: {
13446 		u32 cmd;
13447 		u8 entry_id = *(u8 *)val;
13448 
13449 		rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
13450 
13451 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
13452 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
13453 	}
13454 		break;
13455 	case HW_VAR_RCR_MBSSID_EN:
13456 		if (*((u8 *)val))
13457 			rtw_hal_rcr_add(adapter, RCR_ENMBID);
13458 		else
13459 			rtw_hal_rcr_clear(adapter, RCR_ENMBID);
13460 		break;
13461 #endif
13462 	case HW_VAR_PORT_SWITCH:
13463 		hw_var_port_switch(adapter);
13464 		break;
13465 	case HW_VAR_INIT_RTS_RATE: {
13466 		u16 brate_cfg = *((u16 *)val);
13467 		u8 rate_index = 0;
13468 		HAL_VERSION *hal_ver = &hal_data->version_id;
13469 
13470 		if (IS_8188E(*hal_ver)) {
13471 
13472 			while (brate_cfg > 0x1) {
13473 				brate_cfg = (brate_cfg >> 1);
13474 				rate_index++;
13475 			}
13476 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
13477 		} else
13478 			rtw_warn_on(1);
13479 	}
13480 		break;
13481 	case HW_VAR_SEC_CFG: {
13482 		u16 reg_scr_ori;
13483 		u16 reg_scr;
13484 
13485 		reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
13486 		reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
13487 
13488 		if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
13489 			reg_scr |= SCR_CHK_BMC;
13490 
13491 		if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
13492 			reg_scr |= SCR_NoSKMC;
13493 
13494 		if (reg_scr != reg_scr_ori)
13495 			rtw_write16(adapter, REG_SECCFG, reg_scr);
13496 	}
13497 		break;
13498 	case HW_VAR_SEC_DK_CFG: {
13499 		struct security_priv *sec = &adapter->securitypriv;
13500 		u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
13501 
13502 		if (val) { /* Enable default key related setting */
13503 			reg_scr |= SCR_TXBCUSEDK;
13504 			if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
13505 				reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
13506 		} else /* Disable default key related setting */
13507 			reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
13508 
13509 		rtw_write8(adapter, REG_SECCFG, reg_scr);
13510 	}
13511 		break;
13512 
13513 	case HW_VAR_ASIX_IOT:
13514 		/* enable  ASIX IOT function */
13515 		if (*((u8 *)val) == _TRUE) {
13516 			/* 0xa2e[0]=0 (disable rake receiver) */
13517 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
13518 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
13519 			/* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
13520 			rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
13521 		} else {
13522 			/* restore reg:0xa2e,   reg:0xa1c */
13523 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
13524 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
13525 			rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
13526 		}
13527 		break;
13528 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
13529 	case HW_VAR_WOWLAN: {
13530 		struct wowlan_ioctl_param *poidparam;
13531 
13532 		poidparam = (struct wowlan_ioctl_param *)val;
13533 		switch (poidparam->subcode) {
13534 #ifdef CONFIG_WOWLAN
13535 		case WOWLAN_PATTERN_CLEAN:
13536 			rtw_hal_dl_pattern(adapter, 2);
13537 			break;
13538 		case WOWLAN_ENABLE:
13539 			rtw_hal_wow_enable(adapter);
13540 			break;
13541 		case WOWLAN_DISABLE:
13542 			rtw_hal_wow_disable(adapter);
13543 			break;
13544 #endif /*CONFIG_WOWLAN*/
13545 #ifdef CONFIG_AP_WOWLAN
13546 		case WOWLAN_AP_ENABLE:
13547 			rtw_hal_ap_wow_enable(adapter);
13548 			break;
13549 		case WOWLAN_AP_DISABLE:
13550 			rtw_hal_ap_wow_disable(adapter);
13551 			break;
13552 #endif /*CONFIG_AP_WOWLAN*/
13553 		default:
13554 			break;
13555 		}
13556 	}
13557 		break;
13558 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
13559 
13560 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
13561 	case HW_VAR_BCN_FUNC:
13562 		hw_var_set_bcn_func(adapter, *val);
13563 		break;
13564 #endif
13565 
13566 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
13567 	case HW_VAR_MLME_DISCONNECT:
13568 		hw_var_set_mlme_disconnect(adapter);
13569 		break;
13570 #endif
13571 
13572 	case HW_VAR_MLME_SITESURVEY:
13573 		hw_var_set_mlme_sitesurvey(adapter, *val);
13574 		#ifdef CONFIG_BT_COEXIST
13575 		if (hal_data->EEPROMBluetoothCoexist == 1)
13576 			rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
13577 		#endif
13578 		break;
13579 
13580 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
13581 	case HW_VAR_MLME_JOIN:
13582 		hw_var_set_mlme_join(adapter, *val);
13583 		break;
13584 #endif
13585 
13586 	case HW_VAR_EN_HW_UPDATE_TSF:
13587 		rtw_hal_set_hw_update_tsf(adapter);
13588 		break;
13589 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
13590 	case HW_VAR_CORRECT_TSF:
13591 		hw_var_set_correct_tsf(adapter, *val);
13592 		break;
13593 #endif
13594 
13595 #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
13596 	case HW_VAR_TSF_AUTO_SYNC:
13597 		if (*val == _TRUE)
13598 			hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
13599 		else
13600 			hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
13601 		break;
13602 #endif
13603 	case HW_VAR_APFM_ON_MAC:
13604 		hal_data->bMacPwrCtrlOn = *val;
13605 		RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
13606 		break;
13607 #ifdef CONFIG_WMMPS_STA
13608 	case  HW_VAR_UAPSD_TID:
13609 		rtw_hal_update_uapsd_tid(adapter);
13610 		break;
13611 #endif /* CONFIG_WMMPS_STA */
13612 #ifdef CONFIG_LPS_PG
13613 	case HW_VAR_LPS_PG_HANDLE:
13614 		rtw_hal_lps_pg_handler(adapter, *val);
13615 		break;
13616 #endif
13617 #ifdef CONFIG_LPS_LCLK_WD_TIMER
13618 	case HW_VAR_DM_IN_LPS_LCLK:
13619 		rtw_phydm_wd_lps_lclk_hdl(adapter);
13620 		break;
13621 #endif
13622 	case HW_VAR_ENABLE_RX_BAR:
13623 		if (*val == _TRUE) {
13624 			/* enable RX BAR */
13625 			u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
13626 
13627 			val16 |= BIT(8);
13628 			rtw_write16(adapter, REG_RXFLTMAP1, val16);
13629 		} else {
13630 			/* disable RX BAR */
13631 			u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
13632 
13633 			val16 &= (~BIT(8));
13634 			rtw_write16(adapter, REG_RXFLTMAP1, val16);
13635 		}
13636 		RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
13637 			REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
13638 		break;
13639 	case HW_VAR_HCI_SUS_STATE:
13640 		hal_data->hci_sus_state = *(u8 *)val;
13641 		RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
13642 		break;
13643 #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
13644 		case HW_VAR_BCN_HEAD_SEL:
13645 		{
13646 			u8 vap_id = *(u8 *)val;
13647 
13648 			if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
13649 				RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
13650 				rtw_warn_on(1);
13651 			}
13652 			if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
13653 				u16 drv_pg_bndy = 0, bcn_addr = 0;
13654 				u32 page_size = 0;
13655 
13656 				/*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
13657 				rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
13658 				rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
13659 
13660 				if (vap_id != 0xFF)
13661 					bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
13662 				else
13663 					bcn_addr = drv_pg_bndy;
13664 				RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
13665 					ADPT_ARG(adapter), vap_id, bcn_addr);
13666 				rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
13667 					(bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
13668 			}
13669 		}
13670 		break;
13671 #endif
13672 	case HW_VAR_LPS_STATE_CHK :
13673 		rtw_lps_state_chk(adapter, *(u8 *)val);
13674 		break;
13675 
13676 #ifdef CONFIG_RTS_FULL_BW
13677 	case HW_VAR_SET_RTS_BW:
13678 	{
13679 		#ifdef RTW_HALMAC
13680 			rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
13681 		#else
13682 			u8 temp;
13683 			if(*val)
13684 				temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
13685 			else
13686 				temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
13687 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
13688 			/*RTW_INFO("HW_VAR_SET_RTS_BW	val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
13689 		#endif
13690 	}
13691 	break;
13692 #endif/*CONFIG_RTS_FULL_BW*/
13693 #if defined(CONFIG_PCI_HCI)
13694 	case HW_VAR_ENSWBCN:
13695 	if (*val == _TRUE) {
13696 		rtw_write8(adapter, REG_CR + 1,
13697 			   rtw_read8(adapter, REG_CR + 1) | BIT(0));
13698 	} else
13699 		rtw_write8(adapter, REG_CR + 1,
13700 			   rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
13701 	break;
13702 #endif
13703 	case HW_VAR_BCN_EARLY_C2H_RPT:
13704 		rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(adapter, *(u8 *)val);
13705 		break;
13706 	default:
13707 		if (0)
13708 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
13709 				  FUNC_ADPT_ARG(adapter), variable);
13710 		ret = _FAIL;
13711 		break;
13712 	}
13713 
13714 	return ret;
13715 }
13716 
GetHwReg(_adapter * adapter,u8 variable,u8 * val)13717 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
13718 {
13719 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13720 	u64 val64;
13721 
13722 
13723 	switch (variable) {
13724 	case HW_VAR_MAC_ADDR:
13725 		#ifndef CONFIG_MI_WITH_MBSSID_CAM
13726 		rtw_hal_get_macaddr_port(adapter, val);
13727 		#endif
13728 		break;
13729 	case HW_VAR_BASIC_RATE:
13730 		*((u16 *)val) = hal_data->BasicRateSet;
13731 		break;
13732 	case HW_VAR_MEDIA_STATUS:
13733 		rtw_hal_get_msr(adapter, val);
13734 		break;
13735 	case HW_VAR_DO_IQK:
13736 		*val = hal_data->bNeedIQK;
13737 		break;
13738 	case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
13739 		if (hal_is_band_support(adapter, BAND_ON_5G))
13740 			*val = _TRUE;
13741 		else
13742 			*val = _FALSE;
13743 		break;
13744 	case HW_VAR_APFM_ON_MAC:
13745 		*val = hal_data->bMacPwrCtrlOn;
13746 		break;
13747 	case HW_VAR_RCR:
13748 		hw_var_rcr_get(adapter, (u32 *)val);
13749 		break;
13750 	case HW_VAR_FWLPS_RF_ON:
13751 		/* When we halt NIC, we should check if FW LPS is leave. */
13752 		if (rtw_is_surprise_removed(adapter)
13753 			|| (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
13754 		) {
13755 			/*
13756 			 * If it is in HW/SW Radio OFF or IPS state,
13757 			 * we do not check Fw LPS Leave,
13758 			 * because Fw is unload.
13759 			 */
13760 			*val = _TRUE;
13761 		} else {
13762 			u32 rcr = 0;
13763 
13764 			rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
13765 			if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
13766 				*val = _FALSE;
13767 			else
13768 				*val = _TRUE;
13769 		}
13770 		break;
13771 
13772 	case HW_VAR_HCI_SUS_STATE:
13773 		*((u8 *)val) = hal_data->hci_sus_state;
13774 		break;
13775 
13776 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
13777 	case HW_VAR_BCN_CTRL_ADDR:
13778 		*((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
13779 		break;
13780 #endif
13781 
13782 #ifdef CONFIG_WAPI_SUPPORT
13783 	case HW_VAR_CAM_EMPTY_ENTRY: {
13784 		u8	ucIndex = *((u8 *)val);
13785 		u8	i;
13786 		u32	ulCommand = 0;
13787 		u32	ulContent = 0;
13788 		u32	ulEncAlgo = CAM_AES;
13789 
13790 		for (i = 0; i < CAM_CONTENT_COUNT; i++) {
13791 			/* filled id in CAM config 2 byte */
13792 			if (i == 0)
13793 				ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
13794 			else
13795 				ulContent = 0;
13796 			/* polling bit, and No Write enable, and address */
13797 			ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
13798 			ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
13799 			/* write content 0 is equall to mark invalid */
13800 			rtw_write32(adapter, REG_CAMWRITE, ulContent);  /* delay_ms(40); */
13801 			rtw_write32(adapter, REG_CAMCMD, ulCommand);  /* delay_ms(40); */
13802 		}
13803 	}
13804 #endif
13805 
13806 	default:
13807 		if (0)
13808 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
13809 				  FUNC_ADPT_ARG(adapter), variable);
13810 		break;
13811 	}
13812 
13813 }
13814 
_get_page_size(struct _ADAPTER * a)13815 static u32 _get_page_size(struct _ADAPTER *a)
13816 {
13817 #ifdef RTW_HALMAC
13818 	struct dvobj_priv *d;
13819 	u32 size = 0;
13820 	int err = 0;
13821 
13822 
13823 	d = adapter_to_dvobj(a);
13824 
13825 	err = rtw_halmac_get_page_size(d, &size);
13826 	if (!err)
13827 		return size;
13828 
13829 	RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
13830 		 FUNC_ADPT_ARG(a), err);
13831 #endif /* RTW_HALMAC */
13832 
13833 	return PAGE_SIZE_128;
13834 }
13835 
13836 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13837 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13838 {
13839 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13840 	u8 bResult = _SUCCESS;
13841 
13842 	switch (variable) {
13843 
13844 	case HAL_DEF_DBG_DUMP_RXPKT:
13845 		hal_data->bDumpRxPkt = *((u8 *)value);
13846 		break;
13847 	case HAL_DEF_DBG_DUMP_TXPKT:
13848 		hal_data->bDumpTxPkt = *((u8 *)value);
13849 		break;
13850 	case HAL_DEF_ANT_DETECT:
13851 		hal_data->AntDetection = *((u8 *)value);
13852 		break;
13853 	default:
13854 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
13855 		bResult = _FAIL;
13856 		break;
13857 	}
13858 
13859 	return bResult;
13860 }
13861 
13862 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)13863 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
13864 {
13865 	struct registry_priv	*pregistrypriv = &adapter->registrypriv;
13866 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13867 
13868 	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)))
13869 		return pregistrypriv->beamformer_rf_num;
13870 	else if (IS_HARDWARE_TYPE_8814AE(adapter)
13871 #if 0
13872 #if defined(CONFIG_USB_HCI)
13873 		|| (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2))  /* for USB3.0 */
13874 #endif
13875 #endif
13876 		) {
13877 		/*BF cap provided by Yu Chen, Sean, 2015, 01 */
13878 		if (hal_data->rf_type == RF_3T3R)
13879 			return 2;
13880 		else if (hal_data->rf_type == RF_4T4R)
13881 			return 3;
13882 		else
13883 			return 1;
13884 	} else
13885 		return 1;
13886 
13887 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)13888 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
13889 {
13890 	struct registry_priv		*pregistrypriv = &adapter->registrypriv;
13891 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
13892 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13893 
13894 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13895 
13896 	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)))
13897 		return pregistrypriv->beamformee_rf_num;
13898 	else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
13899 		if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
13900 			return 2;
13901 		else
13902 			return 2;/*TODO: May be 3 in the future, by ChenYu. */
13903 	} else
13904 		return 1;
13905 
13906 }
13907 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_hal_beamforming_config_csirate(PADAPTER adapter)13908 void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
13909 {
13910 	struct dm_struct *p_dm_odm;
13911 	struct beamforming_info *bf_info;
13912 	u8 fix_rate_enable = 0;
13913 	u8 new_csi_rate_idx;
13914 	u8 rrsr_54_en;
13915 	u32 temp_rrsr;
13916 
13917 	/* Acting as BFee */
13918 	if (IS_BEAMFORMEE(adapter)) {
13919 	#if 0
13920 		/* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
13921 		if (IS_HARDWARE_TYPE_8821C(Adapter))
13922 			FixRateEnable = 1;	/* Support after 8821C */
13923 	#endif
13924 
13925 		p_dm_odm = adapter_to_phydm(adapter);
13926 		bf_info = GET_BEAMFORM_INFO(adapter);
13927 
13928 		rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
13929 				p_dm_odm->rssi_min,
13930 				bf_info->cur_csi_rpt_rate,
13931 				fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
13932 
13933 		temp_rrsr = rtw_read32(adapter, REG_RRSR);
13934 		if (rrsr_54_en == 1)
13935 			temp_rrsr |= RRSR_54M;
13936 		else if (rrsr_54_en == 0)
13937 			temp_rrsr &= ~RRSR_54M;
13938 		rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
13939 
13940 		if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
13941 			bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
13942 	}
13943 }
13944 #endif
13945 #endif
13946 
13947 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13948 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13949 {
13950 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13951 	u8 bResult = _SUCCESS;
13952 
13953 	switch (variable) {
13954 	case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
13955 		struct mlme_priv *pmlmepriv;
13956 		struct sta_priv *pstapriv;
13957 		struct sta_info *psta;
13958 
13959 		pmlmepriv = &adapter->mlmepriv;
13960 		pstapriv = &adapter->stapriv;
13961 		psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
13962 		if (psta)
13963 			*((int *)value) = psta->cmn.rssi_stat.rssi;
13964 	}
13965 	break;
13966 	case HAL_DEF_DBG_DUMP_RXPKT:
13967 		*((u8 *)value) = hal_data->bDumpRxPkt;
13968 		break;
13969 	case HAL_DEF_DBG_DUMP_TXPKT:
13970 		*((u8 *)value) = hal_data->bDumpTxPkt;
13971 		break;
13972 	case HAL_DEF_ANT_DETECT:
13973 		*((u8 *)value) = hal_data->AntDetection;
13974 		break;
13975 	case HAL_DEF_TX_PAGE_SIZE:
13976 		*((u32 *)value) = _get_page_size(adapter);
13977 		break;
13978 	case HAL_DEF_TX_STBC:
13979 		#ifdef CONFIG_ALPHA_SMART_ANTENNA
13980 		*(u8 *)value = 0;
13981 		#else
13982 		*(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
13983 		#endif
13984 		break;
13985 	case HAL_DEF_EXPLICIT_BEAMFORMER:
13986 	case HAL_DEF_EXPLICIT_BEAMFORMEE:
13987 	case HAL_DEF_VHT_MU_BEAMFORMER:
13988 	case HAL_DEF_VHT_MU_BEAMFORMEE:
13989 		*(u8 *)value = _FALSE;
13990 		break;
13991 #ifdef CONFIG_BEAMFORMING
13992 	case HAL_DEF_BEAMFORMER_CAP:
13993 		*(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
13994 		break;
13995 	case HAL_DEF_BEAMFORMEE_CAP:
13996 		*(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
13997 		break;
13998 #endif
13999 	default:
14000 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
14001 		bResult = _FAIL;
14002 		break;
14003 	}
14004 
14005 	return bResult;
14006 }
14007 
14008 /*
14009  *	Description:
14010  *		Translate a character to hex digit.
14011  *   */
14012 u32
MapCharToHexDigit(char chTmp)14013 MapCharToHexDigit(
14014 			char		chTmp
14015 )
14016 {
14017 	if (chTmp >= '0' && chTmp <= '9')
14018 		return chTmp - '0';
14019 	else if (chTmp >= 'a' && chTmp <= 'f')
14020 		return 10 + (chTmp - 'a');
14021 	else if (chTmp >= 'A' && chTmp <= 'F')
14022 		return 10 + (chTmp - 'A');
14023 	else
14024 		return 0;
14025 }
14026 
14027 
14028 
14029 /*
14030  *	Description:
14031  *		Parse hex number from the string pucStr.
14032  *   */
14033 BOOLEAN
GetHexValueFromString(char * szStr,u32 * pu4bVal,u32 * pu4bMove)14034 GetHexValueFromString(
14035 		char			*szStr,
14036 		u32			*pu4bVal,
14037 		u32			*pu4bMove
14038 )
14039 {
14040 	char		*szScan = szStr;
14041 
14042 	/* Check input parameter. */
14043 	if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
14044 		RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
14045 		return _FALSE;
14046 	}
14047 
14048 	/* Initialize output. */
14049 	*pu4bMove = 0;
14050 	*pu4bVal = 0;
14051 
14052 	/* Skip leading space. */
14053 	while (*szScan != '\0' &&
14054 	       (*szScan == ' ' || *szScan == '\t')) {
14055 		szScan++;
14056 		(*pu4bMove)++;
14057 	}
14058 
14059 	/* Skip leading '0x' or '0X'. */
14060 	if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
14061 		szScan += 2;
14062 		(*pu4bMove) += 2;
14063 	}
14064 
14065 	/* Check if szScan is now pointer to a character for hex digit, */
14066 	/* if not, it means this is not a valid hex number. */
14067 	if (!IsHexDigit(*szScan))
14068 		return _FALSE;
14069 
14070 	/* Parse each digit. */
14071 	do {
14072 		(*pu4bVal) <<= 4;
14073 		*pu4bVal += MapCharToHexDigit(*szScan);
14074 
14075 		szScan++;
14076 		(*pu4bMove)++;
14077 	} while (IsHexDigit(*szScan));
14078 
14079 	return _TRUE;
14080 }
14081 
14082 BOOLEAN
GetFractionValueFromString(char * szStr,u8 * pInteger,u8 * pFraction,u32 * pu4bMove)14083 GetFractionValueFromString(
14084 		char			*szStr,
14085 		u8				*pInteger,
14086 		u8				*pFraction,
14087 		u32			*pu4bMove
14088 )
14089 {
14090 	char	*szScan = szStr;
14091 
14092 	/* Initialize output. */
14093 	*pu4bMove = 0;
14094 	*pInteger = 0;
14095 	*pFraction = 0;
14096 
14097 	/* Skip leading space. */
14098 	while (*szScan != '\0' &&	(*szScan == ' ' || *szScan == '\t')) {
14099 		++szScan;
14100 		++(*pu4bMove);
14101 	}
14102 
14103 	if (*szScan < '0' || *szScan > '9')
14104 		return _FALSE;
14105 
14106 	/* Parse each digit. */
14107 	do {
14108 		(*pInteger) *= 10;
14109 		*pInteger += (*szScan - '0');
14110 
14111 		++szScan;
14112 		++(*pu4bMove);
14113 
14114 		if (*szScan == '.') {
14115 			++szScan;
14116 			++(*pu4bMove);
14117 
14118 			if (*szScan < '0' || *szScan > '9')
14119 				return _FALSE;
14120 
14121 			*pFraction += (*szScan - '0') * 10;
14122 			++szScan;
14123 			++(*pu4bMove);
14124 
14125 			if (*szScan >= '0' && *szScan <= '9') {
14126 				*pFraction += *szScan - '0';
14127 				++szScan;
14128 				++(*pu4bMove);
14129 			}
14130 			return _TRUE;
14131 		}
14132 	} while (*szScan >= '0' && *szScan <= '9');
14133 
14134 	return _TRUE;
14135 }
14136 
14137 /*
14138  *	Description:
14139  * Return TRUE if szStr is comment out with leading " */ /* ".
14140  *   */
14141 BOOLEAN
IsCommentString(char * szStr)14142 IsCommentString(
14143 		char			*szStr
14144 )
14145 {
14146 	if (*szStr == '/' && *(szStr + 1) == '/')
14147 		return _TRUE;
14148 	else
14149 		return _FALSE;
14150 }
14151 
14152 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)14153 GetU1ByteIntegerFromStringInDecimal(
14154 		char	*Str,
14155 		u8		*pInt
14156 )
14157 {
14158 	u16 i = 0;
14159 	*pInt = 0;
14160 
14161 	while (Str[i] != '\0') {
14162 		if (Str[i] >= '0' && Str[i] <= '9') {
14163 			*pInt *= 10;
14164 			*pInt += (Str[i] - '0');
14165 		} else
14166 			return _FALSE;
14167 		++i;
14168 	}
14169 
14170 	return _TRUE;
14171 }
14172 
14173 /* <20121004, Kordan> For example,
14174  * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
14175  * If RightQualifier does not exist, it will hang on in the while loop */
14176 BOOLEAN
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)14177 ParseQualifiedString(
14178 			char	*In,
14179 			u32	*Start,
14180 			char	*Out,
14181 			char		LeftQualifier,
14182 			char		RightQualifier
14183 )
14184 {
14185 	u32	i = 0, j = 0;
14186 	char	c = In[(*Start)++];
14187 
14188 	if (c != LeftQualifier)
14189 		return _FALSE;
14190 
14191 	i = (*Start);
14192 	c = In[(*Start)++];
14193 	while (c != RightQualifier && c != '\0')
14194 		c = In[(*Start)++];
14195 
14196 	if (c == '\0')
14197 		return _FALSE;
14198 
14199 	j = (*Start) - 2;
14200 	strncpy((char *)Out, (const char *)(In + i), j - i + 1);
14201 
14202 	return _TRUE;
14203 }
14204 
14205 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)14206 isAllSpaceOrTab(
14207 	u8	*data,
14208 	u8	size
14209 )
14210 {
14211 	u8	cnt = 0, NumOfSpaceAndTab = 0;
14212 
14213 	while (size > cnt) {
14214 		if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
14215 			++NumOfSpaceAndTab;
14216 
14217 		++cnt;
14218 	}
14219 
14220 	return size == NumOfSpaceAndTab;
14221 }
14222 
14223 
rtw_hal_check_rxfifo_full(_adapter * adapter)14224 void rtw_hal_check_rxfifo_full(_adapter *adapter)
14225 {
14226 	struct dvobj_priv *psdpriv = adapter->dvobj;
14227 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
14228 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
14229 	struct registry_priv *regsty = &adapter->registrypriv;
14230 	int save_cnt = _FALSE;
14231 
14232 	if (regsty->check_hw_status == 1) {
14233 		/* switch counter to RX fifo */
14234 		if (IS_8188E(pHalData->version_id) ||
14235 		    IS_8188F(pHalData->version_id) ||
14236 		    IS_8188GTV(pHalData->version_id) ||
14237 		    IS_8812_SERIES(pHalData->version_id) ||
14238 		    IS_8821_SERIES(pHalData->version_id) ||
14239 		    IS_8723B_SERIES(pHalData->version_id) ||
14240 		    IS_8192E(pHalData->version_id) ||
14241 		    IS_8703B_SERIES(pHalData->version_id) ||
14242 		    IS_8723D_SERIES(pHalData->version_id) ||
14243 		    IS_8192F_SERIES(pHalData->version_id) ||
14244 		    IS_8822C_SERIES(pHalData->version_id)) {
14245 			rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
14246 			save_cnt = _TRUE;
14247 		} else {
14248 			/* todo: other chips */
14249 		}
14250 
14251 
14252 		if (save_cnt) {
14253 			pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
14254 			pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
14255 			pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
14256 		} else {
14257 			/* special value to indicate no implementation */
14258 			pdbgpriv->dbg_rx_fifo_last_overflow = 1;
14259 			pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
14260 			pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
14261 		}
14262 	}
14263 }
14264 
linked_info_dump(_adapter * padapter,u8 benable)14265 void linked_info_dump(_adapter *padapter, u8 benable)
14266 {
14267 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
14268 
14269 	if (padapter->bLinkInfoDump == benable)
14270 		return;
14271 
14272 	RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
14273 
14274 	if (benable) {
14275 #ifdef CONFIG_LPS
14276 		pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
14277 		rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
14278 #endif
14279 
14280 #ifdef CONFIG_IPS
14281 		pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
14282 		rtw_pm_set_ips(padapter, IPS_NONE);
14283 #endif
14284 	} else {
14285 #ifdef CONFIG_IPS
14286 		rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
14287 #endif /* CONFIG_IPS */
14288 
14289 #ifdef CONFIG_LPS
14290 		rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
14291 #endif /* CONFIG_LPS */
14292 	}
14293 	padapter->bLinkInfoDump = benable ;
14294 }
14295 
14296 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)14297 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
14298 {
14299 	u8 isCCKrate, rf_path;
14300 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14301 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14302 	RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
14303 		HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
14304 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14305 
14306 	if (isCCKrate)
14307 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
14308 
14309 	for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14310 		if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14311 			continue;
14312 		RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
14313 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
14314 
14315 		if (!isCCKrate) {
14316 			RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
14317 				psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
14318 		}
14319 	}
14320 }
14321 
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)14322 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
14323 {
14324 	u8 isCCKrate, rf_path;
14325 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14326 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14327 	_RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
14328 	_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);
14329 
14330 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14331 
14332 	if (isCCKrate)
14333 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
14334 
14335 	for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14336 		if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14337 			continue;
14338 		_RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
14339 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
14340 
14341 		if (!isCCKrate)
14342 			_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]);
14343 		else
14344 			_RTW_PRINT_SEL(sel , "\n");
14345 
14346 	}
14347 }
14348 #endif
14349 
14350 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)14351 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
14352 {
14353 #define DBG_RX_DFRAME_RAW_DATA_UC		0
14354 #define DBG_RX_DFRAME_RAW_DATA_BMC		1
14355 #define DBG_RX_DFRAME_RAW_DATA_TYPES	2
14356 
14357 	_irqL irqL;
14358 	u8 isCCKrate, rf_path;
14359 	struct recv_priv *precvpriv = &(padapter->recvpriv);
14360 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14361 	struct sta_priv *pstapriv = &padapter->stapriv;
14362 	struct sta_info *psta;
14363 	struct sta_recv_dframe_info *psta_dframe_info;
14364 	int i, j;
14365 	_list	*plist, *phead;
14366 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14367 	u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14368 
14369 	if (precvpriv->store_law_data_flag) {
14370 
14371 		_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
14372 
14373 		for (i = 0; i < NUM_STA; i++) {
14374 			phead = &(pstapriv->sta_hash[i]);
14375 			plist = get_next(phead);
14376 
14377 			while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
14378 
14379 				psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
14380 				plist = get_next(plist);
14381 
14382 				if (psta) {
14383 					if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN)  !=   _TRUE)
14384 					    && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN)  !=  _TRUE)
14385 					    && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN)  !=  _TRUE)) {
14386 
14387 						RTW_PRINT_SEL(sel, "==============================\n");
14388 						RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
14389 
14390 						for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
14391 							if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
14392 								psta_dframe_info = &psta->sta_dframe_info;
14393 								RTW_PRINT_SEL(sel, "\n");
14394 								RTW_PRINT_SEL(sel, "Unicast:\n");
14395 							} else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
14396 								psta_dframe_info = &psta->sta_dframe_info_bmc;
14397 								RTW_PRINT_SEL(sel, "\n");
14398 								RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
14399 							}
14400 
14401 							isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14402 
14403 							RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
14404 							RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
14405 
14406 							for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14407 								if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14408 									continue;
14409 								if (!isCCKrate) {
14410 									RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
14411 									_RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
14412 								} else
14413 									RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
14414 							}
14415 						}
14416 
14417 					}
14418 				}
14419 			}
14420 		}
14421 		_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
14422 	}
14423 }
14424 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)14425 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
14426 {
14427 	u8 isCCKrate, rf_path , dframe_type;
14428 	u8 *ptr;
14429 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14430 #ifdef DBG_RX_DFRAME_RAW_DATA
14431 	struct sta_recv_dframe_info *psta_dframe_info;
14432 #endif
14433 	struct recv_priv *precvpriv = &(padapter->recvpriv);
14434 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14435 	struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
14436 	struct sta_info *psta = prframe->u.hdr.psta;
14437 	struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
14438 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14439 	psample_pkt_rssi->data_rate = pattrib->data_rate;
14440 	ptr = prframe->u.hdr.rx_data;
14441 	dframe_type = GetFrameType(ptr);
14442 	/*RTW_INFO("=>%s\n", __FUNCTION__);*/
14443 
14444 
14445 	if (precvpriv->store_law_data_flag) {
14446 		isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14447 
14448 		psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
14449 		psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
14450 
14451 		for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14452 			psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
14453 			psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
14454 			if (!isCCKrate) {
14455 				psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
14456 				psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
14457 			}
14458 		}
14459 #ifdef DBG_RX_DFRAME_RAW_DATA
14460 		if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
14461 
14462 			/*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
14463 			if (psta) {
14464 				if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
14465 					psta_dframe_info = &psta->sta_dframe_info_bmc;
14466 				else
14467 					psta_dframe_info = &psta->sta_dframe_info;
14468 				/*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
14469 					__FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
14470 				if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
14471 					psta_dframe_info->sta_data_rate = pattrib->data_rate;
14472 					psta_dframe_info->sta_sgi = pattrib->sgi;
14473 					psta_dframe_info->sta_bw_mode = pattrib->bw;
14474 					for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14475 
14476 						psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
14477 
14478 						if (!isCCKrate) {
14479 							psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
14480 							psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
14481 						}
14482 					}
14483 				}
14484 			}
14485 		}
14486 #endif
14487 	}
14488 
14489 }
14490 
hal_efuse_macaddr_offset(_adapter * adapter)14491 int hal_efuse_macaddr_offset(_adapter *adapter)
14492 {
14493 	u8 interface_type = 0;
14494 	int addr_offset = -1;
14495 
14496 	interface_type = rtw_get_intf_type(adapter);
14497 
14498 	switch (rtw_get_chip_type(adapter)) {
14499 #ifdef CONFIG_RTL8723B
14500 	case RTL8723B:
14501 		if (interface_type == RTW_USB)
14502 			addr_offset = EEPROM_MAC_ADDR_8723BU;
14503 		else if (interface_type == RTW_SDIO)
14504 			addr_offset = EEPROM_MAC_ADDR_8723BS;
14505 		else if (interface_type == RTW_PCIE)
14506 			addr_offset = EEPROM_MAC_ADDR_8723BE;
14507 		break;
14508 #endif
14509 #ifdef CONFIG_RTL8703B
14510 	case RTL8703B:
14511 		if (interface_type == RTW_USB)
14512 			addr_offset = EEPROM_MAC_ADDR_8703BU;
14513 		else if (interface_type == RTW_SDIO)
14514 			addr_offset = EEPROM_MAC_ADDR_8703BS;
14515 		break;
14516 #endif
14517 #ifdef CONFIG_RTL8723D
14518 	case RTL8723D:
14519 		if (interface_type == RTW_USB)
14520 			addr_offset = EEPROM_MAC_ADDR_8723DU;
14521 		else if (interface_type == RTW_SDIO)
14522 			addr_offset = EEPROM_MAC_ADDR_8723DS;
14523 		else if (interface_type == RTW_PCIE)
14524 			addr_offset = EEPROM_MAC_ADDR_8723DE;
14525 		break;
14526 #endif
14527 
14528 #ifdef CONFIG_RTL8188E
14529 	case RTL8188E:
14530 		if (interface_type == RTW_USB)
14531 			addr_offset = EEPROM_MAC_ADDR_88EU;
14532 		else if (interface_type == RTW_SDIO)
14533 			addr_offset = EEPROM_MAC_ADDR_88ES;
14534 		else if (interface_type == RTW_PCIE)
14535 			addr_offset = EEPROM_MAC_ADDR_88EE;
14536 		break;
14537 #endif
14538 #ifdef CONFIG_RTL8188F
14539 	case RTL8188F:
14540 		if (interface_type == RTW_USB)
14541 			addr_offset = EEPROM_MAC_ADDR_8188FU;
14542 		else if (interface_type == RTW_SDIO)
14543 			addr_offset = EEPROM_MAC_ADDR_8188FS;
14544 		break;
14545 #endif
14546 #ifdef CONFIG_RTL8188GTV
14547 	case RTL8188GTV:
14548 		if (interface_type == RTW_USB)
14549 			addr_offset = EEPROM_MAC_ADDR_8188GTVU;
14550 		else if (interface_type == RTW_SDIO)
14551 			addr_offset = EEPROM_MAC_ADDR_8188GTVS;
14552 		break;
14553 #endif
14554 #ifdef CONFIG_RTL8812A
14555 	case RTL8812:
14556 		if (interface_type == RTW_USB)
14557 			addr_offset = EEPROM_MAC_ADDR_8812AU;
14558 		else if (interface_type == RTW_PCIE)
14559 			addr_offset = EEPROM_MAC_ADDR_8812AE;
14560 		break;
14561 #endif
14562 #ifdef CONFIG_RTL8821A
14563 	case RTL8821:
14564 		if (interface_type == RTW_USB)
14565 			addr_offset = EEPROM_MAC_ADDR_8821AU;
14566 		else if (interface_type == RTW_SDIO)
14567 			addr_offset = EEPROM_MAC_ADDR_8821AS;
14568 		else if (interface_type == RTW_PCIE)
14569 			addr_offset = EEPROM_MAC_ADDR_8821AE;
14570 		break;
14571 #endif
14572 #ifdef CONFIG_RTL8192E
14573 	case RTL8192E:
14574 		if (interface_type == RTW_USB)
14575 			addr_offset = EEPROM_MAC_ADDR_8192EU;
14576 		else if (interface_type == RTW_SDIO)
14577 			addr_offset = EEPROM_MAC_ADDR_8192ES;
14578 		else if (interface_type == RTW_PCIE)
14579 			addr_offset = EEPROM_MAC_ADDR_8192EE;
14580 		break;
14581 #endif
14582 #ifdef CONFIG_RTL8814A
14583 	case RTL8814A:
14584 		if (interface_type == RTW_USB)
14585 			addr_offset = EEPROM_MAC_ADDR_8814AU;
14586 		else if (interface_type == RTW_PCIE)
14587 			addr_offset = EEPROM_MAC_ADDR_8814AE;
14588 		break;
14589 #endif
14590 
14591 #ifdef CONFIG_RTL8822B
14592 	case RTL8822B:
14593 		if (interface_type == RTW_USB)
14594 			addr_offset = EEPROM_MAC_ADDR_8822BU;
14595 		else if (interface_type == RTW_SDIO)
14596 			addr_offset = EEPROM_MAC_ADDR_8822BS;
14597 		else if (interface_type == RTW_PCIE)
14598 			addr_offset = EEPROM_MAC_ADDR_8822BE;
14599 		break;
14600 #endif /* CONFIG_RTL8822B */
14601 
14602 #ifdef CONFIG_RTL8821C
14603 	case RTL8821C:
14604 		if (interface_type == RTW_USB)
14605 			addr_offset = EEPROM_MAC_ADDR_8821CU;
14606 		else if (interface_type == RTW_SDIO)
14607 			addr_offset = EEPROM_MAC_ADDR_8821CS;
14608 		else if (interface_type == RTW_PCIE)
14609 			addr_offset = EEPROM_MAC_ADDR_8821CE;
14610 		break;
14611 #endif /* CONFIG_RTL8821C */
14612 
14613 #ifdef CONFIG_RTL8710B
14614 	case RTL8710B:
14615 		if (interface_type == RTW_USB)
14616 			addr_offset = EEPROM_MAC_ADDR_8710B;
14617 		break;
14618 #endif
14619 
14620 #ifdef CONFIG_RTL8192F
14621 	case RTL8192F:
14622 		if (interface_type == RTW_USB)
14623 			addr_offset = EEPROM_MAC_ADDR_8192FU;
14624 		else if (interface_type == RTW_SDIO)
14625 			addr_offset = EEPROM_MAC_ADDR_8192FS;
14626 		else if (interface_type == RTW_PCIE)
14627 			addr_offset = EEPROM_MAC_ADDR_8192FE;
14628 		break;
14629 #endif /* CONFIG_RTL8192F */
14630 
14631 #ifdef CONFIG_RTL8822C
14632 	case RTL8822C:
14633 		if (interface_type == RTW_USB)
14634 			addr_offset = EEPROM_MAC_ADDR_8822CU;
14635 		else if (interface_type == RTW_SDIO)
14636 			addr_offset = EEPROM_MAC_ADDR_8822CS;
14637 		else if (interface_type == RTW_PCIE)
14638 			addr_offset = EEPROM_MAC_ADDR_8822CE;
14639 		break;
14640 #endif /* CONFIG_RTL8822C */
14641 
14642 #ifdef CONFIG_RTL8814B
14643 	case RTL8814B:
14644 		if (interface_type == RTW_USB)
14645 			addr_offset = EEPROM_MAC_ADDR_8814BU;
14646 		else if (interface_type == RTW_PCIE)
14647 			addr_offset = EEPROM_MAC_ADDR_8814BE;
14648 		break;
14649 #endif /* CONFIG_RTL8814B */
14650 
14651 #ifdef CONFIG_RTL8723F
14652 	case RTL8723F:
14653 		if (interface_type == RTW_USB)
14654 			addr_offset = EEPROM_MAC_ADDR_8723FU;
14655 		else if (interface_type == RTW_SDIO)
14656 			addr_offset = EEPROM_MAC_ADDR_8723FS;
14657 		break;
14658 #endif /* CONFIG_RTL8723F */
14659 	}
14660 
14661 	if (addr_offset == -1) {
14662 		RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
14663 			, __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
14664 	}
14665 
14666 	return addr_offset;
14667 }
14668 
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)14669 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
14670 {
14671 	int ret = _FAIL;
14672 	int addr_offset;
14673 
14674 	addr_offset = hal_efuse_macaddr_offset(padapter);
14675 	if (addr_offset == -1)
14676 		goto exit;
14677 
14678 	ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
14679 
14680 exit:
14681 	return ret;
14682 }
14683 
rtw_dump_cur_efuse(PADAPTER padapter)14684 void rtw_dump_cur_efuse(PADAPTER padapter)
14685 {
14686 	int mapsize =0;
14687 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14688 
14689 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
14690 
14691 	if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
14692 		RTW_ERR("wrong map size %d\n", mapsize);
14693 		return;
14694 	}
14695 
14696 #ifdef CONFIG_RTW_DEBUG
14697 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14698 		RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
14699 	else {
14700 #ifdef CONFIG_MP_INCLUDED
14701 		if (rtw_mp_mode_check(padapter) && GET_EFUSE_UPDATE_ON(padapter))
14702 			RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "FAKE EFUSE", hal_data->efuse_eeprom_data, mapsize);
14703 		else
14704 #endif
14705 			RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
14706 	}
14707 #endif
14708 }
14709 
14710 
14711 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)14712 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
14713 {
14714 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14715 	u32 ret = _FALSE;
14716 	u32 maplen = 0;
14717 #ifdef CONFIG_MP_INCLUDED
14718 		struct mp_priv *pmp_priv = &padapter->mppriv;
14719 #endif
14720 
14721 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
14722 
14723 	if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
14724 		RTW_ERR("eFuse length error :%d\n", maplen);
14725 		return _FALSE;
14726 	}
14727 #ifdef CONFIG_MP_INCLUDED
14728 	if (pmp_priv->efuse_update_file == _TRUE && (rtw_mp_mode_check(padapter))) {
14729 		RTW_INFO("%s, eFuse read from file :%s\n", __func__, pmp_priv->efuse_file_path);
14730 		ret = rtw_read_efuse_from_file(pmp_priv->efuse_file_path, hal_data->efuse_eeprom_data, maplen);
14731 		pmp_priv->efuse_update_file = _FALSE;
14732 	} else
14733 #endif
14734 	{
14735 		ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
14736 	}
14737 
14738 	hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
14739 
14740 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14741 		rtw_dump_cur_efuse(padapter);
14742 
14743 	return ret;
14744 }
14745 
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)14746 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
14747 {
14748 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14749 	u32 ret = _FAIL;
14750 
14751 	if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
14752 		&& rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
14753 	) {
14754 		hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
14755 		ret = _SUCCESS;
14756 	} else
14757 		hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
14758 
14759 	return ret;
14760 }
14761 #endif /* CONFIG_EFUSE_CONFIG_FILE */
14762 
hal_config_macaddr(_adapter * adapter,bool autoload_fail)14763 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
14764 {
14765 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
14766 	u8 addr[ETH_ALEN];
14767 	int addr_offset = hal_efuse_macaddr_offset(adapter);
14768 	u8 *hw_addr = NULL;
14769 	int ret = _SUCCESS;
14770 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
14771 	u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
14772 #endif
14773 
14774 	if (autoload_fail)
14775 		goto bypass_hw_pg;
14776 
14777 	if (addr_offset != -1)
14778 		hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
14779 
14780 #ifdef CONFIG_EFUSE_CONFIG_FILE
14781 	/* if the hw_addr is written by efuse file, set to NULL */
14782 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14783 		hw_addr = NULL;
14784 #endif
14785 
14786 	if (!hw_addr) {
14787 		/* try getting hw pg data */
14788 		if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
14789 			hw_addr = addr;
14790 	}
14791 
14792 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
14793 	if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
14794 		hw_addr[0] = 0xff;
14795 #endif
14796 
14797 	/* check hw pg data */
14798 	if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
14799 		_rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
14800 		goto exit;
14801 	}
14802 
14803 bypass_hw_pg:
14804 
14805 #ifdef CONFIG_EFUSE_CONFIG_FILE
14806 	/* check wifi mac file */
14807 	if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
14808 		_rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
14809 		goto exit;
14810 	}
14811 #endif
14812 
14813 	_rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
14814 	ret = _FAIL;
14815 
14816 exit:
14817 	return ret;
14818 }
14819 
14820 #ifdef CONFIG_RF_POWER_TRIM
14821 u32 Array_kfreemap[] = {
14822 	0x08, 0xe,
14823 	0x06, 0xc,
14824 	0x04, 0xa,
14825 	0x02, 0x8,
14826 	0x00, 0x6,
14827 	0x03, 0x4,
14828 	0x05, 0x2,
14829 	0x07, 0x0,
14830 	0x09, 0x0,
14831 	0x0c, 0x0,
14832 };
14833 
rtw_bb_rf_gain_offset(_adapter * padapter)14834 void rtw_bb_rf_gain_offset(_adapter *padapter)
14835 {
14836 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14837 	struct registry_priv  *registry_par = &padapter->registrypriv;
14838 	struct kfree_data_t *kfree_data = &pHalData->kfree_data;
14839 	u8		value = pHalData->EEPROMRFGainOffset;
14840 	u8		tmp = 0x3e;
14841 	u32		res, i = 0;
14842 	u32		ArrayLen	= sizeof(Array_kfreemap) / sizeof(u32);
14843 	u32		*Array = Array_kfreemap;
14844 	u32		v1 = 0, v2 = 0, GainValue = 0, target = 0;
14845 
14846 	if (registry_par->RegPwrTrimEnable == 2) {
14847 		RTW_INFO("Registry kfree default force disable.\n");
14848 		return;
14849 	}
14850 
14851 #if defined(CONFIG_RTL8723B)
14852 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
14853 		RTW_INFO("Offset RF Gain.\n");
14854 		RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
14855 
14856 		if (pHalData->EEPROMRFGainVal != 0xff) {
14857 
14858 			if (pHalData->ant_path == RF_PATH_A)
14859 				GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
14860 
14861 			else
14862 				GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
14863 			RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
14864 
14865 			for (i = 0; i < ArrayLen; i += 2) {
14866 				/* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
14867 				v1 = Array[i];
14868 				v2 = Array[i + 1];
14869 				if (v1 == GainValue) {
14870 					RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
14871 					target = v2;
14872 					break;
14873 				}
14874 			}
14875 			RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
14876 
14877 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
14878 			RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
14879 			phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
14880 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
14881 
14882 			RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
14883 
14884 		} else
14885 
14886 			RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x	!= 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
14887 	} else
14888 		RTW_INFO("Using the default RF gain.\n");
14889 
14890 #elif defined(CONFIG_RTL8188E)
14891 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
14892 		RTW_INFO("8188ES Offset RF Gain.\n");
14893 		RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
14894 			 pHalData->EEPROMRFGainVal);
14895 
14896 		if (pHalData->EEPROMRFGainVal != 0xff) {
14897 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
14898 					 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
14899 
14900 			RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
14901 			res &= 0xfff87fff;
14902 
14903 			res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
14904 			RTW_INFO("Offset RF Gain. res=0x%x\n", res);
14905 
14906 			rtw_hal_write_rfreg(padapter, RF_PATH_A,
14907 					    REG_RF_BB_GAIN_OFFSET,
14908 					    RF_GAIN_OFFSET_MASK, res);
14909 		} else {
14910 			RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
14911 				 pHalData->EEPROMRFGainVal);
14912 		}
14913 	} else
14914 		RTW_INFO("Using the default RF gain.\n");
14915 #else
14916 	/* TODO: call this when channel switch */
14917 	if (kfree_data->flag & KFREE_FLAG_ON)
14918 		rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
14919 #endif
14920 
14921 }
14922 #endif /*CONFIG_RF_POWER_TRIM */
14923 
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)14924 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
14925 {
14926 #ifdef CONFIG_RF_POWER_TRIM
14927 	int i, j;
14928 
14929 	for (i = 0; i < BB_GAIN_NUM; i++)
14930 		for (j = 0; j < RF_PATH_MAX; j++)
14931 			if (data->bb_gain[i][j] != 0)
14932 				return 0;
14933 #endif
14934 	return 1;
14935 }
14936 
14937 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)14938 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
14939 {
14940 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14941 	if (cur_wireless_mode < WIRELESS_11_24N
14942 	    && cur_wireless_mode > 0) { /* ABG mode */
14943 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14944 		u32 remainder = 0;
14945 		u8 quotient = 0;
14946 
14947 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
14948 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14949 
14950 		if (quotient > 5) {
14951 			pHalData->rxagg_usb_size = 0x6;
14952 			pHalData->rxagg_usb_timeout = 0x10;
14953 		} else {
14954 			if (remainder >= 2048) {
14955 				pHalData->rxagg_usb_size = quotient;
14956 				pHalData->rxagg_usb_timeout = 0x10;
14957 			} else {
14958 				pHalData->rxagg_usb_size = (quotient - 1);
14959 				pHalData->rxagg_usb_timeout = 0x10;
14960 			}
14961 		}
14962 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14963 		if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
14964 			pHalData->rxagg_usb_size = 0x6;
14965 			pHalData->rxagg_usb_timeout = 0x10;
14966 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14967 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14968 		}
14969 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14970 
14971 	} else if (cur_wireless_mode >= WIRELESS_11_24N
14972 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14973 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14974 		u32 remainder = 0;
14975 		u8 quotient = 0;
14976 
14977 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
14978 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14979 
14980 		if (quotient > 5) {
14981 			pHalData->rxagg_usb_size = 0x5;
14982 			pHalData->rxagg_usb_timeout = 0x20;
14983 		} else {
14984 			if (remainder >= 2048) {
14985 				pHalData->rxagg_usb_size = quotient;
14986 				pHalData->rxagg_usb_timeout = 0x10;
14987 			} else {
14988 				pHalData->rxagg_usb_size = (quotient - 1);
14989 				pHalData->rxagg_usb_timeout = 0x10;
14990 			}
14991 		}
14992 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14993 		if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
14994 			pHalData->rxagg_usb_size = 0x5;
14995 			pHalData->rxagg_usb_timeout = 0x20;
14996 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14997 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14998 		}
14999 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
15000 
15001 	} else {
15002 		/* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
15003 	}
15004 }
15005 
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)15006 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
15007 {
15008 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
15009 
15010 	if (cur_wireless_mode < WIRELESS_11_24N
15011 	    && cur_wireless_mode > 0) { /* ABG mode */
15012 		if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
15013 		    || 0x10 != pHalData->rxagg_usb_timeout) {
15014 			pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
15015 			pHalData->rxagg_usb_timeout = 0x10;
15016 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
15017 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
15018 		}
15019 	} else if (cur_wireless_mode >= WIRELESS_11_24N
15020 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
15021 		if (UsbDmaSize != pHalData->rxagg_usb_size
15022 		    || 0x20 != pHalData->rxagg_usb_timeout) {
15023 			pHalData->rxagg_usb_size = UsbDmaSize;
15024 			pHalData->rxagg_usb_timeout = 0x20;
15025 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
15026 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
15027 		}
15028 	} else {
15029 		/* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
15030 	}
15031 }
15032 
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)15033 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
15034 {
15035 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
15036 	rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
15037 	return;
15038 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
15039 
15040 	rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
15041 }
15042 #endif /* CONFIG_USB_RX_AGGREGATION */
15043 
15044 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)15045 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
15046 {
15047 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
15048 	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
15049 	struct registry_priv *registry_par = &padapter->registrypriv;
15050 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
15051 	u8 cur_wireless_mode = WIRELESS_INVALID;
15052 
15053 #ifdef CONFIG_USB_RX_AGGREGATION
15054 	if (!registry_par->dynamic_agg_enable)
15055 		return;
15056 
15057 #ifdef RTW_HALMAC
15058 	if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter)
15059 		|| IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter)
15060 		|| IS_HARDWARE_TYPE_8723FU(padapter))
15061 		rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
15062 #else /* !RTW_HALMAC */
15063 	if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
15064 		/* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
15065 		if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) {
15066 			if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
15067 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
15068 			else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
15069 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
15070 			else
15071 				rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
15072 
15073 			/* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
15074 		}
15075 	} else if (IS_HARDWARE_TYPE_8812(padapter)) {
15076 #ifdef CONFIG_CONCURRENT_MODE
15077 		u8 i;
15078 		_adapter *iface;
15079 		u8 bassocaed = _FALSE;
15080 		struct mlme_ext_priv *mlmeext;
15081 
15082 		for (i = 0; i < pdvobjpriv->iface_nums; i++) {
15083 			iface = pdvobjpriv->padapters[i];
15084 			mlmeext = &iface->mlmeextpriv;
15085 			if (rtw_linked_check(iface) == _TRUE) {
15086 				if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
15087 					cur_wireless_mode = mlmeext->cur_wireless_mode;
15088 				bassocaed = _TRUE;
15089 			}
15090 		}
15091 		if (bassocaed)
15092 #endif
15093 			rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
15094 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
15095 	} else {
15096 		rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
15097 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
15098 	}
15099 #endif /* RTW_HALMAC */
15100 #endif /* CONFIG_USB_RX_AGGREGATION */
15101 
15102 }
15103 
15104 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)15105 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
15106 {
15107 #ifdef CONFIG_AP_MODE
15108 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
15109 	u8 chk_rst = _SUCCESS;
15110 
15111 	if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
15112 		return chk_rst;
15113 
15114 	/* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
15115 	/*	return chk_rst; */
15116 
15117 	if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
15118 	    && (pre_qsel != next_qsel)) {
15119 		/* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
15120 		/*	pre_qsel,next_qsel); */
15121 		chk_rst = _FAIL;
15122 	}
15123 	return chk_rst;
15124 #else
15125 	return _SUCCESS;
15126 #endif /* CONFIG_AP_MODE */
15127 }
15128 
15129 #ifdef CONFIG_WOWLAN
15130 /*
15131  * Description:
15132  * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
15133  * contant.
15134  *
15135  * Input:
15136  * adapter: adapter pointer.
15137  * page_num: The max. page number that user want to dump.
15138  * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
15139  */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)15140 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
15141 {
15142 
15143 	int i;
15144 	u8 val = 0;
15145 	u8 base = 0;
15146 	u32 addr = 0;
15147 	u32 count = (page_size / 8);
15148 
15149 	if (page_num <= 0) {
15150 		RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
15151 		return;
15152 	}
15153 
15154 	if (page_size < 128 || page_size > 512) {
15155 		RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
15156 		return;
15157 	}
15158 
15159 	RTW_INFO("+%s+\n", __func__);
15160 	val = rtw_read8(padapter, 0x106);
15161 	rtw_write8(padapter, 0x106, 0x69);
15162 	RTW_INFO("0x106: 0x%02x\n", val);
15163 	base = rtw_read8(padapter, 0x209);
15164 	RTW_INFO("0x209: 0x%02x\n", base);
15165 
15166 	addr = ((base)*page_size) / 8;
15167 	for (i = 0 ; i < page_num * count ; i += 2) {
15168 		rtw_write32(padapter, 0x140, addr + i);
15169 		printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
15170 		rtw_write32(padapter, 0x140, addr + i + 1);
15171 		printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
15172 	}
15173 }
15174 #endif
15175 
15176 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)15177 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
15178 {
15179 	u8 value = 0;
15180 	u8 direction = 0;
15181 	u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
15182 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
15183 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
15184 	u8 gpio_num_to_set = gpio_num;
15185 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
15186 
15187 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15188 		return value;
15189 
15190 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15191 
15192 	RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
15193 	LeaveAllPowerSaveModeDirect(adapter);
15194 
15195 	if (gpio_num > 7) {
15196 		gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
15197 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
15198 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
15199 		gpio_num_to_set = gpio_num - 8;
15200 	}
15201 
15202 	/* Read GPIO Direction */
15203 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15204 
15205 	/* According the direction to read register value */
15206 	if (direction)
15207 		value =  (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15208 	else
15209 		value =  (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15210 
15211 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15212 	RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
15213 
15214 	return value;
15215 }
15216 
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)15217 int  rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
15218 {
15219 	u8 direction = 0;
15220 	u8 res = -1;
15221 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
15222 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
15223 	u8 gpio_num_to_set = gpio_num;
15224 
15225 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15226 		return -1;
15227 
15228 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15229 
15230 	LeaveAllPowerSaveModeDirect(adapter);
15231 
15232 	if (gpio_num > 7) {
15233 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
15234 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
15235 		gpio_num_to_set = gpio_num - 8;
15236 	}
15237 
15238 	/* Read GPIO direction */
15239 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15240 
15241 	/* If GPIO is output direction, setting value. */
15242 	if (direction) {
15243 		if (isHigh)
15244 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
15245 		else
15246 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
15247 
15248 		RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
15249 		res = 0;
15250 	} else {
15251 		RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
15252 		res = -1;
15253 	}
15254 
15255 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15256 	return res;
15257 }
15258 
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)15259 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
15260 {
15261 	u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
15262 	u8 gpio_num_to_set = gpio_num;
15263 
15264 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15265 		return -1;
15266 
15267 	RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
15268 
15269 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15270 
15271 	LeaveAllPowerSaveModeDirect(adapter);
15272 
15273 	rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
15274 
15275 	if (gpio_num > 7) {
15276 		gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
15277 		gpio_num_to_set = gpio_num - 8;
15278 	}
15279 
15280 	if (isOutput)
15281 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
15282 	else
15283 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
15284 
15285 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15286 
15287 	return 0;
15288 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))15289 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
15290 {
15291 	u8 value;
15292 	u8 direction;
15293 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
15294 
15295 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
15296 		if (gpio_num > 7 || gpio_num < 4) {
15297 			RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
15298 			return -1;
15299 		}
15300 	}
15301 
15302 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15303 
15304 	LeaveAllPowerSaveModeDirect(adapter);
15305 
15306 	/* Read GPIO direction */
15307 	direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
15308 	if (direction) {
15309 		RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
15310 		return -1;
15311 	}
15312 
15313 	/* Config GPIO Mode */
15314 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
15315 
15316 	/* Register GPIO interrupt handler*/
15317 	adapter->gpiointpriv.callback[gpio_num] = callback;
15318 
15319 	/* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
15320 	value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
15321 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
15322 	rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
15323 
15324 	/* Enable GPIO interrupt */
15325 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
15326 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
15327 
15328 	rtw_hal_update_hisr_hsisr_ind(adapter, 1);
15329 
15330 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15331 
15332 	return 0;
15333 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)15334 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
15335 {
15336 	u8 value;
15337 	u8 direction;
15338 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
15339 
15340 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
15341 		if (gpio_num > 7 || gpio_num < 4) {
15342 			RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
15343 			return -1;
15344 		}
15345 	}
15346 
15347 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15348 
15349 	LeaveAllPowerSaveModeDirect(adapter);
15350 
15351 	/* Config GPIO Mode */
15352 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
15353 
15354 	/* Unregister GPIO interrupt handler*/
15355 	adapter->gpiointpriv.callback[gpio_num] = NULL;
15356 
15357 	/* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
15358 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
15359 	rtw_write8(adapter, REG_GPIO_INTM, 0x00);
15360 
15361 	/* Disable GPIO interrupt */
15362 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
15363 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
15364 
15365 	if (!adapter->gpiointpriv.interrupt_enable_mask)
15366 		rtw_hal_update_hisr_hsisr_ind(adapter, 0);
15367 
15368 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15369 
15370 	return 0;
15371 }
15372 #endif
15373 
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)15374 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
15375 {
15376 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15377 	u8 i;
15378 
15379 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
15380 		if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
15381 			if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
15382 			    && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
15383 				return i;
15384 		}
15385 	}
15386 
15387 	return -1;
15388 }
15389 
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)15390 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
15391 {
15392 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15393 	s8 res;
15394 	u8 i;
15395 
15396 	/* If it's an existed record, overwrite it */
15397 	res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
15398 	if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
15399 		rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
15400 		return;
15401 	}
15402 
15403 	/* Search for the empty record to use */
15404 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
15405 		if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
15406 			rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
15407 			return;
15408 		}
15409 	}
15410 
15411 	/* Else, overwrite the oldest record */
15412 	for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
15413 		_rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
15414 
15415 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
15416 }
15417 
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)15418 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
15419 {
15420 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
15421 }
15422 
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15423 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15424 {
15425 	u32	mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
15426 	u32	mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
15427 	u32	mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
15428 	u32	DropPacket = 0;
15429 
15430 	if (!rx_counter) {
15431 		rtw_warn_on(1);
15432 		return;
15433 	}
15434 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
15435 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15436 
15437 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
15438 	mac_cck_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	  */
15439 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
15440 	mac_ofdm_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15441 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
15442 	mac_ht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15443 	mac_vht_ok	= 0;
15444 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15445 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
15446 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
15447 		mac_vht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
15448 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15449 	}
15450 
15451 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
15452 	mac_cck_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15453 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
15454 	mac_ofdm_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15455 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
15456 	mac_ht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
15457 	mac_vht_err	= 0;
15458 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15459 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
15460 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
15461 		mac_vht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
15462 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15463 	}
15464 
15465 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
15466 	mac_cck_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15467 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
15468 	mac_ofdm_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15469 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
15470 	mac_ht_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
15471 
15472 	/* Mac_DropPacket */
15473 	rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
15474 	DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
15475 
15476 	rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
15477 	rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
15478 	rx_counter->rx_cck_fa = mac_cck_fa;
15479 	rx_counter->rx_ofdm_fa = mac_ofdm_fa;
15480 	rx_counter->rx_ht_fa = mac_ht_fa;
15481 	rx_counter->rx_pkt_drop = DropPacket;
15482 }
rtw_reset_mac_rx_counters(_adapter * padapter)15483 void rtw_reset_mac_rx_counters(_adapter *padapter)
15484 {
15485 
15486 	/* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
15487 	if (IS_HARDWARE_TYPE_8703B(padapter) ||
15488 		IS_HARDWARE_TYPE_8723D(padapter) ||
15489 		IS_HARDWARE_TYPE_8188F(padapter) ||
15490 		IS_HARDWARE_TYPE_8188GTV(padapter) ||
15491 		IS_HARDWARE_TYPE_8192F(padapter) ||
15492 		IS_HARDWARE_TYPE_8822C(padapter))
15493 		phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
15494 
15495 	/* reset mac counter */
15496 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
15497 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
15498 }
15499 
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15500 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15501 {
15502 	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;
15503 	if (!rx_counter) {
15504 		rtw_warn_on(1);
15505 		return;
15506 	}
15507 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15508 		cckok	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF);	     /* [13:0] */
15509 		ofdmok	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF);	     /* [13:0] */
15510 		htok		= phy_query_bb_reg(padapter, 0xF10, 0x3FFF);     /* [13:0] */
15511 		vht_ok	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF);     /* [13:0] */
15512 		cckcrc	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16]	 */
15513 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
15514 		htcrc	= phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
15515 		vht_err	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
15516 		CCK_FA	= phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
15517 		OFDM_FA	= phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
15518 	} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
15519 		cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
15520 		ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
15521 		htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
15522 		vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
15523 		cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
15524 		ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
15525 		htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
15526 		vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
15527 		CCK_FA	= phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
15528 		OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
15529 	} else if(IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)){
15530 		cckok = phy_query_bb_reg(padapter, 0x2aac, 0xffff);
15531 		ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
15532 		htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
15533 		cckcrc = phy_query_bb_reg(padapter, 0x2aac, 0xffff0000);
15534 		ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
15535 		htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
15536 		CCK_FA	= phy_query_bb_reg(padapter, 0x2aa8, 0xffff0000) + phy_query_bb_reg(padapter, 0x2aa8, 0x0000ffff);
15537 		OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
15538 	} else {
15539 		cckok	= phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
15540 		ofdmok	= phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
15541 		htok		= phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
15542 		vht_ok	= 0;
15543 		cckcrc	= phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
15544 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
15545 		htcrc	= phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
15546 		vht_err	= 0;
15547 		OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF0, bMaskHWord) +
15548 			phy_query_bb_reg(padapter, 0xDA0, bMaskHWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
15549 			phy_query_bb_reg(padapter, 0xDA4, bMaskHWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
15550 
15551 		CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
15552 	}
15553 
15554 	rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
15555 	rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
15556 	rx_counter->rx_ofdm_fa = OFDM_FA;
15557 	rx_counter->rx_cck_fa = CCK_FA;
15558 
15559 }
15560 
rtw_reset_phy_trx_ok_counters(_adapter * padapter)15561 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
15562 {
15563 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15564 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
15565 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
15566 	} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) {
15567 		phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
15568 		phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
15569 	} else {
15570 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
15571 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
15572 	}
15573 }
15574 
rtw_reset_phy_rx_counters(_adapter * padapter)15575 void rtw_reset_phy_rx_counters(_adapter *padapter)
15576 {
15577 	/* reset phy counter */
15578 	if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
15579 		/* reset CCK FA counter */
15580 		phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
15581 		phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
15582 
15583 		/* reset CCK CCA counter */
15584 		phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
15585 		phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
15586 
15587 	} else if (IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) {
15588 		/* reset CCK FA and CCK CCA counter */
15589 		phy_set_bb_reg(padapter, 0x2a44, BIT21, 0);
15590 		phy_set_bb_reg(padapter, 0x2a44, BIT21, 1);
15591 		rtw_reset_phy_trx_ok_counters(padapter);
15592 
15593 	} else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15594 		rtw_reset_phy_trx_ok_counters(padapter);
15595 
15596 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset  OFDA FA counter */
15597 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
15598 
15599 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
15600 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
15601 	} else {
15602 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
15603 		rtw_msleep_os(10);
15604 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
15605 
15606 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset  OFDA FA counter */
15607 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset  OFDA FA counter */
15608 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
15609 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
15610 
15611 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
15612 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
15613 	}
15614 }
15615 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15616 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15617 {
15618 	struct recv_priv *precvpriv = &padapter->recvpriv;
15619 	if (!rx_counter) {
15620 		rtw_warn_on(1);
15621 		return;
15622 	}
15623 	rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
15624 	rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
15625 	rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
15626 }
rtw_reset_drv_rx_counters(_adapter * padapter)15627 void rtw_reset_drv_rx_counters(_adapter *padapter)
15628 {
15629 	struct recv_priv *precvpriv = &padapter->recvpriv;
15630 	padapter->drv_rx_cnt_ok = 0;
15631 	padapter->drv_rx_cnt_crcerror = 0;
15632 	padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
15633 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)15634 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
15635 {
15636 	u8 initialgain;
15637 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15638 
15639 	if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
15640 		rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
15641 		RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
15642 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
15643 		/*disable dynamic functions, such as high power, DIG*/
15644 		rtw_phydm_ability_backup(padapter);
15645 		rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
15646 	} else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
15647 		/* turn on phy-dynamic functions */
15648 		rtw_phydm_ability_restore(padapter);
15649 		initialgain = 0xff; /* restore RX GAIN */
15650 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
15651 
15652 	}
15653 }
15654 
rtw_dump_rx_counters(_adapter * padapter)15655 void rtw_dump_rx_counters(_adapter *padapter)
15656 {
15657 	struct dbg_rx_counter rx_counter;
15658 
15659 	if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
15660 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15661 		rtw_dump_drv_rx_counters(padapter, &rx_counter);
15662 		RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
15663 			rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
15664 		rtw_reset_drv_rx_counters(padapter);
15665 	}
15666 
15667 	if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
15668 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15669 		rtw_dump_mac_rx_counters(padapter, &rx_counter);
15670 		RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
15671 			 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
15672 			rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
15673 			 rx_counter.rx_pkt_drop);
15674 		rtw_reset_mac_rx_counters(padapter);
15675 	}
15676 
15677 	if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
15678 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15679 		rtw_dump_phy_rx_counters(padapter, &rx_counter);
15680 		/* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
15681 		/* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
15682 		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,
15683 			 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
15684 		rtw_reset_phy_rx_counters(padapter);
15685 	}
15686 }
15687 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)15688 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
15689 {
15690 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15691 	u8 curr_tx_sgi = 0;
15692 	struct ra_sta_info *ra_info;
15693 
15694 	if (!psta)
15695 		return curr_tx_sgi;
15696 
15697 	if (padapter->fix_rate == 0xff) {
15698 #if defined(CONFIG_RTL8188E)
15699 #if (RATE_ADAPTIVE_SUPPORT == 1)
15700 		curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
15701 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
15702 #else
15703 		ra_info = &psta->cmn.ra_info;
15704 		curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
15705 #endif
15706 	} else {
15707 		curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
15708 	}
15709 
15710 	return curr_tx_sgi;
15711 }
15712 
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)15713 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
15714 {
15715 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15716 	u8 rate_id = 0;
15717 	struct ra_sta_info *ra_info;
15718 
15719 	if (!psta)
15720 		return rate_id;
15721 
15722 	if (padapter->fix_rate == 0xff) {
15723 #if defined(CONFIG_RTL8188E)
15724 #if (RATE_ADAPTIVE_SUPPORT == 1)
15725 		rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
15726 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
15727 #else
15728 		ra_info = &psta->cmn.ra_info;
15729 		rate_id = ra_info->curr_tx_rate & 0x7f;
15730 #endif
15731 	} else {
15732 		rate_id = padapter->fix_rate & 0x7f;
15733 	}
15734 
15735 	return rate_id;
15736 }
15737 
update_IOT_info(_adapter * padapter)15738 void update_IOT_info(_adapter *padapter)
15739 {
15740 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
15741 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
15742 
15743 	switch (pmlmeinfo->assoc_AP_vendor) {
15744 	case HT_IOT_PEER_MARVELL:
15745 		pmlmeinfo->turboMode_cts2self = 1;
15746 		pmlmeinfo->turboMode_rtsen = 0;
15747 		break;
15748 
15749 	case HT_IOT_PEER_RALINK:
15750 		pmlmeinfo->turboMode_cts2self = 0;
15751 		pmlmeinfo->turboMode_rtsen = 1;
15752 		break;
15753 	case HT_IOT_PEER_REALTEK:
15754 		/* rtw_write16(padapter, 0x4cc, 0xffff); */
15755 		/* rtw_write16(padapter, 0x546, 0x01c0); */
15756 		break;
15757 	default:
15758 		pmlmeinfo->turboMode_cts2self = 0;
15759 		pmlmeinfo->turboMode_rtsen = 1;
15760 		break;
15761 	}
15762 
15763 }
15764 #ifdef CONFIG_RTS_FULL_BW
15765 /*
15766 8188E: not support full RTS BW feature(mac REG no define 480[5])
15767 */
rtw_set_rts_bw(_adapter * padapter)15768 void rtw_set_rts_bw(_adapter *padapter) {
15769 	int i;
15770 	u8 enable = 1;
15771 	bool connect_to_8812 = _FALSE;
15772 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
15773 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
15774 	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
15775 	struct sta_info *station = NULL;
15776 
15777 	for (i = 0; i < macid_ctl->num; i++) {
15778 		if (rtw_macid_is_used(macid_ctl, i)) {
15779 
15780 			station = NULL;
15781 			station = macid_ctl->sta[i];
15782 			if(station) {
15783 
15784 				 _adapter *sta_adapter =station->padapter;
15785 				struct mlme_ext_priv	*pmlmeext = &(sta_adapter->mlmeextpriv);
15786 				struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
15787 
15788 				if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
15789 					if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) !=  _TRUE) {
15790 						if (  macid_ctl->sta[i]->vendor_8812) {
15791 							connect_to_8812 = _TRUE;
15792 							enable = 0;
15793 						}
15794 					}
15795 				}
15796 			}
15797 		}
15798 
15799 		if(connect_to_8812)
15800 			break;
15801 	}
15802 
15803 		RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
15804 		rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
15805 }
15806 #endif/*CONFIG_RTS_FULL_BW*/
15807 
hal_spec_init(_adapter * adapter)15808 int hal_spec_init(_adapter *adapter)
15809 {
15810 	u8 interface_type = 0;
15811 	int ret = _SUCCESS;
15812 
15813 	interface_type = rtw_get_intf_type(adapter);
15814 
15815 	switch (rtw_get_chip_type(adapter)) {
15816 #ifdef CONFIG_RTL8723B
15817 	case RTL8723B:
15818 		init_hal_spec_8723b(adapter);
15819 		break;
15820 #endif
15821 #ifdef CONFIG_RTL8703B
15822 	case RTL8703B:
15823 		init_hal_spec_8703b(adapter);
15824 		break;
15825 #endif
15826 #ifdef CONFIG_RTL8723D
15827 	case RTL8723D:
15828 		init_hal_spec_8723d(adapter);
15829 		break;
15830 #endif
15831 #ifdef CONFIG_RTL8188E
15832 	case RTL8188E:
15833 		init_hal_spec_8188e(adapter);
15834 		break;
15835 #endif
15836 #ifdef CONFIG_RTL8188F
15837 	case RTL8188F:
15838 		init_hal_spec_8188f(adapter);
15839 		break;
15840 #endif
15841 #ifdef CONFIG_RTL8188GTV
15842 	case RTL8188GTV:
15843 		init_hal_spec_8188gtv(adapter);
15844 		break;
15845 #endif
15846 #ifdef CONFIG_RTL8812A
15847 	case RTL8812:
15848 		init_hal_spec_8812a(adapter);
15849 		break;
15850 #endif
15851 #ifdef CONFIG_RTL8821A
15852 	case RTL8821:
15853 		init_hal_spec_8821a(adapter);
15854 		break;
15855 #endif
15856 #ifdef CONFIG_RTL8192E
15857 	case RTL8192E:
15858 		init_hal_spec_8192e(adapter);
15859 		break;
15860 #endif
15861 #ifdef CONFIG_RTL8814A
15862 	case RTL8814A:
15863 		init_hal_spec_8814a(adapter);
15864 		break;
15865 #endif
15866 #ifdef CONFIG_RTL8822B
15867 	case RTL8822B:
15868 		rtl8822b_init_hal_spec(adapter);
15869 		break;
15870 #endif
15871 #ifdef CONFIG_RTL8821C
15872 	case RTL8821C:
15873 		init_hal_spec_rtl8821c(adapter);
15874 		break;
15875 #endif
15876 #ifdef CONFIG_RTL8710B
15877 	case RTL8710B:
15878 		init_hal_spec_8710b(adapter);
15879 		break;
15880 #endif
15881 #ifdef CONFIG_RTL8192F
15882 	case RTL8192F:
15883 		init_hal_spec_8192f(adapter);
15884 		break;
15885 #endif
15886 #ifdef CONFIG_RTL8822C
15887 	case RTL8822C:
15888 		rtl8822c_init_hal_spec(adapter);
15889 		break;
15890 #endif
15891 #ifdef CONFIG_RTL8814B
15892 	case RTL8814B:
15893 		rtl8814b_init_hal_spec(adapter);
15894 		break;
15895 #endif
15896 #ifdef CONFIG_RTL8723F
15897 	case RTL8723F:
15898 		rtl8723f_init_hal_spec(adapter);
15899 		break;
15900 #endif
15901 	default:
15902 		RTW_ERR("%s: unknown chip_type:%u\n"
15903 			, __func__, rtw_get_chip_type(adapter));
15904 		ret = _FAIL;
15905 		break;
15906 	}
15907 
15908 	return ret;
15909 }
15910 
15911 static const char *const _band_cap_str[] = {
15912 	/* BIT0 */"2G",
15913 	/* BIT1 */"5G",
15914 };
15915 
15916 static const char *const _bw_cap_str[] = {
15917 	/* BIT0 */"5M",
15918 	/* BIT1 */"10M",
15919 	/* BIT2 */"20M",
15920 	/* BIT3 */"40M",
15921 	/* BIT4 */"80M",
15922 	/* BIT5 */"160M",
15923 	/* BIT6 */"80_80M",
15924 };
15925 
15926 static const char *const _proto_cap_str[] = {
15927 	/* BIT0 */"b",
15928 	/* BIT1 */"g",
15929 	/* BIT2 */"n",
15930 	/* BIT3 */"ac",
15931 };
15932 
15933 static const char *const _wl_func_str[] = {
15934 	/* BIT0 */"P2P",
15935 	/* BIT1 */"MIRACAST",
15936 	/* BIT2 */"TDLS",
15937 	/* BIT3 */"FTM",
15938 };
15939 
dump_hal_spec(void * sel,_adapter * adapter)15940 void dump_hal_spec(void *sel, _adapter *adapter)
15941 {
15942 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15943 	int i;
15944 
15945 	RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
15946 	RTW_PRINT_SEL(sel, "macid_cap:%u\n", hal_spec->macid_cap);
15947 	RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
15948 	RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
15949 
15950 	RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
15951 	RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
15952 	RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
15953 	RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num);
15954 	RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp);
15955 	RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
15956 
15957 	RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
15958 	RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
15959 
15960 	RTW_PRINT_SEL(sel, "band_cap:");
15961 	for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
15962 		if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
15963 			_RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
15964 	}
15965 	_RTW_PRINT_SEL(sel, "\n");
15966 
15967 	RTW_PRINT_SEL(sel, "bw_cap:");
15968 	for (i = 0; i < BW_CAP_BIT_NUM; i++) {
15969 		if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
15970 			_RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
15971 	}
15972 	_RTW_PRINT_SEL(sel, "\n");
15973 
15974 	RTW_PRINT_SEL(sel, "proto_cap:");
15975 	for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
15976 		if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
15977 			_RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
15978 	}
15979 	_RTW_PRINT_SEL(sel, "\n");
15980 
15981 	RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
15982 	RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
15983 
15984 	RTW_PRINT_SEL(sel, "wl_func:");
15985 	for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
15986 		if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
15987 			_RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
15988 	}
15989 	_RTW_PRINT_SEL(sel, "\n");
15990 
15991 #if CONFIG_TX_AC_LIFETIME
15992 	RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
15993 		, hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
15994 #endif
15995 
15996 	RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
15997 
15998 	RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
15999 	RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
16000 }
16001 
hal_chk_band_cap(_adapter * adapter,u8 cap)16002 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
16003 {
16004 	return GET_HAL_SPEC(adapter)->band_cap & cap;
16005 }
16006 
hal_chk_bw_cap(_adapter * adapter,u8 cap)16007 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
16008 {
16009 	return GET_HAL_SPEC(adapter)->bw_cap & cap;
16010 }
16011 
hal_chk_proto_cap(_adapter * adapter,u8 cap)16012 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
16013 {
16014 	return GET_HAL_SPEC(adapter)->proto_cap & cap;
16015 }
16016 
hal_chk_wl_func(_adapter * adapter,u8 func)16017 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
16018 {
16019 	return GET_HAL_SPEC(adapter)->wl_func & func;
16020 }
16021 
hal_is_band_support(_adapter * adapter,u8 band)16022 inline bool hal_is_band_support(_adapter *adapter, u8 band)
16023 {
16024 	return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
16025 }
16026 
hal_is_bw_support(_adapter * adapter,u8 bw)16027 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
16028 {
16029 	return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
16030 }
16031 
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)16032 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
16033 {
16034 	u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
16035 
16036 	if (mode == WIRELESS_11B)
16037 		if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
16038 			return 1;
16039 
16040 	if (mode == WIRELESS_11G)
16041 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
16042 			return 1;
16043 
16044 	if (mode == WIRELESS_11A)
16045 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
16046 			return 1;
16047 
16048 	if (mode == WIRELESS_11_24N)
16049 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
16050 			return 1;
16051 
16052 	if (mode == WIRELESS_11_5N)
16053 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
16054 			return 1;
16055 
16056 	if (mode == WIRELESS_11AC)
16057 		if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
16058 			return 1;
16059 
16060 	return 0;
16061 }
hal_is_mimo_support(_adapter * adapter)16062 inline bool hal_is_mimo_support(_adapter *adapter)
16063 {
16064 	if ((GET_HAL_TX_NSS(adapter) == 1) &&
16065 		(GET_HAL_RX_NSS(adapter) == 1))
16066 		return 0;
16067 	return 1;
16068 }
16069 
16070 /*
16071 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
16072 * @adapter:
16073 * @in_bw: starting bw, value of enum channel_width
16074 *
16075 * Returns: value of enum channel_width
16076 */
hal_largest_bw(_adapter * adapter,u8 in_bw)16077 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
16078 {
16079 	for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
16080 		if (hal_is_bw_support(adapter, in_bw))
16081 			break;
16082 	}
16083 
16084 	if (!hal_is_bw_support(adapter, in_bw))
16085 		rtw_warn_on(1);
16086 
16087 	return in_bw;
16088 }
16089 
16090 #ifndef CONFIG_HAS_TX_BEACON_PAUSE
ResumeTxBeacon(_adapter * padapter)16091 void ResumeTxBeacon(_adapter *padapter)
16092 {
16093 	RTW_DBG("ResumeTxBeacon\n");
16094 	#ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE
16095 	rtw_write8(padapter, REG_TXPAUSE,
16096 		rtw_read8(padapter, REG_TXPAUSE) & (~BIT6));
16097 	#else
16098 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
16099 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
16100 	#endif
16101 
16102 #ifdef RTW_HALMAC
16103 	/* Add this for driver using HALMAC because driver doesn't have setup time init by self */
16104 	/* TBTT setup time */
16105 	rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
16106 #endif
16107 
16108 	/* TBTT hold time: 0x540[19:8] */
16109 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
16110 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
16111 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
16112 }
16113 
StopTxBeacon(_adapter * padapter)16114 void StopTxBeacon(_adapter *padapter)
16115 {
16116 	RTW_DBG("StopTxBeacon\n");
16117 	#ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE
16118 	rtw_write8(padapter, REG_TXPAUSE,
16119 	rtw_read8(padapter, REG_TXPAUSE) | BIT6);
16120 	#else
16121 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
16122 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
16123 	#endif
16124 
16125 	/* TBTT hold time: 0x540[19:8] */
16126 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
16127 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
16128 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
16129 }
16130 #endif /* CONFIG_HAS_TX_BEACON_PAUSE */
16131 
16132 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
16133 
16134 #ifdef CONFIG_CLIENT_PORT_CFG
16135 const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
16136 	CLT_PORT0,
16137 	CLT_PORT1,
16138 	CLT_PORT2,
16139 	CLT_PORT3
16140 };
16141 
rtw_clt_port_init(struct clt_port_t * cltp)16142 void rtw_clt_port_init(struct clt_port_t  *cltp)
16143 {
16144 	cltp->bmp = 0;
16145 	cltp->num = 0;
16146 	_rtw_spinlock_init(&cltp->lock);
16147 }
rtw_clt_port_deinit(struct clt_port_t * cltp)16148 void rtw_clt_port_deinit(struct clt_port_t *cltp)
16149 {
16150 	_rtw_spinlock_free(&cltp->lock);
16151 }
_hw_client_port_alloc(_adapter * adapter)16152 static void _hw_client_port_alloc(_adapter *adapter)
16153 {
16154 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
16155 	struct clt_port_t  *cltp = &dvobj->clt_port;
16156 	_irqL irql;
16157 	int i;
16158 
16159 	#if 0
16160 	if (cltp->num > MAX_CLIENT_PORT_NUM) {
16161 		RTW_ERR(ADPT_FMT" cann't  alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
16162 		rtw_warn_on(1);
16163 		return;
16164 	}
16165 	#endif
16166 
16167 	if (adapter->client_id !=  MAX_CLIENT_PORT_NUM) {
16168 		RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
16169 			ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
16170 		return;
16171 	}
16172 	_enter_critical_bh(&cltp->lock, &irql);
16173 	for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
16174 		if (!(cltp->bmp & BIT(i)))
16175 			break;
16176 	}
16177 
16178 	if (i < MAX_CLIENT_PORT_NUM) {
16179 		adapter->client_id = i;
16180 		cltp->bmp |= BIT(i);
16181 		adapter->client_port = _clt_port_id[i];
16182 	}
16183 	cltp->num++;
16184 	_exit_critical_bh(&cltp->lock, &irql);
16185 	RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
16186 		__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
16187 }
_hw_client_port_free(_adapter * adapter)16188 static void _hw_client_port_free(_adapter *adapter)
16189 {
16190 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
16191 	struct clt_port_t  *cltp = &dvobj->clt_port;
16192 	_irqL irql;
16193 
16194 	#if 0
16195 	if (adapter->client_id >=  MAX_CLIENT_PORT_NUM) {
16196 		RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
16197 		/*rtw_warn_on(1);*/
16198 	}
16199 	#endif
16200 
16201 	RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
16202 		__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
16203 
16204 	_enter_critical_bh(&cltp->lock, &irql);
16205 	if (adapter->client_id !=  MAX_CLIENT_PORT_NUM) {
16206 		cltp->bmp &= ~ BIT(adapter->client_id);
16207 		adapter->client_id = MAX_CLIENT_PORT_NUM;
16208 		adapter->client_port = CLT_PORT_INVALID;
16209 	}
16210 	cltp->num--;
16211 	if (cltp->num < 0)
16212 		cltp->num = 0;
16213 	_exit_critical_bh(&cltp->lock, &irql);
16214 }
rtw_hw_client_port_allocate(_adapter * adapter)16215 void rtw_hw_client_port_allocate(_adapter *adapter)
16216 {
16217 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16218 
16219 	if (hal_spec->port_num != 5)
16220 		return;
16221 
16222 	_hw_client_port_alloc(adapter);
16223 }
rtw_hw_client_port_release(_adapter * adapter)16224 void rtw_hw_client_port_release(_adapter *adapter)
16225 {
16226 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16227 
16228 	if (hal_spec->port_num != 5)
16229 		return;
16230 
16231 	_hw_client_port_free(adapter);
16232 }
16233 #endif /*CONFIG_CLIENT_PORT_CFG*/
16234 
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)16235 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
16236 {
16237 	RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
16238 
16239 	rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
16240 
16241 	/* set net_type */
16242 	Set_MSR(Adapter, mode);
16243 
16244 	if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
16245 		if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
16246 			StopTxBeacon(Adapter);
16247 	} else if (mode == _HW_STATE_ADHOC_)
16248 		ResumeTxBeacon(Adapter);
16249 	else if (mode == _HW_STATE_AP_)
16250 		/* enable rx ps-poll */
16251 		rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
16252 
16253 	/* enable rx data frame */
16254 	rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
16255 
16256 #ifdef CONFIG_CLIENT_PORT_CFG
16257 	if (mode == _HW_STATE_STATION_)
16258 		rtw_hw_client_port_allocate(Adapter);
16259 	else
16260 		rtw_hw_client_port_release(Adapter);
16261 #endif
16262 #if defined(CONFIG_RTL8192F)
16263 		rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
16264 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
16265 #endif
16266 }
16267 #endif
16268 
16269 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)16270 u8	rtw_hal_antdiv_before_linked(_adapter *padapter)
16271 {
16272 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16273 	u8 cur_ant, change_ant;
16274 
16275 	if (!pHalData->AntDivCfg)
16276 		return _FALSE;
16277 
16278 	if (pHalData->sw_antdiv_bl_state == 0) {
16279 		pHalData->sw_antdiv_bl_state = 1;
16280 
16281 		rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
16282 		change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
16283 
16284 		return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
16285 	}
16286 
16287 	pHalData->sw_antdiv_bl_state = 0;
16288 	return _FALSE;
16289 }
16290 
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)16291 void	rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
16292 {
16293 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16294 
16295 	if (pHalData->AntDivCfg) {
16296 		/*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
16297 		/*select optimum_antenna for before linked =>For antenna diversity*/
16298 		if (dst->Rssi >=  src->Rssi) {/*keep org parameter*/
16299 			src->Rssi = dst->Rssi;
16300 			src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
16301 		}
16302 	}
16303 }
16304 #endif
16305 
16306 #ifdef CONFIG_PROC_DEBUG
16307 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)16308 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
16309 {
16310 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
16311 	struct phy_spec_t *phy_spec = &pHalData->phy_spec;
16312 
16313 	RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
16314 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
16315 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
16316 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index	[15:8]*/
16317 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index	[7:0]*/
16318 
16319 	RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
16320 	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]*/
16321 	/*VHT STBC Rx [23:16]
16322 	0 = not support
16323 	1 = support for 1 spatial stream
16324 	2 = support for 1 or 2 spatial streams
16325 	3 = support for 1 or 2 or 3 spatial streams
16326 	4 = support for 1 or 2 or 3 or 4 spatial streams*/
16327 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
16328 	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]*/
16329 	/*HT STBC Rx [7:0]
16330 	0 = not support
16331 	1 = support for 1 spatial stream
16332 	2 = support for 1 or 2 spatial streams
16333 	3 = support for 1 or 2 or 3 spatial streams*/
16334 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
16335 
16336 	RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
16337 	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]*/
16338 	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]*/
16339 	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]*/
16340 	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]*/
16341 	#ifdef CONFIG_BEAMFORMING
16342 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
16343 	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]*/
16344 	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]*/
16345 	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]*/
16346 	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]*/
16347 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF)  ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
16348 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
16349 
16350 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
16351 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
16352 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
16353 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
16354 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
16355 	#endif
16356 }
16357 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)16358 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
16359 {
16360 	u8 phy_cap = _FALSE;
16361 
16362 	/* STBC */
16363 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
16364 	RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16365 
16366 	phy_cap = _FALSE;
16367 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
16368 	RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16369 
16370 	/* LDPC support */
16371 	phy_cap = _FALSE;
16372 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
16373 	RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16374 
16375 	phy_cap = _FALSE;
16376 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
16377 	RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16378 
16379 	#ifdef CONFIG_BEAMFORMING
16380 	phy_cap = _FALSE;
16381 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
16382 	RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16383 
16384 	phy_cap = _FALSE;
16385 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
16386 	RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16387 
16388 	phy_cap = _FALSE;
16389 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
16390 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16391 
16392 	phy_cap = _FALSE;
16393 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
16394 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16395 	#endif
16396 }
16397 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)16398 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
16399 {
16400 	RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
16401 #ifdef CONFIG_PHY_CAPABILITY_QUERY
16402 	rtw_dump_phy_cap_by_phydmapi(sel, adapter);
16403 #else
16404 	rtw_dump_phy_cap_by_hal(sel, adapter);
16405 #endif
16406 }
16407 #endif
16408 
translate_dbm_to_percentage(s16 signal)16409 inline s16 translate_dbm_to_percentage(s16 signal)
16410 {
16411 	if ((signal <= -100) || (signal >= 20))
16412 		return	0;
16413 	else if (signal >= 0)
16414 		return	100;
16415 	else
16416 		return 100 + signal;
16417 }
16418 
16419 #ifdef CONFIG_SWTIMER_BASED_TXBCN
16420 #ifdef CONFIG_BCN_RECOVERY
16421 #define REG_CPU_MGQ_INFO	0x041C
16422 #define BIT_BCN_POLL			BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)16423 u8 rtw_ap_bcn_recovery(_adapter *padapter)
16424 {
16425 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
16426 
16427 	if (hal_data->issue_bcn_fail >= 2) {
16428 		RTW_ERR("%s ISSUE BCN Fail\n", __func__);
16429 		rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
16430 		hal_data->issue_bcn_fail = 0;
16431 	}
16432 	return _SUCCESS;
16433 }
16434 #endif /*CONFIG_BCN_RECOVERY*/
16435 
16436 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)16437 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
16438 {
16439 	u32 start_time = rtw_get_current_time();
16440 	u8 bcn_queue_empty = _FALSE;
16441 
16442 	do {
16443 		if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
16444 			bcn_queue_empty = _TRUE;
16445 			break;
16446 		}
16447 	} while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
16448 
16449 	if (bcn_queue_empty == _FALSE)
16450 		RTW_ERR("%s BCN queue not empty\n", __func__);
16451 
16452 	return bcn_queue_empty;
16453 }
16454 #endif /*CONFIG_BCN_XMIT_PROTECT*/
16455 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
16456 
16457 /**
16458  * rtw_hal_get_trx_path() - Get RF path related information
16459  * @d:		struct dvobj_priv*
16460  * @type:	RF type, nTnR
16461  * @tx:		Tx path
16462  * @rx:		Rx path
16463  *
16464  * Get RF type, TX path and RX path information.
16465  */
rtw_hal_get_trx_path(struct dvobj_priv * d,enum rf_type * type,enum bb_path * tx,enum bb_path * rx)16466 void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
16467 			 enum bb_path *tx, enum bb_path *rx)
16468 {
16469 	struct _ADAPTER *a = dvobj_get_primary_adapter(d);
16470 	enum rf_type t = GET_HAL_RFPATH(a);
16471 
16472 	if (type)
16473 		*type = t;
16474 
16475 	if (tx || rx) {
16476 		u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
16477 		u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
16478 
16479 		if (!tx_bmp && !rx_bmp)
16480 			rf_type_to_default_trx_bmp(t, tx, rx);
16481 		else {
16482 			if (tx)
16483 				*tx = GET_HAL_TX_PATH_BMP(a);
16484 			if (rx)
16485 				*rx = GET_HAL_RX_PATH_BMP(a);
16486 		}
16487 	}
16488 }
16489 
16490 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
rtw_hal_switch_chnl_and_set_bw_offload(_adapter * adapter,u8 central_ch,u8 pri_ch_idx,u8 bw)16491 void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
16492 {
16493 	u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
16494 	PHAL_DATA_TYPE hal;
16495 	struct submit_ctx *chsw_sctx;
16496 
16497 	hal = GET_HAL_DATA(adapter);
16498 	chsw_sctx = &hal->chsw_sctx;
16499 
16500 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
16501 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
16502 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
16503 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_IQK_UPDATE_EN(h2c, 1);
16504 
16505 	rtw_sctx_init(chsw_sctx, 10);
16506 	rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
16507 	rtw_sctx_wait(chsw_sctx, __func__);
16508 }
16509 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
16510 
phy_get_capable_tx_num(_adapter * adapter,enum MGN_RATE rate)16511 u8 phy_get_capable_tx_num(_adapter *adapter, enum MGN_RATE rate)
16512 {
16513 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16514 	u8 tx_num = 0;
16515 
16516 	if (IS_1T_RATE(rate))
16517 		tx_num = hal_data->txpath_cap_num_nss[0];
16518 	else if (IS_2T_RATE(rate))
16519 		tx_num = hal_data->txpath_cap_num_nss[1];
16520 	else if (IS_3T_RATE(rate))
16521 		tx_num = hal_data->txpath_cap_num_nss[2];
16522 	else if (IS_4T_RATE(rate))
16523 		tx_num = hal_data->txpath_cap_num_nss[3];
16524 	else
16525 		rtw_warn_on(1);
16526 
16527 	return tx_num == 0 ? RF_1TX : tx_num - 1;
16528 }
16529 
phy_get_current_tx_num(_adapter * adapter,enum MGN_RATE rate)16530 u8 phy_get_current_tx_num(_adapter *adapter, enum MGN_RATE rate)
16531 {
16532 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16533 	u8 tx_num = 0;
16534 
16535 	if (IS_1T_RATE(rate))
16536 		tx_num = hal_data->txpath_num_nss[0];
16537 	else if (IS_2T_RATE(rate))
16538 		tx_num = hal_data->txpath_num_nss[1];
16539 	else if (IS_3T_RATE(rate))
16540 		tx_num = hal_data->txpath_num_nss[2];
16541 	else if (IS_4T_RATE(rate))
16542 		tx_num = hal_data->txpath_num_nss[3];
16543 	else
16544 		rtw_warn_on(1);
16545 
16546 	return tx_num == 0 ? RF_1TX : tx_num - 1;
16547 }
16548 
16549 #ifdef CONFIG_RTL8812A
rtw_hal_set_8812a_vendor_ie(_adapter * padapter,u8 * pframe,uint * frlen)16550 u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
16551 	int vender_len = 7;
16552 	unsigned char	vendor_info[vender_len];
16553 	unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
16554 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
16555 
16556 	if( !IS_HARDWARE_TYPE_8812(padapter) )
16557 		return pframe;
16558 
16559 	_rtw_memset(vendor_info,0,vender_len);
16560 	_rtw_memcpy(vendor_info, REALTEK_OUI, 3);
16561 	vendor_info[4] =2;
16562 	if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
16563 		vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
16564 	else
16565 		vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
16566 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
16567 
16568 	return pframe;
16569 }
16570 #endif /*CONFIG_RTL8812A*/
16571 
rtw_enter_protsel(struct protsel * protsel,u32 sel)16572 static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
16573 {
16574 	int refcnt;
16575 
16576 	_enter_critical_mutex(&protsel->mutex, NULL);
16577 
16578 	refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
16579 
16580 	WARN_ON(refcnt > 1 && protsel->sel != sel);
16581 
16582 	protsel->sel = sel;
16583 
16584 	_exit_critical_mutex(&protsel->mutex, NULL);
16585 }
16586 
rtw_leave_protsel(struct protsel * protsel)16587 static inline void rtw_leave_protsel(struct protsel *protsel)
16588 {
16589 	int refcnt;
16590 
16591 	_enter_critical_mutex(&protsel->mutex, NULL);
16592 
16593 	refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
16594 
16595 	_exit_critical_mutex(&protsel->mutex, NULL);
16596 
16597 	WARN_ON(refcnt < 0);
16598 }
16599 
rtw_assert_protsel(struct protsel * protsel)16600 static inline bool rtw_assert_protsel(struct protsel *protsel)
16601 {
16602 	int refcnt = ATOMIC_READ(&protsel->refcnt);
16603 
16604 	if (refcnt > 0)
16605 		return true;
16606 
16607 	return false;
16608 }
16609 
16610 #ifdef CONFIG_PROTSEL_PORT
rtw_enter_protsel_port(_adapter * padapter,u8 port_sel)16611 void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
16612 {
16613 	u8 val8;
16614 
16615 	rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
16616 
16617 	val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
16618 	val8 &= ~BIT_MASK_PORT_CTRL_SEL;
16619 	val8 |= BIT_PORT_CTRL_SEL(port_sel);
16620 	rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
16621 }
16622 
rtw_assert_protsel_port(_adapter * padapter,u32 addr,u8 len)16623 bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
16624 {
16625 	if (!padapter->bup)	/* don't assert before IF up */
16626 		return true;
16627 
16628 	return rtw_assert_protsel(&padapter->dvobj->protsel_port);
16629 }
16630 
rtw_leave_protsel_port(_adapter * padapter)16631 void rtw_leave_protsel_port(_adapter *padapter)
16632 {
16633 	rtw_leave_protsel(&padapter->dvobj->protsel_port);
16634 }
16635 #endif
16636 
16637 #ifdef CONFIG_PROTSEL_ATIMDTIM
rtw_enter_protsel_atimdtim(_adapter * padapter,u8 port_sel)16638 void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
16639 {
16640 	/* 0~15 is for port 0 MBSSID setting
16641 	 * 16 is for port 1 setting
16642 	 * 17 is for port 2 setting
16643 	 * 18 is for port 3 setting
16644 	 * 19 is for port 4 setting
16645 	 */
16646 	u8 val8;
16647 
16648 	if (port_sel >= 1 && port_sel <= 4)
16649 		port_sel += 15;
16650 
16651 	rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
16652 
16653 	val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
16654 	val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
16655 	val8 |= BIT_ATIM_DTIM_SEL(port_sel);
16656 	rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
16657 }
16658 
rtw_assert_protsel_atimdtim(_adapter * padapter,u32 addr,u8 len)16659 bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
16660 {
16661 	return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
16662 }
16663 
rtw_leave_protsel_atimdtim(_adapter * padapter)16664 void rtw_leave_protsel_atimdtim(_adapter *padapter)
16665 {
16666 	rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
16667 }
16668 #endif
16669 
16670 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_enter_protsel_macsleep(_adapter * padapter,u8 sel)16671 void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
16672 {
16673 	u32 val32;
16674 
16675 	rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
16676 
16677 	val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
16678 	val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
16679 	val32 |= BIT_MACID_SLEEP_SEL(sel);
16680 	rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
16681 }
16682 
rtw_assert_protsel_macsleep(_adapter * padapter,u32 addr,u8 len)16683 bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
16684 {
16685 	return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
16686 }
16687 
rtw_leave_protsel_macsleep(_adapter * padapter)16688 void rtw_leave_protsel_macsleep(_adapter *padapter)
16689 {
16690 	rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
16691 }
16692 #endif
16693 
rtw_hal_bcn_early_rpt_c2h_handler(_adapter * padapter)16694 void rtw_hal_bcn_early_rpt_c2h_handler(_adapter *padapter)
16695 {
16696 
16697 	if(0)
16698 		RTW_INFO("Recv Bcn Early report!!\n");
16699 
16700 #ifdef CONFIG_TDLS
16701 #ifdef CONFIG_TDLS_CH_SW
16702 	if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
16703 		rtw_tdls_ch_sw_back_to_base_chnl(padapter);
16704 #endif
16705 #endif
16706 }
16707