• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,const char * hw_alpha2,u8 hw_chplan,u8 hw_chplan_6g,BOOLEAN AutoLoadFail)380 void hal_com_config_channel_plan(
381 		PADAPTER padapter,
382 		const char *hw_alpha2,
383 		u8 hw_chplan,
384 		u8 hw_chplan_6g,
385 		BOOLEAN AutoLoadFail
386 )
387 {
388 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
389 	u8 force_hw_chplan = _FALSE;
390 
391 	/*
392 	* autoload fail, by pass all hw settings
393 	*/
394 	if (AutoLoadFail == _TRUE) {
395 		hw_alpha2 = NULL;
396 		hw_chplan = RTW_CHPLAN_UNSPECIFIED;
397 		goto init;
398 	}
399 
400 	/*
401 	* treat {0xFF, 0xFF} as unspecified
402 	*/
403 	if (hw_alpha2 && strncmp(hw_alpha2, "\xFF\xFF", 2) == 0)
404 		hw_alpha2 = NULL;
405 
406 	/*
407 	* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing
408 	* and check hw setting with only country code
409 	*/
410 	if (hw_chplan == 0xFF) {
411 		hw_chplan = RTW_CHPLAN_UNSPECIFIED;
412 		goto init;
413 	}
414 
415 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
416 	if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
417 		force_hw_chplan = _TRUE;
418 #endif
419 	hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
420 
421 init:
422 	rtw_rfctl_decide_init_chplan(adapter_to_rfctl(padapter), hw_alpha2, hw_chplan, hw_chplan_6g, force_hw_chplan);
423 }
424 
425 BOOLEAN
HAL_IsLegalChannel(PADAPTER Adapter,u32 Channel)426 HAL_IsLegalChannel(
427 		PADAPTER	Adapter,
428 		u32			Channel
429 )
430 {
431 	BOOLEAN bLegalChannel = _TRUE;
432 
433 	if (Channel > 14) {
434 		if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
435 			bLegalChannel = _FALSE;
436 			RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
437 		}
438 	} else if ((Channel <= 14) && (Channel >= 1)) {
439 		if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
440 			bLegalChannel = _FALSE;
441 			RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
442 		}
443 	} else {
444 		bLegalChannel = _FALSE;
445 		RTW_INFO("Channel is Invalid !!!\n");
446 	}
447 
448 	return bLegalChannel;
449 }
450 
451 static const u8 _MRateToHwRate[MGN_UNKNOWN] = {
452 	[MGN_1M] = DESC_RATE1M,
453 	[MGN_2M] = DESC_RATE2M,
454 	[MGN_5_5M] = DESC_RATE5_5M,
455 	[MGN_11M] = DESC_RATE11M,
456 	[MGN_6M] = DESC_RATE6M,
457 	[MGN_9M] = DESC_RATE9M,
458 	[MGN_12M] = DESC_RATE12M,
459 	[MGN_18M] = DESC_RATE18M,
460 	[MGN_24M] = DESC_RATE24M,
461 	[MGN_36M] = DESC_RATE36M,
462 	[MGN_48M] = DESC_RATE48M,
463 	[MGN_54M] = DESC_RATE54M,
464 	[MGN_MCS0] = DESC_RATEMCS0,
465 	[MGN_MCS1] = DESC_RATEMCS1,
466 	[MGN_MCS2] = DESC_RATEMCS2,
467 	[MGN_MCS3] = DESC_RATEMCS3,
468 	[MGN_MCS4] = DESC_RATEMCS4,
469 	[MGN_MCS5] = DESC_RATEMCS5,
470 	[MGN_MCS6] = DESC_RATEMCS6,
471 	[MGN_MCS7] = DESC_RATEMCS7,
472 	[MGN_MCS8] = DESC_RATEMCS8,
473 	[MGN_MCS9] = DESC_RATEMCS9,
474 	[MGN_MCS10] = DESC_RATEMCS10,
475 	[MGN_MCS11] = DESC_RATEMCS11,
476 	[MGN_MCS12] = DESC_RATEMCS12,
477 	[MGN_MCS13] = DESC_RATEMCS13,
478 	[MGN_MCS14] = DESC_RATEMCS14,
479 	[MGN_MCS15] = DESC_RATEMCS15,
480 	[MGN_MCS16] = DESC_RATEMCS16,
481 	[MGN_MCS17] = DESC_RATEMCS17,
482 	[MGN_MCS18] = DESC_RATEMCS18,
483 	[MGN_MCS19] = DESC_RATEMCS19,
484 	[MGN_MCS20] = DESC_RATEMCS20,
485 	[MGN_MCS21] = DESC_RATEMCS21,
486 	[MGN_MCS22] = DESC_RATEMCS22,
487 	[MGN_MCS23] = DESC_RATEMCS23,
488 	[MGN_MCS24] = DESC_RATEMCS24,
489 	[MGN_MCS25] = DESC_RATEMCS25,
490 	[MGN_MCS26] = DESC_RATEMCS26,
491 	[MGN_MCS27] = DESC_RATEMCS27,
492 	[MGN_MCS28] = DESC_RATEMCS28,
493 	[MGN_MCS29] = DESC_RATEMCS29,
494 	[MGN_MCS30] = DESC_RATEMCS30,
495 	[MGN_MCS31] = DESC_RATEMCS31,
496 	[MGN_VHT1SS_MCS0] = DESC_RATEVHTSS1MCS0,
497 	[MGN_VHT1SS_MCS1] = DESC_RATEVHTSS1MCS1,
498 	[MGN_VHT1SS_MCS2] = DESC_RATEVHTSS1MCS2,
499 	[MGN_VHT1SS_MCS3] = DESC_RATEVHTSS1MCS3,
500 	[MGN_VHT1SS_MCS4] = DESC_RATEVHTSS1MCS4,
501 	[MGN_VHT1SS_MCS5] = DESC_RATEVHTSS1MCS5,
502 	[MGN_VHT1SS_MCS6] = DESC_RATEVHTSS1MCS6,
503 	[MGN_VHT1SS_MCS7] = DESC_RATEVHTSS1MCS7,
504 	[MGN_VHT1SS_MCS8] = DESC_RATEVHTSS1MCS8,
505 	[MGN_VHT1SS_MCS9] = DESC_RATEVHTSS1MCS9,
506 	[MGN_VHT2SS_MCS0] = DESC_RATEVHTSS2MCS0,
507 	[MGN_VHT2SS_MCS1] = DESC_RATEVHTSS2MCS1,
508 	[MGN_VHT2SS_MCS2] = DESC_RATEVHTSS2MCS2,
509 	[MGN_VHT2SS_MCS3] = DESC_RATEVHTSS2MCS3,
510 	[MGN_VHT2SS_MCS4] = DESC_RATEVHTSS2MCS4,
511 	[MGN_VHT2SS_MCS5] = DESC_RATEVHTSS2MCS5,
512 	[MGN_VHT2SS_MCS6] = DESC_RATEVHTSS2MCS6,
513 	[MGN_VHT2SS_MCS7] = DESC_RATEVHTSS2MCS7,
514 	[MGN_VHT2SS_MCS8] = DESC_RATEVHTSS2MCS8,
515 	[MGN_VHT2SS_MCS9] = DESC_RATEVHTSS2MCS9,
516 	[MGN_VHT3SS_MCS0] = DESC_RATEVHTSS3MCS0,
517 	[MGN_VHT3SS_MCS1] = DESC_RATEVHTSS3MCS1,
518 	[MGN_VHT3SS_MCS2] = DESC_RATEVHTSS3MCS2,
519 	[MGN_VHT3SS_MCS3] = DESC_RATEVHTSS3MCS3,
520 	[MGN_VHT3SS_MCS4] = DESC_RATEVHTSS3MCS4,
521 	[MGN_VHT3SS_MCS5] = DESC_RATEVHTSS3MCS5,
522 	[MGN_VHT3SS_MCS6] = DESC_RATEVHTSS3MCS6,
523 	[MGN_VHT3SS_MCS7] = DESC_RATEVHTSS3MCS7,
524 	[MGN_VHT3SS_MCS8] = DESC_RATEVHTSS3MCS8,
525 	[MGN_VHT3SS_MCS9] = DESC_RATEVHTSS3MCS9,
526 	[MGN_VHT4SS_MCS0] = DESC_RATEVHTSS4MCS0,
527 	[MGN_VHT4SS_MCS1] = DESC_RATEVHTSS4MCS1,
528 	[MGN_VHT4SS_MCS2] = DESC_RATEVHTSS4MCS2,
529 	[MGN_VHT4SS_MCS3] = DESC_RATEVHTSS4MCS3,
530 	[MGN_VHT4SS_MCS4] = DESC_RATEVHTSS4MCS4,
531 	[MGN_VHT4SS_MCS5] = DESC_RATEVHTSS4MCS5,
532 	[MGN_VHT4SS_MCS6] = DESC_RATEVHTSS4MCS6,
533 	[MGN_VHT4SS_MCS7] = DESC_RATEVHTSS4MCS7,
534 	[MGN_VHT4SS_MCS8] = DESC_RATEVHTSS4MCS8,
535 	[MGN_VHT4SS_MCS9] = DESC_RATEVHTSS4MCS9,
536 };
537 
MRateToHwRate(enum MGN_RATE rate)538 u8 MRateToHwRate(enum MGN_RATE rate)
539 {
540 	u8 hw_rate = DESC_RATE1M; /* default value, also is zero */
541 
542 	if (rate < MGN_UNKNOWN)
543 		hw_rate = _MRateToHwRate[rate];
544 
545 	if (rate != MGN_1M && hw_rate == DESC_RATE1M)
546 		RTW_WARN("Invalid rate 0x%x in %s\n", rate, __FUNCTION__);
547 
548 	return hw_rate;
549 }
550 
551 const char * const _HDATA_RATE[DESC_RATE_NUM + 1] = {
552 	[DESC_RATE1M] = "CCK_1M",
553 	[DESC_RATE2M] = "CCK_2M",
554 	[DESC_RATE5_5M] = "CCK5_5M",
555 	[DESC_RATE11M] = "CCK_11M",
556 	[DESC_RATE6M] = "OFDM_6M",
557 	[DESC_RATE9M] = "OFDM_9M",
558 	[DESC_RATE12M] = "OFDM_12M",
559 	[DESC_RATE18M] = "OFDM_18M",
560 	[DESC_RATE24M] = "OFDM_24M",
561 	[DESC_RATE36M] = "OFDM_36M",
562 	[DESC_RATE48M] = "OFDM_48M",
563 	[DESC_RATE54M] = "OFDM_54M",
564 	[DESC_RATEMCS0] = "MCS0",
565 	[DESC_RATEMCS1] = "MCS1",
566 	[DESC_RATEMCS2] = "MCS2",
567 	[DESC_RATEMCS3] = "MCS3",
568 	[DESC_RATEMCS4] = "MCS4",
569 	[DESC_RATEMCS5] = "MCS5",
570 	[DESC_RATEMCS6] = "MCS6",
571 	[DESC_RATEMCS7] = "MCS7",
572 	[DESC_RATEMCS8] = "MCS8",
573 	[DESC_RATEMCS9] = "MCS9",
574 	[DESC_RATEMCS10] = "MCS10",
575 	[DESC_RATEMCS11] = "MCS11",
576 	[DESC_RATEMCS12] = "MCS12",
577 	[DESC_RATEMCS13] = "MCS13",
578 	[DESC_RATEMCS14] = "MCS14",
579 	[DESC_RATEMCS15] = "MCS15",
580 	[DESC_RATEMCS16] = "MCS16",
581 	[DESC_RATEMCS17] = "MCS17",
582 	[DESC_RATEMCS18] = "MCS18",
583 	[DESC_RATEMCS19] = "MCS19",
584 	[DESC_RATEMCS20] = "MCS20",
585 	[DESC_RATEMCS21] = "MCS21",
586 	[DESC_RATEMCS22] = "MCS22",
587 	[DESC_RATEMCS23] = "MCS23",
588 	[DESC_RATEMCS24] = "MCS24",
589 	[DESC_RATEMCS25] = "MCS25",
590 	[DESC_RATEMCS26] = "MCS26",
591 	[DESC_RATEMCS27] = "MCS27",
592 	[DESC_RATEMCS28] = "MCS28",
593 	[DESC_RATEMCS29] = "MCS29",
594 	[DESC_RATEMCS30] = "MCS30",
595 	[DESC_RATEMCS31] = "MCS31",
596 	[DESC_RATEVHTSS1MCS0] = "VHT1SMCS0",
597 	[DESC_RATEVHTSS1MCS1] = "VHT1SMCS1",
598 	[DESC_RATEVHTSS1MCS2] = "VHT1SMCS2",
599 	[DESC_RATEVHTSS1MCS3] = "VHT1SMCS3",
600 	[DESC_RATEVHTSS1MCS4] = "VHT1SMCS4",
601 	[DESC_RATEVHTSS1MCS5] = "VHT1SMCS5",
602 	[DESC_RATEVHTSS1MCS6] = "VHT1SMCS6",
603 	[DESC_RATEVHTSS1MCS7] = "VHT1SMCS7",
604 	[DESC_RATEVHTSS1MCS8] = "VHT1SMCS8",
605 	[DESC_RATEVHTSS1MCS9] = "VHT1SMCS9",
606 	[DESC_RATEVHTSS2MCS0] = "VHT2SMCS0",
607 	[DESC_RATEVHTSS2MCS1] = "VHT2SMCS1",
608 	[DESC_RATEVHTSS2MCS2] = "VHT2SMCS2",
609 	[DESC_RATEVHTSS2MCS3] = "VHT2SMCS3",
610 	[DESC_RATEVHTSS2MCS4] = "VHT2SMCS4",
611 	[DESC_RATEVHTSS2MCS5] = "VHT2SMCS5",
612 	[DESC_RATEVHTSS2MCS6] = "VHT2SMCS6",
613 	[DESC_RATEVHTSS2MCS7] = "VHT2SMCS7",
614 	[DESC_RATEVHTSS2MCS8] = "VHT2SMCS8",
615 	[DESC_RATEVHTSS2MCS9] = "VHT2SMCS9",
616 	[DESC_RATEVHTSS3MCS0] = "VHT3SMCS0",
617 	[DESC_RATEVHTSS3MCS1] = "VHT3SMCS1",
618 	[DESC_RATEVHTSS3MCS2] = "VHT3SMCS2",
619 	[DESC_RATEVHTSS3MCS3] = "VHT3SMCS3",
620 	[DESC_RATEVHTSS3MCS4] = "VHT3SMCS4",
621 	[DESC_RATEVHTSS3MCS5] = "VHT3SMCS5",
622 	[DESC_RATEVHTSS3MCS6] = "VHT3SMCS6",
623 	[DESC_RATEVHTSS3MCS7] = "VHT3SMCS7",
624 	[DESC_RATEVHTSS3MCS8] = "VHT3SMCS8",
625 	[DESC_RATEVHTSS3MCS9] = "VHT3SMCS9",
626 	[DESC_RATEVHTSS4MCS0] = "VHT4SMCS0",
627 	[DESC_RATEVHTSS4MCS1] = "VHT4SMCS1",
628 	[DESC_RATEVHTSS4MCS2] = "VHT4SMCS2",
629 	[DESC_RATEVHTSS4MCS3] = "VHT4SMCS3",
630 	[DESC_RATEVHTSS4MCS4] = "VHT4SMCS4",
631 	[DESC_RATEVHTSS4MCS5] = "VHT4SMCS5",
632 	[DESC_RATEVHTSS4MCS6] = "VHT4SMCS6",
633 	[DESC_RATEVHTSS4MCS7] = "VHT4SMCS7",
634 	[DESC_RATEVHTSS4MCS8] = "VHT4SMCS8",
635 	[DESC_RATEVHTSS4MCS9] = "VHT4SMCS9",
636 	[DESC_RATE_NUM] = "UNKNOWN",
637 };
638 
639 static const u8 _hw_rate_to_m_rate[DESC_RATE_NUM] = {
640 	[DESC_RATE1M] = MGN_1M,
641 	[DESC_RATE2M] = MGN_2M,
642 	[DESC_RATE5_5M] = MGN_5_5M,
643 	[DESC_RATE11M] = MGN_11M,
644 	[DESC_RATE6M] = MGN_6M,
645 	[DESC_RATE9M] = MGN_9M,
646 	[DESC_RATE12M] = MGN_12M,
647 	[DESC_RATE18M] = MGN_18M,
648 	[DESC_RATE24M] = MGN_24M,
649 	[DESC_RATE36M] = MGN_36M,
650 	[DESC_RATE48M] = MGN_48M,
651 	[DESC_RATE54M] = MGN_54M,
652 	[DESC_RATEMCS0] = MGN_MCS0,
653 	[DESC_RATEMCS1] = MGN_MCS1,
654 	[DESC_RATEMCS2] = MGN_MCS2,
655 	[DESC_RATEMCS3] = MGN_MCS3,
656 	[DESC_RATEMCS4] = MGN_MCS4,
657 	[DESC_RATEMCS5] = MGN_MCS5,
658 	[DESC_RATEMCS6] = MGN_MCS6,
659 	[DESC_RATEMCS7] = MGN_MCS7,
660 	[DESC_RATEMCS8] = MGN_MCS8,
661 	[DESC_RATEMCS9] = MGN_MCS9,
662 	[DESC_RATEMCS10] = MGN_MCS10,
663 	[DESC_RATEMCS11] = MGN_MCS11,
664 	[DESC_RATEMCS12] = MGN_MCS12,
665 	[DESC_RATEMCS13] = MGN_MCS13,
666 	[DESC_RATEMCS14] = MGN_MCS14,
667 	[DESC_RATEMCS15] = MGN_MCS15,
668 	[DESC_RATEMCS16] = MGN_MCS16,
669 	[DESC_RATEMCS17] = MGN_MCS17,
670 	[DESC_RATEMCS18] = MGN_MCS18,
671 	[DESC_RATEMCS19] = MGN_MCS19,
672 	[DESC_RATEMCS20] = MGN_MCS20,
673 	[DESC_RATEMCS21] = MGN_MCS21,
674 	[DESC_RATEMCS22] = MGN_MCS22,
675 	[DESC_RATEMCS23] = MGN_MCS23,
676 	[DESC_RATEMCS24] = MGN_MCS24,
677 	[DESC_RATEMCS25] = MGN_MCS25,
678 	[DESC_RATEMCS26] = MGN_MCS26,
679 	[DESC_RATEMCS27] = MGN_MCS27,
680 	[DESC_RATEMCS28] = MGN_MCS28,
681 	[DESC_RATEMCS29] = MGN_MCS29,
682 	[DESC_RATEMCS30] = MGN_MCS30,
683 	[DESC_RATEMCS31] = MGN_MCS31,
684 	[DESC_RATEVHTSS1MCS0] = MGN_VHT1SS_MCS0,
685 	[DESC_RATEVHTSS1MCS1] = MGN_VHT1SS_MCS1,
686 	[DESC_RATEVHTSS1MCS2] = MGN_VHT1SS_MCS2,
687 	[DESC_RATEVHTSS1MCS3] = MGN_VHT1SS_MCS3,
688 	[DESC_RATEVHTSS1MCS4] = MGN_VHT1SS_MCS4,
689 	[DESC_RATEVHTSS1MCS5] = MGN_VHT1SS_MCS5,
690 	[DESC_RATEVHTSS1MCS6] = MGN_VHT1SS_MCS6,
691 	[DESC_RATEVHTSS1MCS7] = MGN_VHT1SS_MCS7,
692 	[DESC_RATEVHTSS1MCS8] = MGN_VHT1SS_MCS8,
693 	[DESC_RATEVHTSS1MCS9] = MGN_VHT1SS_MCS9,
694 	[DESC_RATEVHTSS2MCS0] = MGN_VHT2SS_MCS0,
695 	[DESC_RATEVHTSS2MCS1] = MGN_VHT2SS_MCS1,
696 	[DESC_RATEVHTSS2MCS2] = MGN_VHT2SS_MCS2,
697 	[DESC_RATEVHTSS2MCS3] = MGN_VHT2SS_MCS3,
698 	[DESC_RATEVHTSS2MCS4] = MGN_VHT2SS_MCS4,
699 	[DESC_RATEVHTSS2MCS5] = MGN_VHT2SS_MCS5,
700 	[DESC_RATEVHTSS2MCS6] = MGN_VHT2SS_MCS6,
701 	[DESC_RATEVHTSS2MCS7] = MGN_VHT2SS_MCS7,
702 	[DESC_RATEVHTSS2MCS8] = MGN_VHT2SS_MCS8,
703 	[DESC_RATEVHTSS2MCS9] = MGN_VHT2SS_MCS9,
704 	[DESC_RATEVHTSS3MCS0] = MGN_VHT3SS_MCS0,
705 	[DESC_RATEVHTSS3MCS1] = MGN_VHT3SS_MCS1,
706 	[DESC_RATEVHTSS3MCS2] = MGN_VHT3SS_MCS2,
707 	[DESC_RATEVHTSS3MCS3] = MGN_VHT3SS_MCS3,
708 	[DESC_RATEVHTSS3MCS4] = MGN_VHT3SS_MCS4,
709 	[DESC_RATEVHTSS3MCS5] = MGN_VHT3SS_MCS5,
710 	[DESC_RATEVHTSS3MCS6] = MGN_VHT3SS_MCS6,
711 	[DESC_RATEVHTSS3MCS7] = MGN_VHT3SS_MCS7,
712 	[DESC_RATEVHTSS3MCS8] = MGN_VHT3SS_MCS8,
713 	[DESC_RATEVHTSS3MCS9] = MGN_VHT3SS_MCS9,
714 	[DESC_RATEVHTSS4MCS0] = MGN_VHT4SS_MCS0,
715 	[DESC_RATEVHTSS4MCS1] = MGN_VHT4SS_MCS1,
716 	[DESC_RATEVHTSS4MCS2] = MGN_VHT4SS_MCS2,
717 	[DESC_RATEVHTSS4MCS3] = MGN_VHT4SS_MCS3,
718 	[DESC_RATEVHTSS4MCS4] = MGN_VHT4SS_MCS4,
719 	[DESC_RATEVHTSS4MCS5] = MGN_VHT4SS_MCS5,
720 	[DESC_RATEVHTSS4MCS6] = MGN_VHT4SS_MCS6,
721 	[DESC_RATEVHTSS4MCS7] = MGN_VHT4SS_MCS7,
722 	[DESC_RATEVHTSS4MCS8] = MGN_VHT4SS_MCS8,
723 	[DESC_RATEVHTSS4MCS9] = MGN_VHT4SS_MCS9,
724 };
725 
hw_rate_to_m_rate(u8 hw_rate)726 u8 hw_rate_to_m_rate(u8 hw_rate)
727 {
728 	u8 rate = MGN_1M; /* default value */
729 
730 	if (hw_rate < DESC_RATE_NUM)
731 		rate = _hw_rate_to_m_rate[hw_rate];
732 	else
733 		RTW_WARN("Invalid hw_rate 0x%x in %s\n", hw_rate, __FUNCTION__);
734 
735 	return rate;
736 }
737 
738 #ifdef CONFIG_RTW_DEBUG
dump_hw_rate_map_test(void * sel)739 void dump_hw_rate_map_test(void *sel)
740 {
741 	RATE_SECTION rs;
742 	u8 hw_rate;
743 	enum MGN_RATE m_rate;
744 	int i;
745 
746 	for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
747 		for (i = 0; i < rates_by_sections[rs].rate_num; i++) {
748 			hw_rate = MRateToHwRate(rates_by_sections[rs].rates[i]);
749 			RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
750 				, MGN_RATE_STR(rates_by_sections[rs].rates[i]), rates_by_sections[rs].rates[i]
751 				, HDATA_RATE(hw_rate), hw_rate
752 			);
753 		}
754 		if (rs == HT_4SS) { /* show MCS32 after MCS31 */
755 			hw_rate = MRateToHwRate(MGN_MCS32);
756 			RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
757 				, MGN_RATE_STR(MGN_MCS32), MGN_MCS32
758 				, HDATA_RATE(hw_rate), hw_rate
759 			);
760 		}
761 	}
762 	hw_rate = MRateToHwRate(MGN_UNKNOWN);
763 	RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
764 		, MGN_RATE_STR(MGN_UNKNOWN), MGN_UNKNOWN
765 		, HDATA_RATE(hw_rate), hw_rate
766 	);
767 
768 	for (i = DESC_RATE1M; i <= DESC_RATE_NUM; i++) {
769 		m_rate = hw_rate_to_m_rate(i);
770 		RTW_PRINT_SEL(sel, "hw_rate:%s(%d) to m_rate:%s(%d)\n"
771 			, HDATA_RATE(i), i
772 			, MGN_RATE_STR(m_rate), m_rate
773 		);
774 	}
775 }
776 #endif /* CONFIG_RTW_DEBUG */
777 
HalSetBrateCfg(PADAPTER Adapter,u8 * mBratesOS,u16 * pBrateCfg)778 void	HalSetBrateCfg(
779 	PADAPTER		Adapter,
780 	u8			*mBratesOS,
781 	u16			*pBrateCfg)
782 {
783 	u8	i, is_brate, brate;
784 
785 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
786 		is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
787 		brate = mBratesOS[i] & 0x7f;
788 
789 		if (is_brate) {
790 			switch (brate) {
791 			case IEEE80211_CCK_RATE_1MB:
792 				*pBrateCfg |= RATE_1M;
793 				break;
794 			case IEEE80211_CCK_RATE_2MB:
795 				*pBrateCfg |= RATE_2M;
796 				break;
797 			case IEEE80211_CCK_RATE_5MB:
798 				*pBrateCfg |= RATE_5_5M;
799 				break;
800 			case IEEE80211_CCK_RATE_11MB:
801 				*pBrateCfg |= RATE_11M;
802 				break;
803 			case IEEE80211_OFDM_RATE_6MB:
804 				*pBrateCfg |= RATE_6M;
805 				break;
806 			case IEEE80211_OFDM_RATE_9MB:
807 				*pBrateCfg |= RATE_9M;
808 				break;
809 			case IEEE80211_OFDM_RATE_12MB:
810 				*pBrateCfg |= RATE_12M;
811 				break;
812 			case IEEE80211_OFDM_RATE_18MB:
813 				*pBrateCfg |= RATE_18M;
814 				break;
815 			case IEEE80211_OFDM_RATE_24MB:
816 				*pBrateCfg |= RATE_24M;
817 				break;
818 			case IEEE80211_OFDM_RATE_36MB:
819 				*pBrateCfg |= RATE_36M;
820 				break;
821 			case IEEE80211_OFDM_RATE_48MB:
822 				*pBrateCfg |= RATE_48M;
823 				break;
824 			case IEEE80211_OFDM_RATE_54MB:
825 				*pBrateCfg |= RATE_54M;
826 				break;
827 			}
828 		}
829 	}
830 }
831 
832 static void
_OneOutPipeMapping(PADAPTER pAdapter)833 _OneOutPipeMapping(
834 		PADAPTER	pAdapter
835 )
836 {
837 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
838 
839 	pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
840 	pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
841 	pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
842 	pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
843 
844 	pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
845 	pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
846 	pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
847 	pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
848 }
849 
850 static void
_TwoOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)851 _TwoOutPipeMapping(
852 		PADAPTER	pAdapter,
853 		BOOLEAN		bWIFICfg
854 )
855 {
856 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
857 
858 	if (bWIFICfg) { /* WMM */
859 
860 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
861 		/* {  0, 	1, 	0, 	1, 	0, 	0, 	0, 	0, 		0	}; */
862 		/* 0:ep_0 num, 1:ep_1 num */
863 
864 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
865 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
866 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
867 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
868 
869 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
870 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
871 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
872 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
873 
874 	} else { /* typical setting */
875 
876 
877 		/* BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA */
878 		/* {  1, 	1, 	0, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
879 		/* 0:ep_0 num, 1:ep_1 num */
880 
881 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
882 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
883 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
884 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
885 
886 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
887 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
888 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
889 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
890 
891 	}
892 
893 }
894 
_ThreeOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)895 static void _ThreeOutPipeMapping(
896 		PADAPTER	pAdapter,
897 		BOOLEAN		bWIFICfg
898 )
899 {
900 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
901 
902 	if (bWIFICfg) { /* for WMM */
903 
904 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
905 		/* {  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	}; */
906 		/* 0:H, 1:N, 2:L */
907 
908 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
909 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
910 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
911 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* 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 		/* {  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
923 		/* 0:H, 1:N, 2:L */
924 
925 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
926 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
927 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
928 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* 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 #if 0
938 static void _FourOutPipeMapping(
939 		PADAPTER	pAdapter,
940 		BOOLEAN		bWIFICfg
941 )
942 {
943 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
944 
945 	if (bWIFICfg) { /* for WMM */
946 
947 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
948 		/* {  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	}; */
949 		/* 0:H, 1:N, 2:L ,3:E */
950 
951 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
952 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
953 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
954 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
955 
956 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
957 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
958 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
959 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
960 
961 	} else { /* typical setting */
962 
963 
964 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
965 		/* {  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
966 		/* 0:H, 1:N, 2:L */
967 
968 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
969 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
970 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
971 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
972 
973 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
974 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
975 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
976 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
977 	}
978 
979 }
980 #endif
981 BOOLEAN
Hal_MappingOutPipe(PADAPTER pAdapter,u8 NumOutPipe)982 Hal_MappingOutPipe(
983 		PADAPTER	pAdapter,
984 		u8		NumOutPipe
985 )
986 {
987 	struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
988 
989 	BOOLEAN	 bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
990 
991 	BOOLEAN result = _TRUE;
992 
993 	switch (NumOutPipe) {
994 	case 2:
995 		_TwoOutPipeMapping(pAdapter, bWIFICfg);
996 		break;
997 	case 3:
998 	case 4:
999 	case 5:
1000 	case 6:
1001 		_ThreeOutPipeMapping(pAdapter, bWIFICfg);
1002 		break;
1003 	case 1:
1004 		_OneOutPipeMapping(pAdapter);
1005 		break;
1006 	default:
1007 		result = _FALSE;
1008 		break;
1009 	}
1010 
1011 	return result;
1012 
1013 }
1014 
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1015 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1016 {
1017 	if (padapter->hal_func.reqtxrpt)
1018 		padapter->hal_func.reqtxrpt(padapter, macid);
1019 }
1020 
rtw_get_sta_tx_stat(_adapter * adapter,u8 mac_id,u8 * macaddr)1021 int rtw_get_sta_tx_stat(_adapter *adapter, u8 mac_id, u8 *macaddr)
1022 {
1023 	struct sta_priv	*pstapriv_primary = &(GET_PRIMARY_ADAPTER(adapter))->stapriv;
1024 	struct submit_ctx gotc2h;
1025 	u8 cmd_ret;
1026 	int ret = _SUCCESS;
1027 
1028 	if (!adapter->hal_func.reqtxrpt) {
1029 		RTW_INFO("Not support.\n");
1030 		ret = RTW_NOT_SUPPORT;
1031 		goto exit;
1032 	}
1033 
1034 	if (pstapriv_primary->gotc2h != NULL) {
1035 		RTW_INFO("sta tx stat is processing.\n");
1036 		ret = RTW_BUSY;
1037 		goto exit;
1038 	}
1039 
1040 	rtw_sctx_init(&gotc2h, 60);
1041 	pstapriv_primary->gotc2h = &gotc2h;
1042 	_rtw_memcpy(pstapriv_primary->c2h_sta_mac, macaddr, ETH_ALEN);
1043 	pstapriv_primary->c2h_adapter_id = adapter->iface_id;
1044 
1045 	cmd_ret = rtw_reqtxrpt_cmd(adapter, mac_id);
1046 	if (cmd_ret != _SUCCESS) {
1047 		RTW_WARN("rtw_reqtxrpt_cmd fail\n");
1048 		ret = _FAIL;
1049 	} else
1050 		rtw_sctx_wait(&gotc2h, __func__);
1051 
1052 	enter_critical_bh(&pstapriv_primary->tx_rpt_lock);
1053 	pstapriv_primary->gotc2h = NULL;
1054 	exit_critical_bh(&pstapriv_primary->tx_rpt_lock);
1055 
1056 	if (cmd_ret == _SUCCESS && gotc2h.status != RTW_SCTX_DONE_SUCCESS) {
1057 		RTW_WARN("wait for C2H timeout, operation abort!!\n");
1058 		ret = _FAIL;
1059 	}
1060 
1061 	_rtw_memset(pstapriv_primary->c2h_sta_mac, 0, ETH_ALEN);
1062 	pstapriv_primary->c2h_adapter_id = CONFIG_IFACE_NUMBER;
1063 
1064 exit:
1065 	return ret;
1066 }
1067 
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1068 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1069 {
1070 	int i;
1071 	_adapter *iface;
1072 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1073 	u8 mac_addr[ETH_ALEN];
1074 
1075 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1076 	rtw_mbid_cam_dump(sel, __func__, adapter);
1077 #else
1078 	rtw_mi_hal_dump_macaddr(sel, adapter);
1079 #endif
1080 }
1081 
1082 /**
1083  * rtw_hal_set_hw_macaddr() - Set HW MAC address
1084  * @adapter:	struct PADAPTER
1085  * @mac_addr:   6-bytes mac address
1086  *
1087  * Set Wifi Mac address by writing to the relative HW registers,
1088  *
1089  */
rtw_hal_set_hw_macaddr(PADAPTER adapter,u8 * mac_addr)1090 void rtw_hal_set_hw_macaddr(PADAPTER adapter, u8 *mac_addr)
1091 {
1092 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
1093 	LeaveAllPowerSaveModeDirect(adapter);
1094 
1095 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1096 	rtw_hal_change_macaddr_mbid(adapter, mac_addr);
1097 #else
1098 	rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, mac_addr);
1099 #endif
1100 #ifdef CONFIG_RTW_DEBUG
1101 	rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1102 #endif
1103 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
1104 }
1105 
1106 #ifdef RTW_HALMAC
rtw_hal_hw_port_enable(_adapter * adapter)1107 void rtw_hal_hw_port_enable(_adapter *adapter)
1108 {
1109 #if 1
1110 	u8 port_enable = _TRUE;
1111 
1112 	rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1113 #else
1114 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1115 	struct rtw_halmac_bcn_ctrl bcn_ctrl;
1116 
1117 	_rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
1118 	bcn_ctrl.enable_bcn = 1;
1119 	bcn_ctrl.rx_bssid_fit = 1;
1120 	bcn_ctrl.rxbcn_rpt = 1;
1121 
1122 	/*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1123 				struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
1124 	if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
1125 		RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
1126 		rtw_warn_on(1);
1127 	}
1128 #endif
1129 }
rtw_hal_hw_port_disable(_adapter * adapter)1130 void rtw_hal_hw_port_disable(_adapter *adapter)
1131 {
1132 	u8 port_enable = _FALSE;
1133 
1134 	rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1135 }
1136 
rtw_restore_hw_port_cfg(_adapter * adapter)1137 void rtw_restore_hw_port_cfg(_adapter *adapter)
1138 {
1139 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1140 
1141 #else
1142 	int i;
1143 	_adapter *iface;
1144 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1145 
1146 	for (i = 0; i < dvobj->iface_nums; i++) {
1147 		iface = dvobj->padapters[i];
1148 		if (iface)
1149 			rtw_hal_hw_port_enable(iface);
1150 	}
1151 #endif
1152 }
1153 #endif
1154 
rtw_mi_set_mac_addr(_adapter * adapter)1155 void rtw_mi_set_mac_addr(_adapter *adapter)
1156 {
1157 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1158 	rtw_mi_set_mbid_cam(adapter);
1159 #else
1160 	int i;
1161 	_adapter *iface;
1162 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1163 
1164 	for (i = 0; i < dvobj->iface_nums; i++) {
1165 		iface = dvobj->padapters[i];
1166 		if (iface)
1167 			rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
1168 	}
1169 #endif
1170 	if (0)
1171 		rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1172 }
1173 
rtw_init_hal_com_default_value(PADAPTER Adapter)1174 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1175 {
1176 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
1177 	struct registry_priv *regsty = adapter_to_regsty(Adapter);
1178 
1179 	pHalData->AntDetection = 1;
1180 	pHalData->antenna_test = _FALSE;
1181 	pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
1182 	pHalData->ch_switch_offload = regsty->ch_switch_offload;
1183 	pHalData->multi_ch_switch_mode = 0;
1184 #ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
1185 	if (pHalData->ch_switch_offload == 0)
1186 		pHalData->ch_switch_offload = 1;
1187 #endif
1188 }
1189 
1190 #ifdef CONFIG_FW_C2H_REG
c2h_evt_clear(_adapter * adapter)1191 void c2h_evt_clear(_adapter *adapter)
1192 {
1193 	rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1194 }
1195 
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1196 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1197 {
1198 	s32 ret = _FAIL;
1199 	int i;
1200 	u8 trigger;
1201 
1202 	if (buf == NULL)
1203 		goto exit;
1204 
1205 	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1206 
1207 	if (trigger == C2H_EVT_HOST_CLOSE) {
1208 		goto exit; /* Not ready */
1209 	} else if (trigger != C2H_EVT_FW_CLOSE) {
1210 		goto clear_evt; /* Not a valid value */
1211 	}
1212 
1213 	_rtw_memset(buf, 0, C2H_REG_LEN);
1214 
1215 	/* Read ID, LEN, SEQ */
1216 	SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1217 	SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1218 	SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1219 
1220 	if (0) {
1221 		RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1222 			, C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1223 	}
1224 
1225 	/* Read the content */
1226 	for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1227 		*(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1228 
1229 	RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1230 
1231 	ret = _SUCCESS;
1232 
1233 clear_evt:
1234 	/*
1235 	* Clear event to notify FW we have read the command.
1236 	* If this field isn't clear, the FW won't update the next command message.
1237 	*/
1238 	c2h_evt_clear(adapter);
1239 
1240 exit:
1241 	return ret;
1242 }
1243 #endif /* CONFIG_FW_C2H_REG */
1244 
1245 #ifdef CONFIG_FW_C2H_PKT
1246 #ifndef DBG_C2H_PKT_PRE_HDL
1247 #define DBG_C2H_PKT_PRE_HDL 0
1248 #endif
1249 #ifndef DBG_C2H_PKT_HDL
1250 #define DBG_C2H_PKT_HDL 0
1251 #endif
rtw_hal_c2h_pkt_pre_hdl(_adapter * adapter,u8 * buf,u16 len)1252 void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1253 {
1254 #ifdef RTW_HALMAC
1255 	/* TODO: extract hal_mac IC's code here*/
1256 #else
1257 	u8 parse_fail = 0;
1258 	u8 hdl_here = 0;
1259 	s32 ret = _FAIL;
1260 	u8 id, seq, plen;
1261 	u8 *payload;
1262 
1263 	if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1264 		parse_fail = 1;
1265 		goto exit;
1266 	}
1267 
1268 	hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1269 	if (hdl_here)
1270 		ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1271 	else
1272 		ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1273 
1274 exit:
1275 	if (parse_fail)
1276 		RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1277 	else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1278 		RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1279 			, hdl_here ? "handle" : "enqueue"
1280 			, ret == _SUCCESS ? "ok" : "fail"
1281 		);
1282 		if (DBG_C2H_PKT_PRE_HDL >= 2)
1283 			RTW_PRINT_DUMP("dump: ", buf, len);
1284 	}
1285 #endif
1286 }
1287 
rtw_hal_c2h_pkt_hdl(_adapter * adapter,u8 * buf,u16 len)1288 void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1289 {
1290 #ifdef RTW_HALMAC
1291 	adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1292 #else
1293 	u8 parse_fail = 0;
1294 	u8 bypass = 0;
1295 	s32 ret = _FAIL;
1296 	u8 id, seq, plen;
1297 	u8 *payload;
1298 
1299 	if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1300 		parse_fail = 1;
1301 		goto exit;
1302 	}
1303 
1304 #ifdef CONFIG_WOWLAN
1305 	if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1306 		bypass = 1;
1307 		ret = _SUCCESS;
1308 		goto exit;
1309 	}
1310 #endif
1311 
1312 	ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1313 
1314 exit:
1315 	if (parse_fail)
1316 		RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1317 	else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1318 		RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1319 			, !bypass ? "handle" : "bypass"
1320 			, ret == _SUCCESS ? "ok" : "fail"
1321 		);
1322 		if (DBG_C2H_PKT_HDL >= 2)
1323 			RTW_PRINT_DUMP("dump: ", buf, len);
1324 	}
1325 #endif
1326 }
1327 #endif /* CONFIG_FW_C2H_PKT */
1328 
c2h_iqk_offload(_adapter * adapter,u8 * data,u8 len)1329 void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1330 {
1331 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1332 	struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1333 
1334 	RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1335 	if (0)
1336 		RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1337 
1338 	rtw_sctx_done(&iqk_sctx);
1339 }
1340 
c2h_iqk_offload_wait(_adapter * adapter,u32 timeout_ms)1341 int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1342 {
1343 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1344 	struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1345 
1346 	iqk_sctx->submit_time = rtw_get_current_time();
1347 	iqk_sctx->timeout_ms = timeout_ms;
1348 	iqk_sctx->status = RTW_SCTX_SUBMITTED;
1349 
1350 	return rtw_sctx_wait(iqk_sctx, __func__);
1351 }
1352 
1353 #ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX
c2h_txpwr_idx_offload_done(_adapter * adapter,u8 * data,u8 len)1354 void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len)
1355 {
1356 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1357 	struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1358 
1359 	if (0)
1360 		RTW_INFO("txpwr_idx offload finish in %dms\n", rtw_get_passing_time_ms(sctx->submit_time));
1361 	rtw_sctx_done(&sctx);
1362 }
1363 
c2h_txpwr_idx_offload_wait(_adapter * adapter)1364 int c2h_txpwr_idx_offload_wait(_adapter *adapter)
1365 {
1366 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1367 	struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1368 
1369 	return rtw_sctx_wait(sctx, __func__);
1370 }
1371 #endif
1372 
1373 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1374 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1375 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1376 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data)			LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1377 #define	GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1378 #define	GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1379 #define	GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1380 #define	GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1381 #define	GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1382 #define	GET_C2H_MAC_HIDDEN_RPT_BW(_data)				LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1383 #define	GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1384 #define	GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1385 #define	GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1386 
1387 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1388 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1389 #endif
1390 
1391 #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1392 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1393 {
1394 	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
1395 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1396 	enum rf_type rf_type;
1397 	u8 tx_path_num, rx_path_num;
1398 	int ret = _FAIL;
1399 
1400 	u8 uuid_x;
1401 	u8 uuid_y;
1402 	u8 uuid_z;
1403 	u16 uuid_crc;
1404 
1405 	u8 hci_type;
1406 	u8 package_type;
1407 	u8 tr_switch;
1408 	u8 wl_func;
1409 	u8 hw_stype;
1410 	u8 bw;
1411 	u8 ss_num = 4;
1412 	u8 ant_num;
1413 	u8 protocol;
1414 	u8 nic;
1415 
1416 	int i;
1417 
1418 	if (len < MAC_HIDDEN_RPT_LEN) {
1419 		RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1420 		goto exit;
1421 	}
1422 
1423 	uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1424 	uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1425 	uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1426 	uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1427 
1428 	hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1429 	package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1430 
1431 	tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1432 
1433 	wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1434 	hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1435 
1436 	bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1437 	ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1438 
1439 	protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1440 	nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1441 
1442 	if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1443 		for (i = 0; i < len; i++)
1444 			RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1445 
1446 		RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1447 		RTW_PRINT("hci_type:0x%x\n", hci_type);
1448 		RTW_PRINT("package_type:0x%x\n", package_type);
1449 		RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1450 		RTW_PRINT("wl_func:0x%x\n", wl_func);
1451 		RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1452 		RTW_PRINT("bw:0x%x\n", bw);
1453 		RTW_PRINT("ant_num:0x%x\n", ant_num);
1454 		RTW_PRINT("protocol:0x%x\n", protocol);
1455 		RTW_PRINT("nic:0x%x\n", nic);
1456 	}
1457 
1458 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
1459 	if (IS_8822C_SERIES(hal_data->version_id) || IS_8814B_SERIES(hal_data->version_id)) {
1460 		#define GET_C2H_MAC_HIDDEN_RPT_SS_NUM(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
1461 		ss_num = GET_C2H_MAC_HIDDEN_RPT_SS_NUM(data);
1462 
1463 		if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1464 			RTW_PRINT("ss_num:0x%x\n", ss_num);
1465 
1466 		if (ss_num == 0x03)
1467 			ss_num = 4;
1468 	}
1469 #endif
1470 
1471 #if defined(CONFIG_RTL8822C)
1472 	if (IS_8822C_SERIES(hal_data->version_id)) {
1473 		if (ant_num == 1)
1474 			hal_spec->rf_reg_trx_path_bmp = 0x22; /* 1T1R pathB */
1475 		if (hw_stype == 0xE)
1476 			hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */
1477 	}
1478 #endif
1479 	hal_data->PackageType = package_type;
1480 	hal_spec->hci_type = hci_type;
1481 	hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1482 	hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1483 	hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1484 
1485 	rf_type = rtw_chip_rftype_to_hal_rftype(adapter, 0);
1486 	if (!RF_TYPE_VALID(rf_type)) {
1487 		RTW_ERR("%s rtw_chip_rftype_to_hal_rftype failed\n", __func__);
1488 		goto exit;
1489 	}
1490 	hal_spec->rf_reg_path_avail_num = rtw_min(hal_spec->rf_reg_path_num, ant_num);
1491 	tx_path_num = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1492 	rx_path_num = rtw_min(rf_type_to_rf_rx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1493 	hal_spec->rf_reg_trx_path_bmp = rtw_restrict_trx_path_bmp_by_trx_num_lmt(
1494 		hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num, &tx_path_num, &rx_path_num);
1495 	if (!hal_spec->rf_reg_trx_path_bmp) {
1496 		RTW_ERR("%s rtw_restrict_trx_path_bmp_by_trx_num_lmt(0x%x, %u, %u) failed\n"
1497 			, __func__, hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num);
1498 		goto exit;
1499 	}
1500 	hal_spec->rf_reg_path_avail_num = rtw_max(tx_path_num, rx_path_num);
1501 
1502 	/*
1503 	* RF TX path num >= max_tx_cnt >= tx_nss_num
1504 	* ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1)
1505 	* Select at most 2 out of 4 TX RF path to do 1SS 2TX
1506 	*/
1507 	hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, tx_path_num);
1508 	hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt);
1509 	hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num);
1510 
1511 	hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rx_path_num);
1512 	hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num);
1513 
1514 	ret = _SUCCESS;
1515 
1516 exit:
1517 	return ret;
1518 }
1519 
c2h_mac_hidden_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1520 int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1521 {
1522 	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
1523 	int ret = _FAIL;
1524 
1525 	int i;
1526 
1527 	if (len < MAC_HIDDEN_RPT_2_LEN) {
1528 		RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1529 		goto exit;
1530 	}
1531 
1532 	if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1533 		for (i = 0; i < len; i++)
1534 			RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1535 	}
1536 
1537 	#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
1538 	if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {
1539 		#define GET_C2H_MAC_HIDDEN_RPT_IRV(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
1540 		u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
1541 
1542 		if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1543 			RTW_PRINT("irv:0x%x\n", irv);
1544 
1545 		if(irv != 0xf)
1546 			hal_data->version_id.CUTVersion = irv;
1547 	}
1548 	#endif
1549 
1550 	#if defined(CONFIG_8723F)
1551 	if (IS_8723F_SERIES(hal_data->version_id)) {
1552 		#define GET_C2H_MAC_HIDDEN_RPT_BT_SUPPORT(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 1)
1553 		#define GET_C2H_MAC_HIDDEN_RPT_5G_SUPPORT(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 1, 1)
1554 
1555 		struct hal_spec_t *hal_spec;
1556 		u8 bt_support = GET_C2H_MAC_HIDDEN_RPT_BT_SUPPORT(data);
1557 		u8 band_5g_support = GET_C2H_MAC_HIDDEN_RPT_5G_SUPPORT(data);
1558 
1559 		hal_spec = GET_HAL_SPEC(adapter);
1560 
1561 		if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1562 			RTW_PRINT("bt support:%u\n", bt_support);
1563 			RTW_PRINT("band 5g support:%u\n", band_5g_support);
1564 		}
1565 
1566 		hal_spec->rfpath_num_5g = (band_5g_support ? hal_spec->rfpath_num_5g : 0);
1567 		if(!band_5g_support)
1568 			hal_spec->band_cap &= ~BAND_CAP_5G;
1569 
1570 		hal_data->EEPROMBluetoothCoexist = bt_support;
1571 		/* 0 : solo module, 1 : combo module */
1572 		hal_data->InterfaceSel = bt_support;
1573 	}
1574 	#endif
1575 
1576 	ret = _SUCCESS;
1577 
1578 exit:
1579 	return ret;
1580 }
1581 
hal_read_mac_hidden_rpt(_adapter * adapter)1582 int hal_read_mac_hidden_rpt(_adapter *adapter)
1583 {
1584 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(adapter);
1585 	int ret = _FAIL;
1586 	int ret_fwdl;
1587 	u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1588 	systime start = rtw_get_current_time();
1589 	u32 cnt = 0;
1590 	u32 timeout_ms = 800;
1591 	u32 min_cnt = 10;
1592 	u8 id = C2H_DEFEATURE_RSVD;
1593 	int i;
1594 
1595 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1596 	u8 hci_type = rtw_get_intf_type(adapter);
1597 
1598 	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1599 		&& !rtw_is_hw_init_completed(adapter))
1600 		rtw_hal_power_on(adapter);
1601 #endif
1602 
1603 	/* inform FW mac hidden rpt from reg is needed */
1604 	rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1605 
1606 	/* download FW */
1607 	pHalData->not_xmitframe_fw_dl = 1;
1608 	ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1609 	pHalData->not_xmitframe_fw_dl = 0;
1610 	if (ret_fwdl != _SUCCESS)
1611 		goto mac_hidden_rpt_hdl;
1612 
1613 	/* polling for data ready */
1614 	start = rtw_get_current_time();
1615 	do {
1616 		cnt++;
1617 		id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1618 		if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1619 			break;
1620 		rtw_msleep_os(10);
1621 	} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1622 
1623 	if (id == C2H_MAC_HIDDEN_RPT) {
1624 		/* read data */
1625 		for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1626 			mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1627 	}
1628 
1629 	/* inform FW mac hidden rpt has read */
1630 	rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1631 
1632 mac_hidden_rpt_hdl:
1633 	c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1634 	c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1635 
1636 	if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1637 		ret = _SUCCESS;
1638 
1639 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1640 	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1641 		&& !rtw_is_hw_init_completed(adapter))
1642 		rtw_hal_power_off(adapter);
1643 #endif
1644 
1645 	RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1646 		, (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1647 
1648 	return ret;
1649 }
1650 #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1651 
c2h_defeature_dbg_hdl(_adapter * adapter,u8 * data,u8 len)1652 int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1653 {
1654 	int ret = _FAIL;
1655 
1656 	int i;
1657 
1658 	if (len < DEFEATURE_DBG_LEN) {
1659 		RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1660 		goto exit;
1661 	}
1662 
1663 	for (i = 0; i < len; i++)
1664 		RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1665 
1666 	ret = _SUCCESS;
1667 
1668 exit:
1669 	return ret;
1670 }
1671 
1672 #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1673 #define DBG_CUSTOMER_STR_RPT_HANDLE 0
1674 #endif
1675 
1676 #ifdef CONFIG_RTW_CUSTOMER_STR
rtw_hal_h2c_customer_str_req(_adapter * adapter)1677 s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1678 {
1679 	u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1680 
1681 	SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1682 	return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1683 }
1684 
1685 #define	C2H_CUSTOMER_STR_RPT_BYTE0(_data)		((u8 *)(_data))
1686 #define	C2H_CUSTOMER_STR_RPT_2_BYTE8(_data)		((u8 *)(_data))
1687 
c2h_customer_str_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1688 int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1689 {
1690 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1691 	int ret = _FAIL;
1692 	int i;
1693 
1694 	if (len < CUSTOMER_STR_RPT_LEN) {
1695 		RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1696 		goto exit;
1697 	}
1698 
1699 	if (DBG_CUSTOMER_STR_RPT_HANDLE)
1700 		RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1701 
1702 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1703 
1704 	if (dvobj->customer_str_sctx != NULL) {
1705 		if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1706 			RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1707 		_rtw_memcpy(dvobj->customer_str,  C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1708 		dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1709 	} else
1710 		RTW_WARN("%s sctx not set\n", __func__);
1711 
1712 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1713 
1714 	ret = _SUCCESS;
1715 
1716 exit:
1717 	return ret;
1718 }
1719 
c2h_customer_str_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1720 int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1721 {
1722 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1723 	int ret = _FAIL;
1724 	int i;
1725 
1726 	if (len < CUSTOMER_STR_RPT_2_LEN) {
1727 		RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1728 		goto exit;
1729 	}
1730 
1731 	if (DBG_CUSTOMER_STR_RPT_HANDLE)
1732 		RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1733 
1734 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1735 
1736 	if (dvobj->customer_str_sctx != NULL) {
1737 		if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1738 			RTW_WARN("%s rpt not ready\n", __func__);
1739 		_rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN,  C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1740 		rtw_sctx_done(&dvobj->customer_str_sctx);
1741 	} else
1742 		RTW_WARN("%s sctx not set\n", __func__);
1743 
1744 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1745 
1746 	ret = _SUCCESS;
1747 
1748 exit:
1749 	return ret;
1750 }
1751 
1752 /* read customer str */
rtw_hal_customer_str_read(_adapter * adapter,u8 * cs)1753 s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1754 {
1755 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1756 	struct submit_ctx sctx;
1757 	s32 ret = _SUCCESS;
1758 
1759 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1760 	if (dvobj->customer_str_sctx != NULL)
1761 		ret = _FAIL;
1762 	else {
1763 		rtw_sctx_init(&sctx, 2 * 1000);
1764 		dvobj->customer_str_sctx = &sctx;
1765 	}
1766 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1767 
1768 	if (ret == _FAIL) {
1769 		RTW_WARN("%s another handle ongoing\n", __func__);
1770 		goto exit;
1771 	}
1772 
1773 	ret = rtw_customer_str_req_cmd(adapter);
1774 	if (ret != _SUCCESS) {
1775 		RTW_WARN("%s read cmd fail\n", __func__);
1776 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1777 		dvobj->customer_str_sctx = NULL;
1778 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1779 		goto exit;
1780 	}
1781 
1782 	/* wait till rpt done or timeout */
1783 	rtw_sctx_wait(&sctx, __func__);
1784 
1785 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1786 	dvobj->customer_str_sctx = NULL;
1787 	if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1788 		_rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1789 	else
1790 		ret = _FAIL;
1791 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1792 
1793 exit:
1794 	return ret;
1795 }
1796 
rtw_hal_h2c_customer_str_write(_adapter * adapter,const u8 * cs)1797 s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1798 {
1799 	u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1800 	u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1801 	u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1802 	s32 ret;
1803 
1804 	SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1805 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1806 
1807 	SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1808 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1809 
1810 	SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1811 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1812 
1813 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1814 	if (ret != _SUCCESS) {
1815 		RTW_WARN("%s w1 fail\n", __func__);
1816 		goto exit;
1817 	}
1818 
1819 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1820 	if (ret != _SUCCESS) {
1821 		RTW_WARN("%s w2 fail\n", __func__);
1822 		goto exit;
1823 	}
1824 
1825 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1826 	if (ret != _SUCCESS) {
1827 		RTW_WARN("%s w3 fail\n", __func__);
1828 		goto exit;
1829 	}
1830 
1831 exit:
1832 	return ret;
1833 }
1834 
1835 /* write customer str and check if value reported is the same as requested */
rtw_hal_customer_str_write(_adapter * adapter,const u8 * cs)1836 s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1837 {
1838 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1839 	struct submit_ctx sctx;
1840 	s32 ret = _SUCCESS;
1841 
1842 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1843 	if (dvobj->customer_str_sctx != NULL)
1844 		ret = _FAIL;
1845 	else {
1846 		rtw_sctx_init(&sctx, 2 * 1000);
1847 		dvobj->customer_str_sctx = &sctx;
1848 	}
1849 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1850 
1851 	if (ret == _FAIL) {
1852 		RTW_WARN("%s another handle ongoing\n", __func__);
1853 		goto exit;
1854 	}
1855 
1856 	ret = rtw_customer_str_write_cmd(adapter, cs);
1857 	if (ret != _SUCCESS) {
1858 		RTW_WARN("%s write cmd fail\n", __func__);
1859 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1860 		dvobj->customer_str_sctx = NULL;
1861 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1862 		goto exit;
1863 	}
1864 
1865 	ret = rtw_customer_str_req_cmd(adapter);
1866 	if (ret != _SUCCESS) {
1867 		RTW_WARN("%s read cmd fail\n", __func__);
1868 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1869 		dvobj->customer_str_sctx = NULL;
1870 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1871 		goto exit;
1872 	}
1873 
1874 	/* wait till rpt done or timeout */
1875 	rtw_sctx_wait(&sctx, __func__);
1876 
1877 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1878 	dvobj->customer_str_sctx = NULL;
1879 	if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
1880 		if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
1881 			RTW_WARN("%s read back check fail\n", __func__);
1882 			RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
1883 			RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1884 			ret = _FAIL;
1885 		}
1886 	} else
1887 		ret = _FAIL;
1888 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1889 
1890 exit:
1891 	return ret;
1892 }
1893 #endif /* CONFIG_RTW_CUSTOMER_STR */
1894 
1895 #ifdef RTW_PER_CMD_SUPPORT_FW
1896 #define H2C_REQ_PER_RPT_LEN 5
1897 #define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)
1898 #define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)
1899 #define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value)	SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)
1900 
rtw_hal_set_req_per_rpt_cmd(_adapter * adapter,u8 group_macid,u8 rpt_type,u32 macid_bitmap)1901 u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,
1902 				      u8 rpt_type, u32 macid_bitmap)
1903 {
1904 	u8 ret = _FAIL;
1905 	u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};
1906 
1907 	SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);
1908 	SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);
1909 	SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);
1910 
1911 	ret = rtw_hal_fill_h2c_cmd(adapter,
1912 				   H2C_REQ_PER_RPT,
1913 				   H2C_REQ_PER_RPT_LEN,
1914 				   cmd_buf);
1915 	return ret;
1916 }
1917 
1918 #define	GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
1919 #define	GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1920 #define	GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
1921 #define	GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
1922 #define	GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data)	LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)
1923 #define	GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
1924 #define	GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)
1925 #define	GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
1926 #define	GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)
1927 #define	GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data)	LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)
1928 
1929 #define	GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
1930 #define	GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1931 #define	GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
1932 #define	GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
1933 #define	GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)
1934 #define	GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)
1935 #define	GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
1936 #define	GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)
1937 #define	GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
1938 #define	GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)
1939 #define	GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)
1940 #define	GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)
1941 
per_rate_rpt_update(_adapter * adapter,u8 mac_id,u8 per,u8 rate,u8 bw,u8 total_pkt)1942 static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,
1943 				u8 per, u8 rate,
1944 				u8 bw, u8 total_pkt)
1945 {
1946 #ifdef CONFIG_RTW_MESH
1947 	rtw_ieee80211s_update_metric(adapter, mac_id,
1948 				     per, rate,
1949 				     bw, total_pkt);
1950 #endif
1951 }
1952 
c2h_per_rate_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1953 int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1954 {
1955 	/* Now only consider type0, since it covers all params in type1
1956 	 * type0: mac_id, per, rate, bw, total_pkt
1957 	 * type1: mac_id, per, rate, bw
1958 	 */
1959 	u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};
1960 	u16 total_pkt[2] = {0};
1961 	int ret = _FAIL, i, macid_cnt = 0;
1962 
1963 	/* type0:
1964 	 * 1 macid includes   6 bytes info + 1 byte 0xff
1965 	 * 2 macid includes 2*6 bytes info
1966 	 */
1967 	if (!(len == 7 || len == 12)) {
1968 		RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);
1969 		goto exit;
1970 	}
1971 
1972 	macid_cnt++;
1973 	mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);
1974 	per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);
1975 	rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);
1976 	bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);
1977 	total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);
1978 
1979 	mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);
1980 	/* 0xff means no report anymore */
1981 	if (mac_id[1] == 0xff)
1982 		goto update_per;
1983 	if (len != 12) {
1984 		RTW_WARN("%s incorrect format\n", __FUNCTION__);
1985 		goto exit;
1986 	}
1987 	macid_cnt++;
1988 	per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);
1989 	rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);
1990 	bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);
1991 	total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);
1992 
1993 update_per:
1994 	for (i = 0; i < macid_cnt; i++) {
1995 		RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "
1996 			"rate = %u, bw = %u, total_pkt = %u\n",
1997 			__FUNCTION__, i, mac_id[i], per[i],
1998 			rate[i], bw[i], total_pkt[i]);
1999 		per_rate_rpt_update(adapter, mac_id[i],
2000 				    per[i], rate[i],
2001 				    bw[i], total_pkt[i]);
2002 	}
2003 	ret = _SUCCESS;
2004 exit:
2005 	return ret;
2006 }
2007 #endif /* RTW_PER_CMD_SUPPORT_FW */
2008 
2009 #ifdef CONFIG_LPS_ACK
2010 #define	GET_C2H_LPS_STATUS_RPT_GET_ACTION(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2011 #define	GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2012 #define DBG_LPS_STATUS_RPT 0
2013 
c2h_lps_status_rpt(PADAPTER adapter,u8 * data,u8 len)2014 int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len)
2015 {
2016 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
2017 	struct submit_ctx *lps_sctx = &pwrpriv->lps_ack_sctx;
2018 	u8 action = 0;
2019 	s8 status_code = 0;
2020 	int ret = _FAIL;
2021 
2022 	if (len < LPS_STATUS_RPT_LEN) {
2023 		RTW_WARN("%s len(%u) < %d\n", __func__, len, LPS_STATUS_RPT_LEN);
2024 		goto exit;
2025 	}
2026 
2027 	action = GET_C2H_LPS_STATUS_RPT_GET_ACTION(data);
2028 	status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data);
2029 
2030 	/* action=0: report force leave null data status */
2031 	/* action=1: report Rf on status when receiving a SetPwrMode H2C with PwrState = RFON */
2032 	switch (action) {
2033 		case 0:
2034 			/* status code 0: success, 1: no ack, 2: timeout, 3: cancel */
2035 		case 1:
2036 			/* status code 0: FW has already turn to RFON */
2037 			pwrpriv->lps_ack_status = status_code;
2038 
2039 			if (DBG_LPS_STATUS_RPT)
2040 				RTW_INFO("=== [C2H LPS Action(%d)] LPS Status Code:%d ===\n", action, status_code);
2041 
2042 			break;
2043 		default:
2044 			RTW_INFO("UnKnown Action(%d) for C2H LPS RPT\n", action);
2045 			break;
2046 	}
2047 
2048 	rtw_sctx_done(&lps_sctx);
2049 	ret = _SUCCESS;
2050 
2051 exit:
2052 	return ret;
2053 }
2054 #endif /* CONFIG_LPS_ACK */
2055 
rtw_hal_update_sta_wset(_adapter * adapter,struct sta_info * psta)2056 void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
2057 {
2058 	u8 w_set = 0;
2059 
2060 	if (psta->wireless_mode & WIRELESS_11B)
2061 		w_set |= WIRELESS_CCK;
2062 
2063 	if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
2064 		w_set |= WIRELESS_OFDM;
2065 
2066 	if ((psta->wireless_mode & WIRELESS_11_24N) || (psta->wireless_mode & WIRELESS_11_5N))
2067 		w_set |= WIRELESS_HT;
2068 
2069 	if (psta->wireless_mode & WIRELESS_11AC)
2070 		w_set |= WIRELESS_VHT;
2071 
2072 	psta->cmn.support_wireless_set = w_set;
2073 }
2074 
rtw_hal_update_sta_mimo_type(_adapter * adapter,struct sta_info * psta)2075 void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
2076 {
2077 	s8 tx_nss, rx_nss;
2078 
2079 	tx_nss = rtw_get_sta_tx_nss(adapter, psta);
2080 	rx_nss =  rtw_get_sta_rx_nss(adapter, psta);
2081 	if ((tx_nss == 1) && (rx_nss == 1))
2082 		psta->cmn.mimo_type = RF_1T1R;
2083 	else if ((tx_nss == 1) && (rx_nss == 2))
2084 		psta->cmn.mimo_type = RF_1T2R;
2085 	else if ((tx_nss == 2) && (rx_nss == 2))
2086 		psta->cmn.mimo_type = RF_2T2R;
2087 	else if ((tx_nss == 2) && (rx_nss == 3))
2088 		psta->cmn.mimo_type = RF_2T3R;
2089 	else if ((tx_nss == 2) && (rx_nss == 4))
2090 		psta->cmn.mimo_type = RF_2T4R;
2091 	else if ((tx_nss == 3) && (rx_nss == 3))
2092 		psta->cmn.mimo_type = RF_3T3R;
2093 	else if ((tx_nss == 3) && (rx_nss == 4))
2094 		psta->cmn.mimo_type = RF_3T4R;
2095 	else if ((tx_nss == 4) && (rx_nss == 4))
2096 		psta->cmn.mimo_type = RF_4T4R;
2097 	else
2098 		rtw_warn_on(1);
2099 
2100 #ifdef CONFIG_CTRL_TXSS_BY_TP
2101 	rtw_ctrl_txss_update_mimo_type(adapter, psta);
2102 #endif
2103 
2104 	RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
2105 			psta->cmn.mac_id, tx_nss, rx_nss);
2106 }
2107 
rtw_hal_update_sta_smps_cap(_adapter * adapter,struct sta_info * psta)2108 void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
2109 {
2110 	/*Spatial Multiplexing Power Save*/
2111 #if 0
2112 	if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2113 		#ifdef CONFIG_80211N_HT
2114 		if (psta->htpriv.ht_option) {
2115 			if (psta->htpriv.smps_cap == 0)
2116 				psta->cmn.sm_ps = SM_PS_STATIC;
2117 			else if (psta->htpriv.smps_cap == 1)
2118 				psta->cmn.sm_ps = SM_PS_DYNAMIC;
2119 			else
2120 				psta->cmn.sm_ps = SM_PS_DISABLE;
2121 		}
2122 		#endif /* CONFIG_80211N_HT */
2123 	} else
2124 #endif
2125 		psta->cmn.sm_ps = SM_PS_DISABLE;
2126 
2127 	RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
2128 			psta->cmn.mac_id, psta->cmn.sm_ps);
2129 }
2130 
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)2131 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
2132 {
2133 
2134 	u8 raid;
2135 	if (IS_NEW_GENERATION_IC(adapter)) {
2136 
2137 		raid = (network_type & WIRELESS_11B)	? RATEID_IDX_B
2138 		       : RATEID_IDX_G;
2139 	} else {
2140 		raid = (network_type & WIRELESS_11B)	? RATR_INX_WIRELESS_B
2141 		       : RATR_INX_WIRELESS_G;
2142 	}
2143 	return raid;
2144 }
2145 
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)2146 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
2147 {
2148 	u8 i, tx_nss;
2149 	u64 tx_ra_bitmap = 0, tmp64=0;
2150 
2151 	if (psta == NULL)
2152 		return;
2153 
2154 	/* b/g mode ra_bitmap  */
2155 	for (i = 0; i < sizeof(psta->bssrateset); i++) {
2156 		if (psta->bssrateset[i])
2157 			tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
2158 	}
2159 
2160 #ifdef CONFIG_80211N_HT
2161 if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
2162 	tx_nss = GET_HAL_TX_NSS(padapter);
2163 #ifdef CONFIG_80211AC_VHT
2164 	if (psta->vhtpriv.vht_option) {
2165 		/* AC mode ra_bitmap */
2166 		tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
2167 	} else
2168 #endif /* CONFIG_80211AC_VHT */
2169 	if (psta->htpriv.ht_option) {
2170 		/* n mode ra_bitmap */
2171 
2172 		/* Handling SMPS mode for AP MODE only*/
2173 		if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2174 			/*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
2175 			if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
2176 				/*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
2177 				tx_nss = rtw_min(tx_nss, 1);
2178 			}
2179 		}
2180 
2181 		tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);
2182 		tx_ra_bitmap |= (tmp64 << 12);
2183 	}
2184 }
2185 #endif /* CONFIG_80211N_HT */
2186 	psta->cmn.ra_info.ramask = tx_ra_bitmap;
2187 	psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
2188 }
2189 
rtw_hal_update_sta_ra_info(PADAPTER padapter,struct sta_info * psta)2190 void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
2191 {
2192 	rtw_hal_update_sta_mimo_type(padapter, psta);
2193 	rtw_hal_update_sta_smps_cap(padapter, psta);
2194 	rtw_hal_update_sta_rate_mask(padapter, psta);
2195 }
2196 
2197 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
hw_bcn_ctrl_addr(_adapter * adapter,u8 hw_port)2198 static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)
2199 {
2200 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2201 
2202 	if (hw_port >= hal_spec->port_num) {
2203 		RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);
2204 		rtw_warn_on(1);
2205 		return 0;
2206 	}
2207 
2208 	switch (hw_port) {
2209 	case HW_PORT0:
2210 		return REG_BCN_CTRL;
2211 	case HW_PORT1:
2212 		return REG_BCN_CTRL_1;
2213 	}
2214 
2215 	return 0;
2216 }
2217 #endif
2218 
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2219 static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2220 {
2221 #ifdef RTW_HALMAC
2222 	rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
2223 				adapter->hw_port, net_type);
2224 #else /* !RTW_HALMAC */
2225 	switch (adapter->hw_port) {
2226 	case HW_PORT0:
2227 		/*REG_CR - BIT[17:16]-Network Type for port 1*/
2228 		*net_type = rtw_read8(adapter, MSR) & 0x03;
2229 		break;
2230 	case HW_PORT1:
2231 		/*REG_CR - BIT[19:18]-Network Type for port 1*/
2232 		*net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2233 		break;
2234 #if defined(CONFIG_RTL8814A)
2235 	case HW_PORT2:
2236 		/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2237 		*net_type = rtw_read8(adapter, MSR1) & 0x03;
2238 		break;
2239 	case HW_PORT3:
2240 		/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2241 		*net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2242 		break;
2243 	case HW_PORT4:
2244 		/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2245 		*net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2246 		break;
2247 #endif /*#if defined(CONFIG_RTL8814A)*/
2248 	default:
2249 		RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2250 			 ADPT_ARG(adapter), adapter->hw_port);
2251 		rtw_warn_on(1);
2252 		break;
2253 	}
2254 #endif /* !RTW_HALMAC */
2255 }
2256 
2257 #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)2258 static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
2259 {
2260 	if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
2261 		if (net_type != _HW_STATE_NOLINK_)
2262 			return _HW_STATE_AP_;
2263 	}
2264 	return net_type;
2265 }
2266 #endif
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2267 static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2268 {
2269 #ifdef RTW_HALMAC
2270 	#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2271 	net_type = rtw_hal_net_type_decision(adapter, net_type);
2272 	#endif
2273 	rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
2274 				adapter->hw_port, net_type);
2275 #else /* !RTW_HALMAC */
2276 	u8 val8 = 0;
2277 
2278 	switch (adapter->hw_port) {
2279 	case HW_PORT0:
2280 		#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2281 		net_type = rtw_hal_net_type_decision(adapter, net_type);
2282 		#endif
2283 		/*REG_CR - BIT[17:16]-Network Type for port 0*/
2284 		val8 = rtw_read8(adapter, MSR) & 0x0C;
2285 		val8 |= net_type;
2286 		rtw_write8(adapter, MSR, val8);
2287 		break;
2288 	case HW_PORT1:
2289 		/*REG_CR - BIT[19:18]-Network Type for port 1*/
2290 		val8 = rtw_read8(adapter, MSR) & 0x03;
2291 		val8 |= net_type << 2;
2292 		rtw_write8(adapter, MSR, val8);
2293 		break;
2294 #if defined(CONFIG_RTL8814A)
2295 	case HW_PORT2:
2296 		/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2297 		val8 = rtw_read8(adapter, MSR1) & 0xFC;
2298 		val8 |= net_type;
2299 		rtw_write8(adapter, MSR1, val8);
2300 		break;
2301 	case HW_PORT3:
2302 		/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2303 		val8 = rtw_read8(adapter, MSR1) & 0xF3;
2304 		val8 |= net_type << 2;
2305 		rtw_write8(adapter, MSR1, val8);
2306 		break;
2307 	case HW_PORT4:
2308 		/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2309 		val8 = rtw_read8(adapter, MSR1) & 0xCF;
2310 		val8 |= net_type << 4;
2311 		rtw_write8(adapter, MSR1, val8);
2312 		break;
2313 #endif /* CONFIG_RTL8814A */
2314 	default:
2315 		RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2316 			 ADPT_ARG(adapter), adapter->hw_port);
2317 		rtw_warn_on(1);
2318 		break;
2319 	}
2320 #endif /* !RTW_HALMAC */
2321 }
2322 
2323 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
2324 	#define SEC_CAM_ACCESS_TIMEOUT_MS 200
2325 #endif
2326 
2327 #ifndef DBG_SEC_CAM_ACCESS
2328 	#define DBG_SEC_CAM_ACCESS 0
2329 #endif
2330 
rtw_sec_read_cam(_adapter * adapter,u8 addr)2331 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
2332 {
2333 	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2334 	u32 rdata;
2335 	u32 cnt = 0;
2336 	systime start = 0, end = 0;
2337 	u8 timeout = 0;
2338 	u8 sr = 0;
2339 
2340 	_enter_critical_mutex(mutex, NULL);
2341 
2342 	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
2343 
2344 	start = rtw_get_current_time();
2345 	while (1) {
2346 		if (rtw_is_surprise_removed(adapter)) {
2347 			sr = 1;
2348 			break;
2349 		}
2350 
2351 		cnt++;
2352 		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2353 			break;
2354 
2355 		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2356 			timeout = 1;
2357 			break;
2358 		}
2359 	}
2360 	end = rtw_get_current_time();
2361 
2362 	rdata = rtw_read32(adapter, REG_CAMREAD);
2363 
2364 	_exit_critical_mutex(mutex, NULL);
2365 
2366 	if (DBG_SEC_CAM_ACCESS || timeout) {
2367 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
2368 			, FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2369 	}
2370 
2371 	return rdata;
2372 }
2373 
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)2374 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
2375 {
2376 	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2377 	u32 cnt = 0;
2378 	systime start = 0, end = 0;
2379 	u8 timeout = 0;
2380 	u8 sr = 0;
2381 
2382 	_enter_critical_mutex(mutex, NULL);
2383 
2384 	rtw_write32(adapter, REG_CAMWRITE, wdata);
2385 	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
2386 
2387 	start = rtw_get_current_time();
2388 	while (1) {
2389 		if (rtw_is_surprise_removed(adapter)) {
2390 			sr = 1;
2391 			break;
2392 		}
2393 
2394 		cnt++;
2395 		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2396 			break;
2397 
2398 		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2399 			timeout = 1;
2400 			break;
2401 		}
2402 	}
2403 	end = rtw_get_current_time();
2404 
2405 	_exit_critical_mutex(mutex, NULL);
2406 
2407 	if (DBG_SEC_CAM_ACCESS || timeout) {
2408 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
2409 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2410 	}
2411 }
2412 
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)2413 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
2414 {
2415 	u8 i;
2416 	u32 rdata;
2417 	u8 begin = 0;
2418 	u8 end = 5; /* TODO: consider other key length accordingly */
2419 
2420 	if (!ctrl && !mac && !key) {
2421 		rtw_warn_on(1);
2422 		goto exit;
2423 	}
2424 
2425 	/* TODO: check id range */
2426 
2427 	if (!ctrl && !mac)
2428 		begin = 2; /* read from key */
2429 
2430 	if (!key && !mac)
2431 		end = 0; /* read to ctrl */
2432 	else if (!key)
2433 		end = 2; /* read to mac */
2434 
2435 	for (i = begin; i <= end; i++) {
2436 		rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
2437 
2438 		switch (i) {
2439 		case 0:
2440 			if (ctrl)
2441 				_rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
2442 			if (mac)
2443 				_rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
2444 			break;
2445 		case 1:
2446 			if (mac)
2447 				_rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
2448 			break;
2449 		default:
2450 			if (key)
2451 				_rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2452 			break;
2453 		}
2454 	}
2455 
2456 exit:
2457 	return;
2458 }
2459 
2460 
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)2461 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2462 {
2463 	unsigned int i;
2464 	int j;
2465 	u8 addr, addr1 = 0;
2466 	u32 wdata, wdata1 = 0;
2467 
2468 	/* TODO: consider other key length accordingly */
2469 #if 0
2470 	switch ((ctrl & 0x1c) >> 2) {
2471 	case _WEP40_:
2472 	case _TKIP_:
2473 	case _AES_:
2474 	case _WEP104_:
2475 
2476 	}
2477 #else
2478 	j = 7;
2479 #endif
2480 
2481 	for (; j >= 0; j--) {
2482 		switch (j) {
2483 		case 0:
2484 			wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2485 			break;
2486 		case 1:
2487 			wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2488 			break;
2489 		case 6:
2490 		case 7:
2491 			wdata = 0;
2492 			break;
2493 		default:
2494 			i = (j - 2) << 2;
2495 			wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2496 			break;
2497 		}
2498 
2499 		addr = (id << 3) + j;
2500 
2501 #if defined(CONFIG_RTL8192F)
2502 		if(j == 1) {
2503 			wdata1 = wdata;
2504 			addr1 = addr;
2505 			continue;
2506 		}
2507 #endif
2508 
2509 		rtw_sec_write_cam(adapter, addr, wdata);
2510 	}
2511 
2512 #if defined(CONFIG_RTL8192F)
2513 	rtw_sec_write_cam(adapter, addr1, wdata1);
2514 #endif
2515 }
2516 
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)2517 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2518 {
2519 	u8 addr;
2520 
2521 	addr = (id << 3);
2522 	rtw_sec_write_cam(adapter, addr, 0);
2523 }
2524 
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)2525 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2526 {
2527 	bool res;
2528 	u16 ctrl;
2529 
2530 	rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2531 
2532 	res = (ctrl & BIT6) ? _TRUE : _FALSE;
2533 	return res;
2534 }
2535 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)2536 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2537 {
2538 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2539 
2540 	_rtw_spinlock_init(&mbid_cam_ctl->lock);
2541 	mbid_cam_ctl->bitmap = 0;
2542 	ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2543 	_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2544 }
2545 
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)2546 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2547 {
2548 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2549 
2550 	_rtw_spinlock_free(&mbid_cam_ctl->lock);
2551 }
2552 
rtw_mbid_cam_reset(_adapter * adapter)2553 void rtw_mbid_cam_reset(_adapter *adapter)
2554 {
2555 	_irqL irqL;
2556 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2557 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2558 
2559 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2560 	mbid_cam_ctl->bitmap = 0;
2561 	_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2562 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2563 
2564 	ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2565 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2566 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2567 {
2568 	u8 i;
2569 	u8 cam_id = INVALID_CAM_ID;
2570 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2571 
2572 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2573 		if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2574 			cam_id = i;
2575 			break;
2576 		}
2577 	}
2578 
2579 	RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2580 	return cam_id;
2581 }
2582 
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2583 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2584 {
2585 	_irqL irqL;
2586 
2587 	u8 cam_id = INVALID_CAM_ID;
2588 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2589 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2590 
2591 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2592 	cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2593 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2594 
2595 	return cam_id;
2596 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2597 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2598 {
2599 	u8 i;
2600 	u8 cam_id = INVALID_CAM_ID;
2601 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2602 
2603 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2604 		if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2605 			cam_id = i;
2606 			break;
2607 		}
2608 	}
2609 	if (cam_id != INVALID_CAM_ID)
2610 		RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2611 			__func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2612 
2613 	return cam_id;
2614 }
2615 
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2616 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2617 {
2618 	_irqL irqL;
2619 	u8 cam_id = INVALID_CAM_ID;
2620 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2621 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2622 
2623 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2624 	cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2625 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2626 
2627 	return cam_id;
2628 }
rtw_get_max_mbid_cam_id(_adapter * adapter)2629 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2630 {
2631 	_irqL irqL;
2632 	s8 i;
2633 	u8 cam_id = INVALID_CAM_ID;
2634 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2635 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2636 
2637 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2638 	for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2639 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2640 			cam_id = i;
2641 			break;
2642 		}
2643 	}
2644 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2645 	/*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2646 	return cam_id;
2647 }
2648 
rtw_get_mbid_cam_entry_num(_adapter * adapter)2649 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2650 {
2651 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2652 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2653 
2654 	return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2655 }
2656 
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)2657 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2658 {
2659 	if (adapter && pmbid_cam && mac_addr) {
2660 		_rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2661 		pmbid_cam->iface_id = adapter->iface_id;
2662 	}
2663 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)2664 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2665 {
2666 	if (pmbid_cam) {
2667 		_rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2668 		pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2669 	}
2670 }
2671 
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)2672 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2673 {
2674 	_irqL irqL;
2675 	u8 cam_id = INVALID_CAM_ID, i;
2676 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2677 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2678 	u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2679 
2680 	if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2681 		goto exit;
2682 
2683 	if (entry_num >= TOTAL_MBID_CAM_NUM) {
2684 		RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2685 		rtw_warn_on(1);
2686 	}
2687 
2688 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2689 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2690 		if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2691 			mbid_cam_ctl->bitmap |= BIT(i);
2692 			cam_id = i;
2693 			break;
2694 		}
2695 	}
2696 	if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2697 		mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2698 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2699 
2700 	if (cam_id != INVALID_CAM_ID) {
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), cam_id);
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_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2708 exit:
2709 	return cam_id;
2710 }
2711 
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)2712 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2713 {
2714 	_irqL irqL;
2715 	u8 entry_id = INVALID_CAM_ID;
2716 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2717 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2718 
2719 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2720 	entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2721 	if (entry_id != INVALID_CAM_ID)
2722 		mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2723 
2724 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2725 
2726 	return entry_id;
2727 }
2728 
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)2729 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2730 {
2731 	_irqL irqL;
2732 	u8 ret = _FALSE;
2733 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2734 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2735 
2736 	if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2737 		RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2738 		rtw_warn_on(1);
2739 	}
2740 	if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2741 		goto exit;
2742 
2743 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2744 	if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2745 		if (mac_addr) {
2746 			mbid_cam_ctl->bitmap |= BIT(camid);
2747 			mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2748 			ret = _TRUE;
2749 		}
2750 	}
2751 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2752 
2753 	if (ret == _TRUE) {
2754 		ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2755 		RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2756 #ifdef DBG_MBID_CAM_DUMP
2757 		rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2758 #endif
2759 	} else
2760 		RTW_INFO("%s  [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2761 
2762 exit:
2763 	return ret;
2764 }
2765 
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)2766 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2767 {
2768 	_irqL irqL;
2769 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2770 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2771 
2772 	if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2773 		RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2774 		rtw_warn_on(1);
2775 	}
2776 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2777 	mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2778 	mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2779 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2780 	ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2781 	RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2782 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)2783 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2784 {
2785 	_irqL irqL;
2786 	u8 i;
2787 	_adapter *iface;
2788 	u8 iface_id;
2789 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2790 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2791 	u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2792 	u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2793 
2794 	RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2795 
2796 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2797 	RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2798 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2799 		RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2800 
2801 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2802 			iface_id = dvobj->mbid_cam_cache[i].iface_id;
2803 			_RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2804 			_RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2805 
2806 			iface = dvobj->padapters[iface_id];
2807 			if (iface) {
2808 				if (MLME_IS_STA(iface))
2809 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2810 				else if (MLME_IS_AP(iface))
2811 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2812 				else if (MLME_IS_MESH(iface))
2813 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
2814 				else
2815 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2816 			}
2817 
2818 		} else
2819 			_RTW_PRINT_SEL(sel, "N/A\n");
2820 	}
2821 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2822 	return 0;
2823 }
2824 
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2825 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2826 {
2827 	u8 poll = 1;
2828 	u8 cam_ready = _FALSE;
2829 	u32 cam_data1 = 0;
2830 	u16 cam_data2 = 0;
2831 
2832 	if (RTW_CANNOT_RUN(padapter))
2833 		return;
2834 
2835 	rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2836 
2837 	do {
2838 		if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2839 			cam_ready = _TRUE;
2840 			break;
2841 		}
2842 		poll++;
2843 	} while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2844 
2845 	if (cam_ready) {
2846 		cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2847 		mac[0] = cam_data1 & 0xFF;
2848 		mac[1] = (cam_data1 >> 8) & 0xFF;
2849 		mac[2] = (cam_data1 >> 16) & 0xFF;
2850 		mac[3] = (cam_data1 >> 24) & 0xFF;
2851 
2852 		cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
2853 		mac[4] = cam_data2 & 0xFF;
2854 		mac[5] = (cam_data2 >> 8) & 0xFF;
2855 	}
2856 
2857 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)2858 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
2859 {
2860 	/*_irqL irqL;*/
2861 	u8 i;
2862 	u8 mac_addr[ETH_ALEN];
2863 
2864 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2865 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2866 
2867 	RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
2868 
2869 	/*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2870 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2871 		RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2872 		_rtw_memset(mac_addr, 0, ETH_ALEN);
2873 		read_mbssid_cam(adapter, i, mac_addr);
2874 		_RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
2875 	}
2876 	/*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2877 	return 0;
2878 }
2879 
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2880 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2881 {
2882 	u32	cam_val[2] = {0};
2883 
2884 	cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
2885 	cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT)  | (mac[5] << 8) | mac[4];
2886 
2887 	rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
2888 }
2889 
2890 /*
2891 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
2892 {
2893 	rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
2894 }
2895 */
2896 
rtw_ap_set_mbid_num(_adapter * adapter,u8 ap_num)2897 void rtw_ap_set_mbid_num(_adapter *adapter, u8 ap_num)
2898 {
2899 	rtw_write8(adapter, REG_MBID_NUM,
2900 		((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | ((ap_num -1) & 0x07)));
2901 
2902 }
rtw_mbid_cam_enable(_adapter * adapter)2903 void rtw_mbid_cam_enable(_adapter *adapter)
2904 {
2905 	/*enable MBSSID*/
2906 	rtw_hal_rcr_add(adapter, RCR_ENMBID);
2907 }
rtw_mi_set_mbid_cam(_adapter * adapter)2908 void rtw_mi_set_mbid_cam(_adapter *adapter)
2909 {
2910 	u8 i;
2911 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2912 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2913 
2914 #ifdef DBG_MBID_CAM_DUMP
2915 	rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2916 #endif
2917 
2918 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2919 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2920 			write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
2921 			RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2922 		}
2923 	}
2924 	rtw_mbid_cam_enable(adapter);
2925 }
2926 #endif /*CONFIG_MBSSID_CAM*/
2927 
2928 #ifdef CONFIG_FW_HANDLE_TXBCN
2929 #define H2C_BCN_OFFLOAD_LEN	1
2930 
2931 #define SET_H2CCMD_BCN_OFFLOAD_EN(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
2932 #define SET_H2CCMD_BCN_ROOT_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
2933 #define SET_H2CCMD_BCN_VAP1_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
2934 #define SET_H2CCMD_BCN_VAP2_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
2935 #define SET_H2CCMD_BCN_VAP3_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)
2936 #define SET_H2CCMD_BCN_VAP4_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)
2937 
rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter * adapter,bool fw_bcn_en,u8 tbtt_rpt_map)2938 void rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter *adapter, bool fw_bcn_en, u8 tbtt_rpt_map)
2939 {
2940 	u8 fw_bcn_offload[1] = {0};
2941 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2942 
2943 	if (fw_bcn_en)
2944 		SET_H2CCMD_BCN_OFFLOAD_EN(fw_bcn_offload, 1);
2945 
2946 	if (tbtt_rpt_map & BIT(0))
2947 		SET_H2CCMD_BCN_ROOT_TBTT_RPT(fw_bcn_offload, 1);
2948 	if (tbtt_rpt_map & BIT(1))
2949 		SET_H2CCMD_BCN_VAP1_TBTT_RPT(fw_bcn_offload, 1);
2950 	if (tbtt_rpt_map & BIT(2))
2951 		SET_H2CCMD_BCN_VAP2_TBTT_RPT(fw_bcn_offload, 1);
2952 	if (tbtt_rpt_map & BIT(3))
2953 			SET_H2CCMD_BCN_VAP3_TBTT_RPT(fw_bcn_offload, 1);
2954 
2955 	dvobj->vap_tbtt_rpt_map = tbtt_rpt_map;
2956 	dvobj->fw_bcn_offload = fw_bcn_en;
2957 	RTW_INFO("[FW BCN] Offload : %s\n", (dvobj->fw_bcn_offload) ? "EN" : "DIS");
2958 	RTW_INFO("[FW BCN] TBTT RPT map : 0x%02x\n", dvobj->vap_tbtt_rpt_map);
2959 
2960 	rtw_hal_fill_h2c_cmd(adapter, H2C_FW_BCN_OFFLOAD,
2961 					H2C_BCN_OFFLOAD_LEN, fw_bcn_offload);
2962 }
2963 
rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter * adapter)2964 void rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter *adapter)
2965 {
2966 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2967 	u8 ret, vap_id;
2968 	u32 page_size = 0;
2969 	u8 bcn_rsvdpage[H2C_BCN_RSVDPAGE_LEN] = {0};
2970 
2971 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
2972 	#if 1
2973 	for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {
2974 		if (dvobj->vap_map & BIT(vap_id))
2975 			bcn_rsvdpage[vap_id] = vap_id * (MAX_BEACON_LEN / page_size);
2976 	}
2977 	#else
2978 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
2979 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 8, __Value)
2980 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 8, __Value)
2981 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 8, __Value)
2982 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 8, __Value)
2983 
2984 	if (dvobj->vap_map & BIT(0))
2985  		SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(bcn_rsvdpage, 0);
2986 	if (dvobj->vap_map & BIT(1))
2987 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(bcn_rsvdpage,
2988 					1 * (MAX_BEACON_LEN / page_size));
2989 	if (dvobj->vap_map & BIT(2))
2990 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(bcn_rsvdpage,
2991 					2 * (MAX_BEACON_LEN / page_size));
2992 	if (dvobj->vap_map & BIT(3))
2993 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(bcn_rsvdpage,
2994 					3 * (MAX_BEACON_LEN / page_size));
2995 	if (dvobj->vap_map & BIT(4))
2996 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(bcn_rsvdpage,
2997 					4 * (MAX_BEACON_LEN / page_size));
2998 	#endif
2999 	if (1) {
3000 		RTW_INFO("[BCN_LOC] vap_map : 0x%02x\n", dvobj->vap_map);
3001 		RTW_INFO("[BCN_LOC] page_size :%d, @bcn_page_num :%d\n"
3002 			, page_size, (MAX_BEACON_LEN / page_size));
3003 		RTW_INFO("[BCN_LOC] root ap : 0x%02x\n", *bcn_rsvdpage);
3004 		RTW_INFO("[BCN_LOC] vap_1 : 0x%02x\n", *(bcn_rsvdpage + 1));
3005 		RTW_INFO("[BCN_LOC] vap_2 : 0x%02x\n", *(bcn_rsvdpage + 2));
3006 		RTW_INFO("[BCN_LOC] vap_3 : 0x%02x\n", *(bcn_rsvdpage + 3));
3007 		RTW_INFO("[BCN_LOC] vap_4 : 0x%02x\n", *(bcn_rsvdpage + 4));
3008 	}
3009 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,
3010 					H2C_BCN_RSVDPAGE_LEN, bcn_rsvdpage);
3011 }
3012 
rtw_ap_multi_bcn_cfg(_adapter * adapter)3013 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3014 {
3015 	u8 dft_bcn_space = DEFAULT_BCN_INTERVAL;
3016 	u8 sub_bcn_space = (DEFAULT_BCN_INTERVAL / CONFIG_LIMITED_AP_NUM);
3017 
3018 	/*enable to rx data frame*/
3019 	rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3020 
3021 	/*Disable Port0's beacon function*/
3022 	rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
3023 	/*Reset Port0's TSF*/
3024 	rtw_write8(adapter, REG_DUAL_TSF_RST, BIT_TSFTR_RST);
3025 
3026 	rtw_ap_set_mbid_num(adapter, CONFIG_LIMITED_AP_NUM);
3027 
3028 	/*BCN space & BCN sub-space 0x554[15:0] = 0x64,0x5BC[23:16] = 0x21*/
3029 	rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), HW_PORT0, dft_bcn_space);
3030 	rtw_write8(adapter, REG_MBSSID_BCN_SPACE3 + 2, sub_bcn_space);
3031 
3032 	#if 0 /*setting in hw_var_set_opmode_mbid - ResumeTxBeacon*/
3033 	/*BCN hold time  0x540[19:8] = 0x80*/
3034 	rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
3035 	rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,
3036 		(rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
3037 	#endif
3038 
3039 	/*ATIM window -0x55A = 0x32, reg 0x570 = 0x32, reg 0x5A0 = 0x32 */
3040 	rtw_write8(adapter, REG_ATIMWND, 0x32);
3041 	rtw_write8(adapter, REG_ATIMWND1_V1, 0x32);
3042 	rtw_write8(adapter, REG_ATIMWND2, 0x32);
3043 	rtw_write8(adapter, REG_ATIMWND3, 0x32);
3044 	/*
3045 	rtw_write8(adapter, REG_ATIMWND4, 0x32);
3046 	rtw_write8(adapter, REG_ATIMWND5, 0x32);
3047 	rtw_write8(adapter, REG_ATIMWND6, 0x32);
3048 	rtw_write8(adapter, REG_ATIMWND7, 0x32);*/
3049 
3050 	/*no limit setting - 0x5A7 = 0xFF - Packet in Hi Queue Tx immediately*/
3051 	rtw_write8(adapter, REG_HIQ_NO_LMT_EN, 0xFF);
3052 
3053 	/*Mask all beacon*/
3054 	rtw_write8(adapter, REG_MBSSID_CTRL, 0);
3055 
3056 	/*BCN invalid bit setting 0x454[6] = 1*/
3057 	/*rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);*/
3058 
3059 	/*Enable Port0's beacon function*/
3060 	rtw_write8(adapter, REG_BCN_CTRL,
3061 	rtw_read8(adapter, REG_BCN_CTRL) | BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT  | BIT_EN_BCN_FUNCTION);
3062 
3063 	/* Enable HW seq for BCN
3064 	* 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT  */
3065 	 #ifdef CONFIG_RTL8822B
3066 	if (IS_HARDWARE_TYPE_8822B(adapter))
3067 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3068 	#endif
3069 
3070 	 #ifdef CONFIG_RTL8822C
3071 	if (IS_HARDWARE_TYPE_8822C(adapter))
3072 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3073 	#endif
3074 }
_rtw_mbid_bcn_cfg(_adapter * adapter,bool mbcnq_en,u8 mbcnq_id)3075 static void _rtw_mbid_bcn_cfg(_adapter *adapter, bool mbcnq_en, u8 mbcnq_id)
3076 {
3077 	if (mbcnq_id >= CONFIG_LIMITED_AP_NUM) {
3078 		RTW_ERR(FUNC_ADPT_FMT"- mbid bcnq_id(%d) invalid\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3079 		rtw_warn_on(1);
3080 	}
3081 
3082 	if (mbcnq_en) {
3083 		rtw_write8(adapter, REG_MBSSID_CTRL,
3084 			rtw_read8(adapter, REG_MBSSID_CTRL) | BIT(mbcnq_id));
3085 		RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) enabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3086 	} else {
3087 		rtw_write8(adapter, REG_MBSSID_CTRL,
3088 			rtw_read8(adapter, REG_MBSSID_CTRL) & (~BIT(mbcnq_id)));
3089 		RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) disabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3090 	}
3091 }
3092 /*#define CONFIG_FW_TBTT_RPT*/
rtw_ap_mbid_bcn_en(_adapter * adapter,u8 ap_id)3093 void rtw_ap_mbid_bcn_en(_adapter *adapter, u8 ap_id)
3094 {
3095 	RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3096 
3097 	#ifdef CONFIG_FW_TBTT_RPT
3098 	if (rtw_ap_get_nums(adapter) >= 1) {
3099 		u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3100 
3101 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3102 			tbtt_rpt_map | BIT(ap_id));/*H2C-0xBA*/
3103 	}
3104 	#else
3105 	if (rtw_ap_get_nums(adapter) == 1)
3106 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE, 0);/*H2C-0xBA*/
3107 	#endif
3108 
3109 	rtw_hal_set_bcn_rsvdpage_loc_cmd(adapter);/*H2C-0x09*/
3110 
3111 	_rtw_mbid_bcn_cfg(adapter, _TRUE, ap_id);
3112 }
rtw_ap_mbid_bcn_dis(_adapter * adapter,u8 ap_id)3113 void rtw_ap_mbid_bcn_dis(_adapter *adapter, u8 ap_id)
3114 {
3115 	RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3116 	_rtw_mbid_bcn_cfg(adapter, _FALSE, ap_id);
3117 
3118 	if (rtw_ap_get_nums(adapter) == 0)
3119 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _FALSE, 0);
3120 	#ifdef CONFIG_FW_TBTT_RPT
3121 	else if (rtw_ap_get_nums(adapter) >= 1) {
3122 		u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3123 
3124 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3125 			tbtt_rpt_map & ~BIT(ap_id));/*H2C-0xBA*/
3126 	}
3127 	#endif
3128 }
3129 #endif
3130 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_ap_multi_bcn_cfg(_adapter * adapter)3131 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3132 {
3133 	#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3134 	rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT);
3135 	#else
3136 	rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
3137 	#endif
3138 	/*enable to rx data frame*/
3139 	rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3140 
3141 	/*Beacon Control related register for first time*/
3142 	rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */
3143 
3144 	/*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
3145 	rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */
3146 
3147 	#ifndef CONFIG_HW_P0_TSF_SYNC
3148 	#ifdef CONFIG_RTL8192F
3149 	rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x640);/*unit:32us*/
3150 	#else/*not CONFIG_RTL8192F*/
3151 	rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3152 	#endif
3153 	#endif
3154 
3155 	/*reset TSF*/
3156 	rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
3157 
3158 	/*enable BCN0 Function for if1*/
3159 	/*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
3160 	#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3161 	rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
3162 	#else
3163 	rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3164 	#endif
3165 	#ifdef CONFIG_BCN_XMIT_PROTECT
3166 	rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
3167 	#endif
3168 
3169 	if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
3170 		rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
3171 
3172 	/* Enable HW seq for BCN
3173 	 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT  */
3174 	#ifdef CONFIG_RTL8822B
3175 	if (IS_HARDWARE_TYPE_8822B(adapter))
3176 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3177 	#endif
3178 
3179 	#ifdef CONFIG_RTL8822C
3180 	if (IS_HARDWARE_TYPE_8822C(adapter))
3181 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3182 	#endif
3183 }
3184 #endif
3185 
3186 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3187 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3188 {
3189 
3190 #if 0 /*TODO - modify for more flexible*/
3191 	u8 idx = 0;
3192 
3193 	if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
3194 	    (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
3195 		for (idx = 0; idx < 6; idx++)
3196 			rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
3197 	}  else {
3198 		/*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
3199 		u8 entry_id;
3200 
3201 		if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
3202 		    (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
3203 			entry_id = 0;
3204 			if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
3205 				RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
3206 				write_mbssid_cam(adapter, entry_id, val);
3207 			}
3208 		} else {
3209 			entry_id = rtw_mbid_camid_alloc(adapter, val);
3210 			if (entry_id != INVALID_CAM_ID)
3211 				write_mbssid_cam(adapter, entry_id, val);
3212 		}
3213 	}
3214 #else
3215 	{
3216 		/*
3217 			MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
3218 		*/
3219 		u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
3220 
3221 
3222 		if (entry_id != INVALID_CAM_ID) {
3223 			write_mbssid_cam(adapter, entry_id, mac_addr);
3224 			RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
3225 				ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
3226 		}
3227 	}
3228 #endif
3229 }
3230 
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3231 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3232 {
3233 	u8 idx = 0;
3234 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3235 	u8 entry_id;
3236 
3237 	if (!mac_addr) {
3238 		rtw_warn_on(1);
3239 		return;
3240 	}
3241 
3242 
3243 	entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
3244 
3245 	if (entry_id != INVALID_CAM_ID)
3246 		write_mbssid_cam(adapter, entry_id, mac_addr);
3247 }
3248 
3249 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)3250 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
3251 {
3252 	if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
3253 		return adapter_to_dvobj(adapter)->inter_bcn_space;
3254 	else
3255 		return bcn_interval;
3256 }
3257 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
3258 
3259 #else
3260 
3261 #ifndef RTW_HALMAC
_get_macaddr_reg(enum _hw_port hwport)3262 static u32 _get_macaddr_reg(enum _hw_port hwport)
3263 {
3264 	u32 reg_macaddr = REG_MACID;
3265 
3266 	#ifdef CONFIG_CONCURRENT_MODE
3267 	if (hwport == HW_PORT1)
3268 		reg_macaddr = REG_MACID1;
3269 	#if defined(CONFIG_RTL8814A)
3270 	else if (hwport == HW_PORT2)
3271 		reg_macaddr = REG_MACID2;
3272 	else if (hwport == HW_PORT3)
3273 		reg_macaddr = REG_MACID3;
3274 	else if (hwport == HW_PORT4)
3275 		reg_macaddr = REG_MACID4;
3276 	#endif /*CONFIG_RTL8814A*/
3277 	#endif /*CONFIG_CONCURRENT_MODE*/
3278 
3279 	return reg_macaddr;
3280 }
3281 #endif /*!RTW_HALMAC*/
3282 
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * mac_addr)3283 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)
3284 {
3285 	enum _hw_port hwport;
3286 
3287 	if (mac_addr == NULL)
3288 		return;
3289 	hwport = get_hw_port(adapter);
3290 
3291 	RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
3292 		 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3293 
3294 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3295 	rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3296 #else /* !RTW_HALMAC */
3297 	{
3298 		u8 idx = 0;
3299 		u32 reg_macaddr = _get_macaddr_reg(hwport);
3300 
3301 		for (idx = 0; idx < ETH_ALEN; idx++)
3302 			rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);
3303 	}
3304 #endif /* !RTW_HALMAC */
3305 }
3306 
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)3307 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
3308 {
3309 	enum _hw_port hwport;
3310 
3311 	if (mac_addr == NULL)
3312 		return;
3313 	hwport = get_hw_port(adapter);
3314 
3315 	_rtw_memset(mac_addr, 0, ETH_ALEN);
3316 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3317 	rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3318 #else /* !RTW_HALMAC */
3319 	{
3320 		u8 idx = 0;
3321 		u32 reg_macaddr = _get_macaddr_reg(hwport);
3322 
3323 		for (idx = 0; idx < ETH_ALEN; idx++)
3324 			mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));
3325 	}
3326 #endif /* !RTW_HALMAC */
3327 
3328 	RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
3329 		 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3330 }
3331 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
3332 
3333 #ifndef RTW_HALMAC
_get_bssid_reg(enum _hw_port hw_port)3334 static u32 _get_bssid_reg(enum _hw_port hw_port)
3335 {
3336 	u32 reg_bssid = REG_BSSID;
3337 
3338 	#ifdef CONFIG_CONCURRENT_MODE
3339 	if (hw_port == HW_PORT1)
3340 		reg_bssid = REG_BSSID1;
3341 	#if defined(CONFIG_RTL8814A)
3342 	else if (hw_port == HW_PORT2)
3343 		reg_bssid = REG_BSSID2;
3344 	else if (hw_port == HW_PORT3)
3345 		reg_bssid = REG_BSSID3;
3346 	else if (hw_port == HW_PORT4)
3347 		reg_bssid = REG_BSSID4;
3348 	#endif /*CONFIG_RTL8814A*/
3349 	#endif /*CONFIG_CONCURRENT_MODE*/
3350 
3351 	return reg_bssid;
3352 }
3353 #endif /*!RTW_HALMAC*/
rtw_hal_set_bssid(_adapter * adapter,u8 * val)3354 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
3355 {
3356 	enum _hw_port hw_port = rtw_hal_get_port(adapter);
3357 #ifdef RTW_HALMAC
3358 
3359 	rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
3360 #else /* !RTW_HALMAC */
3361 	u8 idx = 0;
3362 	u32 reg_bssid = _get_bssid_reg(hw_port);
3363 
3364 	for (idx = 0 ; idx < ETH_ALEN; idx++)
3365 		rtw_write8(adapter, (reg_bssid + idx), val[idx]);
3366 #endif /* !RTW_HALMAC */
3367 
3368 	RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
3369 		__func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
3370 }
3371 
3372 #ifndef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_tsf_update(_adapter * adapter,u8 en)3373 static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
3374 {
3375 	u32 addr = 0;
3376 	u8 val8;
3377 
3378 	rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
3379 	if (addr) {
3380 		rtw_enter_protsel_port(adapter, get_hw_port(adapter));
3381 		val8 = rtw_read8(adapter, addr);
3382 		if (en && (val8 & DIS_TSF_UDT)) {
3383 			rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
3384 			#ifdef DBG_TSF_UPDATE
3385 			RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3386 			#endif
3387 		}
3388 		if (!en && !(val8 & DIS_TSF_UDT)) {
3389 			rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
3390 			#ifdef DBG_TSF_UPDATE
3391 			RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3392 			#endif
3393 		}
3394 		rtw_leave_protsel_port(adapter);
3395 	} else {
3396 		RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
3397 			, adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
3398 		rtw_warn_on(1);
3399 	}
3400 }
3401 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_set_hw_update_tsf(PADAPTER padapter)3402 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
3403 {
3404 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3405 
3406 #else
3407 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3408 
3409 	if (!pmlmeext->en_hw_update_tsf)
3410 		return;
3411 
3412 	/* check RCR */
3413 	if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
3414 		return;
3415 
3416 	if (pmlmeext->tsf_update_required) {
3417 		pmlmeext->tsf_update_pause_stime = 0;
3418 		rtw_hal_set_tsf_update(padapter, 1);
3419 	}
3420 
3421 	pmlmeext->en_hw_update_tsf = 0;
3422 #endif
3423 }
3424 
rtw_iface_enable_tsf_update(_adapter * adapter)3425 void rtw_iface_enable_tsf_update(_adapter *adapter)
3426 {
3427 	adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3428 	adapter->mlmeextpriv.tsf_update_required = 1;
3429 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3430 
3431 #else
3432 	rtw_hal_set_tsf_update(adapter, 1);
3433 #endif
3434 }
3435 
rtw_iface_disable_tsf_update(_adapter * adapter)3436 void rtw_iface_disable_tsf_update(_adapter *adapter)
3437 {
3438 	adapter->mlmeextpriv.tsf_update_required = 0;
3439 	adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3440 	adapter->mlmeextpriv.en_hw_update_tsf = 0;
3441 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3442 
3443 #else
3444 	rtw_hal_set_tsf_update(adapter, 0);
3445 #endif
3446 }
3447 
rtw_hal_tsf_update_pause(_adapter * adapter)3448 static void rtw_hal_tsf_update_pause(_adapter *adapter)
3449 {
3450 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3451 
3452 #else
3453 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3454 	_adapter *iface;
3455 	int i;
3456 
3457 	for (i = 0; i < dvobj->iface_nums; i++) {
3458 		iface = dvobj->padapters[i];
3459 		if (!iface)
3460 			continue;
3461 
3462 		rtw_hal_set_tsf_update(iface, 0);
3463 		if (iface->mlmeextpriv.tsf_update_required) {
3464 			iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
3465 			if (!iface->mlmeextpriv.tsf_update_pause_stime)
3466 				iface->mlmeextpriv.tsf_update_pause_stime++;
3467 		}
3468 		iface->mlmeextpriv.en_hw_update_tsf = 0;
3469 	}
3470 #endif
3471 }
3472 
rtw_hal_tsf_update_restore(_adapter * adapter)3473 static void rtw_hal_tsf_update_restore(_adapter *adapter)
3474 {
3475 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3476 
3477 #else
3478 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3479 	_adapter *iface;
3480 	int i;
3481 
3482 	for (i = 0; i < dvobj->iface_nums; i++) {
3483 		iface = dvobj->padapters[i];
3484 		if (!iface)
3485 			continue;
3486 
3487 		if (iface->mlmeextpriv.tsf_update_required) {
3488 			/* enable HW TSF update when recive beacon*/
3489 			iface->mlmeextpriv.en_hw_update_tsf = 1;
3490 			#ifdef DBG_TSF_UPDATE
3491 			RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
3492 				, iface->hw_port, ADPT_ARG(iface));
3493 			#endif
3494 		}
3495 	}
3496 #endif
3497 }
3498 
rtw_hal_periodic_tsf_update_chk(_adapter * adapter)3499 void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
3500 {
3501 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3502 
3503 #else
3504 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3505 	_adapter *iface;
3506 	struct mlme_ext_priv *mlmeext;
3507 	int i;
3508 	u32 restore_ms = 0;
3509 
3510 	if (dvobj->periodic_tsf_update_etime) {
3511 		if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
3512 			/* end for restore status */
3513 			dvobj->periodic_tsf_update_etime = 0;
3514 			rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3515 		}
3516 		return;
3517 	}
3518 
3519 	if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
3520 		return;
3521 
3522 	/*
3523 	* all required ifaces can switch to restore status together
3524 	* loop all pause iface to get largest restore time required
3525 	*/
3526 	for (i = 0; i < dvobj->iface_nums; i++) {
3527 		iface = dvobj->padapters[i];
3528 		if (!iface)
3529 			continue;
3530 
3531 		mlmeext = &iface->mlmeextpriv;
3532 
3533 		if (mlmeext->tsf_update_required
3534 			&& mlmeext->tsf_update_pause_stime
3535 			&& rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
3536 				> mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
3537 		) {
3538 			if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
3539 				restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
3540 		}
3541 	}
3542 
3543 	if (!restore_ms)
3544 		return;
3545 
3546 	dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
3547 	if (!dvobj->periodic_tsf_update_etime)
3548 		dvobj->periodic_tsf_update_etime++;
3549 
3550 	rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3551 
3552 	/* set timer to end restore status */
3553 	_set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
3554 #endif
3555 }
3556 
rtw_hal_periodic_tsf_update_end_timer_hdl(void * ctx)3557 void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
3558 {
3559 	struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
3560 
3561 	if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
3562 		return;
3563 
3564 	rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
3565 }
3566 
hw_var_rcr_config(_adapter * adapter,u32 rcr)3567 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
3568 {
3569 	int err;
3570 
3571 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3572 	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;
3573 #endif
3574 	err = rtw_write32(adapter, REG_RCR, rcr);
3575 	if (err == _SUCCESS)
3576 		GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
3577 	return err;
3578 }
3579 
hw_var_rcr_get(_adapter * adapter,u32 * rcr)3580 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
3581 {
3582 	u32 v32;
3583 
3584 	v32 = rtw_read32(adapter, REG_RCR);
3585 	if (rcr)
3586 		*rcr = v32;
3587 	GET_HAL_DATA(adapter)->ReceiveConfig = v32;
3588 	return _SUCCESS;
3589 }
3590 
3591 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)3592 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
3593 {
3594 	PHAL_DATA_TYPE hal;
3595 	u32 rcr;
3596 
3597 	hal = GET_HAL_DATA(adapter);
3598 
3599 	rcr = hal->ReceiveConfig;
3600 	if ((rcr & check_bit) == check_bit)
3601 		return 1;
3602 
3603 	return 0;
3604 }
3605 
rtw_hal_rcr_add(_adapter * adapter,u32 add)3606 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
3607 {
3608 	PHAL_DATA_TYPE hal;
3609 	u32 rcr;
3610 	u8 ret = _SUCCESS;
3611 
3612 	hal = GET_HAL_DATA(adapter);
3613 
3614 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3615 	rcr |= add;
3616 	if (rcr != hal->ReceiveConfig)
3617 		ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3618 
3619 	return ret;
3620 }
3621 
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)3622 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
3623 {
3624 	PHAL_DATA_TYPE hal;
3625 	u32 rcr;
3626 	u8 ret = _SUCCESS;
3627 
3628 	hal = GET_HAL_DATA(adapter);
3629 
3630 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3631 	rcr &= ~clear;
3632 	if (rcr != hal->ReceiveConfig)
3633 		ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3634 
3635 	return ret;
3636 }
3637 
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)3638 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
3639 {
3640 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3641 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3642 	u32 rcr, rcr_new;
3643 #if !defined(CONFIG_MI_WITH_MBSSID_CAM) || defined(CONFIG_CLIENT_PORT_CFG) || defined(CONFIG_RTW_MULTI_AP)
3644 	struct mi_state mstate, mstate_s;
3645 #endif
3646 
3647 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3648 	rcr_new = rcr;
3649 
3650 #if !defined(CONFIG_MI_WITH_MBSSID_CAM) || defined(CONFIG_CLIENT_PORT_CFG) || defined(CONFIG_RTW_MULTI_AP)
3651 	rtw_mi_status_no_self(adapter, &mstate);
3652 	rtw_mi_status_no_others(adapter, &mstate_s);
3653 
3654 	/* only adjust parameters interested */
3655 	switch (self_action) {
3656 	case MLME_SCAN_ENTER:
3657 		mstate_s.scan_num = 1;
3658 		mstate_s.scan_enter_num = 1;
3659 		break;
3660 	case MLME_SCAN_DONE:
3661 		mstate_s.scan_enter_num = 0;
3662 		break;
3663 	case MLME_STA_CONNECTING:
3664 		mstate_s.lg_sta_num = 1;
3665 		mstate_s.ld_sta_num = 0;
3666 		break;
3667 	case MLME_STA_CONNECTED:
3668 		mstate_s.lg_sta_num = 0;
3669 		mstate_s.ld_sta_num = 1;
3670 		break;
3671 	case MLME_STA_DISCONNECTED:
3672 		mstate_s.lg_sta_num = 0;
3673 		mstate_s.ld_sta_num = 0;
3674 		break;
3675 #ifdef CONFIG_TDLS
3676 	case MLME_TDLS_LINKED:
3677 		mstate_s.ld_tdls_num = 1;
3678 		break;
3679 	case MLME_TDLS_NOLINK:
3680 		mstate_s.ld_tdls_num = 0;
3681 		break;
3682 #endif
3683 #ifdef CONFIG_AP_MODE
3684 	case MLME_AP_STARTED:
3685 		mstate_s.ap_num = 1;
3686 		break;
3687 	case MLME_AP_STOPPED:
3688 		mstate_s.ap_num = 0;
3689 		mstate_s.ld_ap_num = 0;
3690 		break;
3691 #endif
3692 #ifdef CONFIG_RTW_MESH
3693 	case MLME_MESH_STARTED:
3694 		mstate_s.mesh_num = 1;
3695 		break;
3696 	case MLME_MESH_STOPPED:
3697 		mstate_s.mesh_num = 0;
3698 		mstate_s.ld_mesh_num = 0;
3699 		break;
3700 #endif
3701 	case MLME_ACTION_NONE:
3702 	case MLME_ADHOC_STARTED:
3703 		/* caller without effect of decision */
3704 		break;
3705 	default:
3706 		rtw_warn_on(1);
3707 	};
3708 
3709 	rtw_mi_status_merge(&mstate, &mstate_s);
3710 #endif /* !defined(CONFIG_MI_WITH_MBSSID_CAM) || defined(CONFIG_CLIENT_PORT_CFG) || defined(CONFIG_RTW_MULTI_AP) */
3711 
3712 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
3713 	rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
3714 #else
3715 	if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
3716 		#ifdef CONFIG_FIND_BEST_CHANNEL
3717 		|| MSTATE_SCAN_ENTER_NUM(&mstate)
3718 		#endif
3719 		|| hal_data->in_cta_test
3720 	)
3721 		rcr_new &= ~RCR_CBSSID_DATA;
3722 	else
3723 		rcr_new |= RCR_CBSSID_DATA;
3724 
3725 	if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
3726 		rcr_new &= ~RCR_CBSSID_BCN;
3727 	else if (MSTATE_STA_LG_NUM(&mstate)
3728 		|| adapter_to_dvobj(adapter)->periodic_tsf_update_etime
3729 	)
3730 		rcr_new |= RCR_CBSSID_BCN;
3731 	else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
3732 		|| MSTATE_MESH_NUM(&mstate)
3733 	)
3734 		rcr_new &= ~RCR_CBSSID_BCN;
3735 	else
3736 		rcr_new |= RCR_CBSSID_BCN;
3737 
3738 	#ifdef CONFIG_CLIENT_PORT_CFG
3739 	if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
3740 		rcr_new &= ~RCR_CBSSID_BCN;
3741 	#endif
3742 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
3743 
3744 #ifdef CONFIG_RTW_MULTI_AP
3745 	if (MSTATE_AP_NUM(&mstate)
3746 		&& rtw_unassoc_sta_src_chk(adapter, UNASOC_STA_SRC_RX_NMY_UC)
3747 	) {
3748 		rcr_new |= RCR_AAP;
3749 	} else
3750 		rcr_new &= ~RCR_AAP;
3751 #endif
3752 
3753 	if (rcr == rcr_new)
3754 		return;
3755 
3756 	if (!hal_spec->rx_tsf_filter
3757 		&& (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
3758 		rtw_hal_tsf_update_pause(adapter);
3759 
3760 	rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
3761 
3762 	if (!hal_spec->rx_tsf_filter
3763 		&& !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
3764 		&& self_action != MLME_STA_CONNECTING)
3765 		rtw_hal_tsf_update_restore(adapter);
3766 }
3767 
rtw_hal_rcr_set_chk_bssid_act_non(_adapter * adapter)3768 void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter)
3769 {
3770 	rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3771 }
3772 
hw_var_set_rcr_am(_adapter * adapter,u8 enable)3773 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
3774 {
3775 	u32 rcr = RCR_AM;
3776 
3777 	if (enable)
3778 		rtw_hal_rcr_add(adapter, rcr);
3779 	else
3780 		rtw_hal_rcr_clear(adapter, rcr);
3781 }
3782 
hw_var_set_bcn_interval(_adapter * adapter,u16 interval)3783 static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
3784 {
3785 #ifdef CONFIG_SWTIMER_BASED_TXBCN
3786 	interval = rtw_hal_bcn_interval_adjust(adapter, interval);
3787 #endif
3788 
3789 #ifdef RTW_HALMAC
3790 	rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
3791 #else
3792 	rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
3793 #endif
3794 
3795 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3796 	{
3797 		struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
3798 		struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3799 
3800 		if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3801 			RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
3802 			rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
3803 		}
3804 	}
3805 #endif
3806 }
3807 
3808 #if CONFIG_TX_AC_LIFETIME
3809 const char *const _tx_aclt_conf_str[] = {
3810 	"DEFAULT",
3811 	"AP_M2U",
3812 	"MESH",
3813 	"INVALID",
3814 };
3815 
dump_tx_aclt_force_val(void * sel,struct dvobj_priv * dvobj)3816 void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)
3817 {
3818 #define TX_ACLT_FORCE_MSG_LEN 64
3819 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3820 	struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3821 	char buf[TX_ACLT_FORCE_MSG_LEN];
3822 	int cnt = 0;
3823 
3824 	RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3825 		, hal_spec->tx_aclt_unit_factor * 32
3826 		, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3827 
3828 	RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");
3829 	RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"
3830 		, conf->en
3831 		, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3832 		, conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3833 	);
3834 
3835 	cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");
3836 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3837 		goto exit;
3838 
3839 	if (conf->vo_vi)
3840 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);
3841 	else
3842 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "         AUTO");
3843 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3844 		goto exit;
3845 
3846 
3847 	if (conf->be_bk)
3848 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);
3849 	else
3850 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "         AUTO");
3851 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3852 		goto exit;
3853 
3854 	RTW_PRINT_SEL(sel, "%s\n", buf);
3855 
3856 exit:
3857 	return;
3858 }
3859 
rtw_hal_set_tx_aclt_force_val(_adapter * adapter,struct tx_aclt_conf_t * input,u8 arg_num)3860 void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)
3861 {
3862 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3863 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3864 	struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3865 
3866 	if (arg_num >= 1) {
3867 		if (input->en == 0xFF)
3868 			conf->en = input->en;
3869 		else
3870 			conf->en = input->en & 0xF;
3871 	}
3872 	if (arg_num >= 2) {
3873 		conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3874 		if (conf->vo_vi > 0xFFFF)
3875 			conf->vo_vi = 0xFFFF;
3876 	}
3877 	if (arg_num >= 3) {
3878 		conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3879 		if (conf->be_bk > 0xFFFF)
3880 			conf->be_bk = 0xFFFF;
3881 	}
3882 }
3883 
dump_tx_aclt_confs(void * sel,struct dvobj_priv * dvobj)3884 void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)
3885 {
3886 #define TX_ACLT_CONF_MSG_LEN 32
3887 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3888 	struct tx_aclt_conf_t *conf;
3889 	char buf[TX_ACLT_CONF_MSG_LEN];
3890 	int cnt;
3891 	int i;
3892 
3893 	RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3894 		, hal_spec->tx_aclt_unit_factor * 32
3895 		, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3896 
3897 	RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"
3898 		, "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");
3899 
3900 	for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3901 		conf = &dvobj->tx_aclt_confs[i];
3902 		cnt = 0;
3903 
3904 		if (conf->vo_vi)
3905 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "     0x%04x", conf->vo_vi);
3906 		else
3907 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "        N/A");
3908 		if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
3909 			continue;
3910 
3911 		if (conf->be_bk)
3912 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "     0x%04x", conf->be_bk);
3913 		else
3914 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "        N/A");
3915 		if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
3916 			continue;
3917 
3918 		RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"
3919 			, tx_aclt_conf_str(i), i
3920 			, conf->en
3921 			, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3922 			, conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3923 			, buf
3924 		);
3925 	}
3926 }
3927 
rtw_hal_set_tx_aclt_conf(_adapter * adapter,u8 conf_idx,struct tx_aclt_conf_t * input,u8 arg_num)3928 void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)
3929 {
3930 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3931 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3932 	struct tx_aclt_conf_t *conf;
3933 
3934 	if (conf_idx >= TX_ACLT_CONF_NUM)
3935 		return;
3936 
3937 	conf = &dvobj->tx_aclt_confs[conf_idx];
3938 
3939 	if (arg_num >= 1) {
3940 		if (input->en != 0xFF)
3941 			conf->en = input->en & 0xF;
3942 	}
3943 	if (arg_num >= 2) {
3944 		conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3945 		if (conf->vo_vi > 0xFFFF)
3946 			conf->vo_vi = 0xFFFF;
3947 	}
3948 	if (arg_num >= 3) {
3949 		conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3950 		if (conf->be_bk > 0xFFFF)
3951 			conf->be_bk = 0xFFFF;
3952 	}
3953 }
3954 
rtw_hal_update_tx_aclt(_adapter * adapter)3955 void rtw_hal_update_tx_aclt(_adapter *adapter)
3956 {
3957 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3958 	struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);
3959 	u8 lt_en = 0, lt_en_ori;
3960 	u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;
3961 	u32 lt, lt_ori;
3962 	struct tx_aclt_conf_t *conf;
3963 	int i;
3964 #ifdef CONFIG_AP_MODE
3965 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
3966 	_adapter *iface;
3967 	u8 ap_m2u_num = 0;
3968 
3969 	for (i = 0; i < dvobj->iface_nums; i++) {
3970 		iface = dvobj->padapters[i];
3971 		if (!iface)
3972 			continue;
3973 
3974 		if (MLME_IS_AP(iface)
3975 			&& ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST)
3976 				|| (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST))
3977 		)
3978 			ap_m2u_num++;
3979 	}
3980 #endif
3981 #endif /* CONFIG_AP_MODE */
3982 
3983 	lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);
3984 	lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);
3985 
3986 	for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3987 		if (!(dvobj->tx_aclt_flags & BIT(i)))
3988 			continue;
3989 
3990 		conf = &dvobj->tx_aclt_confs[i];
3991 
3992 		if (i == TX_ACLT_CONF_DEFAULT) {
3993 			/* first and default status, assign directly */
3994 			lt_en = conf->en;
3995 			if (conf->vo_vi)
3996 				lt_vo_vi = conf->vo_vi;
3997 			if (conf->be_bk)
3998 				lt_be_bk = conf->be_bk;
3999 		}
4000 		#ifdef CONFIG_AP_MODE
4001 		#if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH)
4002 		else if (0
4003 			#if CONFIG_RTW_AP_DATA_BMC_TO_UC
4004 			|| (i == TX_ACLT_CONF_AP_M2U
4005 				&& ap_m2u_num
4006 				&& macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)
4007 			#endif
4008 			#ifdef CONFIG_RTW_MESH
4009 			|| (i == TX_ACLT_CONF_MESH
4010 				&& macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)
4011 			#endif
4012 		) {
4013 			/* long term status, OR en and MIN lifetime */
4014 			lt_en |= conf->en;
4015 			if (conf->vo_vi && lt_vo_vi > conf->vo_vi)
4016 				lt_vo_vi = conf->vo_vi;
4017 			if (conf->be_bk && lt_be_bk > conf->be_bk)
4018 				lt_be_bk = conf->be_bk;
4019 		}
4020 		#endif
4021 		#endif /* CONFIG_AP_MODE */
4022 	}
4023 
4024 	if (dvobj->tx_aclt_force_val.en != 0xFF)
4025 		lt_en = dvobj->tx_aclt_force_val.en;
4026 	if (dvobj->tx_aclt_force_val.vo_vi)
4027 		lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;
4028 	if (dvobj->tx_aclt_force_val.be_bk)
4029 		lt_be_bk = dvobj->tx_aclt_force_val.be_bk;
4030 
4031 	lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);
4032 	lt = (lt_be_bk << 16) | lt_vo_vi;
4033 
4034 	if (0)
4035 		RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);
4036 
4037 	if (lt_en != lt_en_ori)
4038 		rtw_write8(adapter, REG_LIFETIME_EN, lt_en);
4039 	if (lt != lt_ori)
4040 		rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);
4041 }
4042 #endif /* CONFIG_TX_AC_LIFETIME */
4043 
hw_var_port_switch(_adapter * adapter)4044 void hw_var_port_switch(_adapter *adapter)
4045 {
4046 #ifdef CONFIG_CONCURRENT_MODE
4047 #ifdef CONFIG_RUNTIME_PORT_SWITCH
4048 	/*
4049 	0x102: MSR
4050 	0x550: REG_BCN_CTRL
4051 	0x551: REG_BCN_CTRL_1
4052 	0x55A: REG_ATIMWND
4053 	0x560: REG_TSFTR
4054 	0x568: REG_TSFTR1
4055 	0x570: REG_ATIMWND_1
4056 	0x610: REG_MACID
4057 	0x618: REG_BSSID
4058 	0x700: REG_MACID1
4059 	0x708: REG_BSSID1
4060 	*/
4061 
4062 	int i;
4063 	u8 msr;
4064 	u8 bcn_ctrl;
4065 	u8 bcn_ctrl_1;
4066 	u8 atimwnd[2];
4067 	u8 atimwnd_1[2];
4068 	u8 tsftr[8];
4069 	u8 tsftr_1[8];
4070 	u8 macid[6];
4071 	u8 bssid[6];
4072 	u8 macid_1[6];
4073 	u8 bssid_1[6];
4074 #if defined(CONFIG_RTL8192F)
4075 	u16 wlan_act_mask_ctrl = 0;
4076 	u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
4077 #endif
4078 
4079 	u8 hw_port;
4080 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4081 	_adapter *iface = NULL;
4082 
4083 	msr = rtw_read8(adapter, MSR);
4084 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4085 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4086 #if defined(CONFIG_RTL8192F)
4087 	wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4088 #endif
4089 
4090 	for (i = 0; i < 2; i++)
4091 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4092 	for (i = 0; i < 2; i++)
4093 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4094 
4095 	for (i = 0; i < 8; i++)
4096 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4097 	for (i = 0; i < 8; i++)
4098 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4099 
4100 	for (i = 0; i < 6; i++)
4101 		macid[i] = rtw_read8(adapter, REG_MACID + i);
4102 
4103 	for (i = 0; i < 6; i++)
4104 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4105 
4106 	for (i = 0; i < 6; i++)
4107 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4108 
4109 	for (i = 0; i < 6; i++)
4110 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4111 
4112 #ifdef DBG_RUNTIME_PORT_SWITCH
4113 	RTW_INFO(FUNC_ADPT_FMT" before switch\n"
4114 		 "msr:0x%02x\n"
4115 		 "bcn_ctrl:0x%02x\n"
4116 		 "bcn_ctrl_1:0x%02x\n"
4117 #if defined(CONFIG_RTL8192F)
4118 		 "wlan_act_mask_ctrl:0x%02x\n"
4119 #endif
4120 		 "atimwnd:0x%04x\n"
4121 		 "atimwnd_1:0x%04x\n"
4122 		 "tsftr:%llu\n"
4123 		 "tsftr1:%llu\n"
4124 		 "macid:"MAC_FMT"\n"
4125 		 "bssid:"MAC_FMT"\n"
4126 		 "macid_1:"MAC_FMT"\n"
4127 		 "bssid_1:"MAC_FMT"\n"
4128 		 , FUNC_ADPT_ARG(adapter)
4129 		 , msr
4130 		 , bcn_ctrl
4131 		 , bcn_ctrl_1
4132 #if defined(CONFIG_RTL8192F)
4133 		 , wlan_act_mask_ctrl
4134 #endif
4135 		 , *((u16 *)atimwnd)
4136 		 , *((u16 *)atimwnd_1)
4137 		 , *((u64 *)tsftr)
4138 		 , *((u64 *)tsftr_1)
4139 		 , MAC_ARG(macid)
4140 		 , MAC_ARG(bssid)
4141 		 , MAC_ARG(macid_1)
4142 		 , MAC_ARG(bssid_1)
4143 		);
4144 #endif /* DBG_RUNTIME_PORT_SWITCH */
4145 
4146 	/* disable bcn function, disable update TSF */
4147 	rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4148 	rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4149 
4150 #if defined(CONFIG_RTL8192F)
4151 	rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
4152 #endif
4153 
4154 	/* switch msr */
4155 	msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
4156 	rtw_write8(adapter, MSR, msr);
4157 
4158 	/* write port0 */
4159 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
4160 	for (i = 0; i < 2; i++)
4161 		rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
4162 	for (i = 0; i < 8; i++)
4163 		rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
4164 	for (i = 0; i < 6; i++)
4165 		rtw_write8(adapter, REG_MACID + i, macid_1[i]);
4166 	for (i = 0; i < 6; i++)
4167 		rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
4168 
4169 	/* write port1 */
4170 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
4171 	for (i = 0; i < 2; i++)
4172 		rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
4173 	for (i = 0; i < 8; i++)
4174 		rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
4175 	for (i = 0; i < 6; i++)
4176 		rtw_write8(adapter, REG_MACID1 + i, macid[i]);
4177 	for (i = 0; i < 6; i++)
4178 		rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
4179 
4180 	/* write bcn ctl */
4181 #ifdef CONFIG_BT_COEXIST
4182 	/* always enable port0 beacon function for PSTDMA */
4183 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
4184 	    || IS_HARDWARE_TYPE_8723D(adapter))
4185 		bcn_ctrl_1 |= EN_BCN_FUNCTION;
4186 	/* always disable port1 beacon function for PSTDMA */
4187 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
4188 		bcn_ctrl &= ~EN_BCN_FUNCTION;
4189 #endif
4190 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
4191 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
4192 
4193 #if defined(CONFIG_RTL8192F)
4194 	/* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
4195 	if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
4196 		!= (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
4197 		wlan_act_mask_ctrl ^= en_port_mask;
4198 	rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
4199 #endif
4200 
4201 	if (adapter->iface_id == IFACE_ID0)
4202 		iface = dvobj->padapters[IFACE_ID1];
4203 	else if (adapter->iface_id == IFACE_ID1)
4204 		iface = dvobj->padapters[IFACE_ID0];
4205 
4206 
4207 	if (adapter->hw_port == HW_PORT0) {
4208 		adapter->hw_port = HW_PORT1;
4209 		iface->hw_port = HW_PORT0;
4210 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4211 			  ADPT_ARG(iface), ADPT_ARG(adapter));
4212 	} else {
4213 		adapter->hw_port = HW_PORT0;
4214 		iface->hw_port = HW_PORT1;
4215 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4216 			  ADPT_ARG(adapter), ADPT_ARG(iface));
4217 	}
4218 
4219 #ifdef DBG_RUNTIME_PORT_SWITCH
4220 	msr = rtw_read8(adapter, MSR);
4221 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4222 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4223 #if defined(CONFIG_RTL8192F)
4224 	wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4225 #endif
4226 
4227 	for (i = 0; i < 2; i++)
4228 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4229 	for (i = 0; i < 2; i++)
4230 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4231 
4232 	for (i = 0; i < 8; i++)
4233 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4234 	for (i = 0; i < 8; i++)
4235 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4236 
4237 	for (i = 0; i < 6; i++)
4238 		macid[i] = rtw_read8(adapter, REG_MACID + i);
4239 
4240 	for (i = 0; i < 6; i++)
4241 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4242 
4243 	for (i = 0; i < 6; i++)
4244 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4245 
4246 	for (i = 0; i < 6; i++)
4247 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4248 
4249 	RTW_INFO(FUNC_ADPT_FMT" after switch\n"
4250 		 "msr:0x%02x\n"
4251 		 "bcn_ctrl:0x%02x\n"
4252 		 "bcn_ctrl_1:0x%02x\n"
4253 #if defined(CONFIG_RTL8192F)
4254 		 "wlan_act_mask_ctrl:0x%02x\n"
4255 #endif
4256 		 "atimwnd:%u\n"
4257 		 "atimwnd_1:%u\n"
4258 		 "tsftr:%llu\n"
4259 		 "tsftr1:%llu\n"
4260 		 "macid:"MAC_FMT"\n"
4261 		 "bssid:"MAC_FMT"\n"
4262 		 "macid_1:"MAC_FMT"\n"
4263 		 "bssid_1:"MAC_FMT"\n"
4264 		 , FUNC_ADPT_ARG(adapter)
4265 		 , msr
4266 		 , bcn_ctrl
4267 		 , bcn_ctrl_1
4268 #if defined(CONFIG_RTL8192F)
4269 		 , wlan_act_mask_ctrl
4270 #endif
4271 		 , *((u16 *)atimwnd)
4272 		 , *((u16 *)atimwnd_1)
4273 		 , *((u64 *)tsftr)
4274 		 , *((u64 *)tsftr_1)
4275 		 , MAC_ARG(macid)
4276 		 , MAC_ARG(bssid)
4277 		 , MAC_ARG(macid_1)
4278 		 , MAC_ARG(bssid_1)
4279 		);
4280 #endif /* DBG_RUNTIME_PORT_SWITCH */
4281 
4282 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
4283 #endif /* CONFIG_CONCURRENT_MODE */
4284 }
4285 
4286 const char *const _h2c_msr_role_str[] = {
4287 	"RSVD",
4288 	"STA",
4289 	"AP",
4290 	"GC",
4291 	"GO",
4292 	"TDLS",
4293 	"ADHOC",
4294 	"MESH",
4295 	"INVALID",
4296 };
4297 
4298 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)4299 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
4300 {
4301 	s32 ret = _SUCCESS;
4302 	u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
4303 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4304 	u8 port_id = rtw_hal_get_port(adapter);
4305 
4306 	if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
4307 		return ret;
4308 
4309 	SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
4310 	SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
4311 
4312 	RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
4313 	RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
4314 		__func__, ADPT_ARG(adapter), port_id, mac_id);
4315 
4316 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
4317 	dvobj->dft.port_id = port_id;
4318 	dvobj->dft.mac_id = mac_id;
4319 
4320 	return ret;
4321 }
rtw_set_default_port_id(_adapter * adapter)4322 s32 rtw_set_default_port_id(_adapter *adapter)
4323 {
4324 	s32 ret = _SUCCESS;
4325 	struct sta_info		*psta;
4326 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4327 
4328 	if (is_client_associated_to_ap(adapter)) {
4329 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
4330 		if (psta)
4331 			ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
4332 	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
4333 
4334 	} else {
4335 	}
4336 
4337 	return ret;
4338 }
rtw_set_ps_rsvd_page(_adapter * adapter)4339 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
4340 {
4341 	s32 ret = _SUCCESS;
4342 	u16 media_status_rpt = RT_MEDIA_CONNECT;
4343 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4344 
4345 	if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
4346 		return ret;
4347 
4348 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
4349 			  (u8 *)&media_status_rpt);
4350 
4351 	return ret;
4352 }
4353 
4354 #if 0
4355 _adapter * _rtw_search_dp_iface(_adapter *adapter)
4356 {
4357 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4358 	_adapter *iface;
4359 	_adapter *target_iface = NULL;
4360 	int i;
4361 	u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
4362 	u8 p2p_go_num = 0, p2p_gc_num = 0;
4363 	_adapter *sta_ifs[8];
4364 	_adapter *ap_ifs[8];
4365 	_adapter *mesh_ifs[8];
4366 	_adapter *gc_ifs[8];
4367 	_adapter *go_ifs[8];
4368 
4369 	for (i = 0; i < dvobj->iface_nums; i++) {
4370 		iface = dvobj->padapters[i];
4371 
4372 		if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
4373 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4374 				sta_ifs[sta_num++] = iface;
4375 
4376 				#ifdef CONFIG_TDLS
4377 				if (iface->tdlsinfo.link_established == _TRUE)
4378 					tdls_num++;
4379 				#endif
4380 				#ifdef CONFIG_P2P
4381 				if (MLME_IS_GC(iface))
4382 					gc_ifs[p2p_gc_num++] = iface;
4383 				#endif
4384 			}
4385 #ifdef CONFIG_AP_MODE
4386 		} else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
4387 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4388 				ap_ifs[ap_num++] = iface;
4389 				#ifdef CONFIG_P2P
4390 				if (MLME_IS_GO(iface))
4391 					go_ifs[p2p_go_num++] = iface;
4392 				#endif
4393 			}
4394 #endif
4395 		} else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
4396 			&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4397 		) {
4398 			adhoc_num++;
4399 
4400 #ifdef CONFIG_RTW_MESH
4401 		} else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
4402 			&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4403 		) {
4404 			mesh_ifs[mesh_num++] = iface;
4405 #endif
4406 		}
4407 	}
4408 
4409 	if (p2p_gc_num) {
4410 		target_iface = gc_ifs[0];
4411 	}
4412 	else if (sta_num) {
4413 		if(sta_num == 1) {
4414 			target_iface = sta_ifs[0];
4415 		} else if (sta_num >= 2) {
4416 			/*TODO get target_iface by timestamp*/
4417 			target_iface = sta_ifs[0];
4418 		}
4419 	} else if (ap_num) {
4420 		target_iface = ap_ifs[0];
4421 	}
4422 
4423 	RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
4424 	RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
4425 	RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
4426 	RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
4427 	RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
4428 	RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
4429 	RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
4430 
4431 	if (target_iface)
4432 		RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
4433 			__func__, ADPT_ARG(target_iface));
4434 	else
4435 		RTW_INFO("%s => target_iface NULL\n", __func__);
4436 
4437 	return target_iface;
4438 }
4439 
4440 void rtw_search_default_port(_adapter *adapter)
4441 {
4442 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4443 	_adapter *adp_iface = NULL;
4444 #ifdef CONFIG_WOWLAN
4445 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
4446 
4447 	if (pwrpriv->wowlan_mode == _TRUE) {
4448 		adp_iface = adapter;
4449 		goto exit;
4450 	}
4451 #endif
4452 	adp_iface = _rtw_search_dp_iface(adapter);
4453 
4454 exit :
4455 	if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
4456 		rtw_set_default_port_id(adp_iface);
4457 	else
4458 		rtw_hal_set_default_port_id_cmd(adapter, 0);
4459 
4460 	if (1) {
4461 		_adapter *tmp_adp;
4462 
4463 		tmp_adp = (adp_iface) ? adp_iface : adapter;
4464 
4465 		RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
4466 			__func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
4467 	}
4468 }
4469 #endif
4470 #endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
4471 
4472 #ifdef CONFIG_P2P_PS
4473 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)4474 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
4475 {
4476 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4477 	struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4478 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
4479 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4480 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
4481 	struct sta_priv		*pstapriv = &adapter->stapriv;
4482 	struct sta_info		*psta;
4483 	HAL_P2P_PS_PARA p2p_ps_para;
4484 	int status = -1;
4485 	u8 i;
4486 	u8 hw_port = rtw_hal_get_port(adapter);
4487 
4488 	_rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
4489 	_rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
4490 
4491 	(&p2p_ps_para)->p2p_port_id = hw_port;
4492 	(&p2p_ps_para)->p2p_group = 0;
4493 	psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4494 	if (psta) {
4495 		(&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
4496 	} else {
4497 		if (p2p_ps_state != P2P_PS_DISABLE) {
4498 			RTW_ERR("%s , psta was NULL\n", __func__);
4499 			return;
4500 		}
4501 	}
4502 
4503 
4504 	switch (p2p_ps_state) {
4505 	case P2P_PS_DISABLE:
4506 		RTW_INFO("P2P_PS_DISABLE\n");
4507 		_rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
4508 		break;
4509 
4510 	case P2P_PS_ENABLE:
4511 		RTW_INFO("P2P_PS_ENABLE\n");
4512 		/* update CTWindow value. */
4513 		if (pwdinfo->ctwindow > 0) {
4514 			(&p2p_ps_para)->ctwindow_en = 1;
4515 			(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4516 			/*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
4517 		}
4518 
4519 
4520 		if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
4521 			(&p2p_ps_para)->offload_en = 1;
4522 			if (pwdinfo->role == P2P_ROLE_GO) {
4523 				(&p2p_ps_para)->role = 1;
4524 				(&p2p_ps_para)->all_sta_sleep = 0;
4525 			} else
4526 				(&p2p_ps_para)->role = 0;
4527 
4528 			(&p2p_ps_para)->discovery = 0;
4529 		}
4530 		/* hw only support 2 set of NoA */
4531 		for (i = 0; i < pwdinfo->noa_num; i++) {
4532 			/* To control the register setting for which NOA */
4533 			(&p2p_ps_para)->noa_sel = i;
4534 			(&p2p_ps_para)->noa_en = 1;
4535 			(&p2p_ps_para)->disable_close_rf = 0;
4536 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
4537 #ifdef CONFIG_CONCURRENT_MODE
4538 			if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))
4539 #endif /* CONFIG_CONCURRENT_MODE */
4540 				(&p2p_ps_para)->disable_close_rf = 1;
4541 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
4542 			/* config P2P NoA Descriptor Register */
4543 			/* config NOA duration */
4544 			(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
4545 			/* config NOA interval */
4546 			(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
4547 			/* config NOA start time */
4548 			(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
4549 			/* config NOA count */
4550 			(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
4551 			/*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
4552 				(&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
4553 				(&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
4554 			status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4555 			if (status == -1)
4556 				RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4557 		}
4558 
4559 		break;
4560 
4561 	case P2P_PS_SCAN:
4562 		/*This feature FW not ready 20161116 YiWei*/
4563 		return;
4564 		/*
4565 		RTW_INFO("P2P_PS_SCAN\n");
4566 		(&p2p_ps_para)->discovery = 1;
4567 		(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4568 		(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4569 		(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4570 		(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4571 		(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4572 		*/
4573 		break;
4574 
4575 	case P2P_PS_SCAN_DONE:
4576 		/*This feature FW not ready 20161116 YiWei*/
4577 		return;
4578 		/*
4579 		RTW_INFO("P2P_PS_SCAN_DONE\n");
4580 		(&p2p_ps_para)->discovery = 0;
4581 		pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
4582 		(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4583 		(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4584 		(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4585 		(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4586 		(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4587 		*/
4588 		break;
4589 
4590 	default:
4591 		break;
4592 	}
4593 
4594 	if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
4595 		status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4596 		if (status == -1)
4597 			RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4598 	}
4599 	_rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
4600 
4601 }
4602 #endif /* RTW_HALMAC */
4603 #endif /* CONFIG_P2P */
4604 
4605 #if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR)
_rtw_hal_dtp_macid_set(_adapter * padapter,u8 opmode,u8 mac_id)4606 static void _rtw_hal_dtp_macid_set(
4607 	_adapter *padapter, u8 opmode, u8 mac_id)
4608 {
4609 	struct macid_ctl_t *macid_ctl = &(padapter->dvobj->macid_ctl);
4610 	struct sta_info *psta;
4611 	u8 h2c_cmd[H2C_FW_CRC5_SEARCH_LEN] = {0};
4612 	u8 mac_addr[ETH_ALEN] = {0};
4613 
4614 	if (opmode) {
4615 		psta = macid_ctl->sta[mac_id];
4616 		if (psta)
4617 			_rtw_memcpy(mac_addr, psta->cmn.mac_addr, ETH_ALEN);
4618 
4619 		if (rtw_check_invalid_mac_address(mac_addr, _FALSE))
4620 			return;
4621 	}
4622 	/* else DON'T CARE H2C_FW_CRC5_SEARCH mac addr in disconnected case */
4623 
4624 	if (rtw_get_chip_type(padapter) == RTL8822C) {
4625 		SET_H2CCMD_FW_CRC5_SEARCH_EN(h2c_cmd, opmode);
4626 		SET_H2CCMD_FW_CRC5_SEARCH_MACID(h2c_cmd, mac_id);
4627 		SET_H2CCMD_FW_CRC5_SEARCH_MAC(&h2c_cmd[1], mac_addr);
4628 		if (rtw_hal_fill_h2c_cmd(padapter, H2C_FW_CRC5_SEARCH,
4629 						H2C_FW_CRC5_SEARCH_LEN, h2c_cmd) != _SUCCESS)
4630 			RTW_WARN("%s : set h2c - 0x%02x fail!\n", __func__, H2C_FW_CRC5_SEARCH);
4631 	}
4632 }
4633 
rtw_hal_dtp_macid_set(_adapter * padapter,u8 opmode,bool macid_ind,u8 mac_id,u8 macid_end)4634 static void rtw_hal_dtp_macid_set(_adapter *padapter, u8 opmode,
4635 	bool macid_ind, u8 mac_id, u8 macid_end)
4636 {
4637 	int i;
4638 
4639 	if (macid_ind == 0) {
4640 		_rtw_hal_dtp_macid_set(padapter, opmode, mac_id);
4641 	} else {
4642 		for (i = mac_id; i <= macid_end; i++)
4643 			_rtw_hal_dtp_macid_set(padapter, opmode, i);
4644 	}
4645 }
4646 #endif
4647 
4648 /*
4649 * rtw_hal_set_FwMediaStatusRpt_cmd -
4650 *
4651 * @adapter:
4652 * @opmode:  0:disconnect, 1:connect
4653 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
4654 * @miracast_sink: 0:source. 1:sink
4655 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
4656 * @macid:
4657 * @macid_ind:  0:update Media Status to macid.  1:update Media Status from macid to macid_end
4658 * @macid_end:
4659 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)4660 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)
4661 {
4662 	struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4663 	u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
4664 	int i;
4665 	s32 ret;
4666 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4667 	u8 hw_port = rtw_hal_get_port(adapter);
4668 #endif
4669 	u8 op_num_change_bmp = 0;
4670 
4671 #if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR)
4672 	rtw_hal_dtp_macid_set(adapter, opmode, macid_ind, macid, macid_end);
4673 #endif
4674 
4675 	SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
4676 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
4677 	SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
4678 	SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
4679 	SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
4680 	SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
4681 	SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
4682 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4683 	SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
4684 #endif
4685 	RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
4686 
4687 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
4688 	if (ret != _SUCCESS)
4689 		goto exit;
4690 
4691 #if defined(CONFIG_RTL8188E)
4692 	if (rtw_get_chip_type(adapter) == RTL8188E) {
4693 		HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4694 
4695 		/* 8188E FW doesn't set macid no link, driver does it by self */
4696 		if (opmode)
4697 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
4698 		else
4699 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
4700 
4701 		/* for 8188E RA */
4702 #if (RATE_ADAPTIVE_SUPPORT == 1)
4703 		if (hal_data->fw_ractrl == _FALSE) {
4704 			u8 max_macid;
4705 
4706 			max_macid = rtw_search_max_mac_id(adapter);
4707 			rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
4708 		}
4709 #endif
4710 	}
4711 #endif
4712 
4713 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
4714 	/* TODO: this should move to IOT issue area */
4715 	if (rtw_get_chip_type(adapter) == RTL8812
4716 		|| rtw_get_chip_type(adapter) == RTL8821
4717 	) {
4718 		if (MLME_IS_STA(adapter))
4719 			Hal_PatchwithJaguar_8812(adapter, opmode);
4720 	}
4721 #endif
4722 
4723 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
4724 	if (macid_ind == 0)
4725 		macid_end = macid;
4726 
4727 	for (i = macid; macid <= macid_end; macid++) {
4728 		op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
4729 		if (!opmode) {
4730 			rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
4731 			rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
4732 			rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
4733 			rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
4734 		}
4735 	}
4736 
4737 #if CONFIG_TX_AC_LIFETIME
4738 	if (op_num_change_bmp)
4739 		rtw_hal_update_tx_aclt(adapter);
4740 #endif
4741 
4742 	if (!opmode)
4743 		rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
4744 
4745 exit:
4746 	return ret;
4747 }
4748 
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)4749 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
4750 {
4751 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
4752 }
4753 
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)4754 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
4755 {
4756 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
4757 }
4758 
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4759 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4760 {
4761 	u8	u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
4762 	u8	ret = 0;
4763 
4764 	RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
4765 		 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
4766 		 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
4767 		 rsvdpageloc->LocBTQosNull);
4768 
4769 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
4770 	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
4771 	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
4772 	SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
4773 	SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
4774 
4775 	ret = rtw_hal_fill_h2c_cmd(padapter,
4776 				   H2C_RSVD_PAGE,
4777 				   H2C_RSVDPAGE_LOC_LEN,
4778 				   u1H2CRsvdPageParm);
4779 
4780 }
4781 
4782 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)4783 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
4784 {
4785 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4786 
4787 	if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)
4788 		|| IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)
4789 		|| IS_8822C_SERIES(pHalData->version_id))
4790 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4791 	/*
4792 	* Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
4793 	* It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
4794 	* and implement HAL function.
4795 	* TODO: GPIO_8 multi function?
4796 	*/
4797 
4798 	if ((index == 13 || index == 14)
4799 		#if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
4800 		/* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
4801 		&& (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
4802 		#endif
4803 	)
4804 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4805 }
4806 
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)4807 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
4808 {
4809 #if defined(CONFIG_RTL8192F)
4810 	rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval));
4811 #else
4812 	if (index <= 7) {
4813 		/* config GPIO mode */
4814 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4815 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4816 
4817 		/* config GPIO Sel */
4818 		/* 0: input */
4819 		/* 1: output */
4820 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4821 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
4822 
4823 		/* set output value */
4824 		if (outputval) {
4825 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4826 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
4827 		} else {
4828 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4829 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
4830 		}
4831 	} else if (index <= 15) {
4832 		/* 88C Series: */
4833 		/* index: 11~8 transform to 3~0 */
4834 		/* 8723 Series: */
4835 		/* index: 12~8 transform to 4~0 */
4836 
4837 		index -= 8;
4838 
4839 		/* config GPIO mode */
4840 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4841 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4842 
4843 		/* config GPIO Sel */
4844 		/* 0: input */
4845 		/* 1: output */
4846 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4847 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
4848 
4849 		/* set output value */
4850 		if (outputval) {
4851 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4852 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
4853 		} else {
4854 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4855 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
4856 		}
4857 	} else {
4858 		RTW_INFO("%s: invalid GPIO%d=%d\n",
4859 			 __FUNCTION__, index, outputval);
4860 	}
4861 #endif
4862 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)4863 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
4864 {
4865 #if defined(CONFIG_RTL8192F)
4866 	rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));
4867 #else
4868 	if (index <= 7) {
4869 		/* config GPIO mode */
4870 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4871 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4872 
4873 		/* config GPIO Sel */
4874 		/* 0: input */
4875 		/* 1: output */
4876 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4877 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
4878 
4879 	} else if (index <= 15) {
4880 		/* 88C Series: */
4881 		/* index: 11~8 transform to 3~0 */
4882 		/* 8723 Series: */
4883 		/* index: 12~8 transform to 4~0 */
4884 
4885 		index -= 8;
4886 
4887 		/* config GPIO mode */
4888 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4889 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4890 
4891 		/* config GPIO Sel */
4892 		/* 0: input */
4893 		/* 1: output */
4894 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4895 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
4896 	} else
4897 		RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
4898 #endif
4899 }
4900 
4901 #endif
4902 
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4903 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4904 {
4905 	struct	pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
4906 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
4907 	u8 ret = 0;
4908 #ifdef CONFIG_WOWLAN
4909 	u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
4910 
4911 	RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
4912 		 __func__, rsvdpageloc->LocRemoteCtrlInfo,
4913 		 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
4914 		 rsvdpageloc->LocNDPInfo);
4915 	RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
4916 		 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
4917 		 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
4918 
4919 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
4920 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
4921 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
4922 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
4923 							rsvdpageloc->LocNbrAdv);
4924 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
4925 						      rsvdpageloc->LocNDPInfo);
4926 #ifdef CONFIG_GTK_OL
4927 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
4928 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
4929 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
4930 #endif /* CONFIG_GTK_OL */
4931 		ret = rtw_hal_fill_h2c_cmd(padapter,
4932 					   H2C_AOAC_RSVD_PAGE,
4933 					   H2C_AOAC_RSVDPAGE_LOC_LEN,
4934 					   u1H2CAoacRsvdPageParm);
4935 
4936 		RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
4937 		_rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
4938 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
4939 					 rsvdpageloc->LocAOACReport);
4940 		ret = rtw_hal_fill_h2c_cmd(padapter,
4941 				   H2C_AOAC_RSVDPAGE3,
4942 				   H2C_AOAC_RSVDPAGE_LOC_LEN,
4943 				   u1H2CAoacRsvdPageParm);
4944 		pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
4945 	}
4946 #if defined(CONFIG_PNO_SUPPORT) && !defined(RTW_HALMAC)
4947 	else {
4948 
4949 		if (!pwrpriv->wowlan_in_resume) {
4950 			RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
4951 			_rtw_memset(&u1H2CAoacRsvdPageParm, 0,
4952 				    sizeof(u1H2CAoacRsvdPageParm));
4953 			SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
4954 						      rsvdpageloc->LocPNOInfo);
4955 			ret = rtw_hal_fill_h2c_cmd(padapter,
4956 						   H2C_AOAC_RSVDPAGE3,
4957 						   H2C_AOAC_RSVDPAGE_LOC_LEN,
4958 						   u1H2CAoacRsvdPageParm);
4959 		}
4960 	}
4961 #endif /* defined(CONFIG_PNO_SUPPORT) && !defined(RTW_HALMAC) */
4962 #endif /* CONFIG_WOWLAN */
4963 }
4964 
4965 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4966 void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4967 {
4968 	struct	hal_ops *pHalFunc = &padapter->hal_func;
4969 	u8	u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
4970 	u8	ret = 0;
4971 
4972 
4973 	RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
4974 
4975 	SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
4976 	SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
4977 	ret = rtw_hal_fill_h2c_cmd(padapter,
4978 				   H2C_FW_DBG_MSG_PKT,
4979 				   H2C_FW_DBG_MSG_PKT_LEN,
4980 				   u1H2C_fw_dbg_msg_pkt_parm);
4981 
4982 }
4983 #endif /*DBG_FW_DEBUG_MSG_PKT*/
4984 
4985 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)4986 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
4987 	u32 page_num, u8 *buffer, u32 buffer_size)
4988 {
4989 	u32 addr = 0, size = 0, count = 0;
4990 	u32 page_size = 0, data_low = 0, data_high = 0;
4991 	u16 txbndy = 0, offset = 0;
4992 	u8 i = 0;
4993 	bool rst = _FALSE;
4994 
4995 #ifdef DBG_LA_MODE
4996 	struct registry_priv *registry_par = &adapter->registrypriv;
4997 
4998 	if(registry_par->la_mode_en == 1) {
4999 		RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
5000 		return rst;
5001 	}
5002 #endif
5003 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5004 
5005 	addr = page_offset * page_size;
5006 	size = page_num * page_size;
5007 
5008 	if (buffer_size < size) {
5009 		RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
5010 			__func__, buffer_size, size);
5011 		return rst;
5012 	}
5013 #ifdef RTW_HALMAC
5014 	if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
5015 		rst = _FALSE;
5016 	else
5017 		rst = _TRUE;
5018 #else
5019 	txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
5020 
5021 	offset = (txbndy + page_offset) * page_size / 8;
5022 	count = (buffer_size / 8) + 1;
5023 
5024 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
5025 
5026 	for (i = 0 ; i < count ; i++) {
5027 		rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
5028 		data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
5029 		data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
5030 		_rtw_memcpy(buffer + (i * 8),
5031 			&data_low, sizeof(data_low));
5032 		_rtw_memcpy(buffer + ((i * 8) + 4),
5033 			&data_high, sizeof(data_high));
5034 	}
5035 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
5036 	rst = _TRUE;
5037 #endif /*RTW_HALMAC*/
5038 
5039 #ifdef DBG_GET_RSVD_PAGE
5040 	RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
5041 		 __func__, page_offset, page_num, addr, size);
5042 	RTW_INFO_DUMP("\n", buffer, size);
5043 	RTW_INFO(" ==================================================\n");
5044 #endif
5045 	return rst;
5046 }
5047 
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)5048 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
5049 {
5050 #if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG)
5051 	u32 page_size = 0;
5052 	u8 *buffer = NULL;
5053 	u32 buf_size = 0;
5054 
5055 	if (page_num == 0)
5056 		return;
5057 
5058 	RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
5059 	RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
5060 
5061 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5062 	if (page_size) {
5063 		buf_size = page_size * page_num;
5064 		buffer = rtw_zvmalloc(buf_size);
5065 
5066 		if (buffer) {
5067 			rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
5068 			RTW_DUMP_SEL(sel, buffer, buf_size);
5069 			rtw_vmfree(buffer, buf_size);
5070 		} else
5071 			RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
5072 	} else
5073 			RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
5074 
5075 	RTW_PRINT_SEL(sel, "==========================\n");
5076 #endif
5077 }
5078 
5079 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)5080 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
5081 {
5082 	u8 *buffer = NULL;
5083 	u32 buff_size = 0;
5084 	static const char * const fifo_sel_str[] = {
5085 		"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
5086 	};
5087 
5088 	if (fifo_sel > 5) {
5089 		RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
5090 		return;
5091 	}
5092 
5093 	RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
5094 	RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
5095 
5096 	if (fifo_size) {
5097 		buff_size = RND4(fifo_size);
5098 		buffer = rtw_zvmalloc(buff_size);
5099 		if (buffer == NULL)
5100 			buff_size = 0;
5101 	}
5102 
5103 	rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
5104 
5105 	if (buffer) {
5106 		RTW_DUMP_SEL(sel, buffer, fifo_size);
5107 		rtw_vmfree(buffer, buff_size);
5108 	}
5109 
5110 	RTW_PRINT_SEL(sel, "==========================\n");
5111 }
5112 #endif
5113 
5114 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)5115 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
5116 {
5117 	RTW_INFO("%s: Set 0x690=0x00\n", __func__);
5118 	rtw_write8(adapter, REG_WOW_CTRL,
5119 		   (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
5120 	RTW_PRINT("%s: Release RXDMA\n", __func__);
5121 	rtw_write32(adapter, REG_RXPKT_NUM,
5122 		    (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
5123 }
5124 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)5125 static void rtw_hal_disable_tx_report(_adapter *adapter)
5126 {
5127 	rtw_write8(adapter, REG_TX_RPT_CTRL,
5128 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
5129 	RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5130 }
5131 
rtw_hal_enable_tx_report(_adapter * adapter)5132 static void rtw_hal_enable_tx_report(_adapter *adapter)
5133 {
5134 	rtw_write8(adapter, REG_TX_RPT_CTRL,
5135 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
5136 	RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5137 }
5138 #endif
rtw_hal_release_rx_dma(_adapter * adapter)5139 static void rtw_hal_release_rx_dma(_adapter *adapter)
5140 {
5141 	u32 val32 = 0;
5142 
5143 	val32 = rtw_read32(adapter, REG_RXPKT_NUM);
5144 
5145 	rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
5146 
5147 	RTW_INFO("%s, [0x%04x]: 0x%08x\n",
5148 		 __func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));
5149 }
5150 
rtw_hal_pause_rx_dma(_adapter * adapter)5151 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
5152 {
5153 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
5154 	u8 ret = 0;
5155 	s8 trycnt = 100;
5156 	u32 tmp = 0;
5157 	int res = 0;
5158 	/* RX DMA stop */
5159 	RTW_PRINT("Pause DMA\n");
5160 	rtw_write32(adapter, REG_RXPKT_NUM,
5161 		    (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
5162 	do {
5163 		if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
5164 #ifdef CONFIG_USB_HCI
5165 			/* stop interface before leave */
5166 			if (_TRUE == hal->usb_intf_start) {
5167 				rtw_intf_stop(adapter);
5168 				RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
5169 				RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
5170 			}
5171 #endif /* CONFIG_USB_HCI */
5172 
5173 			RTW_PRINT("RX_DMA_IDLE is true\n");
5174 			ret = _SUCCESS;
5175 			break;
5176 		}
5177 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5178 		else {
5179 			res = RecvOnePkt(adapter);
5180 			RTW_PRINT("RecvOnePkt Result: %d\n", res);
5181 		}
5182 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
5183 
5184 #ifdef CONFIG_USB_HCI
5185 		else {
5186 			/* to avoid interface start repeatedly  */
5187 			if (_FALSE == hal->usb_intf_start)
5188 				rtw_intf_start(adapter);
5189 		}
5190 #endif /* CONFIG_USB_HCI */
5191 	} while (trycnt--);
5192 
5193 	if (trycnt < 0) {
5194 		tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
5195 
5196 		RTW_PRINT("Stop RX DMA failed......\n");
5197 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
5198 		RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
5199 			  __func__, rtw_read16(adapter, REG_RXPKTNUM));
5200 #else
5201 		RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
5202 			  __func__, ((tmp & 0xFF00) >> 8));
5203 #endif
5204 		if (tmp & BIT(3))
5205 			RTW_PRINT("%s, RX DMA has req\n",
5206 				  __func__);
5207 		else
5208 			RTW_PRINT("%s, RX DMA no req\n",
5209 				  __func__);
5210 		ret = _FAIL;
5211 	}
5212 
5213 	return ret;
5214 }
5215 
5216 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5217 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)5218 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
5219 {
5220 	u8 ret = 0;
5221 	int res = 0;
5222 	u32 tmp = 0;
5223 #ifdef CONFIG_GPIO_WAKEUP
5224 	return _SUCCESS;
5225 #else
5226 	RTW_PRINT("%s\n", __func__);
5227 
5228 	res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5229 	if (!res)
5230 		RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
5231 	else
5232 		RTW_INFO("sdio_local_read fail\n");
5233 
5234 	tmp = SDIO_HIMR_CPWM2_MSK;
5235 
5236 	res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5237 
5238 	if (!res) {
5239 		res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5240 		RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
5241 		ret = _SUCCESS;
5242 	} else {
5243 		RTW_INFO("sdio_local_write fail\n");
5244 		ret = _FAIL;
5245 	}
5246 	return ret;
5247 #endif /* CONFIG_CPIO_WAKEUP */
5248 }
5249 #endif
5250 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
5251 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
5252 
5253 #ifdef CONFIG_WOWLAN
5254 /*
5255  * rtw_hal_check_wow_ctrl
5256  * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
5257  *									If 0x1C7 == 0 (for 3081), WOW enable successful.
5258  *		     _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
5259  *									If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
5260  */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)5261 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
5262 {
5263 	u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
5264 	u8 mstatus = 0;
5265 	u8 reason = 0xFF;
5266 	u8 trycnt = 25;
5267 	u8 res = _FALSE;
5268 
5269 	if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
5270 		if (chk_type) {
5271 			reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5272 			RTW_INFO("%s reason:0x%02x\n", __func__, reason);
5273 
5274 			while (reason && trycnt > 1) {
5275 				reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5276 				RTW_PRINT("Loop index: %d :0x%02x\n",
5277 					  trycnt, reason);
5278 				trycnt--;
5279 				rtw_msleep_os(20);
5280 			}
5281 			if (!reason)
5282 				res = _TRUE;
5283 			else
5284 				res = _FALSE;
5285 		} else {
5286 			/* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
5287 			fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
5288 			rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
5289 			RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
5290 
5291 			while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
5292 				rtw_msleep_os(20);
5293 				fe1_imr = rtw_read32(adapter, REG_FE1IMR);
5294 				rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
5295 				RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
5296 					  trycnt, fe1_imr, rxpkt_num);
5297 				trycnt--;
5298 			}
5299 
5300 			if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
5301 				res = _FALSE;
5302 			else
5303 				res = _TRUE;
5304 		}
5305 	} else {
5306 		mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5307 		RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
5308 
5309 
5310 		if (chk_type) {
5311 			while (!(mstatus & BIT1) && trycnt > 1) {
5312 				mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5313 				RTW_PRINT("Loop index: %d :0x%02x\n",
5314 					  trycnt, mstatus);
5315 				trycnt--;
5316 				rtw_msleep_os(20);
5317 			}
5318 			if (mstatus & BIT1)
5319 				res = _TRUE;
5320 			else
5321 				res = _FALSE;
5322 		} else {
5323 			while (mstatus & BIT1 && trycnt > 1) {
5324 				mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5325 				RTW_PRINT("Loop index: %d :0x%02x\n",
5326 					  trycnt, mstatus);
5327 				trycnt--;
5328 				rtw_msleep_os(20);
5329 			}
5330 
5331 			if (mstatus & BIT1)
5332 				res = _FALSE;
5333 			else
5334 				res = _TRUE;
5335 		}
5336 	}
5337 
5338 	RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
5339 		  __func__, chk_type, res, (25 - trycnt));
5340 	return res;
5341 }
5342 
5343 #if defined(CONFIG_PNO_SUPPORT) && !defined(RTW_HALMAC)
rtw_hal_check_pno_enabled(_adapter * adapter)5344 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
5345 {
5346 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5347 	u8 res = 0, count = 0;
5348 	u8 ret = _FALSE;
5349 
5350 	if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
5351 		res = rtw_read8(adapter, REG_PNO_STATUS);
5352 		while (!(res & BIT(7)) && count < 25) {
5353 			RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
5354 				 count, res);
5355 			res = rtw_read8(adapter, REG_PNO_STATUS);
5356 			count++;
5357 			rtw_msleep_os(2);
5358 		}
5359 		if (res & BIT(7))
5360 			ret = _TRUE;
5361 		else
5362 			ret = _FALSE;
5363 		RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
5364 	}
5365 	return ret;
5366 }
5367 #endif
5368 
rtw_hal_backup_rate(_adapter * adapter)5369 static void rtw_hal_backup_rate(_adapter *adapter)
5370 {
5371 	RTW_INFO("%s\n", __func__);
5372 	/* backup data rate to register 0x8b for wowlan FW */
5373 	rtw_write8(adapter, 0x8d, 1);
5374 	rtw_write8(adapter, 0x8c, 0);
5375 	rtw_write8(adapter, 0x8f, 0x40);
5376 	rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
5377 }
5378 
5379 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)5380 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
5381 {
5382 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5383 	int cam_id, index = 0;
5384 	u8 *addr = NULL;
5385 
5386 	if (!MLME_IS_STA(adapter))
5387 		return;
5388 
5389 	addr = get_bssid(pmlmepriv);
5390 
5391 	if (addr == NULL) {
5392 		RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
5393 		return;
5394 	}
5395 
5396 	rtw_clean_dk_section(adapter);
5397 
5398 	do {
5399 		cam_id = rtw_camid_search(adapter, addr, index, 1);
5400 
5401 		if (cam_id == -1)
5402 			RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
5403 		else
5404 			rtw_sec_cam_swap(adapter, cam_id, index);
5405 
5406 		index++;
5407 	} while (index < 4);
5408 
5409 	rtw_write8(adapter, REG_SECCFG, 0xcc);
5410 }
5411 
rtw_hal_update_gtk_offload_info(_adapter * adapter)5412 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
5413 {
5414 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5415 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5416 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5417 	struct security_priv *psecuritypriv = &adapter->securitypriv;
5418 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5419 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
5420 	_irqL irqL;
5421 	u8 get_key[16];
5422 	u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
5423 	u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
5424 
5425 	if (!MLME_IS_STA(adapter))
5426 		return;
5427 
5428 	_rtw_memset(get_key, 0, sizeof(get_key));
5429 	_rtw_memcpy(&replay_count,
5430 		paoac_rpt->replay_counter_eapol_key, 8);
5431 
5432 	/*read gtk key index*/
5433 	gtk_id = paoac_rpt->key_index;
5434 	aoac_rpt_ver = paoac_rpt->version_info;
5435 
5436 	if (aoac_rpt_ver == 0) {
5437 		/* initial verison */
5438 		if (gtk_id == 5)
5439 			has_rekey = _FALSE;
5440 		else
5441 			has_rekey = _TRUE;
5442 	} else if (aoac_rpt_ver >= 1) {
5443 		/* Add krack patch */
5444 		if (gtk_id == 5)
5445 			RTW_WARN("%s FW check iv fail\n", __func__);
5446 
5447 		if (aoac_rpt_ver == 1)
5448 			RTW_WARN("%s aoac report version should be update to v2\n", __func__);
5449 
5450 		/* Fix key id mismatch */
5451 		if (aoac_rpt_ver == 2)
5452 			has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
5453 	}
5454 
5455 	if (has_rekey == _FALSE) {
5456 		RTW_INFO("%s no rekey event happened.\n", __func__);
5457 	} else if (has_rekey == _TRUE) {
5458 		RTW_INFO("%s update security key.\n", __func__);
5459 		/*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
5460 		rtw_sec_read_cam_ent(adapter, gtk_id,
5461 				     NULL, NULL, get_key);
5462 		rtw_clean_hw_dk_cam(adapter);
5463 
5464 		if (_rtw_camid_is_gk(adapter, gtk_id)) {
5465 			_enter_critical_bh(&cam_ctl->lock, &irqL);
5466 			_rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
5467 				    get_key, 16);
5468 			_exit_critical_bh(&cam_ctl->lock, &irqL);
5469 		} else {
5470 			struct setkey_parm parm_gtk;
5471 
5472 			parm_gtk.algorithm = paoac_rpt->security_type;
5473 			parm_gtk.keyid = gtk_id;
5474 			_rtw_memcpy(parm_gtk.key, get_key, 16);
5475 			setkey_hdl(adapter, (u8 *)&parm_gtk);
5476 		}
5477 
5478 		/*update key into related sw variable and sec-cam cache*/
5479 		psecuritypriv->dot118021XGrpKeyid = gtk_id;
5480 		_rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
5481 				get_key, 16);
5482 		/* update SW TKIP TX/RX MIC value */
5483 		if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
5484 			offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
5485 			_rtw_memcpy(
5486 				&psecuritypriv->dot118021XGrptxmickey[gtk_id],
5487 				&(paoac_rpt->group_key[offset]),
5488 				RTW_TKIP_MIC_LEN);
5489 
5490 			offset = RTW_KEK_LEN;
5491 			_rtw_memcpy(
5492 				&psecuritypriv->dot118021XGrprxmickey[gtk_id],
5493 				&(paoac_rpt->group_key[offset]),
5494 				RTW_TKIP_MIC_LEN);
5495 		}
5496 		RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
5497 			KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
5498 	}
5499 
5500 	/* Update broadcast RX IV */
5501 	if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
5502 		sz = sizeof(psecuritypriv->iv_seq[0]);
5503 		for (i = 0 ; i < 4 ; i++) {
5504 			_rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
5505 			tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
5506 			pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
5507 			_rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
5508 		}
5509 	}
5510 
5511 	rtw_clean_dk_section(adapter);
5512 
5513 	rtw_write8(adapter, REG_SECCFG, 0x0c);
5514 
5515 	#ifdef CONFIG_GTK_OL_DBG
5516 	/* if (gtk_keyindex != 5) */
5517 	dump_sec_cam(RTW_DBGDUMP, adapter);
5518 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
5519 	#endif
5520 }
5521 #endif /*CONFIG_GTK_OL*/
5522 
rtw_dump_aoac_rpt(_adapter * adapter)5523 static void rtw_dump_aoac_rpt(_adapter *adapter)
5524 {
5525 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5526 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5527 	int i = 0;
5528 
5529 	RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
5530 	RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
5531 		paoac_rpt->replay_counter_eapol_key, 8);
5532 	RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
5533 	RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
5534 	RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
5535 	RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
5536 		 paoac_rpt->wow_pattern_idx);
5537 	RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
5538 	RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
5539 	RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
5540 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
5541 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
5542 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
5543 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
5544 }
5545 
rtw_hal_get_aoac_rpt(_adapter * adapter)5546 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
5547 {
5548 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5549 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5550 	u32 page_offset = 0, page_number = 0;
5551 	u32 page_size = 0, buf_size = 0;
5552 	u8 *buffer = NULL;
5553 	u8 i = 0, tmp = 0;
5554 	int ret = -1;
5555 
5556 	/* read aoac report from rsvd page */
5557 	page_offset = pwrctl->wowlan_aoac_rpt_loc;
5558 	page_number = 1;
5559 
5560 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5561 	buf_size = page_size * page_number;
5562 
5563 	buffer = rtw_zvmalloc(buf_size);
5564 
5565 	if (buffer == NULL) {
5566 		RTW_ERR("%s buffer allocate failed size(%d)\n",
5567 			__func__, buf_size);
5568 		return;
5569 	}
5570 
5571 	RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
5572 
5573 	ret = rtw_hal_get_rsvd_page(adapter, page_offset,
5574 		page_number, buffer, buf_size);
5575 
5576 	if (ret == _FALSE) {
5577 		RTW_ERR("%s get aoac report failed\n", __func__);
5578 		rtw_warn_on(1);
5579 		goto _exit;
5580 	}
5581 
5582 	_rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
5583 	_rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
5584 
5585 	for (i = 0 ; i < 4 ; i++) {
5586 		tmp = paoac_rpt->replay_counter_eapol_key[i];
5587 		paoac_rpt->replay_counter_eapol_key[i] =
5588 			paoac_rpt->replay_counter_eapol_key[7 - i];
5589 		paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
5590 	}
5591 
5592 	rtw_dump_aoac_rpt(adapter);
5593 
5594 _exit:
5595 	if (buffer)
5596 		rtw_vmfree(buffer, buf_size);
5597 }
5598 
rtw_hal_update_tx_iv(_adapter * adapter)5599 static void rtw_hal_update_tx_iv(_adapter *adapter)
5600 {
5601 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5602 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5603 	struct sta_info	*psta;
5604 	struct mlme_ext_priv	*pmlmeext = &(adapter->mlmeextpriv);
5605 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5606 	struct security_priv	*psecpriv = &adapter->securitypriv;
5607 
5608 	u16 val16 = 0;
5609 	u32 val32 = 0;
5610 	u64 txiv = 0;
5611 	u8 *pval = NULL;
5612 
5613 	psta = rtw_get_stainfo(&adapter->stapriv,
5614 			       get_my_bssid(&pmlmeinfo->network));
5615 
5616 	/* Update TX iv data. */
5617 	pval = (u8 *)&paoac_rpt->iv;
5618 
5619 	if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
5620 		val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
5621 			((u16)(paoac_rpt->iv[0]) << 8);
5622 		val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5623 			((u32)(paoac_rpt->iv[5]) << 8) +
5624 			((u32)(paoac_rpt->iv[6]) << 16) +
5625 			((u32)(paoac_rpt->iv[7]) << 24);
5626 	} else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
5627 		val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
5628 			((u16)(paoac_rpt->iv[1]) << 8);
5629 		val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5630 			((u32)(paoac_rpt->iv[5]) << 8) +
5631 			((u32)(paoac_rpt->iv[6]) << 16) +
5632 			((u32)(paoac_rpt->iv[7]) << 24);
5633 	}
5634 
5635 	if (psta) {
5636 		txiv = val16 + ((u64)val32 << 16);
5637 		if (txiv != 0)
5638 			psta->dot11txpn.val = txiv;
5639 	}
5640 }
5641 
rtw_hal_update_sw_security_info(_adapter * adapter)5642 static void rtw_hal_update_sw_security_info(_adapter *adapter)
5643 {
5644 	struct security_priv *psecpriv = &adapter->securitypriv;
5645 	u8 sz = sizeof (psecpriv->iv_seq);
5646 
5647 	rtw_hal_update_tx_iv(adapter);
5648 #ifdef CONFIG_GTK_OL
5649 	if (psecpriv->binstallKCK_KEK == _TRUE &&
5650 		(psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5651 		rtw_hal_update_gtk_offload_info(adapter);
5652 #else
5653 	_rtw_memset(psecpriv->iv_seq, 0, sz);
5654 #endif
5655 }
5656 #ifdef CONFIG_CUSTOM_PULSE
rtw_hal_set_gpio_custom_cmd(_adapter * adapter,u8 enable)5657 static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable)
5658 {
5659 	u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0};
5660 	u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1;
5661 	u8 ret = _FAIL;
5662 
5663 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5664 
5665 	if(enable) {
5666 		SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid);
5667 		SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason);
5668 		SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason);
5669 
5670 		ret = rtw_hal_fill_h2c_cmd(adapter,
5671 						H2C_GPIO_CUSTOM,
5672 						H2C_GPIO_CUSTOM_LEN,
5673 						H2CGpioCustomParm);
5674 		RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM,
5675 		H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]);
5676 	}
5677 
5678 	return ret;
5679 }
5680 #endif /* CONFIG_CUSTOM_PULSE */
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)5681 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
5682 {
5683 	u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
5684 	u8 adopt = 1, check_period = 5;
5685 	u8 ret = _FAIL;
5686 	u8 hw_port = rtw_hal_get_port(adapter);
5687 
5688 	SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
5689 	SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
5690 	SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
5691 	SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
5692 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5693 	SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
5694 	RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5695 #else
5696 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5697 #endif
5698 	ret = rtw_hal_fill_h2c_cmd(adapter,
5699 				   H2C_KEEP_ALIVE,
5700 				   H2C_KEEP_ALIVE_CTRL_LEN,
5701 				   u1H2CKeepAliveParm);
5702 
5703 	return ret;
5704 }
5705 
5706 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter,u8 enable)5707 static u8 rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter, u8 enable)
5708 {
5709 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5710 	u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_PATTERN_LEN] = {0};
5711 	u8 ret = _FAIL;
5712 	int i;
5713 
5714 	/* If keep alive pattern is set, FW will use pattern for keep alive action */
5715 	if(enable == 0 || (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_disable)) {
5716 		SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _FALSE);
5717 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE);
5718 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5719 		return ret;
5720 	}
5721 	/*step1:set keep alive period*/
5722 	SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_LOW_BIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_period & 0x00FF);
5723 	SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_HI_BIT(u1H2CKeepAliveParm, ((pwrctl->wowlan_keep_alive_period & 0xFF00)>> 8));
5724 
5725 	if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_tx) {
5726 		SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5727 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE);
5728 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5729 		SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5730 		goto exit;
5731 	}
5732 	if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx) {
5733 		SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5734 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE);
5735 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5736 		SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5737 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index);
5738 		SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval);
5739 		SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter);
5740 		goto exit;
5741 	}
5742 	if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx_with_ack) {
5743 		SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5744 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE);
5745 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _TRUE);
5746 		SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5747 		SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index);
5748 		SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_wake_pattern_index);
5749 		SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval);
5750 		SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter);
5751 		goto exit;
5752 	}
5753 exit:
5754 	for(i=0; i<H2C_KEEP_ALIVE_PATTERN_LEN; i++) {
5755 		RTW_INFO("u1H2CKeepAliveParm[%d]= x%0x\n", i, u1H2CKeepAliveParm[i]);
5756 	}
5757 	ret = rtw_hal_fill_h2c_cmd(adapter,
5758 				   H2C_UDP_KEEPALIVE,
5759 				   H2C_KEEP_ALIVE_PATTERN_LEN,
5760 				   u1H2CKeepAliveParm);
5761 
5762 	return ret;
5763 }
5764 #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
5765 
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)5766 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
5767 {
5768 	u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
5769 	u8 adopt = 1, check_period = 100, trypkt_num = 5;
5770 	u8 ret = _FAIL;
5771 	struct registry_priv *pregistry = &adapter->registrypriv;
5772 	u8 hw_port = rtw_hal_get_port(adapter);
5773 
5774 	SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
5775 	SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
5776 	if (!(pregistry->wakeup_event & BIT(2)))
5777 		SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt);
5778 	SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
5779 	SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
5780 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5781 	SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
5782 	RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5783 #else
5784 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5785 #endif
5786 
5787 	ret = rtw_hal_fill_h2c_cmd(adapter,
5788 				   H2C_DISCON_DECISION,
5789 				   H2C_DISCON_DECISION_LEN,
5790 				   u1H2CDisconDecisionParm);
5791 	return ret;
5792 }
5793 
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)5794 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
5795 {
5796 	struct registry_priv  *registry_par = &adapter->registrypriv;
5797 	struct security_priv *psecpriv = &adapter->securitypriv;
5798 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5799 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
5800 
5801 	u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
5802 	u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;
5803 	u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
5804 	u8 sdio_wakeup_enable = 1;
5805 	u8 gpio_high_active = 0;
5806 	u8 magic_pkt = 0;
5807 	u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
5808 	u8 ret = _FAIL;
5809 #ifdef CONFIG_DIS_UPHY
5810 	u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
5811 #endif /* CONFIG_DIS_UPHY */
5812 
5813 #ifdef CONFIG_GPIO_WAKEUP
5814 	gpio_high_active = ppwrpriv->is_high_active;
5815 	gpionum = ppwrpriv->wowlan_gpio_index;
5816 	sdio_wakeup_enable = 0;
5817 #endif /* CONFIG_GPIO_WAKEUP */
5818 
5819 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
5820 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5821 		no_wake = 1;
5822 
5823 	if (!ppwrpriv->wowlan_pno_enable &&
5824 		registry_par->wakeup_event & BIT(0) && !no_wake)
5825 		magic_pkt = enable;
5826 
5827 	if (registry_par->wakeup_event & BIT(2) && !no_wake)
5828 		discont_wake = enable;
5829 
5830 	RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5831 		 enable, change_unit);
5832 
5833 	/* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5834 	if (enable && change_unit) {
5835 		gpio_dur = 0x40;
5836 		gpio_unit = 1;
5837 		gpio_pulse_en = 1;
5838 	}
5839 
5840 #ifdef CONFIG_PLATFORM_ARM_RK3188
5841 	if (enable) {
5842 		gpio_pulse_en = 1;
5843 		gpio_pulse_cnt = 0x04;
5844 	}
5845 #endif
5846 
5847 	SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5848 	if(!no_wake)
5849 		SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5850 	SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5851 	SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5852 	SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5853 	SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5854 
5855 #ifdef CONFIG_GTK_OL
5856 	if (psecpriv->binstallKCK_KEK == _TRUE &&
5857 		(psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5858 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5859 	else
5860 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5861 #else
5862 	SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5863 #endif
5864 	SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5865 	SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5866 	SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5867 
5868 	SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5869 	SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5870 
5871 	SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5872 	SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5873 
5874 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5875 	if (enable)
5876 		SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5877 #endif
5878 
5879 #ifdef CONFIG_DIS_UPHY
5880 	if (enable) {
5881 		dis_uphy = 1;
5882 		/* time unit: 0 -> ms, 1 -> 256 ms*/
5883 		dis_uphy_unit = 1;
5884 		dis_uphy_time = 0x4;
5885 	}
5886 
5887 	SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5888 	SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5889 	SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5890 	if (ppwrpriv->hst2dev_high_active == 1)
5891 		SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5892 #ifdef CONFIG_RTW_ONE_PIN_GPIO
5893 	SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5894 	SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5895 	SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5896 #else
5897 	SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5898 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
5899 #endif /* CONFIG_DIS_UPHY */
5900 
5901 
5902 	ret = rtw_hal_fill_h2c_cmd(adapter,
5903 				   H2C_WOWLAN,
5904 				   H2C_WOWLAN_LEN,
5905 				   u1H2CWoWlanCtrlParm);
5906 	return ret;
5907 }
5908 
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)5909 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5910 {
5911 	struct security_priv *psecuritypriv = &(adapter->securitypriv);
5912 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5913 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
5914 	u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5915 	u8 ret = _FAIL, count = 0, no_wake = 0;
5916 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
5917 
5918 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
5919 
5920 	if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5921 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5922 		no_wake = 1;
5923 	if(no_wake) {
5924 		SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5925 			u1H2CRemoteWakeCtrlParm, enable);
5926 	} else {
5927 		if (!ppwrpriv->wowlan_pno_enable) {
5928 			SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5929 				u1H2CRemoteWakeCtrlParm, enable);
5930 	#ifdef CONFIG_GTK_OL
5931 			if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5932 				(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) {
5933 				SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5934 					u1H2CRemoteWakeCtrlParm, 1);
5935 			} else {
5936 				RTW_INFO("no kck kek\n");
5937 				SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5938 					u1H2CRemoteWakeCtrlParm, 0);
5939 			}
5940 	#endif /* CONFIG_GTK_OL */
5941 
5942 	#ifdef CONFIG_IPV6
5943 			if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5944 				RTW_INFO("enable NS offload\n");
5945 				SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5946 					u1H2CRemoteWakeCtrlParm, enable);
5947 			}
5948 
5949 			/*
5950 			 * filter NetBios name service pkt to avoid being waked-up
5951 			 * by this kind of unicast pkt this exceptional modification
5952 			 * is used for match competitor's behavior
5953 			 */
5954 
5955 			SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5956 				u1H2CRemoteWakeCtrlParm, enable);
5957 	#endif /*CONFIG_IPV6*/
5958 #if 0 /* replaced by WOWLAN pattern match */
5959 	#ifdef CONFIG_RTL8192F
5960 			if (IS_HARDWARE_TYPE_8192F(adapter)){
5961 				SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
5962 					u1H2CRemoteWakeCtrlParm, enable);
5963 			}
5964 	#endif /* CONFIG_RTL8192F */
5965 #endif
5966 			if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
5967 #ifdef CONFIG_GTK_OL
5968 				if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))
5969 					SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5970 						u1H2CRemoteWakeCtrlParm, enable);
5971 #endif /* CONFIG_GTK_OL */
5972 				if (IS_HARDWARE_TYPE_8188E(adapter) ||
5973 				    IS_HARDWARE_TYPE_8812(adapter)) {
5974 					SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5975 						u1H2CRemoteWakeCtrlParm, 0);
5976 				}
5977 			}
5978 
5979 			if (0) {
5980 				/* ARP wake up case */
5981 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5982 					u1H2CRemoteWakeCtrlParm, 1);
5983 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5984 					u1H2CRemoteWakeCtrlParm, 1);
5985 			} else if (pregistrypriv->wakeup_event) {
5986 				/* ARP no wake up case */
5987 				if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
5988 				    (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
5989 					SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5990 						u1H2CRemoteWakeCtrlParm, 1);
5991 				}
5992 				#ifdef CONFIG_GTK_OL
5993 				else if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_ &&
5994 					 _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)) {
5995 					SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5996 						u1H2CRemoteWakeCtrlParm, 1);
5997 				}
5998 				#endif
5999 			} else {
6000 				/* ARP no wake up and no ARP response case */
6001 			}
6002 
6003 			SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
6004 				u1H2CRemoteWakeCtrlParm, 1);
6005 		}
6006 	#ifdef CONFIG_PNO_SUPPORT
6007 		else {
6008 			SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
6009 				u1H2CRemoteWakeCtrlParm, enable);
6010 			SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
6011 				u1H2CRemoteWakeCtrlParm, enable);
6012 		}
6013 	#endif
6014 
6015 	#ifdef CONFIG_P2P_WOWLAN
6016 		if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
6017 			RTW_INFO("P2P OFFLOAD ENABLE\n");
6018 			SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
6019 		} else {
6020 			RTW_INFO("P2P OFFLOAD DISABLE\n");
6021 			SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
6022 		}
6023 	#endif /* CONFIG_P2P_WOWLAN */
6024 	}
6025 
6026 
6027 	ret = rtw_hal_fill_h2c_cmd(adapter,
6028 				   H2C_REMOTE_WAKE_CTRL,
6029 				   H2C_REMOTE_WAKE_CTRL_LEN,
6030 				   u1H2CRemoteWakeCtrlParm);
6031 	return ret;
6032 }
6033 
6034 #ifdef CONFIG_WAR_OFFLOAD
rtw_hal_set_war_offload_ctrl_cmd(_adapter * adapter,u8 enable)6035 static u8 rtw_hal_set_war_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6036 {
6037 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6038 	u8 u1H2CWarOffloadParm[H2C_WAR_OFFLOAD_LEN] = {0};
6039 	u8 ret = _FAIL;
6040 
6041 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
6042 
6043 	if (_TRUE == ppwrpriv->wowlan_war_offload_mode) {
6044 		SET_H2CCMD_WAR_CFG_EN(u1H2CWarOffloadParm, enable);
6045 		SET_H2CCMD_WAR_CFG_ARP_RSP_EN(u1H2CWarOffloadParm, 1);
6046 
6047 #ifdef CONFIG_OFFLOAD_MDNS_V4
6048 		if (WAR_MDNS_V4_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
6049 			SET_H2CCMD_WAR_CFG_MDNSV4_RSP_EN(u1H2CWarOffloadParm, 1);
6050 		}
6051 		if (WAR_MDNS_V4_WAKEUP_EN& ppwrpriv->wowlan_war_offload_ctrl) {
6052 			SET_H2CCMD_WAR_CFG_MDNSV4_WAKE_EN(u1H2CWarOffloadParm, 1);
6053 		}
6054 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
6055 
6056 #ifdef CONFIG_OFFLOAD_MDNS_V6
6057 		if (WAR_MDNS_V6_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
6058 			SET_H2CCMD_WAR_CFG_MDNSV6_RSP_EN(u1H2CWarOffloadParm, 1);
6059 		}
6060 		if (WAR_MDNS_V6_WAKEUP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
6061 			SET_H2CCMD_WAR_CFG_MDNSV6_WAKE_EN(u1H2CWarOffloadParm, 1);
6062 		}
6063 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
6064 
6065 	}
6066 
6067 	ret = rtw_hal_fill_h2c_cmd(adapter,
6068 					H2C_WAR_OFFLOAD,
6069 					H2C_WAR_OFFLOAD_LEN,
6070 					u1H2CWarOffloadParm);
6071 	return ret;
6072 }
6073 
rtw_hal_set_war_offload_parm(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)6074 static u8 rtw_hal_set_war_offload_parm(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
6075 {
6076 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6077 	u8 u1H2CWarOfldParm[H2C_WAROFLD_RSVDPAGE1_LEN] = {0};
6078 	u8 ret = _FAIL;
6079 
6080 	SET_H2CCMD_WAROFLD_RSVDPAGE1_LOC_PARM(u1H2CWarOfldParm, rsvdpageloc->LocIpParm);
6081 	RTW_INFO("%s(): LocIpParm = %d\n", __func__, rsvdpageloc->LocIpParm);
6082 
6083 
6084 	ret = rtw_hal_fill_h2c_cmd(adapter,
6085 					H2C_WAROFLD_RSVDPAGE1,
6086 					H2C_WAROFLD_RSVDPAGE1_LEN,
6087 					u1H2CWarOfldParm);
6088 
6089 	return ret;
6090 }
6091 #endif /* CONFIG_WAR_OFFLOAD */
6092 
6093 
6094 
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)6095 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
6096 {
6097 	u8 ret = _FAIL;
6098 	u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
6099 
6100 	RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
6101 		 __func__, group_alg, pairwise_alg);
6102 	SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
6103 			pairwise_alg);
6104 	SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
6105 			group_alg);
6106 
6107 	ret = rtw_hal_fill_h2c_cmd(adapter,
6108 				   H2C_AOAC_GLOBAL_INFO,
6109 				   H2C_AOAC_GLOBAL_INFO_LEN,
6110 				   u1H2CAOACGlobalInfoParm);
6111 
6112 	return ret;
6113 }
6114 
6115 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)6116 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
6117 		PRSVDPAGE_LOC rsvdpageloc, u8 enable)
6118 {
6119 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6120 	u8 ret = _FAIL;
6121 #ifndef RTW_HALMAC
6122 	u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
6123 
6124 	RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
6125 		 __func__, rsvdpageloc->LocProbePacket,
6126 		 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
6127 
6128 	SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6129 	SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6130 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6131 					       rsvdpageloc->LocScanInfo);
6132 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6133 			rsvdpageloc->LocProbePacket);
6134 	/*
6135 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6136 				rsvdpageloc->LocSSIDInfo);
6137 	*/
6138 	ret = rtw_hal_fill_h2c_cmd(adapter,
6139 				   H2C_D0_SCAN_OFFLOAD_INFO,
6140 				   H2C_SCAN_OFFLOAD_CTRL_LEN,
6141 				   u1H2CScanOffloadInfoParm);
6142 #else
6143 	u8 u1H2CNLOINFOInfoParm[H2C_NLO_INFO_LEN] = {0};
6144 
6145 	RTW_INFO("%s: loc_nlo_info: %d enable %d\n", __func__,
6146 	rsvdpageloc->LocPNOInfo, enable);
6147 
6148 	SET_H2CCMD_NLO_FUN_EN(u1H2CNLOINFOInfoParm, enable);
6149 #ifdef CONFIG_LPS_LCLK
6150 	// TODO(Owen): Controlled by wowlan lps level
6151 	/* This H2C bit requires driver leave LCLK in rtw_resume_process_wow() */
6152 	SET_H2CCMD_NLO_PS_32K(u1H2CNLOINFOInfoParm, enable);
6153 #endif
6154 	SET_H2CCMD_NLO_LOC_NLO_INFO(u1H2CNLOINFOInfoParm, rsvdpageloc->LocPNOInfo);
6155 
6156 	ret = rtw_hal_fill_h2c_cmd(adapter,
6157 		H2C_NLO_INFO,
6158 		H2C_NLO_INFO_LEN,
6159 		u1H2CNLOINFOInfoParm);
6160 #endif
6161 	return ret;
6162 }
6163 #endif /* CONFIG_PNO_SUPPORT */
6164 
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)6165 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6166 {
6167 	struct security_priv *psecpriv = &padapter->securitypriv;
6168 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6169 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
6170 	struct registry_priv *pregistry = &padapter->registrypriv;
6171 	u8	pkt_type = 0, no_wake = 0;
6172 
6173 	if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6174 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
6175 		no_wake = 1;
6176 
6177 	RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6178 
6179 	rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6180 
6181 	if (enable) {
6182 		if(!no_wake)
6183 			rtw_hal_set_global_info_cmd(padapter,
6184 					    psecpriv->dot118021XGrpPrivacy,
6185 					    psecpriv->dot11PrivacyAlgrthm);
6186 
6187 		if (!(ppwrpriv->wowlan_pno_enable)) {
6188 			if (!no_wake)
6189 				rtw_hal_set_disconnect_decision_cmd(padapter,
6190 								    enable);
6191 #ifdef CONFIG_ARP_KEEP_ALIVE
6192 			if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6193 			    (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6194 				pkt_type = 0;
6195 			else
6196 				pkt_type = 1;
6197 #else
6198 			pkt_type = 0;
6199 #endif /* CONFIG_ARP_KEEP_ALIVE */
6200 			if(!no_wake) {
6201 				#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
6202 				rtw_hal_set_keep_alive_pattern_cmd(padapter,enable);
6203 				#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
6204 				rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6205                         }
6206 		}
6207 #if defined(CONFIG_PNO_SUPPORT) && !defined(RTW_HALMAC)
6208 		rtw_hal_check_pno_enabled(padapter);
6209 #endif /* defined(CONFIG_PNO_SUPPORT) && !defined(RTW_HALMAC) */
6210 #ifdef CONFIG_WAR_OFFLOAD
6211 		rtw_hal_set_war_offload_ctrl_cmd(padapter, enable);
6212 #endif /* CONFIG_WAR_OFFLOAD */
6213 
6214 	} else {
6215 #if 0
6216 		{
6217 			u32 PageSize = 0;
6218 			rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
6219 			dump_TX_FIFO(padapter, 4, PageSize);
6220 		}
6221 #endif
6222 	}
6223 #ifdef CONFIG_CUSTOM_PULSE
6224 	rtw_hal_set_gpio_custom_cmd(padapter, enable);
6225 #endif /* CONFIG_CUSTOM_PULSE */
6226 	rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6227 	RTW_PRINT("-%s()-\n", __func__);
6228 }
6229 #endif /* CONFIG_WOWLAN */
6230 
6231 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)6232 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
6233 {
6234 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6235 
6236 	u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
6237 	u8 gpionum = 0, gpio_dur = 0;
6238 	u8 gpio_pulse = enable;
6239 	u8 sdio_wakeup_enable = 1;
6240 	u8 gpio_high_active = 0;
6241 	u8 ret = _FAIL;
6242 
6243 #ifdef CONFIG_GPIO_WAKEUP
6244 	gpio_high_active = ppwrpriv->is_high_active;
6245 	gpionum = ppwrpriv->wowlan_gpio_index;
6246 	sdio_wakeup_enable = 0;
6247 #endif /*CONFIG_GPIO_WAKEUP*/
6248 
6249 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
6250 
6251 	SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
6252 					  gpionum);
6253 	SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
6254 					 gpio_pulse);
6255 	SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
6256 						gpio_high_active);
6257 	SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
6258 				       enable);
6259 	SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
6260 					     gpio_dur);
6261 
6262 	ret = rtw_hal_fill_h2c_cmd(adapter,
6263 				   H2C_AP_WOW_GPIO_CTRL,
6264 				   H2C_AP_WOW_GPIO_CTRL_LEN,
6265 				   u1H2CAPWoWlanCtrlParm);
6266 
6267 	return ret;
6268 }
6269 
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)6270 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6271 {
6272 	u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
6273 	u8 ret = _FAIL;
6274 
6275 	RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
6276 
6277 	SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
6278 
6279 	ret = rtw_hal_fill_h2c_cmd(adapter,
6280 				   H2C_AP_OFFLOAD,
6281 				   H2C_AP_OFFLOAD_LEN,
6282 				   u1H2CAPOffloadCtrlParm);
6283 
6284 	return ret;
6285 }
6286 
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)6287 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
6288 {
6289 	u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
6290 	u8 ret = _FAIL;
6291 
6292 	RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
6293 
6294 	SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
6295 #ifndef CONFIG_USB_HCI
6296 	SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
6297 #endif /*CONFIG_USB_HCI*/
6298 	SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
6299 
6300 	if (enable)
6301 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
6302 	else
6303 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
6304 
6305 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
6306 				   H2C_AP_PS_LEN, ap_ps_parm);
6307 
6308 	return ret;
6309 }
6310 
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)6311 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
6312 		PRSVDPAGE_LOC rsvdpageloc)
6313 {
6314 	struct hal_ops *pHalFunc = &padapter->hal_func;
6315 	u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
6316 	u8 ret = _FAIL, header = 0;
6317 
6318 	if (pHalFunc->fill_h2c_cmd == NULL) {
6319 		RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
6320 		return;
6321 	}
6322 
6323 	header = rtw_read8(padapter, REG_BCNQ_BDNY);
6324 
6325 	RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
6326 		 rsvdpageloc->LocApOffloadBCN,
6327 		 rsvdpageloc->LocProbeRsp,
6328 		 header);
6329 
6330 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
6331 				      rsvdpageloc->LocApOffloadBCN + header);
6332 
6333 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
6334 				   H2C_BCN_RSVDPAGE_LEN, rsvdparm);
6335 
6336 	if (ret == _FAIL)
6337 		RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
6338 
6339 	rtw_msleep_os(10);
6340 
6341 	_rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
6342 
6343 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
6344 			rsvdpageloc->LocProbeRsp + header);
6345 
6346 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
6347 				   H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
6348 
6349 	if (ret == _FAIL)
6350 		RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
6351 
6352 	rtw_msleep_os(10);
6353 }
6354 
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)6355 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
6356 {
6357 	rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
6358 	rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
6359 	rtw_hal_set_ap_ps_cmd(padapter, enable);
6360 }
6361 
rtw_hal_ap_wow_enable(_adapter * padapter)6362 static void rtw_hal_ap_wow_enable(_adapter *padapter)
6363 {
6364 	struct security_priv *psecuritypriv = &padapter->securitypriv;
6365 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6366 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6367 	struct sta_info *psta = NULL;
6368 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6369 #ifdef DBG_CHECK_FW_PS_STATE
6370 	struct dvobj_priv *psdpriv = padapter->dvobj;
6371 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6372 #endif /*DBG_CHECK_FW_PS_STATE*/
6373 	int res;
6374 	u16 media_status_rpt;
6375 #ifdef CONFIG_GPIO_WAKEUP
6376 	u8 val8 = 0;
6377 #endif
6378 
6379 	RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
6380 #ifdef DBG_CHECK_FW_PS_STATE
6381 	if (rtw_fw_ps_state(padapter) == _FAIL) {
6382 		pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
6383 		RTW_PRINT("wowlan enable no leave 32k\n");
6384 	}
6385 #endif /*DBG_CHECK_FW_PS_STATE*/
6386 
6387 	/* 1. Download WOWLAN FW*/
6388 	rtw_hal_fw_dl(padapter, _TRUE);
6389 
6390 	media_status_rpt = RT_MEDIA_CONNECT;
6391 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6392 			  (u8 *)&media_status_rpt);
6393 
6394 	issue_beacon(padapter, 0);
6395 
6396 	rtw_msleep_os(2);
6397 	#if defined(CONFIG_RTL8188E)
6398 	if (IS_HARDWARE_TYPE_8188E(padapter))
6399 		rtw_hal_disable_tx_report(padapter);
6400 	#endif
6401 	/* RX DMA stop */
6402 	res = rtw_hal_pause_rx_dma(padapter);
6403 	if (res == _FAIL)
6404 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
6405 
6406 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6407 	/* Enable CPWM2 only. */
6408 	res = rtw_hal_enable_cpwm2(padapter);
6409 	if (res == _FAIL)
6410 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6411 #endif
6412 
6413 #ifdef CONFIG_GPIO_WAKEUP
6414 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6415 	rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6416 	rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6417 #else
6418 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6419 	if (pwrctrlpriv->is_high_active == 0)
6420 		rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6421 	else
6422 		rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index,
6423 			GPIO_OUTPUT_LOW);
6424 #else
6425 	val8 = (pwrpriv->is_high_active == 0) ? 1 : 0;
6426 	rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8);
6427 	rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6428 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n",
6429 		 __func__, pwrpriv->wowlan_gpio_index,
6430 		 pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW",
6431 		 pwrpriv->is_high_active ? "HIGI" : "LOW");
6432 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
6433 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6434 #endif /* CONFIG_GPIO_WAKEUP */
6435 
6436 	/* 5. Set Enable WOWLAN H2C command. */
6437 	RTW_PRINT("Set Enable AP WOWLan cmd\n");
6438 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
6439 
6440 	rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
6441 #ifdef CONFIG_USB_HCI
6442 	rtw_mi_intf_stop(padapter);
6443 #endif
6444 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
6445 	/* Invoid SE0 reset signal during suspending*/
6446 	rtw_write8(padapter, REG_RSV_CTRL, 0x20);
6447 	if (IS_8188F(pHalData->version_id) == FALSE
6448 		&& IS_8188GTV(pHalData->version_id) == FALSE)
6449 		rtw_write8(padapter, REG_RSV_CTRL, 0x60);
6450 #endif
6451 }
6452 
rtw_hal_ap_wow_disable(_adapter * padapter)6453 static void rtw_hal_ap_wow_disable(_adapter *padapter)
6454 {
6455 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6456 #ifdef DBG_CHECK_FW_PS_STATE
6457 	struct dvobj_priv *psdpriv = padapter->dvobj;
6458 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6459 #endif /*DBG_CHECK_FW_PS_STATE*/
6460 	u16 media_status_rpt;
6461 
6462 	RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
6463 	/* 1. Read wakeup reason*/
6464 	pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
6465 
6466 	RTW_PRINT("wakeup_reason: 0x%02x\n",
6467 		  pwrctl->wowlan_wake_reason);
6468 
6469 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
6470 
6471 	rtw_msleep_os(2);
6472 #ifdef DBG_CHECK_FW_PS_STATE
6473 	if (rtw_fw_ps_state(padapter) == _FAIL) {
6474 		pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
6475 		RTW_PRINT("wowlan enable no leave 32k\n");
6476 	}
6477 #endif /*DBG_CHECK_FW_PS_STATE*/
6478 
6479 	#if defined(CONFIG_RTL8188E)
6480 	if (IS_HARDWARE_TYPE_8188E(padapter))
6481 		rtw_hal_enable_tx_report(padapter);
6482 	#endif
6483 
6484 	rtw_hal_force_enable_rxdma(padapter);
6485 
6486 	rtw_hal_fw_dl(padapter, _FALSE);
6487 
6488 #ifdef CONFIG_GPIO_WAKEUP
6489 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6490 	rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6491 #else
6492 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6493 	if (pwrctl->is_high_active == 0)
6494 		rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6495 	else
6496 		rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index
6497 			, GPIO_OUTPUT_LOW);
6498 #else
6499 	rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index,
6500 		pwrctl->wowlan_gpio_output_state);
6501 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n",
6502 		 __func__, pwrctl->wowlan_gpio_index,
6503 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
6504 		 pwrctl->is_high_active ? "HIGI" : "LOW");
6505 #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
6506 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6507 #endif /* CONFIG_GPIO_WAKEUP */
6508 	media_status_rpt = RT_MEDIA_CONNECT;
6509 
6510 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6511 			  (u8 *)&media_status_rpt);
6512 
6513 	issue_beacon(padapter, 0);
6514 }
6515 #endif /*CONFIG_AP_WOWLAN*/
6516 
6517 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)6518 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6519 {
6520 	u8 *ssid_ie;
6521 	sint ssid_len_ori;
6522 	int len_diff = 0;
6523 
6524 	ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
6525 
6526 	/* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
6527 
6528 	if (ssid_ie && ssid_len_ori > 0) {
6529 		switch (hidden_ssid_mode) {
6530 		case 1: {
6531 			u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6532 			u32 remain_len = 0;
6533 
6534 			remain_len = ies_len - (next_ie - ies);
6535 
6536 			ssid_ie[1] = 0;
6537 			_rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
6538 			len_diff -= ssid_len_ori;
6539 
6540 			break;
6541 		}
6542 		case 2:
6543 			_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6544 			break;
6545 		default:
6546 			break;
6547 		}
6548 	}
6549 
6550 	return len_diff;
6551 }
6552 
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)6553 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
6554 {
6555 	/* struct xmit_frame	*pmgntframe; */
6556 	/* struct pkt_attrib	*pattrib; */
6557 	/* unsigned char	*pframe; */
6558 	struct rtw_ieee80211_hdr *pwlanhdr;
6559 	unsigned short *fctrl;
6560 	unsigned int	rate_len;
6561 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
6562 	u32	pktlen;
6563 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6564 	/*	_irqL irqL;
6565 	 *	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6566 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6567 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6568 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6569 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6570 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
6571 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6572 #ifdef CONFIG_P2P
6573 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6574 #endif /* CONFIG_P2P */
6575 
6576 	/* for debug */
6577 	u8 *dbgbuf = pframe;
6578 	u8 dbgbufLen = 0, index = 0;
6579 
6580 	RTW_INFO("%s\n", __FUNCTION__);
6581 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6582 	/*	_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6583 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6584 
6585 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6586 
6587 
6588 	fctrl = &(pwlanhdr->frame_ctl);
6589 	*(fctrl) = 0;
6590 
6591 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6592 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6593 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6594 
6595 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6596 	/* pmlmeext->mgnt_seq++; */
6597 	set_frame_sub_type(pframe, WIFI_BEACON);
6598 
6599 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6600 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6601 
6602 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6603 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6604 #ifdef CONFIG_P2P
6605 		/* for P2P : Primary Device Type & Device Name */
6606 		u32 wpsielen = 0, insert_len = 0;
6607 		u8 *wpsie = NULL;
6608 		wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
6609 
6610 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
6611 			uint wps_offset, remainder_ielen;
6612 			u8 *premainder_ie, *pframe_wscie;
6613 
6614 			wps_offset = (uint)(wpsie - cur_network->IEs);
6615 
6616 			premainder_ie = wpsie + wpsielen;
6617 
6618 			remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6619 
6620 #ifdef CONFIG_IOCTL_CFG80211
6621 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6622 				if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
6623 					_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
6624 					pframe += wps_offset;
6625 					pktlen += wps_offset;
6626 
6627 					_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6628 					pframe += pmlmepriv->wps_beacon_ie_len;
6629 					pktlen += pmlmepriv->wps_beacon_ie_len;
6630 
6631 					/* copy remainder_ie to pframe */
6632 					_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6633 					pframe += remainder_ielen;
6634 					pktlen += remainder_ielen;
6635 				} else {
6636 					_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6637 					pframe += cur_network->IELength;
6638 					pktlen += cur_network->IELength;
6639 				}
6640 			} else
6641 #endif /* CONFIG_IOCTL_CFG80211 */
6642 			{
6643 				pframe_wscie = pframe + wps_offset;
6644 				_rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
6645 				pframe += (wps_offset + wpsielen);
6646 				pktlen += (wps_offset + wpsielen);
6647 
6648 				/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6649 				/*	Primary Device Type */
6650 				/*	Type: */
6651 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6652 				insert_len += 2;
6653 
6654 				/*	Length: */
6655 				*(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
6656 				insert_len += 2;
6657 
6658 				/*	Value: */
6659 				/*	Category ID */
6660 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6661 				insert_len += 2;
6662 
6663 				/*	OUI */
6664 				*(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
6665 				insert_len += 4;
6666 
6667 				/*	Sub Category ID */
6668 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6669 				insert_len += 2;
6670 
6671 
6672 				/*	Device Name */
6673 				/*	Type: */
6674 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6675 				insert_len += 2;
6676 
6677 				/*	Length: */
6678 				*(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
6679 				insert_len += 2;
6680 
6681 				/*	Value: */
6682 				_rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
6683 				insert_len += pwdinfo->device_name_len;
6684 
6685 
6686 				/* update wsc ie length */
6687 				*(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
6688 
6689 				/* pframe move to end */
6690 				pframe += insert_len;
6691 				pktlen += insert_len;
6692 
6693 				/* copy remainder_ie to pframe */
6694 				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6695 				pframe += remainder_ielen;
6696 				pktlen += remainder_ielen;
6697 			}
6698 		} else
6699 #endif /* CONFIG_P2P */
6700 		{
6701 			int len_diff;
6702 			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6703 			len_diff = update_hidden_ssid(
6704 					   pframe + _BEACON_IE_OFFSET_
6705 				   , cur_network->IELength - _BEACON_IE_OFFSET_
6706 					   , pmlmeinfo->hidden_ssid_mode
6707 				   );
6708 			pframe += (cur_network->IELength + len_diff);
6709 			pktlen += (cur_network->IELength + len_diff);
6710 		}
6711 #if 0
6712 		{
6713 			u8 *wps_ie;
6714 			uint wps_ielen;
6715 			u8 sr = 0;
6716 			wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
6717 				pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
6718 			if (wps_ie && wps_ielen > 0)
6719 				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6720 			if (sr != 0)
6721 				set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6722 			else
6723 				_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6724 		}
6725 #endif
6726 #ifdef CONFIG_P2P
6727 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6728 			u32 len;
6729 #ifdef CONFIG_IOCTL_CFG80211
6730 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6731 				len = pmlmepriv->p2p_beacon_ie_len;
6732 				if (pmlmepriv->p2p_beacon_ie && len > 0)
6733 					_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6734 			} else
6735 #endif /* CONFIG_IOCTL_CFG80211 */
6736 			{
6737 				len = build_beacon_p2p_ie(pwdinfo, pframe);
6738 			}
6739 
6740 			pframe += len;
6741 			pktlen += len;
6742 
6743 			#ifdef CONFIG_WFD
6744 			len = rtw_append_beacon_wfd_ie(padapter, pframe);
6745 			pframe += len;
6746 			pktlen += len;
6747 			#endif
6748 
6749 		}
6750 #endif /* CONFIG_P2P */
6751 
6752 		goto _issue_bcn;
6753 
6754 	}
6755 
6756 	/* below for ad-hoc mode */
6757 
6758 	/* timestamp will be inserted by hardware */
6759 	pframe += 8;
6760 	pktlen += 8;
6761 
6762 	/* beacon interval: 2 bytes */
6763 
6764 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6765 
6766 	pframe += 2;
6767 	pktlen += 2;
6768 
6769 	/* capability info: 2 bytes */
6770 
6771 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6772 
6773 	pframe += 2;
6774 	pktlen += 2;
6775 
6776 	/* SSID */
6777 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6778 
6779 	/* supported rates... */
6780 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6781 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6782 
6783 	/* DS parameter set */
6784 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6785 
6786 	/* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6787 	{
6788 		u8 erpinfo = 0;
6789 		u32 ATIMWindow;
6790 		/* IBSS Parameter Set... */
6791 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
6792 		ATIMWindow = 0;
6793 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6794 
6795 		/* ERP IE */
6796 		pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
6797 	}
6798 
6799 
6800 	/* EXTERNDED SUPPORTED RATE */
6801 	if (rate_len > 8)
6802 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6803 
6804 
6805 	/* todo:HT for adhoc */
6806 
6807 _issue_bcn:
6808 
6809 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6810 	/*	pmlmepriv->update_bcn = _FALSE;
6811 	 *
6812 	 *	_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6813 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6814 
6815 	*pLength = pktlen;
6816 #if 0
6817 	/* printf dbg msg */
6818 	dbgbufLen = pktlen;
6819 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6820 
6821 	for (index = 0; index < dbgbufLen; index++)
6822 		printk("%x ", *(dbgbuf + index));
6823 
6824 	printk("\n");
6825 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6826 
6827 #endif
6828 }
6829 
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6830 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6831 {
6832 	/* struct xmit_frame			*pmgntframe; */
6833 	/* struct pkt_attrib			*pattrib; */
6834 	/* unsigned char					*pframe; */
6835 	struct rtw_ieee80211_hdr	*pwlanhdr;
6836 	unsigned short				*fctrl;
6837 	unsigned char					*mac;
6838 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
6839 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6840 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6841 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6842 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
6843 	u16					beacon_interval = 100;
6844 	u16					capInfo = 0;
6845 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6846 	u8					wpsie[255] = { 0x00 };
6847 	u32					wpsielen = 0, p2pielen = 0;
6848 	u32					pktlen;
6849 #ifdef CONFIG_WFD
6850 	u32					wfdielen = 0;
6851 #endif
6852 
6853 	/* for debug */
6854 	u8 *dbgbuf = pframe;
6855 	u8 dbgbufLen = 0, index = 0;
6856 
6857 	RTW_INFO("%s\n", __FUNCTION__);
6858 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6859 
6860 	mac = adapter_mac_addr(padapter);
6861 
6862 	fctrl = &(pwlanhdr->frame_ctl);
6863 	*(fctrl) = 0;
6864 
6865 	/* DA filled by FW */
6866 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6867 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6868 
6869 	/*	Use the device address for BSSID field.	 */
6870 	_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6871 
6872 	SetSeqNum(pwlanhdr, 0);
6873 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
6874 
6875 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6876 	pframe += pktlen;
6877 
6878 
6879 	/* timestamp will be inserted by hardware */
6880 	pframe += 8;
6881 	pktlen += 8;
6882 
6883 	/* beacon interval: 2 bytes */
6884 	_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6885 	pframe += 2;
6886 	pktlen += 2;
6887 
6888 	/*	capability info: 2 bytes */
6889 	/*	ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6890 	capInfo |= cap_ShortPremble;
6891 	capInfo |= cap_ShortSlot;
6892 
6893 	_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6894 	pframe += 2;
6895 	pktlen += 2;
6896 
6897 
6898 	/* SSID */
6899 	pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
6900 
6901 	/* supported rates... */
6902 	/*	Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6903 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
6904 
6905 	/* DS parameter set */
6906 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
6907 
6908 #ifdef CONFIG_IOCTL_CFG80211
6909 	if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6910 		if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6911 			/* WPS IE */
6912 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6913 			pktlen += pmlmepriv->wps_probe_resp_ie_len;
6914 			pframe += pmlmepriv->wps_probe_resp_ie_len;
6915 
6916 			/* P2P IE */
6917 			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6918 			pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6919 			pframe += pmlmepriv->p2p_probe_resp_ie_len;
6920 		}
6921 	} else
6922 #endif /* CONFIG_IOCTL_CFG80211		 */
6923 	{
6924 
6925 		/*	Todo: WPS IE */
6926 		/*	Noted by Albert 20100907 */
6927 		/*	According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6928 
6929 		wpsielen = 0;
6930 		/*	WPS OUI */
6931 		*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6932 		wpsielen += 4;
6933 
6934 		/*	WPS version */
6935 		/*	Type: */
6936 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6937 		wpsielen += 2;
6938 
6939 		/*	Length: */
6940 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6941 		wpsielen += 2;
6942 
6943 		/*	Value: */
6944 		wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
6945 
6946 		/*	WiFi Simple Config State */
6947 		/*	Type: */
6948 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6949 		wpsielen += 2;
6950 
6951 		/*	Length: */
6952 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6953 		wpsielen += 2;
6954 
6955 		/*	Value: */
6956 		wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;	/*	Not Configured. */
6957 
6958 		/*	Response Type */
6959 		/*	Type: */
6960 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6961 		wpsielen += 2;
6962 
6963 		/*	Length: */
6964 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6965 		wpsielen += 2;
6966 
6967 		/*	Value: */
6968 		wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6969 
6970 		/*	UUID-E */
6971 		/*	Type: */
6972 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6973 		wpsielen += 2;
6974 
6975 		/*	Length: */
6976 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6977 		wpsielen += 2;
6978 
6979 		/*	Value: */
6980 		if (pwdinfo->external_uuid == 0) {
6981 			_rtw_memset(wpsie + wpsielen, 0x0, 16);
6982 			_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6983 		} else
6984 			_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6985 		wpsielen += 0x10;
6986 
6987 		/*	Manufacturer */
6988 		/*	Type: */
6989 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6990 		wpsielen += 2;
6991 
6992 		/*	Length: */
6993 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6994 		wpsielen += 2;
6995 
6996 		/*	Value: */
6997 		_rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6998 		wpsielen += 7;
6999 
7000 		/*	Model Name */
7001 		/*	Type: */
7002 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
7003 		wpsielen += 2;
7004 
7005 		/*	Length: */
7006 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
7007 		wpsielen += 2;
7008 
7009 		/*	Value: */
7010 		_rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
7011 		wpsielen += 6;
7012 
7013 		/*	Model Number */
7014 		/*	Type: */
7015 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
7016 		wpsielen += 2;
7017 
7018 		/*	Length: */
7019 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7020 		wpsielen += 2;
7021 
7022 		/*	Value: */
7023 		wpsie[wpsielen++] = 0x31;		/*	character 1 */
7024 
7025 		/*	Serial Number */
7026 		/*	Type: */
7027 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
7028 		wpsielen += 2;
7029 
7030 		/*	Length: */
7031 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
7032 		wpsielen += 2;
7033 
7034 		/*	Value: */
7035 		_rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
7036 		wpsielen += ETH_ALEN;
7037 
7038 		/*	Primary Device Type */
7039 		/*	Type: */
7040 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
7041 		wpsielen += 2;
7042 
7043 		/*	Length: */
7044 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
7045 		wpsielen += 2;
7046 
7047 		/*	Value: */
7048 		/*	Category ID */
7049 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7050 		wpsielen += 2;
7051 
7052 		/*	OUI */
7053 		*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
7054 		wpsielen += 4;
7055 
7056 		/*	Sub Category ID */
7057 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7058 		wpsielen += 2;
7059 
7060 		/*	Device Name */
7061 		/*	Type: */
7062 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7063 		wpsielen += 2;
7064 
7065 		/*	Length: */
7066 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
7067 		wpsielen += 2;
7068 
7069 		/*	Value: */
7070 		_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
7071 		wpsielen += pwdinfo->device_name_len;
7072 
7073 		/*	Config Method */
7074 		/*	Type: */
7075 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
7076 		wpsielen += 2;
7077 
7078 		/*	Length: */
7079 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7080 		wpsielen += 2;
7081 
7082 		/*	Value: */
7083 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7084 		wpsielen += 2;
7085 
7086 
7087 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7088 
7089 
7090 		p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
7091 		pframe += p2pielen;
7092 		pktlen += p2pielen;
7093 	}
7094 
7095 #ifdef CONFIG_WFD
7096 	wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
7097 	pframe += wfdielen;
7098 	pktlen += wfdielen;
7099 #endif
7100 
7101 	*pLength = pktlen;
7102 
7103 #if 0
7104 	/* printf dbg msg */
7105 	dbgbufLen = pktlen;
7106 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7107 
7108 	for (index = 0; index < dbgbufLen; index++)
7109 		printk("%x ", *(dbgbuf + index));
7110 
7111 	printk("\n");
7112 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7113 #endif
7114 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7115 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7116 {
7117 	struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7118 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7119 	u8			action = P2P_PUB_ACTION_ACTION;
7120 	u32			p2poui = cpu_to_be32(P2POUI);
7121 	u8			oui_subtype = P2P_GO_NEGO_RESP;
7122 	u8			wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
7123 	u8			p2pielen = 0, i;
7124 	uint			wpsielen = 0;
7125 	u16			wps_devicepassword_id = 0x0000;
7126 	uint			wps_devicepassword_id_len = 0;
7127 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
7128 	u16			len_channellist_attr = 0;
7129 	u32			pktlen;
7130 	u8			dialogToken = 0;
7131 
7132 	/* struct xmit_frame			*pmgntframe; */
7133 	/* struct pkt_attrib			*pattrib; */
7134 	/* unsigned char					*pframe; */
7135 	struct rtw_ieee80211_hdr	*pwlanhdr;
7136 	unsigned short				*fctrl;
7137 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7138 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7139 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7140 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7141 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
7142 
7143 #ifdef CONFIG_WFD
7144 	u32					wfdielen = 0;
7145 #endif
7146 
7147 	/* for debug */
7148 	u8 *dbgbuf = pframe;
7149 	u8 dbgbufLen = 0, index = 0;
7150 
7151 	RTW_INFO("%s\n", __FUNCTION__);
7152 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7153 
7154 	fctrl = &(pwlanhdr->frame_ctl);
7155 	*(fctrl) = 0;
7156 
7157 	/* RA, filled by FW */
7158 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7159 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7160 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7161 
7162 	SetSeqNum(pwlanhdr, 0);
7163 	set_frame_sub_type(pframe, WIFI_ACTION);
7164 
7165 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7166 	pframe += pktlen;
7167 
7168 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7169 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7170 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7171 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7172 
7173 	/* dialog token, filled by FW */
7174 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7175 
7176 	_rtw_memset(wpsie, 0x00, 255);
7177 	wpsielen = 0;
7178 
7179 	/*	WPS Section */
7180 	wpsielen = 0;
7181 	/*	WPS OUI */
7182 	*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7183 	wpsielen += 4;
7184 
7185 	/*	WPS version */
7186 	/*	Type: */
7187 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7188 	wpsielen += 2;
7189 
7190 	/*	Length: */
7191 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7192 	wpsielen += 2;
7193 
7194 	/*	Value: */
7195 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
7196 
7197 	/*	Device Password ID */
7198 	/*	Type: */
7199 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
7200 	wpsielen += 2;
7201 
7202 	/*	Length: */
7203 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7204 	wpsielen += 2;
7205 
7206 	/*	Value: */
7207 	if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
7208 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
7209 	else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
7210 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
7211 	else
7212 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
7213 	wpsielen += 2;
7214 
7215 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7216 
7217 
7218 	/*	P2P IE Section. */
7219 
7220 	/*	P2P OUI */
7221 	p2pielen = 0;
7222 	p2pie[p2pielen++] = 0x50;
7223 	p2pie[p2pielen++] = 0x6F;
7224 	p2pie[p2pielen++] = 0x9A;
7225 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
7226 
7227 	/*	Commented by Albert 20100908 */
7228 	/*	According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
7229 	/*	1. Status */
7230 	/*	2. P2P Capability */
7231 	/*	3. Group Owner Intent */
7232 	/*	4. Configuration Timeout */
7233 	/*	5. Operating Channel */
7234 	/*	6. Intended P2P Interface Address */
7235 	/*	7. Channel List */
7236 	/*	8. Device Info */
7237 	/*	9. Group ID	( Only GO ) */
7238 
7239 
7240 	/*	ToDo: */
7241 
7242 	/*	P2P Status */
7243 	/*	Type: */
7244 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
7245 
7246 	/*	Length: */
7247 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7248 	p2pielen += 2;
7249 
7250 	/*	Value, filled by FW */
7251 	p2pie[p2pielen++] = 1;
7252 
7253 	/*	P2P Capability */
7254 	/*	Type: */
7255 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
7256 
7257 	/*	Length: */
7258 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7259 	p2pielen += 2;
7260 
7261 	/*	Value: */
7262 	/*	Device Capability Bitmap, 1 byte */
7263 
7264 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
7265 		/*	Commented by Albert 2011/03/08 */
7266 		/*	According to the P2P specification */
7267 		/*	if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
7268 		p2pie[p2pielen++] = 0;
7269 	} else {
7270 		/*	Be group owner or meet the error case */
7271 		p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
7272 	}
7273 
7274 	/*	Group Capability Bitmap, 1 byte */
7275 	if (pwdinfo->persistent_supported)
7276 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
7277 	else
7278 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
7279 
7280 	/*	Group Owner Intent */
7281 	/*	Type: */
7282 	p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
7283 
7284 	/*	Length: */
7285 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7286 	p2pielen += 2;
7287 
7288 	/*	Value: */
7289 	if (pwdinfo->peer_intent & 0x01) {
7290 		/*	Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
7291 		p2pie[p2pielen++] = (pwdinfo->intent << 1);
7292 	} else {
7293 		/*	Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
7294 		p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
7295 	}
7296 
7297 
7298 	/*	Configuration Timeout */
7299 	/*	Type: */
7300 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7301 
7302 	/*	Length: */
7303 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7304 	p2pielen += 2;
7305 
7306 	/*	Value: */
7307 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
7308 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
7309 
7310 	/*	Operating Channel */
7311 	/*	Type: */
7312 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7313 
7314 	/*	Length: */
7315 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7316 	p2pielen += 2;
7317 
7318 	/*	Value: */
7319 	/*	Country String */
7320 	p2pie[p2pielen++] = 'X';
7321 	p2pie[p2pielen++] = 'X';
7322 
7323 	/*	The third byte should be set to 0x04. */
7324 	/*	Described in the "Operating Channel Attribute" section. */
7325 	p2pie[p2pielen++] = 0x04;
7326 
7327 	/*	Operating Class */
7328 	if (pwdinfo->operating_channel <= 14) {
7329 		/*	Operating Class */
7330 		p2pie[p2pielen++] = 0x51;
7331 	} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
7332 		/*	Operating Class */
7333 		p2pie[p2pielen++] = 0x73;
7334 	} else {
7335 		/*	Operating Class */
7336 		p2pie[p2pielen++] = 0x7c;
7337 	}
7338 
7339 	/*	Channel Number */
7340 	p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
7341 
7342 	/*	Intended P2P Interface Address	 */
7343 	/*	Type: */
7344 	p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
7345 
7346 	/*	Length: */
7347 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7348 	p2pielen += 2;
7349 
7350 	/*	Value: */
7351 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7352 	p2pielen += ETH_ALEN;
7353 
7354 	/*	Channel List */
7355 	/*	Type: */
7356 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7357 
7358 	/* Country String(3) */
7359 	/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7360 	/* + number of channels in all classes */
7361 	len_channellist_attr = 3
7362 		       + (1 + 1) * (u16)ch_list->reg_classes
7363 		       + get_reg_classes_full_count(ch_list);
7364 
7365 #ifdef CONFIG_CONCURRENT_MODE
7366 	if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7367 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7368 	else
7369 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7370 
7371 #else
7372 
7373 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7374 
7375 #endif
7376 	p2pielen += 2;
7377 
7378 	/*	Value: */
7379 	/*	Country String */
7380 	p2pie[p2pielen++] = 'X';
7381 	p2pie[p2pielen++] = 'X';
7382 
7383 	/*	The third byte should be set to 0x04. */
7384 	/*	Described in the "Operating Channel Attribute" section. */
7385 	p2pie[p2pielen++] = 0x04;
7386 
7387 	/*	Channel Entry List */
7388 
7389 #ifdef CONFIG_CONCURRENT_MODE
7390 	if (rtw_mi_check_status(padapter, MI_LINKED)) {
7391 		u8 union_ch = rtw_mi_get_union_chan(padapter);
7392 
7393 		/*	Operating Class */
7394 		if (union_ch > 14) {
7395 			if (union_ch >= 149)
7396 				p2pie[p2pielen++] = 0x7c;
7397 			else
7398 				p2pie[p2pielen++] = 0x73;
7399 		} else
7400 			p2pie[p2pielen++] = 0x51;
7401 
7402 
7403 		/*	Number of Channels */
7404 		/*	Just support 1 channel and this channel is AP's channel */
7405 		p2pie[p2pielen++] = 1;
7406 
7407 		/*	Channel List */
7408 		p2pie[p2pielen++] = union_ch;
7409 	} else
7410 #endif /* CONFIG_CONCURRENT_MODE */
7411 	{
7412 		int i, j;
7413 		for (j = 0; j < ch_list->reg_classes; j++) {
7414 			/*	Operating Class */
7415 			p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7416 
7417 			/*	Number of Channels */
7418 			p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7419 
7420 			/*	Channel List */
7421 			for (i = 0; i < ch_list->reg_class[j].channels; i++)
7422 				p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7423 		}
7424 	}
7425 
7426 	/*	Device Info */
7427 	/*	Type: */
7428 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7429 
7430 	/*	Length: */
7431 	/*	21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
7432 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7433 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
7434 	p2pielen += 2;
7435 
7436 	/*	Value: */
7437 	/*	P2P Device Address */
7438 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7439 	p2pielen += ETH_ALEN;
7440 
7441 	/*	Config Method */
7442 	/*	This field should be big endian. Noted by P2P specification. */
7443 
7444 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7445 
7446 	p2pielen += 2;
7447 
7448 	/*	Primary Device Type */
7449 	/*	Category ID */
7450 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7451 	p2pielen += 2;
7452 
7453 	/*	OUI */
7454 	*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
7455 	p2pielen += 4;
7456 
7457 	/*	Sub Category ID */
7458 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7459 	p2pielen += 2;
7460 
7461 	/*	Number of Secondary Device Types */
7462 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
7463 
7464 	/*	Device Name */
7465 	/*	Type: */
7466 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7467 	p2pielen += 2;
7468 
7469 	/*	Length: */
7470 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
7471 	p2pielen += 2;
7472 
7473 	/*	Value: */
7474 	_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
7475 	p2pielen += pwdinfo->device_name_len;
7476 
7477 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7478 		/*	Group ID Attribute */
7479 		/*	Type: */
7480 		p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
7481 
7482 		/*	Length: */
7483 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
7484 		p2pielen += 2;
7485 
7486 		/*	Value: */
7487 		/*	p2P Device Address */
7488 		_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
7489 		p2pielen += ETH_ALEN;
7490 
7491 		/*	SSID */
7492 		_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
7493 		p2pielen += pwdinfo->nego_ssidlen;
7494 
7495 	}
7496 
7497 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7498 
7499 #ifdef CONFIG_WFD
7500 	wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
7501 	pframe += wfdielen;
7502 	pktlen += wfdielen;
7503 #endif
7504 
7505 	*pLength = pktlen;
7506 #if 0
7507 	/* printf dbg msg */
7508 	dbgbufLen = pktlen;
7509 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7510 
7511 	for (index = 0; index < dbgbufLen; index++)
7512 		printk("%x ", *(dbgbuf + index));
7513 
7514 	printk("\n");
7515 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7516 #endif
7517 }
7518 
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7519 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7520 {
7521 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7522 	u8			action = P2P_PUB_ACTION_ACTION;
7523 	u32			p2poui = cpu_to_be32(P2POUI);
7524 	u8			oui_subtype = P2P_INVIT_RESP;
7525 	u8			p2pie[255] = { 0x00 };
7526 	u8			p2pielen = 0, i;
7527 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
7528 	u16			len_channellist_attr = 0;
7529 	u32			pktlen;
7530 	u8			dialogToken = 0;
7531 #ifdef CONFIG_WFD
7532 	u32					wfdielen = 0;
7533 #endif
7534 
7535 	/* struct xmit_frame			*pmgntframe; */
7536 	/* struct pkt_attrib			*pattrib; */
7537 	/* unsigned char					*pframe; */
7538 	struct rtw_ieee80211_hdr	*pwlanhdr;
7539 	unsigned short				*fctrl;
7540 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7541 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7542 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7543 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7544 
7545 	/* for debug */
7546 	u8 *dbgbuf = pframe;
7547 	u8 dbgbufLen = 0, index = 0;
7548 
7549 
7550 	RTW_INFO("%s\n", __FUNCTION__);
7551 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7552 
7553 	fctrl = &(pwlanhdr->frame_ctl);
7554 	*(fctrl) = 0;
7555 
7556 	/* RA fill by FW */
7557 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7558 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7559 
7560 	/* BSSID fill by FW */
7561 	_rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
7562 
7563 	SetSeqNum(pwlanhdr, 0);
7564 	set_frame_sub_type(pframe, WIFI_ACTION);
7565 
7566 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7567 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7568 
7569 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7570 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7571 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7572 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7573 
7574 	/* dialog token, filled by FW */
7575 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7576 
7577 	/*	P2P IE Section. */
7578 
7579 	/*	P2P OUI */
7580 	p2pielen = 0;
7581 	p2pie[p2pielen++] = 0x50;
7582 	p2pie[p2pielen++] = 0x6F;
7583 	p2pie[p2pielen++] = 0x9A;
7584 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
7585 
7586 	/*	Commented by Albert 20101005 */
7587 	/*	According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
7588 	/*	1. Status */
7589 	/*	2. Configuration Timeout */
7590 	/*	3. Operating Channel	( Only GO ) */
7591 	/*	4. P2P Group BSSID	( Only GO ) */
7592 	/*	5. Channel List */
7593 
7594 	/*	P2P Status */
7595 	/*	Type: */
7596 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
7597 
7598 	/*	Length: */
7599 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7600 	p2pielen += 2;
7601 
7602 	/*	Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
7603 	p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7604 
7605 	/*	Configuration Timeout */
7606 	/*	Type: */
7607 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7608 
7609 	/*	Length: */
7610 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7611 	p2pielen += 2;
7612 
7613 	/*	Value: */
7614 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
7615 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
7616 
7617 	/* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
7618 #if 0
7619 	if (status_code == P2P_STATUS_SUCCESS) {
7620 		struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7621 
7622 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7623 			/*	The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
7624 			/*	In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
7625 			/*	First one is operating channel attribute. */
7626 			/*	Second one is P2P Group BSSID attribute. */
7627 
7628 			/*	Operating Channel */
7629 			/*	Type: */
7630 			p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7631 
7632 			/*	Length: */
7633 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7634 			p2pielen += 2;
7635 
7636 			/*	Value: */
7637 			/*	Country String */
7638 			p2pie[p2pielen++] = 'X';
7639 			p2pie[p2pielen++] = 'X';
7640 
7641 			/*	The third byte should be set to 0x04. */
7642 			/*	Described in the "Operating Channel Attribute" section. */
7643 			p2pie[p2pielen++] = 0x04;
7644 
7645 			/*	Operating Class */
7646 			p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
7647 
7648 			/*	Channel Number */
7649 			p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
7650 
7651 
7652 			/*	P2P Group BSSID */
7653 			/*	Type: */
7654 			p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
7655 
7656 			/*	Length: */
7657 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7658 			p2pielen += 2;
7659 
7660 			/*	Value: */
7661 			/*	P2P Device Address for GO */
7662 			_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7663 			p2pielen += ETH_ALEN;
7664 
7665 		}
7666 
7667 		/*	Channel List */
7668 		/*	Type: */
7669 		p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7670 
7671 		/*	Length: */
7672 		/* Country String(3) */
7673 		/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7674 		/* + number of channels in all classes */
7675 		len_channellist_attr = 3
7676 			+ (1 + 1) * (u16)ch_list->reg_classes
7677 			+ get_reg_classes_full_count(ch_list);
7678 
7679 #ifdef CONFIG_CONCURRENT_MODE
7680 		if (rtw_mi_check_status(padapter, MI_LINKED))
7681 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7682 		else
7683 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7684 
7685 #else
7686 
7687 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7688 
7689 #endif
7690 		p2pielen += 2;
7691 
7692 		/*	Value: */
7693 		/*	Country String */
7694 		p2pie[p2pielen++] = 'X';
7695 		p2pie[p2pielen++] = 'X';
7696 
7697 		/*	The third byte should be set to 0x04. */
7698 		/*	Described in the "Operating Channel Attribute" section. */
7699 		p2pie[p2pielen++] = 0x04;
7700 
7701 		/*	Channel Entry List */
7702 #ifdef CONFIG_CONCURRENT_MODE
7703 		if (rtw_mi_check_status(padapter, MI_LINKED)) {
7704 			u8 union_ch = rtw_mi_get_union_chan(padapter);
7705 
7706 			/*	Operating Class */
7707 			if (union_ch > 14) {
7708 				if (union_ch >= 149)
7709 					p2pie[p2pielen++] = 0x7c;
7710 				else
7711 					p2pie[p2pielen++] = 0x73;
7712 
7713 			} else
7714 				p2pie[p2pielen++] = 0x51;
7715 
7716 
7717 			/*	Number of Channels */
7718 			/*	Just support 1 channel and this channel is AP's channel */
7719 			p2pie[p2pielen++] = 1;
7720 
7721 			/*	Channel List */
7722 			p2pie[p2pielen++] = union_ch;
7723 		} else
7724 #endif /* CONFIG_CONCURRENT_MODE */
7725 		{
7726 			int i, j;
7727 			for (j = 0; j < ch_list->reg_classes; j++) {
7728 				/*	Operating Class */
7729 				p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7730 
7731 				/*	Number of Channels */
7732 				p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7733 
7734 				/*	Channel List */
7735 				for (i = 0; i < ch_list->reg_class[j].channels; i++)
7736 					p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7737 			}
7738 		}
7739 	}
7740 #endif
7741 
7742 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7743 
7744 #ifdef CONFIG_WFD
7745 	wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
7746 	pframe += wfdielen;
7747 	pktlen += wfdielen;
7748 #endif
7749 
7750 	*pLength = pktlen;
7751 
7752 #if 0
7753 	/* printf dbg msg */
7754 	dbgbufLen = pktlen;
7755 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7756 
7757 	for (index = 0; index < dbgbufLen; index++)
7758 		printk("%x ", *(dbgbuf + index));
7759 
7760 	printk("\n");
7761 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7762 #endif
7763 }
7764 
7765 
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7766 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7767 {
7768 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7769 	u8			action = P2P_PUB_ACTION_ACTION;
7770 	u8			dialogToken = 0;
7771 	u32			p2poui = cpu_to_be32(P2POUI);
7772 	u8			oui_subtype = P2P_PROVISION_DISC_RESP;
7773 	u8			wpsie[100] = { 0x00 };
7774 	u8			wpsielen = 0;
7775 	u32			pktlen;
7776 #ifdef CONFIG_WFD
7777 	u32					wfdielen = 0;
7778 #endif
7779 
7780 	/* struct xmit_frame			*pmgntframe; */
7781 	/* struct pkt_attrib			*pattrib; */
7782 	/* unsigned char					*pframe; */
7783 	struct rtw_ieee80211_hdr	*pwlanhdr;
7784 	unsigned short				*fctrl;
7785 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7786 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7787 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7788 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7789 
7790 	/* for debug */
7791 	u8 *dbgbuf = pframe;
7792 	u8 dbgbufLen = 0, index = 0;
7793 
7794 	RTW_INFO("%s\n", __FUNCTION__);
7795 
7796 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7797 
7798 	fctrl = &(pwlanhdr->frame_ctl);
7799 	*(fctrl) = 0;
7800 
7801 	/* RA filled by FW */
7802 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7803 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7804 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7805 
7806 	SetSeqNum(pwlanhdr, 0);
7807 	set_frame_sub_type(pframe, WIFI_ACTION);
7808 
7809 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7810 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7811 
7812 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7813 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7814 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7815 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7816 	/* dialog token, filled by FW */
7817 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7818 
7819 	wpsielen = 0;
7820 	/*	WPS OUI */
7821 	/* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
7822 	RTW_PUT_BE32(wpsie, WPSOUI);
7823 	wpsielen += 4;
7824 
7825 #if 0
7826 	/*	WPS version */
7827 	/*	Type: */
7828 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7829 	wpsielen += 2;
7830 
7831 	/*	Length: */
7832 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7833 	wpsielen += 2;
7834 
7835 	/*	Value: */
7836 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
7837 #endif
7838 
7839 	/*	Config Method */
7840 	/*	Type: */
7841 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
7842 	RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
7843 	wpsielen += 2;
7844 
7845 	/*	Length: */
7846 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
7847 	RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
7848 	wpsielen += 2;
7849 
7850 	/*	Value: filled by FW, default value is PBC */
7851 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
7852 	RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
7853 	wpsielen += 2;
7854 
7855 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7856 
7857 #ifdef CONFIG_WFD
7858 	wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
7859 	pframe += wfdielen;
7860 	pktlen += wfdielen;
7861 #endif
7862 
7863 	*pLength = pktlen;
7864 
7865 	/* printf dbg msg */
7866 #if 0
7867 	dbgbufLen = pktlen;
7868 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT  ProvisionDis Rsp\n");
7869 
7870 	for (index = 0; index < dbgbufLen; index++)
7871 		printk("%x ", *(dbgbuf + index));
7872 
7873 	printk("\n");
7874 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7875 #endif
7876 }
7877 
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)7878 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
7879 {
7880 	u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
7881 	struct hal_ops *pHalFunc = &adapter->hal_func;
7882 	u8 ret = _FAIL;
7883 
7884 	RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
7885 		 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
7886 		 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
7887 		 rsvdpageloc->LocPDRsp);
7888 
7889 	SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
7890 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
7891 	SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
7892 	SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
7893 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
7894 
7895 	/* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
7896 	ret = rtw_hal_fill_h2c_cmd(adapter,
7897 				   H2C_P2P_OFFLOAD_RSVD_PAGE,
7898 				   H2C_P2PRSVDPAGE_LOC_LEN,
7899 				   u1H2CP2PRsvdPageParm);
7900 
7901 	return ret;
7902 }
7903 
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)7904 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
7905 {
7906 
7907 	u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
7908 	struct wifidirect_info	*pwdinfo = &(adapter->wdinfo);
7909 	struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
7910 	struct hal_ops *pHalFunc = &adapter->hal_func;
7911 	u8 ret = _FAIL;
7912 
7913 	_rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
7914 	RTW_INFO("%s\n", __func__);
7915 	switch (pwdinfo->role) {
7916 	case P2P_ROLE_DEVICE:
7917 		RTW_INFO("P2P_ROLE_DEVICE\n");
7918 		p2p_wowlan_offload->role = 0;
7919 		break;
7920 	case P2P_ROLE_CLIENT:
7921 		RTW_INFO("P2P_ROLE_CLIENT\n");
7922 		p2p_wowlan_offload->role = 1;
7923 		break;
7924 	case P2P_ROLE_GO:
7925 		RTW_INFO("P2P_ROLE_GO\n");
7926 		p2p_wowlan_offload->role = 2;
7927 		break;
7928 	default:
7929 		RTW_INFO("P2P_ROLE_DISABLE\n");
7930 		break;
7931 	}
7932 	p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
7933 	p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
7934 	offload_cmd = (u8 *)p2p_wowlan_offload;
7935 	RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
7936 
7937 	ret = rtw_hal_fill_h2c_cmd(adapter,
7938 				   H2C_P2P_OFFLOAD,
7939 				   H2C_P2P_OFFLOAD_LEN,
7940 				   offload_cmd);
7941 	return ret;
7942 
7943 	/* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
7944 }
7945 #endif /* CONFIG_P2P_WOWLAN */
7946 
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)7947 void rtw_hal_construct_beacon(_adapter *padapter,
7948 				     u8 *pframe, u32 *pLength)
7949 {
7950 	struct rtw_ieee80211_hdr	*pwlanhdr;
7951 	u16					*fctrl;
7952 	u32					pktlen;
7953 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7954 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7955 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
7956 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7957 
7958 
7959 	/* RTW_INFO("%s\n", __FUNCTION__); */
7960 
7961 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7962 
7963 	fctrl = &(pwlanhdr->frame_ctl);
7964 	*(fctrl) = 0;
7965 
7966 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7967 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7968 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7969 
7970 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7971 	/* pmlmeext->mgnt_seq++; */
7972 	set_frame_sub_type(pframe, WIFI_BEACON);
7973 
7974 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7975 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7976 
7977 	/* timestamp will be inserted by hardware */
7978 	pframe += 8;
7979 	pktlen += 8;
7980 
7981 	/* beacon interval: 2 bytes */
7982 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7983 
7984 	pframe += 2;
7985 	pktlen += 2;
7986 
7987 #if 0
7988 	/* capability info: 2 bytes */
7989 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7990 
7991 	pframe += 2;
7992 	pktlen += 2;
7993 
7994 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7995 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7996 		pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
7997 		_rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
7998 
7999 		goto _ConstructBeacon;
8000 	}
8001 
8002 	/* below for ad-hoc mode */
8003 
8004 	/* SSID */
8005 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
8006 
8007 	/* supported rates... */
8008 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
8009 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
8010 
8011 	/* DS parameter set */
8012 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
8013 
8014 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
8015 		u32 ATIMWindow;
8016 		/* IBSS Parameter Set... */
8017 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
8018 		ATIMWindow = 0;
8019 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
8020 	}
8021 
8022 
8023 	/* todo: ERP IE */
8024 
8025 
8026 	/* EXTERNDED SUPPORTED RATE */
8027 	if (rate_len > 8)
8028 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
8029 
8030 	/* todo:HT for adhoc */
8031 
8032 _ConstructBeacon:
8033 #endif
8034 
8035 	if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
8036 		RTW_ERR("beacon frame too large ,len(%d,%d)\n",
8037 			(pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
8038 		rtw_warn_on(1);
8039 		return;
8040 	}
8041 
8042 	*pLength = pktlen;
8043 
8044 	/* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
8045 
8046 }
8047 
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)8048 static void rtw_hal_construct_PSPoll(_adapter *padapter,
8049 				     u8 *pframe, u32 *pLength)
8050 {
8051 	struct rtw_ieee80211_hdr	*pwlanhdr;
8052 	u16					*fctrl;
8053 	u32					pktlen;
8054 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8055 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8056 
8057 	/* RTW_INFO("%s\n", __FUNCTION__); */
8058 
8059 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8060 
8061 	/* Frame control. */
8062 	fctrl = &(pwlanhdr->frame_ctl);
8063 	*(fctrl) = 0;
8064 	SetPwrMgt(fctrl);
8065 	set_frame_sub_type(pframe, WIFI_PSPOLL);
8066 
8067 	/* AID. */
8068 	set_duration(pframe, (pmlmeinfo->aid | 0xc000));
8069 
8070 	/* BSSID. */
8071 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8072 
8073 	/* TA. */
8074 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8075 
8076 	*pLength = 16;
8077 }
8078 
8079 
8080 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_construct_fw_dbg_msg_pkt(PADAPTER padapter,u8 * pframe,u32 * plength)8081 void rtw_hal_construct_fw_dbg_msg_pkt(
8082 	PADAPTER padapter,
8083 	u8		*pframe,
8084 	u32		*plength)
8085 {
8086 	struct rtw_ieee80211_hdr	*pwlanhdr;
8087 	u16						*fctrl;
8088 	u32						pktlen;
8089 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
8090 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
8091 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8092 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8093 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8094 
8095 
8096 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8097 
8098 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8099 
8100 	fctrl = &pwlanhdr->frame_ctl;
8101 	*(fctrl) = 0;
8102 
8103 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8104 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8105 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8106 
8107 	SetSeqNum(pwlanhdr, 0);
8108 
8109 	set_frame_sub_type(pframe, WIFI_DATA);
8110 
8111 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8112 
8113 	*plength = pktlen;
8114 }
8115 #endif /*DBG_FW_DEBUG_MSG_PKT*/
8116 
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)8117 void rtw_hal_construct_NullFunctionData(
8118 	PADAPTER padapter,
8119 	u8		*pframe,
8120 	u32		*pLength,
8121 	u8		bQoS,
8122 	u8		AC,
8123 	u8		bEosp,
8124 	u8		bForcePowerSave)
8125 {
8126 	struct rtw_ieee80211_hdr	*pwlanhdr;
8127 	u16						*fctrl;
8128 	u32						pktlen;
8129 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
8130 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
8131 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8132 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8133 	u8 *sta_addr = NULL;
8134 	u8 bssid[ETH_ALEN] = {0};
8135 
8136 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8137 
8138 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8139 
8140 	fctrl = &pwlanhdr->frame_ctl;
8141 	*(fctrl) = 0;
8142 	if (bForcePowerSave)
8143 		SetPwrMgt(fctrl);
8144 
8145 	sta_addr = get_my_bssid(&pmlmeinfo->network);
8146 	if (NULL == sta_addr) {
8147 		_rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
8148 		sta_addr = bssid;
8149 	}
8150 
8151 	switch (cur_network->network.InfrastructureMode) {
8152 	case Ndis802_11Infrastructure:
8153 		SetToDs(fctrl);
8154 		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8155 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8156 		_rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
8157 		break;
8158 	case Ndis802_11APMode:
8159 		SetFrDs(fctrl);
8160 		_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8161 		_rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8162 		_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8163 		break;
8164 	case Ndis802_11IBSS:
8165 	default:
8166 		_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8167 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8168 		_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8169 		break;
8170 	}
8171 
8172 	SetSeqNum(pwlanhdr, 0);
8173 	set_duration(pwlanhdr, 0);
8174 
8175 	if (bQoS == _TRUE) {
8176 		struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
8177 
8178 		set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
8179 
8180 		pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
8181 		SetPriority(&pwlanqoshdr->qc, AC);
8182 		SetEOSP(&pwlanqoshdr->qc, bEosp);
8183 
8184 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8185 	} else {
8186 		set_frame_sub_type(pframe, WIFI_DATA_NULL);
8187 
8188 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8189 	}
8190 
8191 	*pLength = pktlen;
8192 }
8193 
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,BOOLEAN bHideSSID)8194 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
8195 				BOOLEAN bHideSSID)
8196 {
8197 	struct rtw_ieee80211_hdr	*pwlanhdr;
8198 	u16					*fctrl;
8199 	u8					*mac, *bssid, *sta_addr;
8200 	u32					pktlen;
8201 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8202 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8203 	WLAN_BSSID_EX  *cur_network = &(pmlmeinfo->network);
8204 
8205 	/*RTW_INFO("%s\n", __FUNCTION__);*/
8206 
8207 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8208 
8209 	mac = adapter_mac_addr(padapter);
8210 	bssid = cur_network->MacAddress;
8211 	sta_addr = get_my_bssid(&pmlmeinfo->network);
8212 
8213 	fctrl = &(pwlanhdr->frame_ctl);
8214 	*(fctrl) = 0;
8215 	_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8216 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8217 	_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8218 
8219 	SetSeqNum(pwlanhdr, 0);
8220 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
8221 
8222 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8223 	pframe += pktlen;
8224 
8225 	if (cur_network->IELength > MAX_IE_SZ)
8226 		return;
8227 
8228 	_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8229 	pframe += cur_network->IELength;
8230 	pktlen += cur_network->IELength;
8231 
8232 	*pLength = pktlen;
8233 }
8234 
8235 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)8236 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
8237 				    u8 *pframe, u32 offset)
8238 {
8239 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8240 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8241 	struct rtw_ieee80211_hdr	*pwlanhdr;
8242 	struct mic_data	micdata;
8243 	struct sta_info	*psta = NULL;
8244 	int res = 0;
8245 
8246 	u8	*payload = (u8 *)(pframe + offset);
8247 
8248 	u8	mic[8];
8249 	u8	priority[4] = {0x0};
8250 	u8	null_key[16] = {0x0};
8251 
8252 	RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
8253 
8254 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8255 
8256 	psta = rtw_get_stainfo(&padapter->stapriv,
8257 			get_my_bssid(&(pmlmeinfo->network)));
8258 	if (psta != NULL) {
8259 		res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
8260 				  null_key, 16);
8261 		if (res == _TRUE)
8262 			RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
8263 		rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
8264 	}
8265 
8266 	rtw_secmicappend(&micdata, pwlanhdr->addr3, 6);  /* DA */
8267 
8268 	rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
8269 
8270 	priority[0] = 0;
8271 
8272 	rtw_secmicappend(&micdata, &priority[0], 4);
8273 
8274 	rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
8275 
8276 	rtw_secgetmic(&micdata, &(mic[0]));
8277 
8278 	payload += 36;
8279 
8280 	_rtw_memcpy(payload, &(mic[0]), 8);
8281 }
8282 /*
8283  * Description:
8284  *	Construct the ARP response packet to support ARP offload.
8285  *   */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8286 static void rtw_hal_construct_ARPRsp(
8287 	PADAPTER padapter,
8288 	u8			*pframe,
8289 	u32			*pLength,
8290 	u8			*pIPAddress
8291 )
8292 {
8293 	struct rtw_ieee80211_hdr	*pwlanhdr;
8294 	u16	*fctrl;
8295 	u32	pktlen;
8296 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8297 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8298 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8299 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8300 	static u8	ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
8301 	u8	*pARPRspPkt = pframe;
8302 	/* for TKIP Cal MIC */
8303 	u8	*payload = pframe;
8304 	u8	EncryptionHeadOverhead = 0, arp_offset = 0;
8305 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8306 
8307 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8308 
8309 	fctrl = &pwlanhdr->frame_ctl;
8310 	*(fctrl) = 0;
8311 
8312 	/* ------------------------------------------------------------------------- */
8313 	/* MAC Header. */
8314 	/* ------------------------------------------------------------------------- */
8315 	SetFrameType(fctrl, WIFI_DATA);
8316 	/* set_frame_sub_type(fctrl, 0); */
8317 	SetToDs(fctrl);
8318 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8319 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8320 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8321 
8322 	SetSeqNum(pwlanhdr, 0);
8323 	set_duration(pwlanhdr, 0);
8324 	/* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
8325 	/* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
8326 	/* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
8327 	/* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
8328 	/* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
8329 	/* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
8330 
8331 	/* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
8332 	/* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
8333 #ifdef CONFIG_WAPI_SUPPORT
8334 	*pLength = sMacHdrLng;
8335 #else
8336 	*pLength = 24;
8337 #endif
8338 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8339 	case _WEP40_:
8340 	case _WEP104_:
8341 		EncryptionHeadOverhead = 4;
8342 		break;
8343 	case _TKIP_:
8344 		EncryptionHeadOverhead = 8;
8345 		break;
8346 	case _AES_:
8347 		EncryptionHeadOverhead = 8;
8348 		break;
8349 #ifdef CONFIG_WAPI_SUPPORT
8350 	case _SMS4_:
8351 		EncryptionHeadOverhead = 18;
8352 		break;
8353 #endif
8354 	default:
8355 		EncryptionHeadOverhead = 0;
8356 	}
8357 
8358 	if (EncryptionHeadOverhead > 0) {
8359 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8360 		*pLength += EncryptionHeadOverhead;
8361 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8362 		SetPrivacy(fctrl);
8363 	}
8364 
8365 	/* ------------------------------------------------------------------------- */
8366 	/* Frame Body. */
8367 	/* ------------------------------------------------------------------------- */
8368 	arp_offset = *pLength;
8369 	pARPRspPkt = (u8 *)(pframe + arp_offset);
8370 	payload = pARPRspPkt; /* Get Payload pointer */
8371 	/* LLC header */
8372 	_rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
8373 	*pLength += 8;
8374 
8375 	/* ARP element */
8376 	pARPRspPkt += 8;
8377 	SET_ARP_HTYPE(pARPRspPkt, 1);
8378 	SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP);	/* IP protocol */
8379 	SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
8380 	SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
8381 	SET_ARP_OPER(pARPRspPkt, 2);	/* ARP response */
8382 	SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
8383 	SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
8384 #ifdef CONFIG_ARP_KEEP_ALIVE
8385 	if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
8386 		SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
8387 		SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
8388 	} else
8389 #endif
8390 	{
8391 		SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
8392 				    get_my_bssid(&(pmlmeinfo->network)));
8393 		SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
8394 					   pIPAddress);
8395 		RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
8396 			 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
8397 		RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
8398 			 IP_ARG(pIPAddress));
8399 	}
8400 
8401 	*pLength += 28;
8402 
8403 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8404 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8405 		    IS_HARDWARE_TYPE_8812(padapter)) {
8406 			rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
8407 		}
8408 		*pLength += 8;
8409 	}
8410 }
8411 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
8412 /*
8413  * Description:
8414  *	Construct the Keep Alive packet to support specific Keep Alive packet.
8415  *   */
rtw_hal_construct_keepalive(PADAPTER padapter,u8 * pframe,u32 * pLength)8416 static void rtw_hal_construct_keepalive(	PADAPTER padapter,
8417 	u8			*pframe,
8418 	u32			*pLength
8419 ){
8420 	struct rtw_ieee80211_hdr	*pwlanhdr;
8421 	u16	*fctrl;
8422 	u32	pktlen;
8423 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8424 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8425 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8426 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8427 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
8428 	static u8	LLCHeader[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
8429 	u8	*pKeepAlivePkt = pframe;
8430 	/* for TKIP Cal MIC */
8431 	u8	*payload = pframe;
8432 	u8	EncryptionHeadOverhead = 0, frame_offset = 0;
8433 	int i;
8434 
8435 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8436 
8437 	fctrl = &pwlanhdr->frame_ctl;
8438 	*(fctrl) = 0;
8439 
8440 	RTW_INFO("%s======>\n", __func__);
8441 
8442 
8443 	/* ------------------------------------------------------------------------- */
8444 	/* MAC Header. */
8445 	/* ------------------------------------------------------------------------- */
8446 	SetFrameType(fctrl, WIFI_DATA);
8447 	/* set_frame_sub_type(fctrl, 0); */
8448 	SetToDs(fctrl);
8449 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8450 	_rtw_memcpy(pwlanhdr->addr2, pwrpriv->keep_alive_pattern+6, ETH_ALEN);
8451 	_rtw_memcpy(pwlanhdr->addr3,pwrpriv->keep_alive_pattern, ETH_ALEN);
8452 
8453 	SetSeqNum(pwlanhdr, 0);
8454 	set_duration(pwlanhdr, 0);
8455 
8456 #ifdef CONFIG_WAPI_SUPPORT
8457 	*pLength = sMacHdrLng;
8458 #else
8459 	*pLength = 24;
8460 #endif
8461 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8462 	case _WEP40_:
8463 	case _WEP104_:
8464 		EncryptionHeadOverhead = 4;
8465 		break;
8466 	case _TKIP_:
8467 		EncryptionHeadOverhead = 8;
8468 		break;
8469 	case _AES_:
8470 		EncryptionHeadOverhead = 8;
8471 		break;
8472 #ifdef CONFIG_WAPI_SUPPORT
8473 	case _SMS4_:
8474 		EncryptionHeadOverhead = 18;
8475 		break;
8476 #endif
8477 	default:
8478 		EncryptionHeadOverhead = 0;
8479 	}
8480 
8481 	if (EncryptionHeadOverhead > 0) {
8482 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8483 		*pLength += EncryptionHeadOverhead;
8484 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8485 		SetPrivacy(fctrl);
8486 	}
8487 
8488 	/* ------------------------------------------------------------------------- */
8489 	/* Frame Body. */
8490 	/* ------------------------------------------------------------------------- */
8491 	frame_offset = *pLength;
8492 	pKeepAlivePkt = (u8 *)(pframe + frame_offset);
8493 	payload = pKeepAlivePkt; /* Get Payload pointer */
8494 	/* LLC header */
8495 	_rtw_memcpy(pKeepAlivePkt, LLCHeader, 6);
8496 	*pLength += 6;
8497 
8498 	/*From  protocol type*/
8499 	pKeepAlivePkt+=6;
8500 
8501 	_rtw_memcpy(pKeepAlivePkt,pwrpriv->keep_alive_pattern+12,pwrpriv->keep_alive_pattern_len-12);
8502 
8503 	*pLength+=pwrpriv->keep_alive_pattern_len-12;
8504 
8505 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8506 		*pLength += 8;
8507 	}
8508 
8509 	/* for debug
8510 	for (i=0; i< (*pLength) ;i++) {
8511 		RTW_INFO("KA_Pkt[0x%x]=x%0x", i,pKeepAlivePkt[i]);
8512 		if((i%8) == 7)
8513 			RTW_INFO("\n");
8514 	}
8515 	*/
8516 
8517 	RTW_INFO("%s <======\n", __func__);
8518 }
8519 
8520 #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
8521 
8522 #ifdef CONFIG_IPV6
8523 /*
8524  * Description: Neighbor Discovery Offload.
8525  */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)8526 static void rtw_hal_construct_na_message(_adapter *padapter,
8527 				     u8 *pframe, u32 *pLength)
8528 {
8529 	struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8530 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8531 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8532 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
8533 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8534 
8535 	u32 pktlen = 0;
8536 	u16 *fctrl = NULL;
8537 
8538 	u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8539 	u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8540 	u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8541 	u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8542 	u8 val8 = 0;
8543 
8544 	u8 *p_na_msg = pframe;
8545 	/* for TKIP Cal MIC */
8546 	u8 *payload = pframe;
8547 	u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8548 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8549 
8550 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8551 
8552 	fctrl = &pwlanhdr->frame_ctl;
8553 	*(fctrl) = 0;
8554 
8555 	/* ------------------------------------------------------------------------- */
8556 	/* MAC Header. */
8557 	/* ------------------------------------------------------------------------- */
8558 	SetFrameType(fctrl, WIFI_DATA);
8559 	SetToDs(fctrl);
8560 	_rtw_memcpy(pwlanhdr->addr1,
8561 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8562 	_rtw_memcpy(pwlanhdr->addr2,
8563 		    adapter_mac_addr(padapter), ETH_ALEN);
8564 	_rtw_memcpy(pwlanhdr->addr3,
8565 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8566 
8567 	SetSeqNum(pwlanhdr, 0);
8568 	set_duration(pwlanhdr, 0);
8569 
8570 #ifdef CONFIG_WAPI_SUPPORT
8571 	*pLength = sMacHdrLng;
8572 #else
8573 	*pLength = 24;
8574 #endif
8575 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8576 	case _WEP40_:
8577 	case _WEP104_:
8578 		EncryptionHeadOverhead = 4;
8579 		break;
8580 	case _TKIP_:
8581 		EncryptionHeadOverhead = 8;
8582 		break;
8583 	case _AES_:
8584 		EncryptionHeadOverhead = 8;
8585 		break;
8586 #ifdef CONFIG_WAPI_SUPPORT
8587 	case _SMS4_:
8588 		EncryptionHeadOverhead = 18;
8589 		break;
8590 #endif
8591 	default:
8592 		EncryptionHeadOverhead = 0;
8593 	}
8594 
8595 	if (EncryptionHeadOverhead > 0) {
8596 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8597 		*pLength += EncryptionHeadOverhead;
8598 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8599 		SetPrivacy(fctrl);
8600 	}
8601 
8602 	/* ------------------------------------------------------------------------- */
8603 	/* Frame Body. */
8604 	/* ------------------------------------------------------------------------- */
8605 	na_msg_offset = *pLength;
8606 	p_na_msg = (u8 *)(pframe + na_msg_offset);
8607 	payload = p_na_msg; /* Get Payload pointer */
8608 
8609 	/* LLC header */
8610 	val8 = sizeof(ns_hdr);
8611 	_rtw_memcpy(p_na_msg, ns_hdr, val8);
8612 	*pLength += val8;
8613 	p_na_msg += val8;
8614 
8615 	/* IPv6 Header */
8616 	/* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8617 	val8 = sizeof(ipv6_info);
8618 	_rtw_memcpy(p_na_msg, ipv6_info, val8);
8619 	*pLength += val8;
8620 	p_na_msg += val8;
8621 
8622 	/* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8623 	val8 = sizeof(ipv6_contx);
8624 	_rtw_memcpy(p_na_msg, ipv6_contx, val8);
8625 	*pLength += val8;
8626 	p_na_msg += val8;
8627 
8628 	/* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8629 	_rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8630 	*pLength += 32;
8631 	p_na_msg += 32;
8632 
8633 	/* ICMPv6 */
8634 	/* 1. Type : 0x88 (NA)
8635 	 * 2. Code : 0x00
8636 	 * 3. ChechSum : 0x00 0x00 (RSvd)
8637 	 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8638 	 */
8639 	val8 = sizeof(icmpv6_hdr);
8640 	_rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8641 	*pLength += val8;
8642 	p_na_msg += val8;
8643 
8644 	/* TA: 16 bytes*/
8645 	_rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8646 	*pLength += 16;
8647 	p_na_msg += 16;
8648 
8649 	/* ICMPv6 Target Link Layer Address */
8650 	p_na_msg[0] = 0x02; /* type */
8651 	p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8652 	*pLength += 2;
8653 	p_na_msg += 2;
8654 
8655 	_rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8656 	*pLength += 6;
8657 	p_na_msg += 6;
8658 
8659 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8660 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8661 		    IS_HARDWARE_TYPE_8812(padapter)) {
8662 			rtw_hal_append_tkip_mic(padapter, pframe,
8663 						na_msg_offset);
8664 		}
8665 		*pLength += 8;
8666 	}
8667 }
8668 /*
8669  * Description: Neighbor Discovery Protocol Information.
8670  */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)8671 static void rtw_hal_construct_ndp_info(_adapter *padapter,
8672 				     u8 *pframe, u32 *pLength)
8673 {
8674 	struct mlme_ext_priv *pmlmeext = NULL;
8675 	struct mlme_ext_info *pmlmeinfo = NULL;
8676 	struct rtw_ndp_info ndp_info;
8677 	u8	*pndp_info = pframe;
8678 	u8	len = sizeof(struct rtw_ndp_info);
8679 
8680 	RTW_INFO("%s: len: %d\n", __func__, len);
8681 
8682 	pmlmeext =  &padapter->mlmeextpriv;
8683 	pmlmeinfo = &pmlmeext->mlmext_info;
8684 
8685 	_rtw_memset(pframe, 0, len);
8686 	_rtw_memset(&ndp_info, 0, len);
8687 
8688 	ndp_info.enable = 1;
8689 	ndp_info.check_remote_ip = 0;
8690 	ndp_info.num_of_target_ip = 1;
8691 
8692 	_rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8693 		    ETH_ALEN);
8694 	_rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8695 		    RTW_IPv6_ADDR_LEN);
8696 
8697 	_rtw_memcpy(pndp_info, &ndp_info, len);
8698 }
8699 #endif /* CONFIG_IPV6 */
8700 
8701 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)8702 void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8703 				u32 *pLength, pno_ssid_t *ssid)
8704 {
8705 	struct rtw_ieee80211_hdr	*pwlanhdr;
8706 	u16				*fctrl;
8707 	u32				pktlen;
8708 	unsigned char			*mac;
8709 	unsigned char			bssrate[NumRates];
8710 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
8711 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8712 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8713 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8714 	int	bssrate_len = 0;
8715 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8716 
8717 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8718 	mac = adapter_mac_addr(padapter);
8719 
8720 	fctrl = &(pwlanhdr->frame_ctl);
8721 	*(fctrl) = 0;
8722 
8723 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8724 	_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8725 
8726 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8727 
8728 	SetSeqNum(pwlanhdr, 0);
8729 	set_frame_sub_type(pframe, WIFI_PROBEREQ);
8730 
8731 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8732 	pframe += pktlen;
8733 
8734 	if (ssid == NULL)
8735 		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8736 	else {
8737 		/* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8738 		pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8739 	}
8740 
8741 	get_rate_set(padapter, bssrate, &bssrate_len);
8742 
8743 	if (bssrate_len > 8) {
8744 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8745 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8746 	} else
8747 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8748 
8749 	*pLength = pktlen;
8750 }
8751 
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)8752 static void rtw_hal_construct_PNO_info(_adapter *padapter,
8753 				       u8 *pframe, u32 *pLength)
8754 {
8755 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8756 	int i;
8757 
8758 	u8	*pPnoInfoPkt = pframe;
8759 	pPnoInfoPkt = (u8 *)(pframe + *pLength);
8760 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8761 
8762 	pPnoInfoPkt += 1;
8763 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8764 
8765 	pPnoInfoPkt += 3;
8766 #ifdef RTW_HALMAC
8767 	/* Pattern check for 3081 ICs */
8768 	_rtw_memset(pPnoInfoPkt, 0xA5A5A5A5, 4);
8769 	pPnoInfoPkt += 12;
8770 #else
8771 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8772 
8773 	pPnoInfoPkt += 4;
8774 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8775 
8776 	pPnoInfoPkt += 4;
8777 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8778 
8779 	pPnoInfoPkt += 4;
8780 #endif
8781 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8782 
8783 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8784 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8785 
8786 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8787 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8788 
8789 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8790 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8791 
8792 	pPnoInfoPkt += MAX_HIDDEN_AP;
8793 
8794 #ifdef RTW_HALMAC
8795 	/* SSID is located at 72th byte in NLO info Page for ICs that have HAMMAC */
8796 	*pLength += 72;
8797 	pPnoInfoPkt = pframe + 72;
8798 #else
8799 	/* SSID is located at 128th Byte in NLO info Page for ICs that don't have HAMMAC */
8800 	*pLength += 128;
8801 	pPnoInfoPkt = pframe + 128;
8802 #endif
8803 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8804 		_rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8805 			    pwrctl->pnlo_info->ssid_length[i]);
8806 		*pLength += WLAN_SSID_MAXLEN;
8807 		pPnoInfoPkt += WLAN_SSID_MAXLEN;
8808 	}
8809 }
8810 
8811 #ifndef RTW_HALMAC
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)8812 static void rtw_hal_construct_ssid_list(_adapter *padapter,
8813 					u8 *pframe, u32 *pLength)
8814 {
8815 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8816 	u8 *pSSIDListPkt = pframe;
8817 	int i;
8818 
8819 	pSSIDListPkt = (u8 *)(pframe + *pLength);
8820 
8821 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8822 		_rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8823 			    pwrctl->pnlo_info->ssid_length[i]);
8824 
8825 		*pLength += WLAN_SSID_MAXLEN;
8826 		pSSIDListPkt += WLAN_SSID_MAXLEN;
8827 	}
8828 }
8829 
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)8830 static void rtw_hal_construct_scan_info(_adapter *padapter,
8831 					u8 *pframe, u32 *pLength)
8832 {
8833 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8834 	u8 *pScanInfoPkt = pframe;
8835 	int i;
8836 
8837 	pScanInfoPkt = (u8 *)(pframe + *pLength);
8838 
8839 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8840 
8841 	*pLength += 1;
8842 	pScanInfoPkt += 1;
8843 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8844 
8845 
8846 	*pLength += 1;
8847 	pScanInfoPkt += 1;
8848 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8849 
8850 
8851 	*pLength += 1;
8852 	pScanInfoPkt += 1;
8853 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8854 
8855 	*pLength += 1;
8856 	pScanInfoPkt += 1;
8857 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8858 
8859 	*pLength += 1;
8860 	pScanInfoPkt += 1;
8861 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8862 
8863 	*pLength += 1;
8864 	pScanInfoPkt += 1;
8865 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8866 
8867 	*pLength += 1;
8868 	pScanInfoPkt += 1;
8869 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8870 
8871 	*pLength += 1;
8872 	pScanInfoPkt += 1;
8873 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8874 
8875 	*pLength += 8;
8876 	pScanInfoPkt += 8;
8877 
8878 	for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8879 		_rtw_memcpy(pScanInfoPkt,
8880 			    &pwrctl->pscan_info->ssid_channel_info[i], 4);
8881 		*pLength += 4;
8882 		pScanInfoPkt += 4;
8883 	}
8884 }
8885 #endif /* !RTW_HALMAC */
8886 #endif /* CONFIG_PNO_SUPPORT */
8887 
8888 #ifdef CONFIG_WAR_OFFLOAD
8889 #ifdef CONFIG_OFFLOAD_MDNS_V4
8890 
8891 /*
8892  * Description:
8893  *	Construct the MDNS V4 response packet to support MDNS offload.
8894  *
8895  */
rtw_hal_construct_mdns_rsp_v4(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8896 static void rtw_hal_construct_mdns_rsp_v4(
8897 	PADAPTER 	padapter,
8898 	u8			*pframe,
8899 	u32			*pLength,
8900 	u8			*pIPAddress
8901 )
8902 {
8903 	struct rtw_ieee80211_hdr	*pwlanhdr;
8904 	u16	*fctrl;
8905 	u32	pktlen;
8906 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8907 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
8908 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8909 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8910 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8911 	static u8	ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00};
8912 	u8	mulicast_ipv4_addr[4] = {0xe0, 0x00, 0x00, 0xfb};
8913 	u8	mulicast_mac_addr_for_mdns[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb};
8914 	u8	*pMdnsRspPkt = pframe;
8915 	/* for TKIP Cal MIC */
8916 	u8	EncryptionHeadOverhead = 0, mdns_offset = 0;
8917 
8918 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
8919 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
8920 
8921 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8922 
8923 	fctrl = &pwlanhdr->frame_ctl;
8924 	*(fctrl) = 0;
8925 
8926 	/* ------------------------------------------------------------------------- */
8927 	/* MAC Header. */
8928 	/* ------------------------------------------------------------------------- */
8929 	SetFrameType(fctrl, WIFI_DATA);
8930 	/* set_frame_sub_type(fctrl, 0); */
8931 	SetToDs(fctrl);
8932 	//_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8933 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8934 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8935 	_rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN );
8936 
8937 	SetSeqNum(pwlanhdr, 0);
8938 	set_duration(pwlanhdr, 0);
8939 
8940 #ifdef CONFIG_WAPI_SUPPORT
8941 	*pLength = sMacHdrLng;
8942 #else
8943 	*pLength = 24;
8944 #endif
8945 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8946 	case _WEP40_:
8947 	case _WEP104_:
8948 		EncryptionHeadOverhead = 4;
8949 		break;
8950 	case _TKIP_:
8951 		EncryptionHeadOverhead = 8;
8952 		break;
8953 	case _AES_:
8954 		EncryptionHeadOverhead = 8;
8955 		break;
8956 #ifdef CONFIG_WAPI_SUPPORT
8957 	case _SMS4_:
8958 		EncryptionHeadOverhead = 18;
8959 		break;
8960 #endif
8961 	default:
8962 		EncryptionHeadOverhead = 0;
8963 	}
8964 
8965 	if (EncryptionHeadOverhead > 0) {
8966 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8967 		*pLength += EncryptionHeadOverhead;
8968 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8969 		SetPrivacy(fctrl);
8970 	}
8971 
8972 	/* ------------------------------------------------------------------------- */
8973 	/* Frame Body. */
8974 	/* ------------------------------------------------------------------------- */
8975 	mdns_offset = *pLength;
8976 	pMdnsRspPkt = (u8 *)(pframe + mdns_offset);
8977 	/* LLC header */
8978 	_rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8);
8979 	*pLength += 8;
8980 
8981 	/* IP element */
8982 	pMdnsRspPkt += 8;
8983 	SET_IPHDR_VERSION(pMdnsRspPkt, 0x45);
8984 	SET_IPHDR_DSCP(pMdnsRspPkt, 0);
8985 	SET_IPHDR_TOTAL_LEN(pMdnsRspPkt, 0);  // filled by fw
8986 	SET_IPHDR_IDENTIFIER(pMdnsRspPkt, 0);  // filled by fw
8987 	SET_IPHDR_FLAGS(pMdnsRspPkt, 0x40);
8988 	SET_IPHDR_FRAG_OFFSET(pMdnsRspPkt, 0);
8989 	SET_IPHDR_TTL(pMdnsRspPkt, 0x40);
8990 	SET_IPHDR_PROTOCOL(pMdnsRspPkt, 0x11);  // ICMP-UDP
8991 	SET_IPHDR_HDR_CHECKSUM(pMdnsRspPkt, 0);  // filled by fw
8992 	SET_IPHDR_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress);
8993 	SET_IPHDR_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv4_addr);  // filled by fw
8994 
8995 	*pLength += 20;
8996 
8997 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8998 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8999 			IS_HARDWARE_TYPE_8812(padapter)) {
9000 			rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset);
9001 		}
9002 		*pLength += 8;
9003 	}
9004 
9005 	/* UDP element */
9006 	pMdnsRspPkt += 20;
9007 	SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // MDNS
9008 	SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // MDNS
9009 	SET_UDP_LEN(pMdnsRspPkt, 0);      //  filled by fw
9010 	SET_UDP_CHECKSUM(pMdnsRspPkt, 0);     // filled by fw
9011 	*pLength += 8;
9012 
9013 	/* MDNS Header */
9014 	pMdnsRspPkt += 8;
9015 	SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84);
9016 	*pLength += 12;
9017 
9018 }
9019 
9020 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
9021 
9022 #ifdef CONFIG_OFFLOAD_MDNS_V6
9023 
9024 /*
9025  * Description:
9026  *	Construct the MDNS response V6 packet to support MDNS offload.
9027  *
9028  */
rtw_hal_construct_mdns_rsp_v6(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)9029 static void rtw_hal_construct_mdns_rsp_v6(
9030 	PADAPTER 	padapter,
9031 	u8			*pframe,
9032 	u32			*pLength,
9033 	u8			*pIPAddress
9034 )
9035 {
9036 	struct rtw_ieee80211_hdr        *pwlanhdr;
9037 	u16     *fctrl;
9038 	u32     pktlen;
9039 	struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
9040 	struct wlan_network     *cur_network = &pmlmepriv->cur_network;
9041 	struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9042 	struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9043 	struct security_priv    *psecuritypriv = &padapter->securitypriv;
9044 	static u8       ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
9045 	u8	mulicast_ipv6_addr[16] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
9046 	u8	mulicast_mac_addr_for_mdns[6] = {0x33, 0x33, 0x00, 0x00, 0x00, 0xfb}; /* could be revise by fw */
9047 	u8      *pMdnsRspPkt = pframe;
9048 	/* for TKIP Cal MIC */
9049 	u8      EncryptionHeadOverhead = 0, mdns_offset = 0;
9050 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
9051 
9052 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
9053 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
9054 
9055 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9056 
9057 	fctrl = &pwlanhdr->frame_ctl;
9058 	*(fctrl) = 0;
9059 
9060 	/* ------------------------------------------------------------------------- */
9061 	/* MAC Header. */
9062 	/* ------------------------------------------------------------------------- */
9063 	SetFrameType(fctrl, WIFI_DATA);
9064 	/* set_frame_sub_type(fctrl, 0); */
9065 	SetToDs(fctrl);
9066 	//_rtw_memcpy(pwlanhdr->addr1, mulicast_mac_addr_for_mdns, ETH_ALEN);
9067 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9068 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9069 	//_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9070 	_rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN);
9071 
9072 	SetSeqNum(pwlanhdr, 0);
9073 	set_duration(pwlanhdr, 0);
9074 
9075 #ifdef CONFIG_WAPI_SUPPORT
9076 	*pLength = sMacHdrLng;
9077 #else
9078 	*pLength = 24;
9079 #endif
9080 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
9081 	case _WEP40_:
9082 	case _WEP104_:
9083 		EncryptionHeadOverhead = 4;
9084 		break;
9085 	case _TKIP_:
9086 		EncryptionHeadOverhead = 8;
9087 		break;
9088 	case _AES_:
9089 		EncryptionHeadOverhead = 8;
9090 		break;
9091 #ifdef CONFIG_WAPI_SUPPORT
9092 	case _SMS4_:
9093 		EncryptionHeadOverhead = 18;
9094 		break;
9095 #endif
9096 	default:
9097 		EncryptionHeadOverhead = 0;
9098 	}
9099 
9100 	if (EncryptionHeadOverhead > 0) {
9101 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
9102 		*pLength += EncryptionHeadOverhead;
9103 		SetPrivacy(fctrl);
9104 	}
9105 
9106 	/* ------------------------------------------------------------------------- */
9107 	/* Frame Body. */
9108 	/* ------------------------------------------------------------------------- */
9109 	mdns_offset = *pLength;
9110 	pMdnsRspPkt = (u8 *)(pframe + mdns_offset);
9111 	/* LLC header */
9112 	_rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8);
9113 	*pLength += 8;
9114 
9115 	/* ICMP element */
9116 	pMdnsRspPkt += 8;
9117 	SET_IPHDRV6_VERSION(pMdnsRspPkt, 0x06);
9118 	SET_IPHDRV6_PAYLOAD_LENGTH(pMdnsRspPkt, 0); // filled by fw
9119 	SET_IPHDRV6_NEXT_HEADER(pMdnsRspPkt, 0x3A);
9120 	SET_IPHDRV6_HOP_LIMIT(pMdnsRspPkt, 0xFF);
9121 	SET_IPHDRV6_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress);  // filled by fw
9122 	SET_IPHDRV6_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv6_addr);  // filled by fw
9123 
9124 	*pLength += 40;
9125 
9126 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
9127 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
9128 			IS_HARDWARE_TYPE_8812(padapter)) {
9129 				rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset);
9130 		}
9131 		*pLength += 8;
9132 	}
9133 
9134 	/* UDP element */
9135 	pMdnsRspPkt += 40;
9136 	SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // SNMP
9137 	SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // SNMP
9138 	SET_UDP_LEN(pMdnsRspPkt, 0);      //  filled by fw
9139 	SET_UDP_CHECKSUM(pMdnsRspPkt, 0);     // filled by fw
9140 	*pLength += 8;
9141 
9142 	/* MDNS Header */
9143 	pMdnsRspPkt += 8;
9144 	SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84);
9145 	*pLength += 12;
9146 
9147 }
9148 
9149 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
9150 #endif
9151 
9152 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)9153 static void rtw_hal_construct_GTKRsp(
9154 	PADAPTER	padapter,
9155 	u8		*pframe,
9156 	u32		*pLength
9157 )
9158 {
9159 	struct rtw_ieee80211_hdr	*pwlanhdr;
9160 	u16	*fctrl;
9161 	u32	pktlen;
9162 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
9163 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
9164 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9165 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9166 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
9167 	static u8	LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
9168 	static u8	GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
9169 	u8	*pGTKRspPkt = pframe;
9170 	u8	EncryptionHeadOverhead = 0;
9171 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
9172 
9173 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9174 
9175 	fctrl = &pwlanhdr->frame_ctl;
9176 	*(fctrl) = 0;
9177 
9178 	/* ------------------------------------------------------------------------- */
9179 	/* MAC Header. */
9180 	/* ------------------------------------------------------------------------- */
9181 	SetFrameType(fctrl, WIFI_DATA);
9182 	/* set_frame_sub_type(fctrl, 0); */
9183 	SetToDs(fctrl);
9184 
9185 	_rtw_memcpy(pwlanhdr->addr1,
9186 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9187 
9188 	_rtw_memcpy(pwlanhdr->addr2,
9189 		    adapter_mac_addr(padapter), ETH_ALEN);
9190 
9191 	_rtw_memcpy(pwlanhdr->addr3,
9192 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9193 
9194 	SetSeqNum(pwlanhdr, 0);
9195 	set_duration(pwlanhdr, 0);
9196 
9197 #ifdef CONFIG_WAPI_SUPPORT
9198 	*pLength = sMacHdrLng;
9199 #else
9200 	*pLength = 24;
9201 #endif /* CONFIG_WAPI_SUPPORT */
9202 
9203 	/* ------------------------------------------------------------------------- */
9204 	/* Security Header: leave space for it if necessary. */
9205 	/* ------------------------------------------------------------------------- */
9206 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
9207 	case _WEP40_:
9208 	case _WEP104_:
9209 		EncryptionHeadOverhead = 4;
9210 		break;
9211 	case _TKIP_:
9212 		EncryptionHeadOverhead = 8;
9213 		break;
9214 	case _AES_:
9215 		EncryptionHeadOverhead = 8;
9216 		break;
9217 #ifdef CONFIG_WAPI_SUPPORT
9218 	case _SMS4_:
9219 		EncryptionHeadOverhead = 18;
9220 		break;
9221 #endif /* CONFIG_WAPI_SUPPORT */
9222 	default:
9223 		EncryptionHeadOverhead = 0;
9224 	}
9225 
9226 	if (EncryptionHeadOverhead > 0) {
9227 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
9228 		*pLength += EncryptionHeadOverhead;
9229 		/* SET_80211_HDR_WEP(pGTKRspPkt, 1);  */ /* Suggested by CCW. */
9230 		/* GTK's privacy bit is done by FW */
9231 		/* SetPrivacy(fctrl); */
9232 	}
9233 	/* ------------------------------------------------------------------------- */
9234 	/* Frame Body. */
9235 	/* ------------------------------------------------------------------------- */
9236 	pGTKRspPkt = (u8 *)(pframe + *pLength);
9237 	/* LLC header */
9238 	_rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
9239 	*pLength += 8;
9240 
9241 	/* GTK element */
9242 	pGTKRspPkt += 8;
9243 
9244 	/* GTK frame body after LLC, part 1 */
9245 	/* TKIP key_length = 32, AES key_length = 16 */
9246 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
9247 		GTKbody_a[8] = 0x20;
9248 
9249 	/* GTK frame body after LLC, part 1 */
9250 	_rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
9251 	*pLength += 11;
9252 	pGTKRspPkt += 11;
9253 	/* GTK frame body after LLC, part 2 */
9254 	_rtw_memset(&(pframe[*pLength]), 0, 88);
9255 	*pLength += 88;
9256 	pGTKRspPkt += 88;
9257 
9258 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
9259 		*pLength += 8;
9260 }
9261 #endif /* CONFIG_GTK_OL */
9262 
9263 #define PN_2_CCMPH(ch,key_id)	((ch) & 0x000000000000ffff) \
9264 				| (((ch) & 0x0000ffffffff0000) << 16) \
9265 				| (((key_id) << 30)) \
9266 				| BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)9267 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
9268 						  u8 *pframe, u32 *pLength)
9269 {
9270 	struct mlme_priv   *pmlmepriv = &adapter->mlmepriv;
9271 	struct sta_priv *pstapriv = &adapter->stapriv;
9272 	struct security_priv *psecuritypriv = &adapter->securitypriv;
9273 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
9274 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9275 	struct sta_info *psta;
9276 	struct stainfo_rxcache *prxcache;
9277 	u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
9278 	size_t sz = 0, total = 0;
9279 	u64 ccmp_hdr = 0, tmp_key = 0;
9280 
9281 	psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
9282 
9283 	if (psta == NULL) {
9284 		rtw_warn_on(1);
9285 		return;
9286 	}
9287 
9288 	prxcache = &psta->sta_recvpriv.rxcache;
9289 	sz = sizeof(cur_dot11rxiv);
9290 
9291 	/* 3 SEC IV * 1 page */
9292 	rtw_get_sec_iv(adapter, cur_dot11rxiv,
9293 		       get_my_bssid(&pmlmeinfo->network));
9294 
9295 	_rtw_memcpy(pframe, cur_dot11rxiv, sz);
9296 	*pLength += sz;
9297 	pframe += sz;
9298 
9299 	_rtw_memset(&cur_dot11rxiv, 0, sz);
9300 
9301 	if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
9302 		id = psecuritypriv->dot118021XGrpKeyid;
9303 		tid_id = prxcache->last_tid;
9304 		REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
9305 		REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
9306 		REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
9307 		REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
9308 		_rtw_memcpy(pframe, cur_dot11rxiv, sz);
9309 		*pLength += sz;
9310 		pframe += sz;
9311 
9312 		_rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
9313 		*pLength += sz;
9314 		pframe += sz;
9315 
9316 		total = sizeof(psecuritypriv->iv_seq);
9317 		total /= sizeof(psecuritypriv->iv_seq[0]);
9318 
9319 		for (i = 0 ; i < total ; i ++) {
9320 			ccmp_hdr =
9321 				le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
9322 			_rtw_memset(&cur_dot11rxiv, 0, sz);
9323 			if (ccmp_hdr != 0) {
9324 				tmp_key = i;
9325 				ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
9326 				*(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
9327 				_rtw_memcpy(pframe, cur_dot11rxiv, sz);
9328 			}
9329 			*pLength += sz;
9330 			pframe += sz;
9331 		}
9332 	}
9333 }
9334 
rtw_hal_gate_bb(_adapter * adapter,bool stop)9335 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9336 {
9337 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9338 	u8 i = 0, val8 = 0, empty = _FAIL;
9339 
9340 	if (stop) {
9341 		/* checking TX queue status */
9342 		for (i = 0 ; i < 5 ; i++) {
9343 			rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9344 			if (empty) {
9345 				break;
9346 			} else {
9347 				RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9348 					 __func__, i);
9349 				rtw_mdelay_os(10);
9350 			}
9351 		}
9352 
9353 		if (val8 == 5)
9354 			RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9355 
9356 		/* Pause TX*/
9357 		pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9358 		rtw_write8(adapter, REG_TXPAUSE, 0xff);
9359 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9360 		val8 &= ~BIT(0);
9361 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9362 		RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9363 			 __func__,
9364 			 rtw_read8(adapter, REG_SYS_FUNC_EN),
9365 			 pwrpriv->wowlan_txpause_status);
9366 	} else {
9367 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9368 		val8 |= BIT(0);
9369 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9370 		RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9371 			 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9372 			 pwrpriv->wowlan_txpause_status);
9373 		/* release TX*/
9374 		rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9375 	}
9376 }
9377 
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)9378 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9379 {
9380 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9381 	 u8 *pattern;
9382 	 u8 len = 0;
9383 	 u8 *mask;
9384 
9385 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
9386 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9387 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9388 	u8 multicast_addr1[2] = {0x33, 0x33};
9389 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9390 	u8 mask_len = 0;
9391 	u8 mac_addr[ETH_ALEN] = {0};
9392 	u16 count = 0;
9393 	int i;
9394 
9395 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9396 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9397 			 __func__, MAX_WKFM_CAM_NUM);
9398 		return _FAIL;
9399 	}
9400 
9401 	pattern = pwrctl->patterns[idx].content;
9402 	len = pwrctl->patterns[idx].len;
9403 	mask = pwrctl->patterns[idx].mask;
9404 
9405 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9406 	_rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9407 
9408 	mask_len = DIV_ROUND_UP(len, 8);
9409 
9410 	/* 1. setup A1 table */
9411 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9412 		pwow_pattern->type = PATTERN_BROADCAST;
9413 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
9414 		pwow_pattern->type = PATTERN_MULTICAST;
9415 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
9416 		pwow_pattern->type = PATTERN_MULTICAST;
9417 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9418 		pwow_pattern->type = PATTERN_UNICAST;
9419 	else
9420 		pwow_pattern->type = PATTERN_INVALID;
9421 
9422 	/* translate mask from os to mask for hw */
9423 
9424 	/******************************************************************************
9425 	 * pattern from OS uses 'ethenet frame', like this:
9426 
9427 		|    6   |    6   |   2  |     20    |  Variable  |  4  |
9428 		|--------+--------+------+-----------+------------+-----|
9429 		|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
9430 		|   DA   |   SA   | Type |
9431 
9432 	 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9433 
9434 		|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
9435 		|-------------------+--------+------+-----------+------------+-----|
9436 		| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
9437 				    | Others | Tpye |
9438 
9439 	 * Therefore, we need translate mask_from_OS to mask_to_hw.
9440 	 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9441 	 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9442 	 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9443 	 ******************************************************************************/
9444 	/* Shift 6 bits */
9445 	for (i = 0; i < mask_len - 1; i++) {
9446 		mask_hw[i] = mask[i] >> 6;
9447 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9448 	}
9449 
9450 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
9451 	/* Set bit 0-5 to zero */
9452 	mask_hw[0] &= 0xC0;
9453 
9454 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9455 		pwow_pattern->mask[i] = mask_hw[i * 4];
9456 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9457 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9458 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9459 	}
9460 
9461 	/* To get the wake up pattern from the mask.
9462 	 * We do not count first 12 bits which means
9463 	 * DA[6] and SA[6] in the pattern to match HW design. */
9464 	count = 0;
9465 	for (i = 12; i < len; i++) {
9466 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
9467 			content[count] = pattern[i];
9468 			count++;
9469 		}
9470 	}
9471 
9472 	pwow_pattern->crc = rtw_calc_crc(content, count);
9473 
9474 	if (pwow_pattern->crc != 0) {
9475 		if (pwow_pattern->type == PATTERN_INVALID)
9476 			pwow_pattern->type = PATTERN_VALID;
9477 	}
9478 
9479 	return _SUCCESS;
9480 }
9481 
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)9482 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
9483 {
9484 	int j;
9485 
9486 	RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
9487 	RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
9488 	RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
9489 	for (j = 0; j < 4; j++)
9490 		RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
9491 }
9492 /*bit definition of pattern match format*/
9493 #define WOW_VALID_BIT	BIT31
9494 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
9495 #define WOW_BC_BIT		BIT26
9496 #define WOW_MC_BIT		BIT25
9497 #define WOW_UC_BIT		BIT24
9498 #else
9499 #define WOW_BC_BIT		BIT18
9500 #define WOW_UC_BIT		BIT17
9501 #define WOW_MC_BIT		BIT16
9502 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
9503 
9504 #ifndef CONFIG_WOW_PATTERN_HW_CAM
9505 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_hal_reset_mac_rx(_adapter * adapter)9506 static void rtw_hal_reset_mac_rx(_adapter *adapter)
9507 {
9508 	u8 val8 = 0;
9509 	/* Set REG_CR bit1, bit3, bit7 to 0*/
9510 	val8 = rtw_read8(adapter, REG_CR);
9511 	val8 &= 0x75;
9512 	rtw_write8(adapter, REG_CR, val8);
9513 	val8 = rtw_read8(adapter, REG_CR);
9514 	/* Set REG_CR bit1, bit3, bit7 to 1*/
9515 	val8 |= 0x8a;
9516 	rtw_write8(adapter, REG_CR, val8);
9517 	RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
9518 }
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)9519 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
9520 {
9521 	u8 val8 = 0;
9522 	u16 rxff_bndy = 0;
9523 	u32 rx_dma_buff_sz = 0;
9524 
9525 	val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
9526 	if (val8 != 0)
9527 		RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
9528 			 __func__, (REG_FIFOPAGE + 3));
9529 
9530 	rtw_hal_reset_mac_rx(adapter);
9531 
9532 	if (wow_mode) {
9533 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9534 				    (u8 *)&rx_dma_buff_sz);
9535 		rxff_bndy = rx_dma_buff_sz - 1;
9536 
9537 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9538 		RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
9539 			 REG_TRXFF_BNDY + 2,
9540 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9541 	} else {
9542 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
9543 				    (u8 *)&rx_dma_buff_sz);
9544 		rxff_bndy = rx_dma_buff_sz - 1;
9545 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9546 		RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
9547 			 REG_TRXFF_BNDY + 2,
9548 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9549 	}
9550 }
9551 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO*/
9552 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9553 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9554 {
9555 	u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9556 	u16 offset, rx_buf_ptr = 0;
9557 	u16 cam_start_offset = 0;
9558 	u16 ctrl_l = 0, ctrl_h = 0;
9559 	u8 count = 0, tmp = 0;
9560 	int i = 0;
9561 	bool res = _TRUE;
9562 
9563 	if (idx > MAX_WKFM_CAM_NUM) {
9564 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9565 			 __func__);
9566 		return _FALSE;
9567 	}
9568 
9569 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9570 			    (u8 *)&rx_dma_buff_sz);
9571 
9572 	if (rx_dma_buff_sz == 0) {
9573 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9574 		return _FALSE;
9575 	}
9576 
9577 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9578 
9579 	if (page_sz == 0) {
9580 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9581 		return _FALSE;
9582 	}
9583 
9584 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9585 	cam_start_offset = offset * page_sz;
9586 
9587 	ctrl_l = 0x0;
9588 	ctrl_h = 0x0;
9589 
9590 	/* Enable RX packet buffer access */
9591 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9592 
9593 	/* Read the WKFM CAM */
9594 	for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9595 		/*
9596 		 * Set Rx packet buffer offset.
9597 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9598 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9599 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9600 		 * * Index: The index of the wake up frame mask
9601 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9602 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9603 		 */
9604 		rx_buf_ptr =
9605 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9606 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9607 
9608 		rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9609 		data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9610 		data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9611 
9612 		RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9613 
9614 		count = 0;
9615 
9616 		do {
9617 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9618 			rtw_udelay_os(2);
9619 			count++;
9620 		} while (!tmp && count < 100);
9621 
9622 		if (count >= 100) {
9623 			RTW_INFO("%s count:%d\n", __func__, count);
9624 			res = _FALSE;
9625 		}
9626 	}
9627 
9628 	/* Disable RX packet buffer access */
9629 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9630 		   DISABLE_TRXPKT_BUF_ACCESS);
9631 	return res;
9632 }
9633 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9634 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9635 			     struct  rtl_wow_pattern *context)
9636 {
9637 	u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
9638 	u16 offset, rx_buf_ptr = 0;
9639 	u16 cam_start_offset = 0;
9640 	u16 ctrl_l = 0, ctrl_h = 0;
9641 	u8 count = 0, tmp = 0;
9642 	int res = 0, i = 0;
9643 
9644 	if (idx > MAX_WKFM_CAM_NUM) {
9645 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9646 			 __func__);
9647 		return _FALSE;
9648 	}
9649 
9650 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9651 			    (u8 *)&rx_dma_buff_sz);
9652 
9653 	if (rx_dma_buff_sz == 0) {
9654 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9655 		return _FALSE;
9656 	}
9657 
9658 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9659 
9660 	if (page_sz == 0) {
9661 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9662 		return _FALSE;
9663 	}
9664 
9665 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9666 
9667 	cam_start_offset = offset * page_sz;
9668 
9669 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
9670 		ctrl_l = 0x0001;
9671 		ctrl_h = 0x0001;
9672 	} else {
9673 		ctrl_l = 0x0f01;
9674 		ctrl_h = 0xf001;
9675 	}
9676 
9677 	/* Enable RX packet buffer access */
9678 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9679 
9680 	/* Write the WKFM CAM */
9681 	for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
9682 		/*
9683 		 * Set Rx packet buffer offset.
9684 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9685 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9686 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9687 		 * * Index: The index of the wake up frame mask
9688 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9689 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9690 		 */
9691 		rx_buf_ptr =
9692 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
9693 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9694 
9695 		if (i == 0) {
9696 			if (context->type == PATTERN_VALID)
9697 				data = WOW_VALID_BIT;
9698 			else if (context->type == PATTERN_BROADCAST)
9699 				data = WOW_VALID_BIT | WOW_BC_BIT;
9700 			else if (context->type == PATTERN_MULTICAST)
9701 				data = WOW_VALID_BIT | WOW_MC_BIT;
9702 			else if (context->type == PATTERN_UNICAST)
9703 				data = WOW_VALID_BIT | WOW_UC_BIT;
9704 
9705 			if (context->crc != 0)
9706 				data |= context->crc;
9707 
9708 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9709 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9710 		} else if (i == 1) {
9711 			data = 0;
9712 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9713 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9714 		} else if (i == 2 || i == 4) {
9715 			data = context->mask[i - 2];
9716 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9717 			/* write to RX packet buffer*/
9718 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9719 		} else if (i == 3 || i == 5) {
9720 			data = context->mask[i - 2];
9721 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9722 			/* write to RX packet buffer*/
9723 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9724 		}
9725 
9726 		count = 0;
9727 		do {
9728 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9729 			rtw_udelay_os(2);
9730 			count++;
9731 		} while (tmp && count < 100);
9732 
9733 		if (count >= 100)
9734 			res = _FALSE;
9735 		else
9736 			res = _TRUE;
9737 	}
9738 
9739 	/* Disable RX packet buffer access */
9740 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9741 		   DISABLE_TRXPKT_BUF_ACCESS);
9742 
9743 	return res;
9744 }
rtw_fill_pattern(_adapter * adapter)9745 void rtw_fill_pattern(_adapter *adapter)
9746 {
9747 	int i = 0, total = 0, index;
9748 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9749 	struct rtl_wow_pattern wow_pattern;
9750 
9751 	total = pwrpriv->wowlan_pattern_idx;
9752 
9753 	if (total > MAX_WKFM_CAM_NUM)
9754 		total = MAX_WKFM_CAM_NUM;
9755 
9756 	for (i = 0 ; i < total ; i++) {
9757 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
9758 
9759 			index = i;
9760 			if (!pwrpriv->bInSuspend)
9761 				index += 2;
9762 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
9763 			if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
9764 				RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
9765 		}
9766 
9767 	}
9768 	rtw_write8(adapter, REG_WKFMCAM_NUM, total);
9769 
9770 }
9771 #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9772 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9773 {
9774 	u32 data_l = 0, data_h = 0, page_sz = 0;
9775 	u16 tx_page_start, tx_buf_ptr = 0;
9776 	u16 cam_start_offset = 0;
9777 	u16 ctrl_l = 0, ctrl_h = 0;
9778 	u8 count = 0, tmp = 0, last_entry = 0;
9779 	int i = 0;
9780 	bool res = _TRUE;
9781 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9782 	u32 buffer[WKFMCAM_ADDR_NUM];
9783 
9784 
9785 	if (idx > MAX_WKFM_CAM_NUM) {
9786 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9787 			 __func__);
9788 		return _FALSE;
9789 	}
9790 
9791 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9792 	if (page_sz == 0) {
9793 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9794 		return _FALSE;
9795 	}
9796 
9797 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9798 	if (last_entry == 0) {
9799 		RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9800 		return _FALSE;
9801 	}
9802 
9803 
9804 	if(_rtw_wow_chk_cap(adapter, WOW_CAP_HALMAC_ACCESS_PATTERN_IN_TXFIFO)) {
9805 		/* 8723F cannot indirect access tx fifo
9806 		 * rtw_halmac_dump_fifo(dvobj, fifo_sel, fifo_addr, buf_sz, buf)
9807 		 */
9808 		#ifdef RTW_HALMAC
9809 		rtw_halmac_dump_fifo(adapter_to_dvobj(adapter),
9810 		2,
9811 		(pwrctl->pattern_rsvd_page_loc * page_sz) + (idx * WKFMCAM_ADDR_NUM * 4),
9812 		WKFMCAM_ADDR_NUM*4, (u8*)buffer);
9813 		#endif
9814 
9815 		for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9816 			RTW_INFO("[%d]: %08x %08x\n", i, *(buffer + i*2), *(buffer + i*2 + 1));
9817 		}
9818 	} else {
9819 		/* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9820 		tx_page_start = last_entry - 1;
9821 		cam_start_offset = tx_page_start * page_sz / 8;
9822 		ctrl_l = 0x0;
9823 		ctrl_h = 0x0;
9824 
9825 		/* Enable TX packet buffer access */
9826 		rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9827 
9828 		/* Read the WKFM CAM */
9829 		for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9830 			/*
9831 			 * Set Tx packet buffer offset.
9832 			 * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer.
9833 			 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9834 			 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9835 			 * * Index: The index of the wake up frame mask
9836 			 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9837 			 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9838 			 */
9839 			tx_buf_ptr =
9840 				(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9841 			rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr);
9842 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9843 			data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9844 			data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9845 
9846 			RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9847 
9848 			count = 0;
9849 
9850 			do {
9851 				tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9852 				rtw_udelay_os(2);
9853 				count++;
9854 			} while (!tmp && count < 100);
9855 
9856 			if (count >= 100) {
9857 				RTW_INFO("%s count:%d\n", __func__, count);
9858 				res = _FALSE;
9859 			}
9860 		}
9861 
9862 		/* Disable RX packet buffer access */
9863 		rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9864 			   DISABLE_TRXPKT_BUF_ACCESS);
9865 	}
9866 
9867 	return res;
9868 }
9869 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9870 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9871 			     struct  rtl_wow_pattern *context)
9872 {
9873 	u32 tx_page_start = 0, page_sz = 0;
9874 	u16 tx_buf_ptr = 0;
9875 	u16 cam_start_offset = 0;
9876 	u32 data_l = 0, data_h = 0;
9877 	u8 count = 0, tmp = 0, last_entry = 0;
9878 	int res = 0, i = 0;
9879 
9880 	if (idx > MAX_WKFM_CAM_NUM) {
9881 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9882 			 __func__);
9883 		return _FALSE;
9884 	}
9885 
9886 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9887 	if (page_sz == 0) {
9888 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9889 		return _FALSE;
9890 	}
9891 
9892 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9893 	if (last_entry == 0) {
9894 		RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9895 		return _FALSE;
9896 	}
9897 
9898 	/* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9899 	tx_page_start = last_entry - 1;
9900 	cam_start_offset = tx_page_start * page_sz / 8;
9901 
9902 	/* Write the PATTERN location to BIT_TXBUF_WKCAM_OFFSET */
9903 	rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET, cam_start_offset & 0xFF);
9904 	rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET + 1, (cam_start_offset >> 8) & 0xFF);
9905 	/* Enable TX packet buffer access */
9906 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9907 
9908 	/* Write the WKFM CAM */
9909 	for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9910 		/*
9911 		 * Set Tx packet buffer offset.
9912 		 * TxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9913 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9914 		 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9915 		 * * Index: The index of the wake up frame mask
9916 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9917 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9918 		 */
9919 		tx_buf_ptr = cam_start_offset + ((idx * WKFMCAM_SIZE + i * 8) >> 3);
9920 
9921 		if (i == 0) {
9922 			if (context->type == PATTERN_VALID)
9923 				data_l = WOW_VALID_BIT;
9924 			else if (context->type == PATTERN_BROADCAST)
9925 				data_l = WOW_VALID_BIT | WOW_BC_BIT;
9926 			else if (context->type == PATTERN_MULTICAST)
9927 				data_l = WOW_VALID_BIT | WOW_MC_BIT;
9928 			else if (context->type == PATTERN_UNICAST)
9929 				data_l = WOW_VALID_BIT | WOW_UC_BIT;
9930 
9931 			if (context->crc != 0)
9932 				data_l |= context->crc;
9933 
9934 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9935 		} else {
9936 			data_l = context->mask[i * 2 - 2];
9937 			data_h = context->mask[i * 2 - 1];
9938 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9939 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h);
9940 		}
9941 
9942 		rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0x1FFF) | BIT23 | (0xff <<24));
9943 		count = 0;
9944 		do {
9945 			tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9946 			rtw_udelay_os(2);
9947 			count++;
9948 		} while (tmp && count < 100);
9949 
9950 		if (count >= 100) {
9951 			res = _FALSE;
9952 			RTW_INFO("%s write failed\n", __func__);
9953 		} else {
9954 			res = _TRUE;
9955 			RTW_INFO("%s write OK\n", __func__);
9956 		}
9957 	}
9958 
9959 	/* Disable TX packet buffer access */
9960 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
9961 	return res;
9962 }
rtw_write_to_frame_mask_buf(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context,char * pattern_info,u32 * ppattern_info_len)9963 bool rtw_write_to_frame_mask_buf(_adapter *adapter, u8 idx,
9964 			     struct  rtl_wow_pattern *context, char *pattern_info, u32 *ppattern_info_len)
9965 {
9966 
9967 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9968 	u32 page_sz = 0;
9969 	int res = _FALSE, i = 0;
9970 	u32 tmp_pattern_buf[6] = {0};
9971 
9972 	if (pattern_info == NULL) {
9973 		RTW_ERR("[Error]: %s, pattern info is NULL\n", __func__);
9974 	}
9975 	if (idx > MAX_WKFM_CAM_NUM) {
9976 		RTW_ERR("[Error]: %s, pattern index is out of range\n",
9977 			 __func__);
9978 		return _FALSE;
9979 	}
9980 
9981 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9982 	if (page_sz == 0) {
9983 		RTW_ERR("[Error]: %s, page_sz is 0!!\n", __func__);
9984 		return _FALSE;
9985 	}
9986 
9987 	/* Fill WKFM */
9988 	for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9989 		if (i == 0) {
9990 			if (context->type == PATTERN_VALID)
9991 				tmp_pattern_buf[0] = WOW_VALID_BIT;
9992 			else if (context->type == PATTERN_BROADCAST)
9993 				tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_BC_BIT;
9994 			else if (context->type == PATTERN_MULTICAST)
9995 				tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_MC_BIT;
9996 			else if (context->type == PATTERN_UNICAST)
9997 				tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_UC_BIT;
9998 
9999 			if (context->crc != 0)
10000 				tmp_pattern_buf[0] |= context->crc;
10001 			/* pattern[1] is reserved in pattern format, dont care. */
10002 
10003 		} else {
10004 			tmp_pattern_buf[i * 2] = context->mask[i * 2 - 2];
10005 			tmp_pattern_buf[i * 2 + 1] = context->mask[i * 2 - 1];
10006 		}
10007 	}
10008 
10009 
10010 	/* put pattern to pattern_buf */
10011 	_rtw_memcpy((pattern_info + idx * WKFMCAM_SIZE) , tmp_pattern_buf, WKFMCAM_SIZE);
10012 	*ppattern_info_len += WKFMCAM_SIZE;
10013 	#ifdef CONFIG_WOW_PATTERN_IN_TXFIFO_DBG
10014 	RTW_INFO("\nidx : %u pattern_info_len : %u\n", idx, *ppattern_info_len);
10015 	RTW_INFO_DUMP("", (pattern_info + idx * WKFMCAM_SIZE), WKFMCAM_SIZE);
10016 	#endif
10017 	res = _TRUE;
10018 
10019 
10020 	return res;
10021 }
10022 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
10023 
rtw_clean_pattern(_adapter * adapter)10024 void rtw_clean_pattern(_adapter *adapter)
10025 {
10026 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10027 	struct rtl_wow_pattern zero_pattern;
10028 	int i = 0;
10029 
10030 	_rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
10031 
10032 	zero_pattern.type = PATTERN_INVALID;
10033 	/* pattern in tx fifo do not need clear to zero*/
10034 
10035 	rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
10036 }
10037 #if 0
10038 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
10039 			       u8 len, u8 *mask, u8 idx)
10040 {
10041 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10042 	struct mlme_ext_priv *pmlmeext = NULL;
10043 	struct mlme_ext_info *pmlmeinfo = NULL;
10044 	struct rtl_wow_pattern wow_pattern;
10045 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
10046 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
10047 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
10048 	u8 multicast_addr1[2] = {0x33, 0x33};
10049 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
10050 	u8 res = _FALSE, index = 0, mask_len = 0;
10051 	u8 mac_addr[ETH_ALEN] = {0};
10052 	u16 count = 0;
10053 	int i, j;
10054 
10055 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
10056 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
10057 			 __func__, MAX_WKFM_CAM_NUM);
10058 		return _FALSE;
10059 	}
10060 
10061 	pmlmeext = &adapter->mlmeextpriv;
10062 	pmlmeinfo = &pmlmeext->mlmext_info;
10063 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
10064 	_rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
10065 
10066 	mask_len = DIV_ROUND_UP(len, 8);
10067 
10068 	/* 1. setup A1 table */
10069 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
10070 		wow_pattern.type = PATTERN_BROADCAST;
10071 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
10072 		wow_pattern.type = PATTERN_MULTICAST;
10073 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
10074 		wow_pattern.type = PATTERN_MULTICAST;
10075 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
10076 		wow_pattern.type = PATTERN_UNICAST;
10077 	else
10078 		wow_pattern.type = PATTERN_INVALID;
10079 
10080 	/* translate mask from os to mask for hw */
10081 
10082 /******************************************************************************
10083  * pattern from OS uses 'ethenet frame', like this:
10084 
10085 	|    6   |    6   |   2  |     20    |  Variable  |  4  |
10086 	|--------+--------+------+-----------+------------+-----|
10087 	|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
10088 	|   DA   |   SA   | Type |
10089 
10090  * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
10091 
10092 	|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
10093 	|-------------------+--------+------+-----------+------------+-----|
10094 	| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
10095 			    | Others | Tpye |
10096 
10097  * Therefore, we need translate mask_from_OS to mask_to_hw.
10098  * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
10099  * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
10100  * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
10101  ******************************************************************************/
10102 	/* Shift 6 bits */
10103 	for (i = 0; i < mask_len - 1; i++) {
10104 		mask_hw[i] = mask[i] >> 6;
10105 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
10106 	}
10107 
10108 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
10109 	/* Set bit 0-5 to zero */
10110 	mask_hw[0] &= 0xC0;
10111 
10112 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
10113 		wow_pattern.mask[i] = mask_hw[i * 4];
10114 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
10115 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
10116 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
10117 	}
10118 
10119 	/* To get the wake up pattern from the mask.
10120 	 * We do not count first 12 bits which means
10121 	 * DA[6] and SA[6] in the pattern to match HW design. */
10122 	count = 0;
10123 	for (i = 12; i < len; i++) {
10124 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
10125 			content[count] = pattern[i];
10126 			count++;
10127 		}
10128 	}
10129 
10130 	wow_pattern.crc = rtw_calc_crc(content, count);
10131 
10132 	if (wow_pattern.crc != 0) {
10133 		if (wow_pattern.type == PATTERN_INVALID)
10134 			wow_pattern.type = PATTERN_VALID;
10135 	}
10136 
10137 	index = idx;
10138 
10139 	if (!pwrctl->bInSuspend)
10140 		index += 2;
10141 
10142 	/* write pattern */
10143 	res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
10144 
10145 	if (res == _FALSE)
10146 		RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
10147 			 __func__, idx);
10148 
10149 	return res;
10150 }
10151 #endif
10152 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
10153 
10154 #define WOW_CAM_ACCESS_TIMEOUT_MS	200
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)10155 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
10156 {
10157 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10158 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10159 
10160 	u32 rdata = 0;
10161 	u32 cnt = 0;
10162 	systime start = 0;
10163 	u8 timeout = 0;
10164 	u8 rst = _FALSE;
10165 
10166 	_enter_critical_mutex(mutex, NULL);
10167 
10168 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
10169 
10170 	start = rtw_get_current_time();
10171 	while (1) {
10172 		if (rtw_is_surprise_removed(adapter))
10173 			break;
10174 
10175 		cnt++;
10176 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10177 			rst = _SUCCESS;
10178 			break;
10179 		}
10180 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10181 			timeout = 1;
10182 			break;
10183 		}
10184 	}
10185 
10186 	rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
10187 
10188 	_exit_critical_mutex(mutex, NULL);
10189 
10190 	/*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
10191 
10192 	if (timeout)
10193 		RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
10194 
10195 	return rdata;
10196 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10197 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
10198 {
10199 	int i;
10200 	u32 rdata;
10201 
10202 	_rtw_memset(context, 0, sizeof(struct  rtl_wow_pattern));
10203 
10204 	for (i = 4; i >= 0; i--) {
10205 		rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
10206 
10207 		switch (i) {
10208 		case 4:
10209 			if (rdata & WOW_BC_BIT)
10210 				context->type = PATTERN_BROADCAST;
10211 			else if (rdata & WOW_MC_BIT)
10212 				context->type = PATTERN_MULTICAST;
10213 			else if (rdata & WOW_UC_BIT)
10214 				context->type = PATTERN_UNICAST;
10215 			else
10216 				context->type = PATTERN_INVALID;
10217 
10218 			context->crc = rdata & 0xFFFF;
10219 			break;
10220 		default:
10221 			_rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
10222 			break;
10223 		}
10224 	}
10225 }
10226 
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)10227 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
10228 {
10229 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10230 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10231 	u32 cnt = 0;
10232 	systime start = 0, end = 0;
10233 	u8 timeout = 0;
10234 
10235 	/*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
10236 	_enter_critical_mutex(mutex, NULL);
10237 
10238 	rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
10239 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
10240 
10241 	start = rtw_get_current_time();
10242 	while (1) {
10243 		if (rtw_is_surprise_removed(adapter))
10244 			break;
10245 
10246 		cnt++;
10247 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
10248 			break;
10249 
10250 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10251 			timeout = 1;
10252 			break;
10253 		}
10254 	}
10255 	end = rtw_get_current_time();
10256 
10257 	_exit_critical_mutex(mutex, NULL);
10258 
10259 	if (timeout) {
10260 		RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
10261 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
10262 	}
10263 }
10264 
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10265 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
10266 {
10267 	int j;
10268 	u8 addr;
10269 	u32 wdata = 0;
10270 
10271 	for (j = 4; j >= 0; j--) {
10272 		switch (j) {
10273 		case 4:
10274 			wdata = context->crc;
10275 
10276 			if (PATTERN_BROADCAST == context->type)
10277 				wdata |= WOW_BC_BIT;
10278 			if (PATTERN_MULTICAST == context->type)
10279 				wdata |= WOW_MC_BIT;
10280 			if (PATTERN_UNICAST == context->type)
10281 				wdata |= WOW_UC_BIT;
10282 			if (PATTERN_INVALID != context->type)
10283 				wdata |= WOW_VALID_BIT;
10284 			break;
10285 		default:
10286 			wdata = context->mask[j];
10287 			break;
10288 		}
10289 
10290 		addr = (id << 3) + j;
10291 
10292 		_rtw_wow_pattern_write_cam(adapter, addr, wdata);
10293 	}
10294 }
10295 
_rtw_wow_pattern_clean_cam(_adapter * adapter)10296 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
10297 {
10298 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10299 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10300 	u32 cnt = 0;
10301 	systime start = 0;
10302 	u8 timeout = 0;
10303 	u8 rst = _FAIL;
10304 
10305 	_enter_critical_mutex(mutex, NULL);
10306 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
10307 
10308 	start = rtw_get_current_time();
10309 	while (1) {
10310 		if (rtw_is_surprise_removed(adapter))
10311 			break;
10312 
10313 		cnt++;
10314 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10315 			rst = _SUCCESS;
10316 			break;
10317 		}
10318 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10319 			timeout = 1;
10320 			break;
10321 		}
10322 	}
10323 	_exit_critical_mutex(mutex, NULL);
10324 
10325 	if (timeout)
10326 		RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
10327 
10328 	return rst;
10329 }
10330 
rtw_clean_pattern(_adapter * adapter)10331 void rtw_clean_pattern(_adapter *adapter)
10332 {
10333 	if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
10334 		RTW_ERR("rtw_clean_pattern failed\n");
10335 }
rtw_fill_pattern(_adapter * adapter)10336 void rtw_fill_pattern(_adapter *adapter)
10337 {
10338 	int i = 0, total = 0;
10339 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10340 	struct rtl_wow_pattern wow_pattern;
10341 
10342 	total = pwrpriv->wowlan_pattern_idx;
10343 
10344 	if (total > MAX_WKFM_CAM_NUM)
10345 		total = MAX_WKFM_CAM_NUM;
10346 
10347 	for (i = 0 ; i < total ; i++) {
10348 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10349 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10350 			rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
10351 		}
10352 	}
10353 }
10354 
10355 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)10356 void rtw_wow_pattern_cam_dump(_adapter *adapter)
10357 {
10358 
10359 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10360 	int i = 0, total = 0;
10361 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10362 	total = pwrpriv->wowlan_pattern_idx;
10363 
10364 	if (total > MAX_WKFM_CAM_NUM)
10365 		total = MAX_WKFM_CAM_NUM;
10366 
10367 	for (i = 0 ; i < total; i++) {
10368 		RTW_INFO("=======[%d]=======\n", i);
10369 		rtw_read_from_frame_mask(adapter, i);
10370 	}
10371 #else
10372 	struct  rtl_wow_pattern context;
10373 	int i;
10374 
10375 	for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10376 		rtw_wow_pattern_read_cam_ent(adapter, i, &context);
10377 		rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
10378 	}
10379 
10380 #endif
10381 }
10382 
10383 
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)10384 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
10385 {
10386 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10387 
10388 	switch (mode) {
10389 	case 0:
10390 		rtw_clean_pattern(adapter);
10391 		RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
10392 		break;
10393 	case 1:
10394 		#if defined(CONFIG_WOW_PATTERN_IN_TXFIFO)
10395 		RTW_INFO("%s Patterns have been downloaded in rsvd pages\n", __func__);
10396 		#else
10397 		rtw_set_default_pattern(adapter);
10398 		rtw_fill_pattern(adapter);
10399 		RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
10400 		#endif
10401 		break;
10402 	case 2:
10403 		rtw_clean_pattern(adapter);
10404 		rtw_wow_pattern_sw_reset(adapter);
10405 		RTW_INFO("%s: clean patterns\n", __func__);
10406 		break;
10407 	default:
10408 		RTW_INFO("%s: unknown mode\n", __func__);
10409 		break;
10410 	}
10411 }
10412 
rtw_hal_wow_enable(_adapter * adapter)10413 static void rtw_hal_wow_enable(_adapter *adapter)
10414 {
10415 	struct registry_priv  *registry_par = &adapter->registrypriv;
10416 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10417 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10418 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10419 	struct sta_info *psta = NULL;
10420 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
10421 	int res;
10422 	u16 media_status_rpt;
10423 	u8 no_wake = 0, i;
10424 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10425 	_adapter *iface;
10426 #ifdef CONFIG_GPIO_WAKEUP
10427 	u8 val8 = 0;
10428 #endif
10429 
10430 #ifdef CONFIG_LPS_PG
10431 	u8 lps_pg_hdl_id = 0;
10432 #endif
10433 
10434 
10435 
10436 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
10437 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
10438 		no_wake = 1;
10439 
10440 	RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
10441 	rtw_hal_gate_bb(adapter, _TRUE);
10442 
10443 	for (i = 0; i < dvobj->iface_nums; i++) {
10444 		iface = dvobj->padapters[i];
10445 		/* Start Usb TxDMA */
10446 		if(iface) {
10447 			RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface));
10448 			RTW_ENABLE_FUNC(iface, DF_TX_BIT);
10449 		}
10450 	}
10451 
10452 #ifdef CONFIG_GTK_OL
10453 	if (psecuritypriv->binstallKCK_KEK == _TRUE)
10454 		rtw_hal_fw_sync_cam_id(adapter);
10455 #endif
10456 	if (IS_HARDWARE_TYPE_8723B(adapter))
10457 		rtw_hal_backup_rate(adapter);
10458 
10459 	rtw_hal_fw_dl(adapter, _TRUE);
10460 	if(no_wake)
10461 		media_status_rpt = RT_MEDIA_DISCONNECT;
10462 	else
10463 		media_status_rpt = RT_MEDIA_CONNECT;
10464 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10465 			  (u8 *)&media_status_rpt);
10466 
10467 	/* RX DMA stop */
10468 	#if defined(CONFIG_RTL8188E)
10469 	if (IS_HARDWARE_TYPE_8188E(adapter))
10470 		rtw_hal_disable_tx_report(adapter);
10471 	#endif
10472 
10473 	res = rtw_hal_pause_rx_dma(adapter);
10474 	if (res == _FAIL)
10475 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
10476 
10477 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
10478 	/* Reconfig RX_FF Boundary */
10479 	#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10480 	rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
10481 	#endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10482 	#endif
10483 
10484 	/* redownload wow pattern */
10485 	if(!no_wake)
10486 		rtw_hal_dl_pattern(adapter, 1);
10487 
10488 	if (!pwrctl->wowlan_pno_enable) {
10489 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10490 
10491 		if (psta != NULL) {
10492 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10493 			adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10494 			adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10495 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10496 			#endif
10497 			if(!no_wake)
10498 				rtw_sta_media_status_rpt(adapter, psta, 1);
10499 		}
10500 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10501 		else {
10502 			if(registry_par->suspend_type == FW_IPS_WRC) {
10503 				adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10504 				adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10505 				rtw_hal_set_default_port_id_cmd(adapter, 0);
10506 			}
10507 		}
10508 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10509 	}
10510 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10511 	else {
10512 		rtw_hal_set_default_port_id_cmd(adapter, 0);
10513 	}
10514 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10515 
10516 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10517 	/* Enable CPWM2 only. */
10518 	res = rtw_hal_enable_cpwm2(adapter);
10519 	if (res == _FAIL)
10520 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
10521 #endif
10522 #ifdef CONFIG_GPIO_WAKEUP
10523 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10524 	rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10525 	rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10526 #else
10527 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10528 	if (pwrctl->is_high_active == 0)
10529 		rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10530 	else
10531 		rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10532 			GPIO_OUTPUT_LOW);
10533 #else
10534 	val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10535 	rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8);
10536 	rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10537 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n",
10538 		 __func__, pwrctl->wowlan_gpio_index,
10539 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10540 		 pwrctl->is_high_active ? "HIGI" : "LOW");
10541 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10542 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10543 #endif /* CONFIG_GPIO_WAKEUP */
10544 	/* Set WOWLAN H2C command. */
10545 	RTW_PRINT("Set WOWLan cmd\n");
10546 	rtw_hal_set_fw_wow_related_cmd(adapter, 1);
10547 
10548 	res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
10549 
10550 	if (res == _FALSE)
10551 		RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
10552 
10553 	pwrctl->wowlan_wake_reason =
10554 		rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10555 
10556 	RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
10557 		  pwrctl->wowlan_wake_reason);
10558 
10559 #if defined(RTW_HALMAC) && defined(CONFIG_PNO_SUPPORT)
10560 	if(pwrctl->wowlan_pno_enable)
10561 		rtw_halmac_pno_scanoffload(adapter->dvobj, 1);
10562 #endif
10563 
10564 #ifdef CONFIG_GTK_OL_DBG
10565 	dump_sec_cam(RTW_DBGDUMP, adapter);
10566 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
10567 #endif
10568 
10569 #ifdef CONFIG_LPS_PG
10570 	if (pwrctl->lps_level == LPS_PG) {
10571 		lps_pg_hdl_id = LPS_PG_INFO_CFG;
10572 		rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
10573 	}
10574 #endif
10575 
10576 #ifdef CONFIG_USB_HCI
10577 	/* free adapter's resource */
10578 	rtw_mi_intf_stop(adapter);
10579 
10580 #endif
10581 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
10582 	/* Invoid SE0 reset signal during suspending*/
10583 	rtw_write8(adapter, REG_RSV_CTRL, 0x20);
10584 	if (IS_8188F(pHalData->version_id) == FALSE
10585 		&& IS_8188GTV(pHalData->version_id) == FALSE)
10586 		rtw_write8(adapter, REG_RSV_CTRL, 0x60);
10587 #endif
10588 
10589 	rtw_hal_gate_bb(adapter, _FALSE);
10590 }
10591 
10592 #define DBG_WAKEUP_REASON
10593 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)10594 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
10595 {
10596 	RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
10597 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)10598 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
10599 {
10600 	if (RX_PAIRWISEKEY == reason)
10601 		_dbg_wake_up_reason_string(adapter, "Rx pairwise key");
10602 	else if (RX_GTK == reason)
10603 		_dbg_wake_up_reason_string(adapter, "Rx GTK");
10604 	else if (RX_FOURWAY_HANDSHAKE == reason)
10605 		_dbg_wake_up_reason_string(adapter, "Rx four way handshake");
10606 	else if (RX_DISASSOC == reason)
10607 		_dbg_wake_up_reason_string(adapter, "Rx disassoc");
10608 	else if (RX_DEAUTH == reason)
10609 		_dbg_wake_up_reason_string(adapter, "Rx deauth");
10610 	else if (RX_ARP_REQUEST == reason)
10611 		_dbg_wake_up_reason_string(adapter, "Rx ARP request");
10612 	else if (FW_DECISION_DISCONNECT == reason)
10613 		_dbg_wake_up_reason_string(adapter, "FW detect disconnect");
10614 	else if (RX_MAGIC_PKT == reason)
10615 		_dbg_wake_up_reason_string(adapter, "Rx magic packet");
10616 	else if (RX_UNICAST_PKT == reason)
10617 		_dbg_wake_up_reason_string(adapter, "Rx unicast packet");
10618 	else if (RX_PATTERN_PKT == reason)
10619 		_dbg_wake_up_reason_string(adapter, "Rx pattern packet");
10620 	else if (RX_PNO == reason)
10621 		_dbg_wake_up_reason_string(adapter, "RX PNO");
10622 	else if (RTD3_SSID_MATCH == reason)
10623 		_dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
10624 	else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
10625 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
10626 	else if (RX_REALWOW_V2_ACK_LOST == reason)
10627 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
10628 	else if (ENABLE_FAIL_DMA_IDLE == reason)
10629 		_dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
10630 	else if (ENABLE_FAIL_DMA_PAUSE == reason)
10631 		_dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
10632 	else if (AP_OFFLOAD_WAKEUP == reason)
10633 		_dbg_wake_up_reason_string(adapter, "AP offload wakeup");
10634 	else if (CLK_32K_UNLOCK == reason)
10635 		_dbg_wake_up_reason_string(adapter, "clk 32k unlock");
10636 	else if (RTIME_FAIL_DMA_IDLE == reason)
10637 		_dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
10638 	else if (CLK_32K_LOCK == reason)
10639 		_dbg_wake_up_reason_string(adapter, "clk 32k lock");
10640 	#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10641 	else if (WOW_KEEPALIVE_ACK_TIMEOUT == reason)
10642 		_dbg_wake_up_reason_string(adapter, "rx keep alive ack timeout");
10643 	else if (WOW_KEEPALIVE_WAKE == reason)
10644 		_dbg_wake_up_reason_string(adapter, "rx keep alive wake pattern");
10645 	#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
10646 	else
10647 		_dbg_wake_up_reason_string(adapter, "unknown reasoen");
10648 }
10649 #endif
10650 
rtw_hal_wow_disable(_adapter * adapter)10651 static void rtw_hal_wow_disable(_adapter *adapter)
10652 {
10653 	int i;
10654 	struct recv_reorder_ctrl *preorder_ctrl;
10655 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10656 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10657 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10658 	struct sta_info *psta = NULL;
10659 	struct registry_priv  *registry_par = &adapter->registrypriv;
10660 	int res;
10661 	u16 media_status_rpt;
10662 
10663 	RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
10664 
10665 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
10666 		RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
10667 		return;
10668 	}
10669 
10670 	if (!pwrctl->wowlan_pno_enable) {
10671 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10672 		if (psta != NULL)
10673 			rtw_sta_media_status_rpt(adapter, psta, 0);
10674 		else
10675 			RTW_INFO("%s: psta is null\n", __func__);
10676 	}
10677 #if defined(RTW_HALMAC) && defined(CONFIG_PNO_SUPPORT)
10678 	else {
10679 		rtw_halmac_pno_scanoffload(adapter->dvobj, 0);
10680 	}
10681 #endif
10682 
10683 	if (0) {
10684 		RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
10685 		RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
10686 		RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
10687 		RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
10688 	}
10689 
10690 	pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10691 
10692 	RTW_PRINT("wakeup_reason: 0x%02x\n",
10693 		  pwrctl->wowlan_wake_reason);
10694 	#ifdef DBG_WAKEUP_REASON
10695 	_dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
10696 	#endif
10697 
10698 	rtw_hal_set_fw_wow_related_cmd(adapter, 0);
10699 
10700 	res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
10701 
10702 	#if defined(CONFIG_RTL8188E)
10703 	if (IS_HARDWARE_TYPE_8188E(adapter))
10704 		rtw_hal_enable_tx_report(adapter);
10705 	#endif
10706 
10707 	if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10708 	    (pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
10709 	    (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10710 	    (pwrctl->wowlan_wake_reason != NO_WAKE_RX_PAIRWISEKEY) &&
10711 	    (pwrctl->wowlan_wake_reason != NO_WAKE_RX_GTK) &&
10712 	    (pwrctl->wowlan_wake_reason != NO_WAKE_RX_DISASSOC) &&
10713 	    (pwrctl->wowlan_wake_reason != NO_WAKE_RX_DEAUTH) &&
10714 	    (pwrctl->wowlan_wake_reason != NO_WAKE_RX_EAPREQ_IDENTIFY)) {
10715 		rtw_hal_get_aoac_rpt(adapter);
10716 		rtw_hal_update_sw_security_info(adapter);
10717 	}
10718 
10719 	if (res == _FALSE) {
10720 		RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
10721 		rtw_hal_force_enable_rxdma(adapter);
10722 	}
10723 
10724 	rtw_hal_gate_bb(adapter, _TRUE);
10725 
10726 	res = rtw_hal_pause_rx_dma(adapter);
10727 	if (res == _FAIL)
10728 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
10729 
10730 	/* clean HW pattern match */
10731 	rtw_hal_dl_pattern(adapter, 0);
10732 
10733 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
10734 	/* config RXFF boundary to original */
10735 	#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10736 	rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
10737 	#endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10738 	#endif
10739 	rtw_hal_release_rx_dma(adapter);
10740 
10741 	rtw_hal_fw_dl(adapter, _FALSE);
10742 
10743 #ifdef CONFIG_GPIO_WAKEUP
10744 
10745 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10746 	rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10747 #else
10748 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10749 	if (pwrctl->is_high_active == 0)
10750 		rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10751 	else
10752 		rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10753 			GPIO_OUTPUT_LOW);
10754 #else
10755 	rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index
10756 		, pwrctl->wowlan_gpio_output_state);
10757 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n",
10758 		 __func__, pwrctl->wowlan_gpio_index,
10759 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10760 		 pwrctl->is_high_active ? "HIGI" : "LOW");
10761 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10762 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10763 #endif /* CONFIG_GPIO_WAKEUP */
10764 	if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10765 	    (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
10766 	    (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10767 	    (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
10768 
10769 		media_status_rpt = RT_MEDIA_CONNECT;
10770 		rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10771 				  (u8 *)&media_status_rpt);
10772 
10773 		if (psta != NULL) {
10774 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10775 			adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10776 			adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10777 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10778 			#endif
10779 			rtw_sta_media_status_rpt(adapter, psta, 1);
10780 		}
10781 	}
10782 
10783 	if (psta != NULL) {
10784 		RTW_PRINT("rtw_set_bit RTW_RECV_REORDER_WOW\n");
10785 		for (i = 0; i < TID_NUM; i++) {
10786 			preorder_ctrl = &psta->recvreorder_ctrl[i];
10787 			rtw_set_bit(RTW_RECV_REORDER_WOW,
10788 				    &preorder_ctrl->rec_abba_rsp_ack);
10789 		}
10790 	}
10791 
10792 	rtw_hal_gate_bb(adapter, _FALSE);
10793 }
10794 #if defined(CONFIG_WOW_PATTERN_IN_TXFIFO)
rtw_hal_construct_pattern_info(PADAPTER padapter,u8 * pframe,u32 * pLength)10795 static void rtw_hal_construct_pattern_info(
10796 	PADAPTER	padapter,
10797 	u8		*pframe,
10798 	u32		*pLength
10799 )
10800 {
10801 
10802 	u32 pattern_info_len = 0;
10803 	int i = 0, total = 0, index;
10804 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
10805 	struct rtl_wow_pattern wow_pattern;
10806 	u32 page_sz = 0;
10807 
10808 	total = pwrpriv->wowlan_pattern_idx;
10809 
10810 	if (total > MAX_WKFM_CAM_NUM)
10811 		total = MAX_WKFM_CAM_NUM;
10812 
10813 	/* Generate default pattern */
10814 	rtw_set_default_pattern(padapter);
10815 
10816 	/* Convert pattern to WKFM_CAM pattern */
10817 	for (i = 0 ; i < total ; i++) {
10818 		if (_SUCCESS == rtw_hal_wow_pattern_generate(padapter, i, &wow_pattern)) {
10819 
10820 			index = i;
10821 			if (!pwrpriv->bInSuspend)
10822 				index += 2;
10823 			#ifdef CONFIG_WOW_PATTERN_IN_TXFIFO_DBG
10824 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10825 			#endif
10826 
10827 			if (rtw_write_to_frame_mask_buf(padapter, index, &wow_pattern,
10828 				pframe, &pattern_info_len) == _FALSE)
10829 				RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
10830 		}
10831 	}
10832 	*pLength = pattern_info_len;
10833 
10834 
10835 }
10836 #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)10837 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
10838 		  u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
10839 				  RSVDPAGE_LOC *rsvd_page_loc)
10840 {
10841 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10842 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10843 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10844 	struct mlme_ext_priv	*pmlmeext;
10845 	struct mlme_ext_info	*pmlmeinfo;
10846 	u32	ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
10847 	u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
10848 	u8 CurtPktPageNum = 0;
10849 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10850 	u32 keep_alive_len=0;
10851 	int i;
10852 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN */
10853 #ifdef CONFIG_WAR_OFFLOAD
10854 	u16 tmp_idx = 0;
10855 	u32	buf_len = 0;
10856 #endif
10857 
10858 #ifdef CONFIG_GTK_OL
10859 	struct sta_priv *pstapriv = &adapter->stapriv;
10860 	struct sta_info *psta;
10861 	struct security_priv *psecpriv = &adapter->securitypriv;
10862 	u8 kek[RTW_KEK_LEN];
10863 	u8 kck[RTW_KCK_LEN];
10864 #endif /* CONFIG_GTK_OL */
10865 #ifdef CONFIG_PNO_SUPPORT
10866 	int pno_index;
10867 	u8 ssid_num;
10868 #endif /* CONFIG_PNO_SUPPORT */
10869 #ifdef CONFIG_WOW_PATTERN_IN_TXFIFO
10870 	u32 PatternLen = 0;
10871 	u32 cam_start_offset = 0;
10872 	u32 reg_cam_start_offset_val = 0;
10873 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
10874 
10875 	pmlmeext = &adapter->mlmeextpriv;
10876 	pmlmeinfo = &pmlmeext->mlmext_info;
10877 
10878 	if (pwrctl->wowlan_pno_enable == _FALSE) {
10879 		/* ARP RSP * 1 page */
10880 
10881 		rsvd_page_loc->LocArpRsp = *page_num;
10882 
10883 		RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
10884 
10885 #ifdef CONFIG_WAR_OFFLOAD
10886 		if ((0 != pwrctl->wowlan_war_offload_ipv4.ip_addr[0]) &&
10887 			(_FALSE == _rtw_memcmp(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4))) {
10888 			_rtw_memcpy(pmlmeinfo->ip_addr, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4);
10889 			RTW_INFO("Update IP(%d.%d.%d.%d) to arp rsvd page\n",
10890 			pmlmeinfo->ip_addr[0], pmlmeinfo->ip_addr[1],
10891 			pmlmeinfo->ip_addr[2], pmlmeinfo->ip_addr[3]);
10892 		}
10893 #endif /* CONFIG_WAR_OFFLOAD */
10894 
10895 
10896 		rtw_hal_construct_ARPRsp(adapter, &pframe[index],
10897 					 &ARPLength, pmlmeinfo->ip_addr);
10898 
10899 		rtw_hal_fill_fake_txdesc(adapter,
10900 					 &pframe[index - tx_desc],
10901 					 ARPLength, _FALSE, _FALSE, _TRUE);
10902 
10903 		CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
10904 
10905 		*page_num += CurtPktPageNum;
10906 
10907 		index += (CurtPktPageNum * page_size);
10908 		RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
10909 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10910 		/* Keep Alive * ? page*/
10911 		if(pwrctl->keep_alive_pattern_len){
10912 			rsvd_page_loc->LocKeepAlive = *page_num;
10913 			pwrctl->keep_alive_pattern_loc = rsvd_page_loc->LocKeepAlive;
10914 			RTW_INFO("pwrctl->keep_alive_pattern_loc: %d\n", pwrctl->keep_alive_pattern_loc);
10915 			rtw_hal_construct_keepalive(adapter,&pframe[index],&keep_alive_len);
10916 			rtw_hal_fill_fake_txdesc(adapter,
10917 					 &pframe[index - tx_desc],
10918 					 keep_alive_len, _FALSE, _FALSE, _TRUE);
10919 			CurtPktPageNum = (u8)PageNum(tx_desc + keep_alive_len, page_size);
10920 			*page_num += CurtPktPageNum;
10921 			index += (CurtPktPageNum * page_size);
10922 			RSVD_PAGE_CFG("WOW-KeepAlive:", CurtPktPageNum, *page_num, 0);
10923 		}
10924 #endif /* CONFIG_WOW_KEEP_ALIVE_PATTERN*/
10925 
10926 #ifdef CONFIG_IPV6
10927 		/* 2 NS offload and NDP Info*/
10928 		if (pwrctl->wowlan_ns_offload_en == _TRUE) {
10929 			rsvd_page_loc->LocNbrAdv = *page_num;
10930 			RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
10931 			rtw_hal_construct_na_message(adapter,
10932 						     &pframe[index], &ns_len);
10933 			rtw_hal_fill_fake_txdesc(adapter,
10934 						 &pframe[index - tx_desc],
10935 						 ns_len, _FALSE,
10936 						 _FALSE, _TRUE);
10937 			CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
10938 						      page_size);
10939 			*page_num += CurtPktPageNum;
10940 			index += (CurtPktPageNum * page_size);
10941 			RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
10942 
10943 			rsvd_page_loc->LocNDPInfo = *page_num;
10944 			RTW_INFO("LocNDPInfo: %d\n",
10945 				 rsvd_page_loc->LocNDPInfo);
10946 
10947 			rtw_hal_construct_ndp_info(adapter,
10948 						   &pframe[index - tx_desc],
10949 						   &ns_len);
10950 			CurtPktPageNum =
10951 				(u8)PageNum(tx_desc + ns_len, page_size);
10952 			*page_num += CurtPktPageNum;
10953 			index += (CurtPktPageNum * page_size);
10954 			RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
10955 
10956 		}
10957 #endif /*CONFIG_IPV6*/
10958 		/* 3 Remote Control Info. * 1 page */
10959 		rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
10960 		RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
10961 		rtw_hal_construct_remote_control_info(adapter,
10962 						      &pframe[index - tx_desc],
10963 						      &rc_len);
10964 		CurtPktPageNum = (u8)PageNum(rc_len, page_size);
10965 		*page_num += CurtPktPageNum;
10966 		*total_pkt_len = index + rc_len;
10967 		RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
10968 #ifdef CONFIG_GTK_OL
10969 		index += (CurtPktPageNum * page_size);
10970 
10971 		/* if the ap staion info. exists, get the kek, kck from staion info. */
10972 		psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
10973 		if (psta == NULL) {
10974 			_rtw_memset(kek, 0, RTW_KEK_LEN);
10975 			_rtw_memset(kck, 0, RTW_KCK_LEN);
10976 			RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
10977 				 __func__);
10978 		} else {
10979 			_rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
10980 			_rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
10981 		}
10982 
10983 		/* 3 KEK, KCK */
10984 		rsvd_page_loc->LocGTKInfo = *page_num;
10985 		RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
10986 
10987 		if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
10988 			struct security_priv *psecpriv = NULL;
10989 
10990 			psecpriv = &adapter->securitypriv;
10991 			_rtw_memcpy(pframe + index - tx_desc,
10992 				    &psecpriv->dot11PrivacyAlgrthm, 1);
10993 			_rtw_memcpy(pframe + index - tx_desc + 1,
10994 				    &psecpriv->dot118021XGrpPrivacy, 1);
10995 			_rtw_memcpy(pframe + index - tx_desc + 2,
10996 				    kck, RTW_KCK_LEN);
10997 			_rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
10998 				    kek, RTW_KEK_LEN);
10999 			CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
11000 		} else {
11001 
11002 			_rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
11003 			_rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
11004 				    kek, RTW_KEK_LEN);
11005 			GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
11006 
11007 			if (psta != NULL &&
11008 				psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
11009 				_rtw_memcpy(pframe + index - tx_desc + 56,
11010 					&psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
11011 				GTKLength += RTW_TKIP_MIC_LEN;
11012 			}
11013 			CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
11014 		}
11015 #if 0
11016 		{
11017 			int i;
11018 			printk("\ntoFW KCK: ");
11019 			for (i = 0; i < 16; i++)
11020 				printk(" %02x ", kck[i]);
11021 			printk("\ntoFW KEK: ");
11022 			for (i = 0; i < 16; i++)
11023 				printk(" %02x ", kek[i]);
11024 			printk("\n");
11025 		}
11026 
11027 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
11028 			 __FUNCTION__, &pframe[index - tx_desc],
11029 			 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
11030 #endif
11031 
11032 		*page_num += CurtPktPageNum;
11033 
11034 		index += (CurtPktPageNum * page_size);
11035 		RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
11036 
11037 		/* 3 GTK Response */
11038 		rsvd_page_loc->LocGTKRsp = *page_num;
11039 		RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
11040 		rtw_hal_construct_GTKRsp(adapter, &pframe[index], &GTKLength);
11041 
11042 		rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11043 					 GTKLength, _FALSE, _FALSE, _TRUE);
11044 #if 0
11045 		{
11046 			int gj;
11047 			printk("123GTK pkt=>\n");
11048 			for (gj = 0; gj < GTKLength + tx_desc; gj++) {
11049 				printk(" %02x ", pframe[index - tx_desc + gj]);
11050 				if ((gj + 1) % 16 == 0)
11051 					printk("\n");
11052 			}
11053 			printk(" <=end\n");
11054 		}
11055 
11056 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
11057 			 __FUNCTION__, &pframe[index - tx_desc],
11058 			 (tx_desc + GTKLength));
11059 #endif
11060 
11061 		CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
11062 
11063 		*page_num += CurtPktPageNum;
11064 
11065 		index += (CurtPktPageNum * page_size);
11066 		RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
11067 
11068 		/* below page is empty for GTK extension memory */
11069 		/* 3(11) GTK EXT MEM */
11070 		rsvd_page_loc->LocGTKEXTMEM = *page_num;
11071 		RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
11072 		CurtPktPageNum = 2;
11073 
11074 		if (page_size >= 256)
11075 			CurtPktPageNum = 1;
11076 
11077 		*page_num += CurtPktPageNum;
11078 		/* extension memory for FW */
11079 		*total_pkt_len = index + (page_size * CurtPktPageNum);
11080 		RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
11081 #endif /* CONFIG_GTK_OL */
11082 
11083 		index += (CurtPktPageNum * page_size);
11084 
11085 #ifdef CONFIG_WAR_OFFLOAD
11086 		if(_TRUE == pwrctl->wowlan_war_offload_mode) {
11087 			u8 zero_ary[16] = {0x00};
11088 			u8 war_tmp_cnt = 0;
11089 
11090 			/* Reserve 2 page for Ip parameters */
11091 			/* First page
11092 			   | Byte 15 -----------Byte 0 |
11093 			   | IP-4 | IP-3 | IP-2 | IP-1 |
11094 			   | location of each feature | mac addr |
11095 			   | NetBIOS name			   |
11096 			   | location of each feature  |
11097 			Second page
11098 			   | IPv6 - 1				   |
11099 			   | IPv6 - 2				   |
11100 			   | IPv6 - 3				   |
11101 			   | IPv6 - 4				   |
11102 			   | IPv6 - 5				   |
11103 			   | IPv6 - 6				   |
11104 			   | IPv6 - 7				   |
11105 			   | IPv6 - 8				   |
11106 			*/
11107 
11108 			/* location of each feature : Byte 22 ~ Byte 31
11109 			 * Byte22 : location of SNMP RX
11110 			 * Byte23 : location of SNMP V4
11111 			 * Byte24 : location of SNMP V6
11112 			 * Byte25 : location of MDNS Param
11113 			 * Byte26 : location of MDNS V4
11114 			 * Byte27 : location of MDNS V6
11115 			 * Byte28 : location of SSDP pattern
11116 			 * Byte29 : location of WSD pattern
11117 			 * Byte30 : location of SLP pattern
11118 			 * Byte31 : location of LLMNR
11119 			 */
11120 
11121 			/* ipv4 : 4 */
11122 			if (0 == pwrctl->wowlan_war_offload_ipv4.ip_addr[0])
11123 				_rtw_memcpy(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4);
11124 			for(war_tmp_cnt=0; war_tmp_cnt<4 ;war_tmp_cnt++)
11125 				_rtw_memcpy(pframe + index - tx_desc + (war_tmp_cnt*4), &pwrctl->wowlan_war_offload_ipv4.ip_addr[war_tmp_cnt], 4);
11126 
11127 			if (is_zero_mac_addr(pwrctl->wowlan_war_offload_mac)) {
11128 				_rtw_memcpy(pwrctl->wowlan_war_offload_mac, adapter_mac_addr(adapter), 6);
11129 			}
11130 			_rtw_memcpy(pframe + index + 16 - tx_desc, pwrctl->wowlan_war_offload_mac, 6);
11131 
11132 
11133 			/* ipv6 : 8 */
11134 			if (_TRUE == _rtw_memcmp(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], zero_ary, RTW_IPv6_ADDR_LEN))
11135 				_rtw_memcpy(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], pmlmeinfo->ip6_addr, RTW_IPv6_ADDR_LEN);
11136 
11137 			for(war_tmp_cnt=0; war_tmp_cnt<8 ;war_tmp_cnt++)
11138 				_rtw_memcpy(pframe + index + page_size - tx_desc + (war_tmp_cnt*16), pwrctl->wowlan_war_offload_ipv6.ipv6_addr[war_tmp_cnt], 16);
11139 
11140 			rsvd_page_loc->LocIpParm = *page_num;
11141 
11142 			tmp_idx = index;
11143 			CurtPktPageNum = 2;
11144 			*page_num += CurtPktPageNum;
11145 			*total_pkt_len = index + (page_size * CurtPktPageNum);
11146 			index += (CurtPktPageNum * page_size);
11147 
11148 
11149 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
11150 			if ( (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) ||
11151 				 (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) ||
11152 				 (WAR_MDNS_V4_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl) ||
11153 				 (WAR_MDNS_V6_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl)) {
11154 
11155 				struct war_mdns_service_info *psinfo = pwrctl->wowlan_war_offload_mdns_service;
11156 				u8 txt_in_ptr[31]={ 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
11157 									 0x00, 0x13, 0x09, 0x74, 0x78, 0x74, 0x76, 0x65, 0x72, 0x73,
11158 									 0x3d, 0x31, 0x08, 0x71, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x3d, 0x31};
11159 				u16 mdns_offset = index - tx_desc;
11160 				u8 i = 0;
11161 
11162 				rsvd_page_loc->LocMdnsPara = *page_num;
11163 				RTW_INFO("LocMdnsPara : %d\n", rsvd_page_loc->LocMdnsPara);
11164 
11165 				/* 1. service info */
11166 				pframe[mdns_offset] = 0x01;  // TLV(T)
11167 				mdns_offset += 1;
11168 				_rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_service_info_num, 1);
11169 				mdns_offset += 1;
11170 
11171 				for(i=0; i<pwrctl->wowlan_war_offload_mdns_service_info_num ;i++)
11172 				{
11173 					u16 srv_rsp_len = 0;
11174 
11175 					// 1.1 : construct service name string
11176 					//	   : length of total service name string (service+transport+domain)
11177 					pframe[mdns_offset] = psinfo[i].service_len + psinfo[i].transport_len + psinfo[i].domain_len + 4;
11178 					mdns_offset += 1;
11179 
11180 					//	   :  service name
11181 					pframe[mdns_offset] = psinfo[i].service_len;
11182 					mdns_offset += 1;
11183 					_rtw_memcpy(pframe + mdns_offset, &psinfo[i].service, psinfo[i].service_len);
11184 					mdns_offset += psinfo[i].service_len;
11185 
11186 					//	   : transport name
11187 					pframe[mdns_offset] = psinfo[i].transport_len;
11188 					mdns_offset += 1;
11189 					_rtw_memcpy(pframe + mdns_offset, &psinfo[i].transport, psinfo[i].transport_len);
11190 					mdns_offset += psinfo[i].transport_len;
11191 
11192 					//	   : domain name
11193 					pframe[mdns_offset] = psinfo[i].domain_len;
11194 					mdns_offset += 1;
11195 					_rtw_memcpy(pframe + mdns_offset, &psinfo[i].domain, psinfo[i].domain_len);
11196 					mdns_offset += psinfo[i].domain_len;
11197 
11198 					//	   : delimiter
11199 					mdns_offset += 1;
11200 
11201 					// 1.2 : construct type srv rsp
11202 					pframe[mdns_offset] = psinfo[i].target_len + 19; // length
11203 					pframe[mdns_offset + 2] = 0x21; // rsp type (srv)
11204 					pframe[mdns_offset + 4] = 0x01; // cache flush + class
11205 					_rtw_memcpy(pframe + mdns_offset + 5, &psinfo[i].ttl, 4); // ttl
11206 					pframe[mdns_offset + 5] = (u8) ( (psinfo[i].ttl & 0xff000000) >> 24);	// ttl - byte0
11207 					pframe[mdns_offset + 6] = (u8) ( (psinfo[i].ttl & 0x00ff0000) >> 16);	// ttl - byte1
11208 					pframe[mdns_offset + 7] = (u8) ( (psinfo[i].ttl & 0x0000ff00) >> 8 );		// ttl - byte2
11209 					pframe[mdns_offset + 8] = (u8) (psinfo[i].ttl & 0x000000ff);			// ttl - byte3
11210 					pframe[mdns_offset + 10] = psinfo[i].target_len + 9;	  // data length
11211 					_rtw_memcpy(pframe + mdns_offset + 15, &psinfo[i].port, 2); // port
11212 					_rtw_memcpy(pframe + mdns_offset + 17, &psinfo[i].target_len, 1); // target len
11213 					_rtw_memcpy(pframe + mdns_offset + 18, &psinfo[i].target, psinfo[i].target_len); // target
11214 					pframe[mdns_offset + 18 + psinfo[i].target_len] = 0xc0; // message compresion, offset will be filled by fw.
11215 					mdns_offset += (1 + psinfo[i].target_len + 19);
11216 
11217 					// 1.3 : set the idx of txt rsp
11218 					pframe[mdns_offset] = psinfo[i].txt_rsp_idx;
11219 					mdns_offset += 1;
11220 				}
11221 
11222 				/* 2. machine name */
11223 				pframe[mdns_offset] = 0x02; // TLV(T)
11224 				mdns_offset += 1;
11225 				_rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_mnane_num, 1); // NUM
11226 				mdns_offset += 1;
11227 
11228 				for(i=0; i<pwrctl->wowlan_war_offload_mdns_mnane_num; i++)
11229 				{
11230 					pframe[mdns_offset] = pwrctl->wowlan_war_offload_mdns_mnane[i].name_len;
11231 					_rtw_memcpy(pframe + mdns_offset + 1, pwrctl->wowlan_war_offload_mdns_mnane[i].name,
11232 						pwrctl->wowlan_war_offload_mdns_mnane[i].name_len); // machine name
11233 					mdns_offset += (1+pwrctl->wowlan_war_offload_mdns_mnane[i].name_len);
11234 				}
11235 
11236 				/* 3. A rsp */
11237 				pframe[mdns_offset] = 0x03; // TLV(T)
11238 				pframe[mdns_offset + 1] = 14;	// TLV(L)
11239 				pframe[mdns_offset + 3] = 0x01; // rsp type (a)
11240 				pframe[mdns_offset + 5] = 0x01; // cache flush + class
11241 				pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec)
11242 				pframe[mdns_offset + 11] = 4;	// length of ipv4 addr.
11243 				_rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4);
11244 				mdns_offset += (2 + 14);
11245 
11246 				/* 4. AAAA rsp */
11247 				pframe[mdns_offset] = 0x04; // TLV(T)
11248 				pframe[mdns_offset + 1] = 26;	// TLV(L)
11249 				pframe[mdns_offset + 3] = 0x1c; // rsp type (aaaa)
11250 				pframe[mdns_offset + 5] = 0x01; // cache flush + class
11251 				pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec)
11252 				pframe[mdns_offset + 11] = 16;	// length of ipv6 addr.
11253 				_rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], 16);
11254 				mdns_offset += (2 + 26);
11255 
11256 				/* 5. PTR rsp */
11257 				pframe[mdns_offset] = 0x05; // TLV(T)
11258 				pframe[mdns_offset + 1] = 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // TLV(L)
11259 				pframe[mdns_offset + 3] = 0x0c; // rsp type (aaaa)
11260 				pframe[mdns_offset + 5] = 0x01; // cache flush + class
11261 				pframe[mdns_offset + 8] = 0x1c; // ttl
11262 				pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec)
11263 				pframe[mdns_offset + 11] = 3 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // data length
11264 				pframe[mdns_offset + 12] = pwrctl->wowlan_war_offload_mdns_domain_name_len; // domain name length
11265 				_rtw_memcpy(pframe + mdns_offset + 13, &pwrctl->wowlan_war_offload_mdns_domain_name,
11266 					pwrctl->wowlan_war_offload_mdns_domain_name_len);
11267 				pframe[mdns_offset + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len] = 0xc0; // message compression
11268 				mdns_offset += (2 + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len);
11269 
11270 				/* 6. TXT in PTR rsp */
11271 				pframe[mdns_offset] = 0x06; 		// TLV(T)
11272 				pframe[mdns_offset + 1] = 31;	// TLV(L)
11273 				_rtw_memcpy(pframe + mdns_offset + 2, &txt_in_ptr, 31);
11274 				mdns_offset += (2 + 31);
11275 
11276 				/* 7. TXT rsp */
11277 				pframe[mdns_offset] = 0x07; // TLV(T)
11278 				mdns_offset += 1;
11279 				_rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_txt_rsp_num, 1); // NUM
11280 				mdns_offset += 1;
11281 
11282 				for(i=0; i<pwrctl->wowlan_war_offload_mdns_txt_rsp_num; i++)
11283 				{
11284 					u16 txt_rsp_len = pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len;
11285 
11286 					if(pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len==0)
11287 					{
11288 						_rtw_memcpy(pframe + mdns_offset, &txt_rsp_len,  2);
11289 						mdns_offset += ( 2 + txt_rsp_len );
11290 						continue;
11291 					}
11292 
11293 					txt_rsp_len += 10;
11294 					_rtw_memcpy(pframe + mdns_offset, &txt_rsp_len,  2);
11295 					pframe[mdns_offset + 3] = 0x10; // rsp type (txt)
11296 					pframe[mdns_offset + 5] = 0x01; // cache flush + class
11297 					pframe[mdns_offset + 8] = 0x1c; // ttl
11298 					pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec)
11299 					pframe[mdns_offset + 10] = (u8) ((pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0xff00) >> 8);
11300 					pframe[mdns_offset + 11] = (u8) (pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0x00ff);
11301 						_rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt,
11302 							pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len);
11303 					mdns_offset  += ( 2 + txt_rsp_len );
11304 				}
11305 
11306 				CurtPktPageNum = (u8)PageNum(mdns_offset - index, page_size)+1;
11307 				*page_num += CurtPktPageNum;
11308 				*total_pkt_len = index + (page_size * CurtPktPageNum);
11309 				index += (CurtPktPageNum * page_size);
11310 			}
11311 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
11312 
11313 #ifdef CONFIG_OFFLOAD_MDNS_V4
11314 			if (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) {
11315 				rsvd_page_loc->LocMdnsv4 = *page_num;
11316 				RTW_INFO("LocMdnsv4: %d\n", rsvd_page_loc->LocMdnsv4);
11317 
11318 				rtw_hal_construct_mdns_rsp_v4(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr);
11319 				rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE);
11320 				CurtPktPageNum = 16;
11321 				*page_num += CurtPktPageNum;
11322 				index += (CurtPktPageNum * page_size);
11323 			}
11324 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
11325 
11326 #ifdef CONFIG_OFFLOAD_MDNS_V6
11327 			if (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) {
11328 				rsvd_page_loc->LocMdnsv6 = *page_num;
11329 				RTW_INFO("LocMdnsv6: %d\n", rsvd_page_loc->LocMdnsv6);
11330 
11331 				rtw_hal_construct_mdns_rsp_v6(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr);
11332 				rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE);
11333 				CurtPktPageNum = 16;
11334 				*page_num += CurtPktPageNum;
11335 				index += (CurtPktPageNum * page_size);
11336 			}
11337 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
11338 
11339 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
11340 			*(pframe+tmp_idx+25-tx_desc) = rsvd_page_loc->LocMdnsPara;
11341 			*(pframe+tmp_idx+26-tx_desc) = rsvd_page_loc->LocMdnsv4;
11342 			*(pframe+tmp_idx+27-tx_desc) = rsvd_page_loc->LocMdnsv6;
11343 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
11344 
11345 			}
11346 			//rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, rsvd_page_loc->LocIpParm, 46);
11347 #endif /* CONFIG_WAR_OFFLOAD */
11348 
11349 #if defined(CONFIG_WOW_PATTERN_IN_TXFIFO)
11350 		/* pattern_rsvd_page_loc will be used by rtw_read_from_frame_mask() */
11351 		pwrctl->pattern_rsvd_page_loc = *page_num;
11352 		RTW_INFO("LocPatternInfo: %d\n", pwrctl->pattern_rsvd_page_loc);
11353 		rtw_hal_construct_pattern_info(adapter,
11354 								&pframe[index - tx_desc],
11355 								&PatternLen);
11356 
11357 		/* Set cam_start_offset to REG_TXBUF_WKCAM_OFFSET
11358 		 * Cam address(TxBufer pointer) access 8 bytes at a time
11359 		 */
11360 
11361 		// Get rsvd page start page number + pattern located page
11362 		cam_start_offset = rtw_read8(adapter, REG_BCNQ_BDNY) + *page_num;
11363 		cam_start_offset *= page_size;
11364 		cam_start_offset /= 8;
11365 
11366 		reg_cam_start_offset_val = rtw_read32(adapter, REG_TXBUF_WKCAM_OFFSET);
11367 		reg_cam_start_offset_val &= ~(WKCAM_OFFSET_BIT_MASK << WKCAM_OFFSET_BIT_MASK_OFFSET);
11368 		reg_cam_start_offset_val |= (cam_start_offset << WKCAM_OFFSET_BIT_MASK_OFFSET);
11369 		rtw_write32(adapter, REG_TXBUF_WKCAM_OFFSET, reg_cam_start_offset_val);
11370 
11371 		/* Set pattern number to REG_WKFMCAM_NUM */
11372 		rtw_write8(adapter, REG_WKFMCAM_NUM, PatternLen / WKFMCAM_SIZE);
11373 
11374 		CurtPktPageNum = (u8)PageNum(PatternLen, page_size);
11375 		*page_num += CurtPktPageNum;
11376 		index += (CurtPktPageNum * page_size);
11377 		RSVD_PAGE_CFG("WOW-PatternInfo", CurtPktPageNum, *page_num, index);
11378 
11379 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
11380 
11381 		/*Reserve 1 page for AOAC report*/
11382 		rsvd_page_loc->LocAOACReport = *page_num;
11383 		RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
11384 		*page_num += 1;
11385 		*total_pkt_len = index + (page_size * 1);
11386 		RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
11387 
11388 
11389 	} else {
11390 #ifdef CONFIG_PNO_SUPPORT
11391 		if (pwrctl->wowlan_in_resume == _FALSE &&
11392 		    pwrctl->pno_inited == _TRUE) {
11393 #ifndef RTW_HALMAC
11394 			/* Broadcast Probe Request */
11395 			rsvd_page_loc->LocProbePacket = *page_num;
11396 
11397 			RTW_INFO("loc_probe_req: %d\n",
11398 				 rsvd_page_loc->LocProbePacket);
11399 
11400 			rtw_hal_construct_ProbeReq(
11401 				adapter,
11402 				&pframe[index],
11403 				&ProbeReqLength,
11404 				NULL);
11405 
11406 			rtw_hal_fill_fake_txdesc(adapter,
11407 						 &pframe[index - tx_desc],
11408 				 ProbeReqLength, _FALSE, _FALSE, _FALSE);
11409 
11410 			CurtPktPageNum =
11411 				(u8)PageNum(tx_desc + ProbeReqLength, page_size);
11412 
11413 			*page_num += CurtPktPageNum;
11414 
11415 			index += (CurtPktPageNum * page_size);
11416 			RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
11417 
11418 			/* Scan Info Page */
11419 			rsvd_page_loc->LocScanInfo = *page_num;
11420 			RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
11421 			rtw_hal_construct_scan_info(adapter,
11422 						    &pframe[index - tx_desc],
11423 						    &ScanInfoLength);
11424 
11425 			CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
11426 			*page_num += CurtPktPageNum;
11427 
11428 			index += (CurtPktPageNum * page_size);
11429 			RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
11430 #endif
11431 			/* Hidden SSID Probe Request */
11432 			ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
11433 
11434 			for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
11435 				pwrctl->pnlo_info->loc_probe_req[pno_index] =
11436 					*page_num;
11437 
11438 				rtw_hal_construct_ProbeReq(
11439 					adapter,
11440 					&pframe[index],
11441 					&ProbeReqLength,
11442 					&pwrctl->pno_ssid_list->node[pno_index]);
11443 
11444 				rtw_hal_fill_fake_txdesc(adapter,
11445 						 &pframe[index - tx_desc],
11446 					ProbeReqLength, _FALSE, _FALSE, _FALSE);
11447 
11448 				CurtPktPageNum =
11449 					(u8)PageNum(tx_desc + ProbeReqLength, page_size);
11450 
11451 				*page_num += CurtPktPageNum;
11452 
11453 				index += (CurtPktPageNum * page_size);
11454 				RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
11455 			}
11456 
11457 			/* PNO INFO Page */
11458 			rsvd_page_loc->LocPNOInfo = *page_num;
11459 			RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
11460 			rtw_hal_construct_PNO_info(adapter,
11461 						   &pframe[index - tx_desc],
11462 						   &PNOLength);
11463 
11464 			CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
11465 			*page_num += CurtPktPageNum;
11466 			*total_pkt_len = index + PNOLength;
11467 			index += (CurtPktPageNum * page_size);
11468 			RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
11469 		}
11470 #endif /* CONFIG_PNO_SUPPORT */
11471 	}
11472 }
11473 #endif /*CONFIG_WOWLAN*/
11474 
11475 #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)11476 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
11477 	      u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
11478 				      RSVDPAGE_LOC *rsvd_page_loc)
11479 {
11480 	u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
11481 	u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
11482 	u8 CurtPktPageNum = 0;
11483 
11484 	/* P2P Beacon */
11485 	rsvd_page_loc->LocP2PBeacon = *page_num;
11486 	rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
11487 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11488 				 P2PBCNLength, _FALSE, _FALSE, _FALSE);
11489 
11490 #if 0
11491 	RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
11492 		__FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
11493 #endif
11494 
11495 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
11496 
11497 	*page_num += CurtPktPageNum;
11498 
11499 	index += (CurtPktPageNum * page_size);
11500 	RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
11501 
11502 	/* P2P Probe rsp */
11503 	rsvd_page_loc->LocP2PProbeRsp = *page_num;
11504 	rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
11505 				      &P2PProbeRspLength);
11506 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11507 				 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
11508 
11509 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",  */
11510 	/*	__FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
11511 
11512 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
11513 
11514 	*page_num += CurtPktPageNum;
11515 
11516 	index += (CurtPktPageNum * page_size);
11517 	RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
11518 
11519 	/* P2P nego rsp */
11520 	rsvd_page_loc->LocNegoRsp = *page_num;
11521 	rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
11522 				     &P2PNegoRspLength);
11523 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11524 				 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
11525 
11526 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
11527 	/*	__FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
11528 
11529 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
11530 
11531 	*page_num += CurtPktPageNum;
11532 
11533 	index += (CurtPktPageNum * page_size);
11534 	RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
11535 
11536 	/* P2P invite rsp */
11537 	rsvd_page_loc->LocInviteRsp = *page_num;
11538 	rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
11539 				       &P2PInviteRspLength);
11540 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11541 				 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
11542 
11543 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
11544 	/* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
11545 
11546 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
11547 
11548 	*page_num += CurtPktPageNum;
11549 
11550 	index += (CurtPktPageNum * page_size);
11551 	RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
11552 
11553 	/* P2P provision discovery rsp */
11554 	rsvd_page_loc->LocPDRsp = *page_num;
11555 	rtw_hal_construct_P2PProvisionDisRsp(adapter,
11556 					     &pframe[index], &P2PPDRspLength);
11557 
11558 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11559 				 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
11560 
11561 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
11562 	/*	__FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
11563 
11564 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
11565 
11566 	*page_num += CurtPktPageNum;
11567 
11568 	*total_pkt_len = index + P2PPDRspLength;
11569 	RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
11570 
11571 	index += (CurtPktPageNum * page_size);
11572 
11573 
11574 }
11575 #endif /* CONFIG_P2P_WOWLAN */
11576 
11577 #ifdef CONFIG_LPS_PG
11578 #ifndef DBG_LPSPG_INFO_DUMP
11579 #define DBG_LPSPG_INFO_DUMP 1
11580 #endif
11581 
11582 #include "hal_halmac.h"
11583 
11584 #ifdef CONFIG_RTL8822C
rtw_lps_pg_set_dpk_info_rsvd_page(_adapter * adapter)11585 static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
11586 {
11587 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11588 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11589 	struct dm_struct *dm = adapter_to_phydm(adapter);
11590 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
11591 	u8 *info = NULL;
11592 	u32 info_len;
11593 	int ret = _FAIL;
11594 
11595 	/* get length */
11596 	halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
11597 	if (!info_len) {
11598 		RTW_ERR("get %s length fail\n", cache->name);
11599 		goto exit;
11600 	}
11601 
11602 	/* allocate buf */
11603 	info = rtw_zmalloc(info_len);
11604 	if (!info) {
11605 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11606 		goto exit;
11607 	}
11608 
11609 	/* get content */
11610 	halrf_dpk_info_rsvd_page(dm, info, NULL);
11611 
11612 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
11613 
11614 		#if (DBG_LPSPG_INFO_DUMP >= 1)
11615 		RTW_INFO_DUMP(cache->name, info, info_len);
11616 		#endif
11617 
11618 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11619 		ret = !ret ? _SUCCESS : _FAIL;
11620 		if (ret != _SUCCESS) {
11621 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11622 			goto free_mem;
11623 		}
11624 
11625 		#if (DBG_LPSPG_INFO_DUMP >= 2)
11626 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11627 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11628 		#endif
11629 	}
11630 
11631 free_mem:
11632 	rtw_mfree(info, info_len);
11633 
11634 exit:
11635 	return ret;
11636 }
11637 
rtw_lps_pg_set_iqk_info_rsvd_page(_adapter * adapter)11638 static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
11639 {
11640 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11641 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11642 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11643 	struct dm_struct *dm = adapter_to_phydm(adapter);
11644 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
11645 	u8 *info = NULL;
11646 	u32 info_len = 0;
11647 	int ret = _FAIL;
11648 
11649 	if (hal_data->RegIQKFWOffload) {
11650 		rsvd_page_cache_free_data(cache);
11651 		ret = _SUCCESS;
11652 		goto exit;
11653 	}
11654 
11655 	/* get length */
11656 	halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
11657 	if (!info_len) {
11658 		RTW_ERR("get %s length fail\n", cache->name);
11659 		goto exit;
11660 	}
11661 
11662 	/* allocate buf */
11663 	info = rtw_zmalloc(info_len);
11664 	if (!info) {
11665 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11666 		goto exit;
11667 	}
11668 
11669 	/* get content */
11670 	halrf_iqk_info_rsvd_page(dm, info, NULL);
11671 
11672 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
11673 
11674 		#if (DBG_LPSPG_INFO_DUMP >= 1)
11675 		RTW_INFO_DUMP(cache->name, info, info_len);
11676 		#endif
11677 
11678 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11679 		ret = !ret ? _SUCCESS : _FAIL;
11680 		if (ret != _SUCCESS) {
11681 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11682 			goto free_mem;
11683 		}
11684 
11685 		#if (DBG_LPSPG_INFO_DUMP >= 2)
11686 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11687 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11688 		#endif
11689 	}
11690 
11691 free_mem:
11692 	rtw_mfree(info, info_len);
11693 
11694 exit:
11695 	return ret;
11696 }
11697 #endif /* CONFIG_RTL8822C */
11698 
rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv * dvobj,_adapter * ld_sta_iface,u8 * buf,u32 * buf_size)11699 static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size)
11700 {
11701 #define LPS_PG_INFO_RSVD_LEN	16
11702 
11703 	if (buf) {
11704 		_adapter *adapter = dvobj_get_primary_adapter(dvobj);
11705 		struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11706 		struct sta_info *psta;
11707 #ifdef CONFIG_MBSSID_CAM
11708 		u8 cam_id = INVALID_CAM_ID;
11709 #endif
11710 		u8 *psec_cam_id = buf + 8;
11711 		u8 sec_cam_num = 0;
11712 		u8 drv_rsvdpage_num = 0;
11713 
11714 		if (ld_sta_iface) {
11715 			psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv));
11716 			if (!psta) {
11717 				RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
11718 				rtw_warn_on(1);
11719 				goto size_chk;
11720 			}
11721 			/*Byte 0 - used macid*/
11722 			LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
11723 			RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
11724 		}
11725 
11726 #ifdef CONFIG_MBSSID_CAM
11727 		/*Byte 1 - used BSSID CAM entry*/
11728 		cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
11729 		if (cam_id != INVALID_CAM_ID)
11730 			LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
11731 		RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
11732 #endif
11733 
11734 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
11735 		/*Btye 2 - Max used Pattern Match CAM entry*/
11736 		if (pwrpriv->wowlan_mode == _TRUE
11737 			&& ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11738 			LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
11739 			RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
11740 		}
11741 #endif
11742 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
11743 		/*Btye 3 - Max MU rate table Group ID*/
11744 		LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
11745 		RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
11746 #endif
11747 
11748 		/*Btye 8 ~15 - used Security CAM entry */
11749 		sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
11750 
11751 		/*Btye 4 - used Security CAM entry number*/
11752 		if (sec_cam_num < 8)
11753 			LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
11754 		RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
11755 
11756 		/*Btye 5 - Txbuf used page number for fw offload*/
11757 		if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
11758 			drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11759 		else
11760 			drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11761 		LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
11762 		RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
11763 	}
11764 
11765 size_chk:
11766 	if (buf_size)
11767 		*buf_size = LPS_PG_INFO_RSVD_LEN;
11768 }
11769 
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)11770 static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
11771 {
11772 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11773 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11774 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
11775 	u8 *info = NULL;
11776 	u32 info_len = 0;
11777 	int ret = _FAIL;
11778 
11779 	/* get length */
11780 	rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len);
11781 	if (!info_len) {
11782 		RTW_ERR("get %s length fail\n", cache->name);
11783 		goto exit;
11784 	}
11785 
11786 	/* allocate buf */
11787 	info = rtw_zmalloc(info_len);
11788 	if (!info) {
11789 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11790 		goto exit;
11791 	}
11792 
11793 	/* get content */
11794 	rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL);
11795 
11796 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
11797 
11798 		#if (DBG_LPSPG_INFO_DUMP >= 1)
11799 		RTW_INFO_DUMP(cache->name, info, info_len);
11800 		#endif
11801 
11802 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11803 		ret = !ret ? _SUCCESS : _FAIL;
11804 		if (ret != _SUCCESS) {
11805 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11806 			goto free_mem;
11807 		}
11808 
11809 		#if (DBG_LPSPG_INFO_DUMP >= 2)
11810 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11811 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11812 		#endif
11813 	}
11814 
11815 free_mem:
11816 	rtw_mfree(info, info_len);
11817 
11818 exit:
11819 	return ret;
11820 }
11821 
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)11822 static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
11823 	, u8 txdesc_size, u32 page_size, u8 *total_page_num
11824 	, bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num)
11825 {
11826 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11827 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
11828 	struct rsvd_page_cache_t *cache;
11829 	bool rsvd = 1;
11830 	u8 *pos;
11831 	u32 len;
11832 
11833 	if (is_wow_mode) {
11834 		/* lps_level will not change when enter wow_mode */
11835 		if (pwrctl->lps_level != LPS_PG)
11836 			rsvd = 0;
11837 	} else {
11838 		if (!only_get_page_num && !ld_sta_iface)
11839 			rsvd = 0;
11840 	}
11841 
11842 	pos = only_get_page_num ? NULL : frame + *index;
11843 
11844 #ifdef CONFIG_RTL8822C
11845 	if (IS_8822C_SERIES(hal_data->version_id)) {
11846 		/* LPSPG_DPK_INFO */
11847 		cache = &pwrctl->lpspg_dpk_info;
11848 		if (rsvd) {
11849 			if (pwrctl->lps_level != LPS_PG)
11850 				pos = NULL;
11851 			len = 0;
11852 			halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
11853 			#if (DBG_LPSPG_INFO_DUMP >= 1)
11854 			if (pos)
11855 				RTW_INFO_DUMP(cache->name, pos, len);
11856 			#endif
11857 			rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11858 			*total_page_num += cache->page_num;
11859 			*index += page_size * cache->page_num;
11860 			pos = only_get_page_num ? NULL : frame + *index;
11861 			RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11862 		} else
11863 			rsvd_page_cache_free(cache);
11864 
11865 		/* LPSPG_IQK_INFO */
11866 		cache = &pwrctl->lpspg_iqk_info;
11867 		if (rsvd
11868 			/* RegIQKFWOffload will not change when enter wow_mode */
11869 			&& !(is_wow_mode && hal_data->RegIQKFWOffload)
11870 		) {
11871 			if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
11872 				pos = NULL;
11873 			len = 0;
11874 			halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
11875 			#if (DBG_LPSPG_INFO_DUMP >= 1)
11876 			if (pos)
11877 				RTW_INFO_DUMP(cache->name, pos, len);
11878 			#endif
11879 			rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11880 			*total_page_num += cache->page_num;
11881 			*index += page_size * cache->page_num;
11882 			pos = only_get_page_num ? NULL : frame + *index;
11883 			RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11884 		} else
11885 			rsvd_page_cache_free(cache);
11886 	}
11887 #endif
11888 
11889 	/* LPSPG_INFO */
11890 	cache = &pwrctl->lpspg_info;
11891 	if (rsvd) {
11892 		if (pwrctl->lps_level != LPS_PG)
11893 			pos = NULL;
11894 		rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len);
11895 		#if (DBG_LPSPG_INFO_DUMP >= 1)
11896 		if (pos)
11897 			RTW_INFO_DUMP(cache->name, pos, len);
11898 		#endif
11899 		rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11900 		*total_page_num += cache->page_num;
11901 		*index += page_size * cache->page_num;
11902 		pos = only_get_page_num ? NULL : frame + *index;
11903 		RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11904 	} else
11905 		rsvd_page_cache_free(cache);
11906 }
11907 
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)11908 u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
11909 {
11910 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11911 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11912 
11913 	u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
11914 	u8 ret = _FAIL;
11915 
11916 	if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
11917 		SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1);	/*SecurityCAM_En*/
11918 
11919 #ifdef CONFIG_MBSSID_CAM
11920 	SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1);		/*BSSIDCAM_En*/
11921 #endif
11922 
11923 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
11924 	if (pwrpriv->wowlan_mode == _TRUE &&
11925 	    check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11926 
11927 		SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1);	/*PatternMatchCAM_En*/
11928 	}
11929 #endif
11930 
11931 #ifdef CONFIG_MACID_SEARCH
11932 	SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1);	/*MACIDSearch_En*/
11933 #endif
11934 
11935 #ifdef CONFIG_TX_SC
11936 	SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1);	/*TXSC_En*/
11937 #endif
11938 
11939 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
11940 	SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1);	/*MURateTable_En*/
11941 #endif
11942 
11943 	SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
11944 
11945 #ifdef CONFIG_RTL8822C
11946 	if (pwrpriv->bFwCurrentInPSMode == _FALSE) {
11947 		SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
11948 		if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11949 			SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
11950 	} else {
11951 		SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0);
11952 		if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11953 			SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0);
11954 	}
11955 #endif
11956 
11957 #if (DBG_LPSPG_INFO_DUMP >= 1)
11958 	RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
11959 #endif
11960 
11961 	ret = rtw_hal_fill_h2c_cmd(adapter,
11962 				   H2C_LPS_PG_INFO,
11963 				   H2C_LPS_PG_INFO_LEN,
11964 				   lpspg_info);
11965 	return ret;
11966 }
rtw_hal_set_lps_pg_info(_adapter * adapter)11967 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
11968 {
11969 	u8 ret = _FAIL;
11970 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11971 
11972 	if (pwrpriv->lpspg_info.loc == 0) {
11973 		RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
11974 		rtw_warn_on(1);
11975 		return ret;
11976 	}
11977 	#ifdef CONFIG_RTL8822C
11978 	rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
11979 	rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
11980 	#endif
11981 	rtw_hal_set_lps_pg_info_rsvd_page(adapter);
11982 
11983 	ret = rtw_hal_set_lps_pg_info_cmd(adapter);
11984 
11985 	return ret;
11986 }
11987 
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)11988 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
11989 {
11990 #if 0
11991 	if (sta->cmn.ra_info.rssi_level >= 4)
11992 		sta->lps_pg_rssi_lv = 3;	/*RSSI High - 1SS_VHT_MCS7*/
11993 	else if (sta->cmn.ra_info.rssi_level >=  2)
11994 		sta->lps_pg_rssi_lv = 2;	/*RSSI Middle - 1SS_VHT_MCS3*/
11995 	else
11996 		sta->lps_pg_rssi_lv = 1;	/*RSSI Lower - Lowest_rate*/
11997 #else
11998 	sta->lps_pg_rssi_lv = 0;
11999 #endif
12000 	RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
12001 		__func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
12002 }
12003 
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)12004 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
12005 {
12006 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12007 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12008 	struct sta_priv *pstapriv = &adapter->stapriv;
12009 	struct sta_info *sta;
12010 
12011 	sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
12012 
12013 	switch (hdl_id) {
12014 	case LPS_PG_INFO_CFG:
12015 		rtw_hal_set_lps_pg_info(adapter);
12016 		break;
12017 	case LPS_PG_REDLEMEM:
12018 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
12019 			break;
12020 
12021 		/*set xmit_block*/
12022 		rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
12023 		if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
12024 			rtw_warn_on(1);
12025 		/*clearn xmit_block*/
12026 		rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
12027 		break;
12028 	case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
12029 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
12030 			break;
12031 
12032 		if (sta)
12033 			rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
12034 		break;
12035 	case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
12036 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
12037 			break;
12038 
12039 		if (sta) {
12040 			rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
12041 			rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
12042 			sta->lps_pg_rssi_lv = 0;
12043 		}
12044 		break;
12045 
12046 	default:
12047 		break;
12048 	}
12049 }
12050 
12051 #endif /*CONFIG_LPS_PG*/
12052 
_rtw_mi_assoc_if_num(_adapter * adapter)12053 static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
12054 {
12055 	u8 mi_iface_num = 0;
12056 
12057 	if (0) {
12058 		RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
12059 		RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
12060 		RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
12061 		RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
12062 		RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
12063 		/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
12064 		/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
12065 	}
12066 
12067 	mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
12068 		DEV_AP_NUM(adapter_to_dvobj(adapter)) +
12069 		DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
12070 	return mi_iface_num;
12071 }
12072 #ifdef CONFIG_CONCURRENT_MODE
_rtw_search_sta_iface(_adapter * adapter)12073 static _adapter *_rtw_search_sta_iface(_adapter *adapter)
12074 {
12075 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12076 	_adapter *iface = NULL;
12077 	_adapter *sta_iface = NULL;
12078 	int i;
12079 
12080 	for (i = 0; i < dvobj->iface_nums; i++) {
12081 		iface = dvobj->padapters[i];
12082 		if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
12083 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
12084 				sta_iface = iface;
12085 				break;
12086 			}
12087 		}
12088 	}
12089 	return sta_iface;
12090 }
12091 #if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
_rtw_search_ap_iface(_adapter * adapter)12092 static _adapter *_rtw_search_ap_iface(_adapter *adapter)
12093 {
12094 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12095 	_adapter *iface = NULL;
12096 	_adapter *ap_iface = NULL;
12097 	int i;
12098 
12099 	for (i = 0; i < dvobj->iface_nums; i++) {
12100 		iface = dvobj->padapters[i];
12101 		if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
12102 			ap_iface = iface;
12103 			break;
12104 		}
12105 	}
12106 	return ap_iface;
12107 }
12108 #endif/*CONFIG_AP_MODE*/
12109 #endif/*CONFIG_CONCURRENT_MODE*/
12110 
12111 #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
rtw_hal_set_pathb_phase(_adapter * adapter,u8 phase_idx)12112 void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
12113 {
12114 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(adapter);
12115 	struct PHY_DM_STRUCT		*pDM_Odm = &pHalData->odmpriv;
12116 
12117 	return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
12118 }
12119 #endif
12120 
12121 /*
12122  * Description: Fill the reserved packets that FW will use to RSVD page.
12123  *			Now we just send 4 types packet to rsvd page.
12124  *			(1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
12125  * Input:
12126  * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
12127  *		    so we need to set the packet length to total lengh.
12128  *	      TRUE: At the second time, we should send the first packet (default:beacon)
12129  *		    to Hw again and set the lengh in descriptor to the real beacon lengh.
12130  * page_num - The amount of reserved page which driver need.
12131  *	      If this is not NULL, this function doesn't real download reserved
12132  *	      page, but just count the number of reserved page.
12133  *
12134  * 2009.10.15 by tynli.
12135  * 2017.06.20 modified by Lucas.
12136  *
12137  * Page Size = 128: 8188e, 8723a/b, 8192c/d,
12138  * Page Size = 256: 8192e, 8821a
12139  * Page Size = 512: 8812a
12140  */
12141 
12142 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)12143 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
12144 {
12145 	PHAL_DATA_TYPE pHalData;
12146 	struct xmit_frame	*pcmdframe = NULL;
12147 	struct pkt_attrib	*pattrib;
12148 	struct xmit_priv	*pxmitpriv;
12149 	struct pwrctrl_priv *pwrctl;
12150 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12151 	u32	BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
12152 	u32	NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
12153 	u32	ProbeReqLength = 0, NullFunctionDataLength = 0;
12154 	u8	TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
12155 	u8	TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
12156 	u8	*ReservedPagePacket;
12157 	u16	BufIndex = 0;
12158 	u32	TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
12159 	RSVDPAGE_LOC	RsvdPageLoc;
12160 	struct registry_priv  *registry_par = &adapter->registrypriv;
12161 
12162 #ifdef DBG_FW_DEBUG_MSG_PKT
12163 	u32	fw_dbg_msg_pkt_len = 0;
12164 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12165 
12166 #ifdef DBG_CONFIG_ERROR_DETECT
12167 	struct sreset_priv *psrtpriv;
12168 #endif /* DBG_CONFIG_ERROR_DETECT */
12169 
12170 #ifdef CONFIG_MCC_MODE
12171 	u8 dl_mcc_page = _FAIL;
12172 #endif /* CONFIG_MCC_MODE */
12173 	u8 nr_assoc_if;
12174 
12175 	_adapter *sta_iface = NULL;
12176 	_adapter *ap_iface = NULL;
12177 
12178 	bool is_wow_mode = _FALSE;
12179 
12180 	pHalData = GET_HAL_DATA(adapter);
12181 #ifdef DBG_CONFIG_ERROR_DETECT
12182 	psrtpriv = &pHalData->srestpriv;
12183 #endif
12184 	pxmitpriv = &adapter->xmitpriv;
12185 	pwrctl = adapter_to_pwrctl(adapter);
12186 
12187 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
12188 
12189 	if (PageSize == 0) {
12190 		RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
12191 		return;
12192 	}
12193 	nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
12194 
12195 	if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
12196 		pwrctl->wowlan_ap_mode == _TRUE ||
12197 		pwrctl->wowlan_p2p_mode == _TRUE)
12198 		is_wow_mode = _TRUE;
12199 
12200 	/*page_num for init time to get rsvd page number*/
12201 	/* Prepare ReservedPagePacket */
12202 	if (page_num) {
12203 		ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
12204 		if (!ReservedPagePacket) {
12205 			RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
12206 			*page_num = 0xFF;
12207 			return;
12208 		}
12209 		RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm  ==>\n",
12210 			FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
12211 
12212 	} else {
12213 		if (is_wow_mode)
12214 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
12215 		else
12216 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
12217 
12218 		RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
12219 			FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
12220 
12221 		MaxRsvdPageBufSize = RsvdPageNum * PageSize;
12222 		if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
12223 			RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
12224 				 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
12225 			rtw_warn_on(1);
12226 			return;
12227 		}
12228 
12229 		pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
12230 		if (pcmdframe == NULL) {
12231 			RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
12232 			return;
12233 		}
12234 
12235 		ReservedPagePacket = pcmdframe->buf_addr;
12236 	}
12237 
12238 	_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
12239 
12240 	BufIndex = TxDescOffset;
12241 
12242 	/*======== beacon content =======*/
12243 	rtw_hal_construct_beacon(adapter,
12244 				 &ReservedPagePacket[BufIndex], &BeaconLength);
12245 
12246 	/*
12247 	* When we count the first page size, we need to reserve description size for the RSVD
12248 	* packet, it will be filled in front of the packet in TXPKTBUF.
12249 	*/
12250 	BeaconLength = MAX_BEACON_LEN - TxDescLen;
12251 	CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
12252 
12253 #if defined(CONFIG_FW_HANDLE_TXBCN) || defined(CONFIG_PORT_BASED_TXBCN)
12254 	CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
12255 #endif
12256 	TotalPageNum += CurtPktPageNum;
12257 
12258 	BufIndex += (CurtPktPageNum * PageSize);
12259 
12260 	RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12261 
12262 	/*======== probe response content ========*/
12263 	if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
12264 		#ifdef CONFIG_CONCURRENT_MODE
12265 		if (nr_assoc_if >= 2)
12266 			RTW_ERR("Not support > 2 net-interface in WOW\n");
12267 		#endif
12268 		/* (4) probe response*/
12269 		RsvdPageLoc.LocProbeRsp = TotalPageNum;
12270 		rtw_hal_construct_ProbeRsp(
12271 			adapter, &ReservedPagePacket[BufIndex],
12272 			&ProbeRspLength,
12273 			_FALSE);
12274 		rtw_hal_fill_fake_txdesc(adapter,
12275 				 &ReservedPagePacket[BufIndex - TxDescLen],
12276 				 ProbeRspLength, _FALSE, _FALSE, _FALSE);
12277 
12278 		CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
12279 		TotalPageNum += CurtPktPageNum;
12280 		TotalPacketLen = BufIndex + ProbeRspLength;
12281 		BufIndex += (CurtPktPageNum * PageSize);
12282 		RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12283 		goto download_page;
12284 	}
12285 
12286 	/*======== ps-poll content * 1 page ========*/
12287 	sta_iface = adapter;
12288 	#ifdef CONFIG_CONCURRENT_MODE
12289 	if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
12290 		sta_iface = _rtw_search_sta_iface(adapter);
12291 		RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
12292 	}
12293 	#endif
12294 
12295 	if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12296 		RsvdPageLoc.LocPsPoll = TotalPageNum;
12297 		RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
12298 		rtw_hal_construct_PSPoll(sta_iface,
12299 					 &ReservedPagePacket[BufIndex], &PSPollLength);
12300 		rtw_hal_fill_fake_txdesc(sta_iface,
12301 					 &ReservedPagePacket[BufIndex - TxDescLen],
12302 					 PSPollLength, _TRUE, _FALSE, _FALSE);
12303 
12304 		CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
12305 
12306 		TotalPageNum += CurtPktPageNum;
12307 
12308 		BufIndex += (CurtPktPageNum * PageSize);
12309 		RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12310 	}
12311 
12312 #ifdef CONFIG_MCC_MODE
12313 	/*======== MCC * n page ======== */
12314 	if (MCC_EN(adapter)) {/*Normal mode*/
12315 		dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
12316 				&BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
12317 	} else {
12318 		dl_mcc_page = _FAIL;
12319 	}
12320 
12321 	if (dl_mcc_page == _FAIL)
12322 #endif /* CONFIG_MCC_MODE */
12323 	{	/*======== null data * 1 page ======== */
12324 		if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12325 			RsvdPageLoc.LocNullData = TotalPageNum;
12326 			RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
12327 			rtw_hal_construct_NullFunctionData(
12328 				sta_iface,
12329 				&ReservedPagePacket[BufIndex],
12330 				&NullDataLength,
12331 				_FALSE, 0, 0, _FALSE);
12332 			rtw_hal_fill_fake_txdesc(sta_iface,
12333 				 &ReservedPagePacket[BufIndex - TxDescLen],
12334 				 NullDataLength, _FALSE, _FALSE, _FALSE);
12335 
12336 			CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
12337 
12338 			TotalPageNum += CurtPktPageNum;
12339 
12340 			BufIndex += (CurtPktPageNum * PageSize);
12341 			RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12342 		}
12343 	}
12344 
12345 	/*======== Qos null data * 1 page ======== */
12346 	if (pwrctl->wowlan_mode == _FALSE ||
12347 		pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
12348 		if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12349 			RsvdPageLoc.LocQosNull = TotalPageNum;
12350 			RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
12351 			rtw_hal_construct_NullFunctionData(sta_iface,
12352 						&ReservedPagePacket[BufIndex],
12353 						&QosNullLength,
12354 						_TRUE, 0, 0, _FALSE);
12355 			rtw_hal_fill_fake_txdesc(sta_iface,
12356 					 &ReservedPagePacket[BufIndex - TxDescLen],
12357 					 QosNullLength, _FALSE, _FALSE, _FALSE);
12358 
12359 			CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
12360 						     PageSize);
12361 
12362 			TotalPageNum += CurtPktPageNum;
12363 
12364 			BufIndex += (CurtPktPageNum * PageSize);
12365 			RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12366 		}
12367 	}
12368 
12369 #ifdef CONFIG_BT_COEXIST
12370 	/*======== BT Qos null data * 1 page ======== */
12371 	if (pwrctl->wowlan_mode == _FALSE ||
12372 		pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
12373 
12374 		ap_iface = adapter;
12375 		#if defined (CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
12376 		if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) {	/*DEV_AP_STARTING_NUM*/
12377 			ap_iface = _rtw_search_ap_iface(adapter);
12378 			RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
12379 		}
12380 		#endif
12381 
12382 		if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
12383 			RsvdPageLoc.LocBTQosNull = TotalPageNum;
12384 
12385 			RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
12386 
12387 			rtw_hal_construct_NullFunctionData(ap_iface,
12388 						&ReservedPagePacket[BufIndex],
12389 						&BTQosNullLength,
12390 						_TRUE, 0, 0, _FALSE);
12391 
12392 			rtw_hal_fill_fake_txdesc(ap_iface,
12393 					&ReservedPagePacket[BufIndex - TxDescLen],
12394 					BTQosNullLength, _FALSE, _TRUE, _FALSE);
12395 
12396 			CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
12397 							 PageSize);
12398 
12399 			TotalPageNum += CurtPktPageNum;
12400 			BufIndex += (CurtPktPageNum * PageSize);
12401 
12402 			RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12403 		}
12404 	}
12405 #endif /* CONFIG_BT_COEXIT */
12406 
12407 	TotalPacketLen = BufIndex;
12408 
12409 #ifdef DBG_FW_DEBUG_MSG_PKT
12410 		/*======== FW DEBUG MSG * n page ======== */
12411 		RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
12412 		RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
12413 		rtw_hal_construct_fw_dbg_msg_pkt(
12414 			adapter,
12415 			&ReservedPagePacket[BufIndex],
12416 			&fw_dbg_msg_pkt_len);
12417 
12418 		rtw_hal_fill_fake_txdesc(adapter,
12419 				 &ReservedPagePacket[BufIndex - TxDescLen],
12420 				 fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
12421 
12422 		CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
12423 
12424 		if (CurtPktPageNum < 2)
12425 			CurtPktPageNum = 2; /*Need at least 2 rsvd page*/
12426 		TotalPageNum += CurtPktPageNum;
12427 
12428 		TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
12429 		BufIndex += (CurtPktPageNum * PageSize);
12430 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12431 
12432 #ifdef CONFIG_LPS_PG
12433 	rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
12434 		, TxDescLen, PageSize, &TotalPageNum, is_wow_mode
12435 		, (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL
12436 		, page_num ? 1 : 0
12437 	);
12438 	TotalPacketLen = BufIndex;
12439 #endif
12440 
12441 #ifdef CONFIG_WOWLAN
12442 	/*======== WOW * n page ======== */
12443 	if (pwrctl->wowlan_mode == _TRUE &&
12444 		pwrctl->wowlan_in_resume == _FALSE) {
12445 		rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
12446 					     BufIndex, TxDescLen, PageSize,
12447 			     &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
12448 #ifdef CONFIG_WAR_OFFLOAD
12449 		rtw_hal_set_war_offload_parm(adapter, &RsvdPageLoc);
12450 #endif /* CONFIG_WAR_OFFLOAD */
12451 	}
12452 #endif /* CONFIG_WOWLAN */
12453 
12454 #ifdef CONFIG_P2P_WOWLAN
12455 	/*======== P2P WOW * n page ======== */
12456 	if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
12457 		rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
12458 						 BufIndex, TxDescLen, PageSize,
12459 				 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
12460 	}
12461 #endif /* CONFIG_P2P_WOWLAN */
12462 
12463 	/*Note:  BufIndex already add a TxDescOffset offset in first Beacon page
12464 	* The "TotalPacketLen" is calculate by BufIndex.
12465 	* We need to decrease TxDescOffset before doing length check. by yiwei
12466 	*/
12467 	TotalPacketLen = TotalPacketLen - TxDescOffset;
12468 
12469 download_page:
12470 	if (page_num) {
12471 		*page_num = TotalPageNum;
12472 		rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
12473 		ReservedPagePacket = NULL;
12474 		RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
12475 			FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
12476 		return;
12477 	}
12478 
12479 	/* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
12480 	RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
12481 		 __func__, TotalPageNum, TotalPacketLen);
12482 
12483 	if (TotalPacketLen > MaxRsvdPageBufSize) {
12484 		RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
12485 			 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
12486 		rtw_warn_on(1);
12487 		goto error;
12488 	} else {
12489 		/* update attribute */
12490 		pattrib = &pcmdframe->attrib;
12491 		update_mgntframe_attrib(adapter, pattrib);
12492 		pattrib->qsel = QSLT_BEACON;
12493 		pattrib->pktlen = TotalPacketLen;
12494 		pattrib->last_txcmdsz = TotalPacketLen;
12495 #ifdef CONFIG_PCI_HCI
12496 		dump_mgntframe(adapter, pcmdframe);
12497 #else
12498 		dump_mgntframe_and_wait(adapter, pcmdframe, 100);
12499 #endif
12500 	}
12501 
12502 	RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
12503 		 __func__, TotalPacketLen, TotalPageNum);
12504 #ifdef DBG_DUMP_SET_RSVD_PAGE
12505 	RTW_INFO(" ==================================================\n");
12506 	RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
12507 	RTW_INFO(" ==================================================\n");
12508 #endif
12509 
12510 
12511 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
12512 		|| MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
12513 		rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
12514 #ifdef DBG_FW_DEBUG_MSG_PKT
12515 		rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
12516 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12517 #ifdef CONFIG_WOWLAN
12518 		if (pwrctl->wowlan_mode == _TRUE &&
12519 			pwrctl->wowlan_in_resume == _FALSE)
12520 			rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
12521 #endif /* CONFIG_WOWLAN */
12522 #ifdef CONFIG_AP_WOWLAN
12523 		if (pwrctl->wowlan_ap_mode == _TRUE)
12524 			rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
12525 #endif /* CONFIG_AP_WOWLAN */
12526 	} else if (pwrctl->wowlan_pno_enable) {
12527 #ifdef CONFIG_PNO_SUPPORT
12528 		rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
12529 		if (pwrctl->wowlan_in_resume)
12530 			rtw_hal_set_scan_offload_info_cmd(adapter,
12531 							  &RsvdPageLoc, 0);
12532 		else
12533 			rtw_hal_set_scan_offload_info_cmd(adapter,
12534 							  &RsvdPageLoc, 1);
12535 #endif /* CONFIG_PNO_SUPPORT */
12536 	}
12537 
12538 #ifdef CONFIG_P2P_WOWLAN
12539 	if (_TRUE == pwrctl->wowlan_p2p_mode)
12540 		rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
12541 #endif /* CONFIG_P2P_WOWLAN */
12542 
12543 	return;
12544 error:
12545 	rtw_free_xmitframe(pxmitpriv, pcmdframe);
12546 }
12547 
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)12548 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
12549 {
12550 #ifdef CONFIG_AP_MODE
12551 	if (finished)
12552 		rtw_mi_tx_beacon_hdl(adapter);
12553 	else
12554 #endif
12555 		_rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
12556 }
12557 
rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER * adapter,u8 enable)12558 static u8 rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER *adapter, u8 enable)
12559 {
12560 	u8	u1H2CSetPwrMode[H2C_PWRMODE_LEN] = {0};
12561 	u8	ret = _FAIL;
12562 
12563 #ifdef CONFIG_TDLS
12564 #ifdef CONFIG_TDLS_CH_SW
12565 	if (ATOMIC_READ(&adapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12566 	{
12567 		SET_H2CCMD_PWRMODE_PARM_RLBM(u1H2CSetPwrMode, 1);
12568 		SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, 0);
12569 	}
12570 #endif
12571 #endif
12572 
12573 	SET_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, 0);
12574 	SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CSetPwrMode, 0x0C);
12575 	SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_C2H_RPT(u1H2CSetPwrMode, enable);
12576 
12577 	ret = rtw_hal_fill_h2c_cmd(adapter,
12578 					H2C_SET_PWR_MODE,
12579 					H2C_PWRMODE_LEN,
12580 					u1H2CSetPwrMode);
12581 
12582 	RTW_PRINT("-%s()-\n", __func__);
12583 
12584 	return ret;
12585 }
12586 
12587 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_ap_bcn_imr_cmd(struct _ADAPTER * adapter,u8 enable)12588 u8 rtw_hal_set_ap_bcn_imr_cmd(struct _ADAPTER *adapter, u8 enable)
12589 {
12590 	u8 ap_port_id;
12591 	u8 ret = _FAIL;
12592 
12593 	if (!MLME_IS_AP(adapter))
12594 		goto exit;
12595 
12596 	ap_port_id = get_hw_port(adapter);
12597 	if (ap_port_id != HW_PORT0) {
12598 		RTW_WARN("AP mode should use port0\n");
12599 		goto exit;
12600 	}
12601 
12602 	ret = rtw_hal_fill_h2c_cmd(adapter,
12603 					H2C_SET_AP_BCN_IMR,
12604 					H2C_AP_BCN_MIR_LEN,
12605 					&enable);
12606 
12607 	RTW_INFO(FUNC_ADPT_FMT" : AP mode %s beacon early IMR\n",
12608 			FUNC_ADPT_ARG(adapter), enable ? "enable" : "disable");
12609 exit:
12610 	return ret;
12611 }
12612 #endif
12613 
12614 /**
12615  * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
12616  * @adapter:	struct _ADAPTER*
12617  *
12618  * Caculate needed reserved page number.
12619  * In different state would get different number, for example normal mode and
12620  * WOW mode would need different reserved page size.
12621  *
12622  * Return the number of reserved page which driver need.
12623  */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)12624 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
12625 {
12626 	u8 num = 0;
12627 
12628 
12629 	_rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
12630 
12631 	return num;
12632 }
12633 
12634 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
hw_var_set_bcn_func(_adapter * adapter,u8 enable)12635 static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
12636 {
12637 	u32 bcn_ctrl_reg;
12638 
12639 #ifdef CONFIG_CONCURRENT_MODE
12640 	if (adapter->hw_port == HW_PORT1)
12641 		bcn_ctrl_reg = REG_BCN_CTRL_1;
12642 	else
12643 #endif
12644 		bcn_ctrl_reg = REG_BCN_CTRL;
12645 
12646 	if (enable)
12647 		rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
12648 	else {
12649 		u8 val8;
12650 
12651 		val8 = rtw_read8(adapter, bcn_ctrl_reg);
12652 		val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
12653 
12654 #ifdef CONFIG_BT_COEXIST
12655 		if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
12656 			/* Always enable port0 beacon function for PSTDMA */
12657 			if (REG_BCN_CTRL == bcn_ctrl_reg)
12658 				val8 |= EN_BCN_FUNCTION;
12659 		}
12660 #endif
12661 
12662 		rtw_write8(adapter, bcn_ctrl_reg, val8);
12663 	}
12664 
12665 #ifdef CONFIG_RTL8192F
12666 	if (IS_HARDWARE_TYPE_8192F(adapter)) {
12667 		u16 val16, val16_ori;
12668 
12669 		val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
12670 
12671 		#ifdef CONFIG_CONCURRENT_MODE
12672 		if (adapter->hw_port == HW_PORT1) {
12673 			if (enable)
12674 				val16 |= EN_PORT_1_FUNCTION;
12675 			else
12676 				val16 &= ~EN_PORT_1_FUNCTION;
12677 		} else
12678 		#endif
12679 		{
12680 			if (enable)
12681 				val16 |= EN_PORT_0_FUNCTION;
12682 			else
12683 				val16 &= ~EN_PORT_0_FUNCTION;
12684 
12685 			#ifdef CONFIG_BT_COEXIST
12686 			if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
12687 				val16 |= EN_PORT_0_FUNCTION;
12688 			#endif
12689 		}
12690 
12691 		if (val16 != val16_ori)
12692 			rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1,  val16);
12693 	}
12694 #endif
12695 }
12696 #endif
12697 
12698 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
hw_var_set_mlme_disconnect(_adapter * adapter)12699 static void hw_var_set_mlme_disconnect(_adapter *adapter)
12700 {
12701 	u8 val8;
12702 
12703 	/* reject all data frames */
12704 #ifdef CONFIG_CONCURRENT_MODE
12705 	if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
12706 #endif
12707 		rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
12708 
12709 #ifdef CONFIG_CONCURRENT_MODE
12710 	if (adapter->hw_port == HW_PORT1) {
12711 		/* reset TSF1 */
12712 		rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
12713 
12714 		/* disable update TSF1 */
12715 		rtw_iface_disable_tsf_update(adapter);
12716 
12717 		if (!IS_HARDWARE_TYPE_8723D(adapter)
12718 			&& !IS_HARDWARE_TYPE_8192F(adapter)
12719 			&& !IS_HARDWARE_TYPE_8710B(adapter)
12720 		) {
12721 			/* disable Port1's beacon function */
12722 			val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
12723 			val8 &= ~EN_BCN_FUNCTION;
12724 			rtw_write8(adapter, REG_BCN_CTRL_1, val8);
12725 		}
12726 	} else
12727 #endif
12728 	{
12729 		/* reset TSF */
12730 		rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
12731 
12732 		/* disable update TSF */
12733 		rtw_iface_disable_tsf_update(adapter);
12734 	}
12735 }
12736 #endif
12737 
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 enable)12738 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
12739 {
12740 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12741 	u16 value_rxfltmap2;
12742 
12743 #ifdef DBG_IFACE_STATUS
12744 	DBG_IFACE_STATUS_DUMP(adapter);
12745 #endif
12746 
12747 #ifdef CONFIG_FIND_BEST_CHANNEL
12748 	/* Receive all data frames */
12749 	value_rxfltmap2 = 0xFFFF;
12750 #else
12751 	/* not to receive data frame */
12752 	value_rxfltmap2 = 0;
12753 #endif
12754 
12755 	if (enable) { /* under sitesurvey */
12756 		/*
12757 		* 1. configure REG_RXFLTMAP2
12758 		* 2. disable TSF update &  buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
12759 		* 3. config RCR to receive different BSSID BCN or probe rsp
12760 		*/
12761 		rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
12762 
12763 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
12764 
12765 		/* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
12766 		#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
12767 		hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
12768 		hal_data->RegRRSR &= 0x000FFFFF;
12769 		#endif
12770 
12771 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
12772 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
12773 			/* set 718[1:0]=2'b00 to avoid BF scan hang */
12774 			hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
12775 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
12776 		}
12777 		#endif
12778 
12779 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12780 			StopTxBeacon(adapter);
12781 	} else { /* sitesurvey done */
12782 		/*
12783 		* 1. enable rx data frame
12784 		* 2. config RCR not to receive different BSSID BCN or probe rsp
12785 		* 3. doesn't enable TSF update &  buddy TSF right now to avoid HW conflict
12786 		*	 so, we enable TSF update when rx first BCN after sitesurvey done
12787 		*/
12788 		if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) {
12789 			/* enable to rx data frame */
12790 			rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12791 		}
12792 
12793 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
12794 
12795 		/* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
12796 		#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
12797 			rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
12798 		#endif
12799 
12800 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
12801 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
12802 			/* Restore orignal 0x718 setting*/
12803 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
12804 		}
12805 		#endif
12806 
12807 		#ifdef CONFIG_AP_MODE
12808 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12809 			ResumeTxBeacon(adapter);
12810 			rtw_mi_tx_beacon_hdl(adapter);
12811 		}
12812 		#endif
12813 	}
12814 }
12815 
12816 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
hw_var_set_mlme_join(_adapter * adapter,u8 type)12817 static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
12818 {
12819 	u8 val8;
12820 	u16 val16;
12821 	u32 val32;
12822 	u8 RetryLimit = RL_VAL_STA;
12823 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12824 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12825 
12826 #ifdef CONFIG_CONCURRENT_MODE
12827 	if (type == 0) {
12828 		/* prepare to join */
12829 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12830 			StopTxBeacon(adapter);
12831 
12832 		/* enable to rx data frame.Accept all data frame */
12833 		rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12834 
12835 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
12836 			RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
12837 		else /* Ad-hoc Mode */
12838 			RetryLimit = RL_VAL_AP;
12839 
12840 		rtw_iface_enable_tsf_update(adapter);
12841 
12842 	} else if (type == 1) {
12843 		/* joinbss_event call back when join res < 0 */
12844 		if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
12845 			rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
12846 
12847 		rtw_iface_disable_tsf_update(adapter);
12848 
12849 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12850 			ResumeTxBeacon(adapter);
12851 
12852 			/* reset TSF 1/2 after ResumeTxBeacon */
12853 			rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
12854 		}
12855 
12856 	} else if (type == 2) {
12857 		/* sta add event call back */
12858 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
12859 			/* fixed beacon issue for 8191su........... */
12860 			rtw_write8(adapter, 0x542 , 0x02);
12861 			RetryLimit = RL_VAL_AP;
12862 		}
12863 
12864 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12865 			ResumeTxBeacon(adapter);
12866 
12867 			/* reset TSF 1/2 after ResumeTxBeacon */
12868 			rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
12869 		}
12870 	}
12871 
12872 	val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
12873 	rtw_write16(adapter, REG_RETRY_LIMIT, val16);
12874 #else /* !CONFIG_CONCURRENT_MODE */
12875 	if (type == 0) { /* prepare to join */
12876 		/* enable to rx data frame.Accept all data frame */
12877 		rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12878 
12879 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
12880 			RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
12881 		else /* Ad-hoc Mode */
12882 			RetryLimit = RL_VAL_AP;
12883 
12884 		rtw_iface_enable_tsf_update(adapter);
12885 
12886 	} else if (type == 1) { /* joinbss_event call back when join res < 0 */
12887 		rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
12888 
12889 		rtw_iface_disable_tsf_update(adapter);
12890 
12891 	} else if (type == 2) { /* sta add event call back */
12892 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
12893 			RetryLimit = RL_VAL_AP;
12894 	}
12895 
12896 	val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
12897 	rtw_write16(adapter, REG_RETRY_LIMIT, val16);
12898 #endif /* !CONFIG_CONCURRENT_MODE */
12899 }
12900 #endif
12901 
12902 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)12903 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
12904 {
12905 	u8 buf[2];
12906 	int ret;
12907 
12908 	if (reset_port == HW_PORT0) {
12909 		buf[0] = 0x1;
12910 		buf[1] = 0;
12911 	} else {
12912 		buf[0] = 0x0;
12913 		buf[1] = 0x1;
12914 	}
12915 
12916 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
12917 
12918 	return ret;
12919 }
12920 
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)12921 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
12922 {
12923 	u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
12924 	u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
12925 				REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
12926 	int ret;
12927 
12928 	/* site survey will cause reset tsf fail */
12929 	rtw_mi_buddy_scan_abort(adapter, _FALSE);
12930 	reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
12931 	ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
12932 	if (ret != _SUCCESS)
12933 		return ret;
12934 
12935 	while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
12936 		rtw_msleep_os(100);
12937 		loop_cnt++;
12938 		reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
12939 	}
12940 
12941 	return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
12942 }
12943 #endif /* CONFIG_TSF_RESET_OFFLOAD */
12944 
12945 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12946 #ifdef CONFIG_HW_P0_TSF_SYNC
12947 #ifdef CONFIG_CONCURRENT_MODE
hw_port0_tsf_sync_sel(_adapter * adapter,u8 benable,u8 hw_port,u16 tr_offset)12948 static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
12949 {
12950 	u8 val8;
12951 	u8 client_id = 0;
12952 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12953 
12954 #ifdef CONFIG_MCC_MODE
12955 	if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
12956 		RTW_INFO("[MCC] do not set HW TSF sync\n");
12957 		return;
12958 	}
12959 #endif
12960 	/* check if port0 is already synced */
12961 	if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
12962 		RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
12963 			FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
12964 		return;
12965 	}
12966 
12967 	/* check if port0 already disable sync */
12968 	if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
12969 		RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
12970 		return;
12971 	}
12972 
12973 	/* check if port0 sync to port0 */
12974 	if (benable && hw_port == HW_PORT0) {
12975 		RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
12976 		rtw_warn_on(1);
12977 		return;
12978 	}
12979 
12980 	/*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
12981 	/*	Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
12982 		Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
12983 
12984 	val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
12985 
12986 	if (benable) {
12987 		/*Disable Port0's beacon function*/
12988 		rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
12989 
12990 		/*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
12991 		if (tr_offset)
12992 			rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
12993 
12994 		/*reg 0x577[6]=1*/	/*auto sync by tbtt*/
12995 		rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
12996 
12997 		if (HW_PORT1 == hw_port)
12998 			client_id = 0;
12999 		else if (HW_PORT2 == hw_port)
13000 			client_id = 1;
13001 		else if (HW_PORT3 == hw_port)
13002 			client_id = 2;
13003 		else if (HW_PORT4 == hw_port)
13004 			client_id = 3;
13005 
13006 		val8 &= 0x8F;
13007 		val8 |= (BIT(6) | (client_id << 4));
13008 
13009 		dvobj->p0_tsf.sync_port = hw_port;
13010 		dvobj->p0_tsf.offset = tr_offset;
13011 		rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
13012 
13013 		/*Enable Port0's beacon function*/
13014 		rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)  | BIT_EN_BCN_FUNCTION);
13015 		RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
13016 	} else {
13017 		val8 &= ~BIT(6);
13018 
13019 		dvobj->p0_tsf.sync_port = MAX_HW_PORT;
13020 		dvobj->p0_tsf.offset = 0;
13021 		rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
13022 		RTW_INFO("%s P0 TSF sync disable\n", __func__);
13023 	}
13024 }
_search_ld_sta(_adapter * adapter,u8 include_self)13025 static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
13026 {
13027 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
13028 	u8 i;
13029 	_adapter *iface = NULL;
13030 
13031 	if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
13032 		RTW_ERR("STA_LD_NUM == 0\n");
13033 		rtw_warn_on(1);
13034 	}
13035 
13036 	for (i = 0; i < dvobj->iface_nums; i++) {
13037 		iface = dvobj->padapters[i];
13038 		if (!iface)
13039 			continue;
13040 		if (include_self == _FALSE && adapter == iface)
13041 			continue;
13042 		if (is_client_associated_to_ap(iface))
13043 			break;
13044 	}
13045 	if (iface)
13046 		RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
13047 	return iface;
13048 }
13049 #endif /*CONFIG_CONCURRENT_MODE*/
13050 /*Correct port0's TSF*/
13051 /*#define DBG_P0_TSF_SYNC*/
hw_var_set_correct_tsf(PADAPTER adapter,u8 mlme_state)13052 void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
13053 {
13054 #ifdef CONFIG_CONCURRENT_MODE
13055 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
13056 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13057 	_adapter *sta_if = NULL;
13058 	u8 hw_port;
13059 
13060 	RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
13061 	#ifdef DBG_P0_TSF_SYNC
13062 	RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
13063 	RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
13064 	RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
13065 	if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
13066 		RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
13067 	else
13068 		RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
13069 	RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
13070 	#endif
13071 	switch (mlme_state) {
13072 		case MLME_STA_CONNECTED :
13073 			{
13074 				hw_port = rtw_hal_get_port(adapter);
13075 
13076 				if (!MLME_IS_STA(adapter)) {
13077 					RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
13078 					rtw_warn_on(1);
13079 				}
13080 
13081 				if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
13082 					RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
13083 					rtw_warn_on(1);
13084 					hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
13085 				}
13086 
13087 				if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
13088 					(rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
13089 					hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
13090 					#ifdef DBG_P0_TSF_SYNC
13091 					RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
13092 					#endif
13093 				}
13094 			}
13095 			break;
13096 		case MLME_STA_DISCONNECTED :
13097 			{
13098 				hw_port = rtw_hal_get_port(adapter);
13099 
13100 				if (!MLME_IS_STA(adapter)) {
13101 					RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
13102 					rtw_warn_on(1);
13103 				}
13104 
13105 				if (dvobj->p0_tsf.sync_port == hw_port) {
13106 					if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
13107 						/* search next appropriate sta*/
13108 						sta_if = _search_ld_sta(adapter, _FALSE);
13109 						if (sta_if) {
13110 							hw_port = rtw_hal_get_port(sta_if);
13111 							hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
13112 							#ifdef DBG_P0_TSF_SYNC
13113 							RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
13114 							#endif
13115 						}
13116 					} else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
13117 						hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
13118 						#ifdef DBG_P0_TSF_SYNC
13119 						RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
13120 						#endif
13121 					}
13122 				}
13123 			}
13124 			break;
13125 #ifdef CONFIG_AP_MODE
13126 		case MLME_AP_STARTED :
13127 		case MLME_MESH_STARTED :
13128 			{
13129 				if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
13130 					RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
13131 					rtw_warn_on(1);
13132 				}
13133 
13134 				if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
13135 					rtw_mi_get_assoced_sta_num(adapter)) {
13136 					/* get port of sta */
13137 					sta_if = _search_ld_sta(adapter, _FALSE);
13138 					if (sta_if) {
13139 						hw_port = rtw_hal_get_port(sta_if);
13140 						hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
13141 						#ifdef DBG_P0_TSF_SYNC
13142 						RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
13143 						#endif
13144 					}
13145 				}
13146 			}
13147 			break;
13148 		case MLME_AP_STOPPED :
13149 		case MLME_MESH_STOPPED :
13150 			{
13151 				if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
13152 					RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
13153 					rtw_warn_on(1);
13154 				}
13155 				/*stop ap mode*/
13156 				if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
13157 					(dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
13158 					hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
13159 					#ifdef DBG_P0_TSF_SYNC
13160 					RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
13161 					#endif
13162 				}
13163 			}
13164 			break;
13165 #endif /* CONFIG_AP_MODE */
13166 		default :
13167 			RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
13168 			break;
13169 	}
13170 
13171 	/*#ifdef DBG_P0_TSF_SYNC*/
13172 	#if 1
13173 	if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
13174 		RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
13175 	else
13176 		RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
13177 	RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
13178 	#endif
13179 #endif /*CONFIG_CONCURRENT_MODE*/
13180 }
13181 
13182 #else /*! CONFIG_HW_P0_TSF_SYNC*/
13183 
13184 #ifdef CONFIG_MI_WITH_MBSSID_CAM
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)13185 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
13186 {
13187 	/*do nothing*/
13188 }
13189 #else /* !CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)13190 static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
13191 {
13192 	if (hw_port == HW_PORT0) {
13193 		/*disable related TSF function*/
13194 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
13195 #if defined(CONFIG_RTL8192F)
13196 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13197 					REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
13198 #endif
13199 
13200 		rtw_write32(padapter, REG_TSFTR, tsf);
13201 		rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
13202 
13203 		/*enable related TSF function*/
13204 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
13205 #if defined(CONFIG_RTL8192F)
13206 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13207 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
13208 #endif
13209 	} else if (hw_port == HW_PORT1) {
13210 		/*disable related TSF function*/
13211 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
13212 #if defined(CONFIG_RTL8192F)
13213 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13214 					REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
13215 #endif
13216 
13217 		rtw_write32(padapter, REG_TSFTR1, tsf);
13218 		rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
13219 
13220 		/*enable related TSF function*/
13221 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
13222 #if defined(CONFIG_RTL8192F)
13223 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13224 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
13225 #endif
13226 	} else
13227 		RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
13228 }
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)13229 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
13230 {
13231 	u64 tsf;
13232 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
13233 	struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
13234 
13235 	tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
13236 
13237 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
13238 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
13239 		StopTxBeacon(adapter);
13240 
13241 	rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
13242 
13243 #ifdef CONFIG_CONCURRENT_MODE
13244 	/* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
13245 	if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
13246 		&& (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
13247 	) {
13248 		struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
13249 		int i;
13250 		_adapter *iface;
13251 
13252 		for (i = 0; i < dvobj->iface_nums; i++) {
13253 			iface = dvobj->padapters[i];
13254 			if (!iface)
13255 				continue;
13256 			if (iface == adapter)
13257 				continue;
13258 
13259 			#ifdef CONFIG_AP_MODE
13260 			if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
13261 				&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
13262 			) {
13263 				rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
13264 				#ifdef CONFIG_TSF_RESET_OFFLOAD
13265 				if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
13266 					RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
13267 						, __func__, ADPT_ARG(iface), iface->hw_port);
13268 				#endif	/* CONFIG_TSF_RESET_OFFLOAD*/
13269 				#ifdef CONFIG_TSF_SYNC
13270 				if(iface->hw_port == HW_PORT0)
13271 					rtw_write8(iface, REG_DUAL_TSF_RST, rtw_read8(iface, REG_DUAL_TSF_RST) | BIT(2));
13272 				else if(iface->hw_port == HW_PORT1)
13273 					rtw_write8(iface, REG_DUAL_TSF_RST, rtw_read8(iface, REG_DUAL_TSF_RST) | BIT(3));
13274 				#endif
13275 			}
13276 			#endif /* CONFIG_AP_MODE */
13277 		}
13278 	}
13279 #endif /* CONFIG_CONCURRENT_MODE */
13280 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
13281 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
13282 		ResumeTxBeacon(adapter);
13283 }
13284 #endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
13285 #endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
13286 #endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
13287 
rtw_hal_get_tsftr_by_port(_adapter * adapter,u8 port)13288 u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
13289 {
13290 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
13291 	u64 tsftr = 0;
13292 
13293 	if (port >= hal_spec->port_num) {
13294 		RTW_ERR("%s invalid port(%d) \n", __func__, port);
13295 		goto exit;
13296 	}
13297 
13298 	switch (rtw_get_chip_type(adapter)) {
13299 #if defined(CONFIG_RTL8814B)
13300 	case RTL8814B:
13301 	{
13302 		u8 val8;
13303 
13304 		/* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
13305 		val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
13306 		val8 &= ~0x70;
13307 		val8 |= port << 4;
13308 		rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
13309 
13310 		tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
13311 		tsftr = tsftr << 32;
13312 		tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
13313 
13314 		break;
13315 	}
13316 #endif
13317 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
13318 	case RTL8814A:
13319 	case RTL8822B:
13320 	case RTL8821C:
13321 	case RTL8822C:
13322 	{
13323 		u8 val8;
13324 
13325 		/* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
13326 		val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
13327 		val8 &= 0x8F;
13328 		val8 |= port << 4;
13329 		rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
13330 
13331 		tsftr = rtw_read32(adapter, REG_TSFTR + 4);
13332 		tsftr = tsftr << 32;
13333 		tsftr |= rtw_read32(adapter, REG_TSFTR);
13334 
13335 		break;
13336 	}
13337 #endif
13338 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
13339 		|| defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
13340 		|| defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
13341 		|| defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
13342 		|| defined(CONFIG_RTL8710B)
13343 	case RTL8188E:
13344 	case RTL8188F:
13345 	case RTL8188GTV:
13346 	case RTL8192E:
13347 	case RTL8192F:
13348 	case RTL8723B:
13349 	case RTL8703B:
13350 	case RTL8723D:
13351 	case RTL8812:
13352 	case RTL8821:
13353 	case RTL8710B:
13354 	{
13355 		u32 addr;
13356 
13357 		if (port == HW_PORT0)
13358 			addr = REG_TSFTR;
13359 		else if (port == HW_PORT1)
13360 			addr = REG_TSFTR1;
13361 		else {
13362 			RTW_ERR("%s unknown port(%d) \n", __func__, port);
13363 			goto exit;
13364 		}
13365 
13366 		tsftr = rtw_read32(adapter, addr + 4);
13367 		tsftr = tsftr << 32;
13368 		tsftr |= rtw_read32(adapter, addr);
13369 
13370 		break;
13371 	}
13372 #endif
13373 	default:
13374 		RTW_ERR("%s unknow chip type\n", __func__);
13375 	}
13376 
13377 exit:
13378 	return tsftr;
13379 }
13380 
13381 #ifdef CONFIG_TDLS
13382 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)13383 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
13384 {
13385 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
13386 	u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
13387 
13388 
13389 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
13390 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
13391 	switch (bwmode) {
13392 	case CHANNEL_WIDTH_40:
13393 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
13394 		break;
13395 	case CHANNEL_WIDTH_80:
13396 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
13397 		break;
13398 	case CHANNEL_WIDTH_20:
13399 	default:
13400 		break;
13401 	}
13402 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
13403 
13404 	return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
13405 }
13406 #endif
13407 #endif
13408 
13409 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)13410 void rtw_hal_update_uapsd_tid(_adapter *adapter)
13411 {
13412 	struct mlme_priv		*pmlmepriv = &adapter->mlmepriv;
13413 	struct qos_priv		*pqospriv = &pmlmepriv->qospriv;
13414 
13415 	/* write complement of pqospriv->uapsd_tid to mac register 0x693 because
13416 	    it's designed  for "0" represents "enable" and "1" represents "disable" */
13417 	rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
13418 }
13419 #endif /* CONFIG_WMMPS_STA */
13420 
13421 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
13422 /* 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)13423 s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
13424 {
13425 	u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
13426 	u8 hw_port = rtw_hal_get_port(adapter);
13427 
13428 	SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
13429 	RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
13430 	return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
13431 }
13432 #endif
13433 
13434 #define LPS_ACTIVE_TIMEOUT	50 /*number of times*/
rtw_lps_state_chk(_adapter * adapter,u8 ps_mode)13435 void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
13436 {
13437 	struct pwrctrl_priv 		*pwrpriv = adapter_to_pwrctl(adapter);
13438 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
13439 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13440 	struct sta_priv		*pstapriv = &adapter->stapriv;
13441 	struct sta_info		*psta = NULL;
13442 	u8 ps_ready = _FALSE;
13443 	s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
13444 
13445 	if (ps_mode == PS_MODE_ACTIVE) {
13446 #ifdef CONFIG_LPS_ACK
13447 		if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
13448 			if (pwrpriv->lps_ack_status > 0) {
13449 				psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
13450 				if (psta != NULL) {
13451 					if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
13452 						RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
13453 				}
13454 			}
13455 		} else {
13456 			RTW_WARN("LPS sctx query timeout, operation abort!!\n");
13457 			return;
13458 		}
13459 		pwrpriv->lps_ack_status = -1;
13460 #else
13461 		do {
13462 			if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
13463 				ps_ready = _TRUE;
13464 				break;
13465 			}
13466 			rtw_msleep_os(1);
13467 		} while (leave_wait_count--);
13468 
13469 		if (ps_ready == _FALSE) {
13470 			RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
13471 			return;
13472 		}
13473 #endif /* CONFIG_LPS_ACK */
13474 		}
13475 	}
13476 
rtw_var_set_basic_rate(PADAPTER padapter,u8 * val)13477 void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
13478 
13479 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
13480 	struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
13481 	u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
13482 	u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
13483 	u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
13484 	#if CONFIG_IEEE80211_BAND_5GHZ
13485 	u16 rrsr_5g_force_mask = (RRSR_6M);
13486 	u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
13487 	#endif
13488 	u32 temp_RRSR;
13489 
13490 	HalSetBrateCfg(padapter, val, &BrateCfg);
13491 	input_b = BrateCfg;
13492 
13493 	/* apply force and allow mask */
13494 	#if CONFIG_IEEE80211_BAND_5GHZ
13495 	if (pHalData->current_band_type != BAND_ON_2_4G) {
13496 		BrateCfg |= rrsr_5g_force_mask;
13497 		BrateCfg &= rrsr_5g_allow_mask;
13498 	} else
13499 	#endif
13500 	{ /* 2.4G */
13501 		BrateCfg |= rrsr_2g_force_mask;
13502 		BrateCfg &= rrsr_2g_allow_mask;
13503 	}
13504 	masked = BrateCfg;
13505 
13506 #ifdef CONFIG_CMCC_TEST
13507 	BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
13508 	BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
13509 #endif
13510 
13511 	/* IOT consideration */
13512 	if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
13513 		/* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
13514 		if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
13515 			BrateCfg |= RRSR_6M;
13516 	}
13517 		ioted = BrateCfg;
13518 
13519 #ifdef CONFIG_NARROWBAND_SUPPORTING
13520 	if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
13521 		|| (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
13522 		BrateCfg &= ~RRSR_CCK_RATES;
13523 		BrateCfg |= RRSR_6M;
13524 	}
13525 #endif
13526 	pHalData->BasicRateSet = BrateCfg;
13527 
13528 	RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
13529 
13530 	/* Set RRSR rate table. */
13531 		temp_RRSR = rtw_read32(padapter, REG_RRSR);
13532 		temp_RRSR &=0xFFFF0000;
13533 		temp_RRSR |=BrateCfg;
13534 		rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
13535 
13536 	rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
13537 
13538 	#if defined(CONFIG_RTL8188E)
13539 	rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
13540 	#endif
13541 }
13542 
SetHwReg(_adapter * adapter,u8 variable,u8 * val)13543 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
13544 {
13545 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13546 	u8 ret = _SUCCESS;
13547 
13548 	switch (variable) {
13549 	case HW_VAR_MEDIA_STATUS: {
13550 		u8 net_type = *((u8 *)val);
13551 
13552 		rtw_hal_set_msr(adapter, net_type);
13553 	}
13554 	break;
13555 	case HW_VAR_DO_IQK:
13556 		if (*val)
13557 			hal_data->bNeedIQK = _TRUE;
13558 		else
13559 			hal_data->bNeedIQK = _FALSE;
13560 		break;
13561 	case HW_VAR_MAC_ADDR:
13562 #ifdef CONFIG_MI_WITH_MBSSID_CAM
13563 		rtw_hal_set_macaddr_mbid(adapter, val);
13564 #else
13565 		rtw_hal_set_macaddr_port(adapter, val);
13566 #endif
13567 		break;
13568 	case HW_VAR_BSSID:
13569 		rtw_hal_set_bssid(adapter, val);
13570 		break;
13571 	case HW_VAR_RCR:
13572 		ret = hw_var_rcr_config(adapter, *((u32 *)val));
13573 		break;
13574 	case HW_VAR_ON_RCR_AM:
13575 		hw_var_set_rcr_am(adapter, 1);
13576 		break;
13577 	case HW_VAR_OFF_RCR_AM:
13578 		hw_var_set_rcr_am(adapter, 0);
13579 		break;
13580 	case HW_VAR_BEACON_INTERVAL:
13581 		hw_var_set_bcn_interval(adapter, *(u16 *)val);
13582 		break;
13583 #ifdef CONFIG_MBSSID_CAM
13584 	case HW_VAR_MBSSID_CAM_WRITE: {
13585 		u32	cmd = 0;
13586 		u32	*cam_val = (u32 *)val;
13587 
13588 		rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
13589 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
13590 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
13591 	}
13592 		break;
13593 	case HW_VAR_MBSSID_CAM_CLEAR: {
13594 		u32 cmd;
13595 		u8 entry_id = *(u8 *)val;
13596 
13597 		rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
13598 
13599 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
13600 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
13601 	}
13602 		break;
13603 	case HW_VAR_RCR_MBSSID_EN:
13604 		if (*((u8 *)val))
13605 			rtw_hal_rcr_add(adapter, RCR_ENMBID);
13606 		else
13607 			rtw_hal_rcr_clear(adapter, RCR_ENMBID);
13608 		break;
13609 #endif
13610 	case HW_VAR_PORT_SWITCH:
13611 		hw_var_port_switch(adapter);
13612 		break;
13613 	case HW_VAR_INIT_RTS_RATE: {
13614 		u16 brate_cfg = *((u16 *)val);
13615 		u8 rate_index = 0;
13616 		HAL_VERSION *hal_ver = &hal_data->version_id;
13617 
13618 		if (IS_8188E(*hal_ver)) {
13619 
13620 			while (brate_cfg > 0x1) {
13621 				brate_cfg = (brate_cfg >> 1);
13622 				rate_index++;
13623 			}
13624 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
13625 		} else
13626 			rtw_warn_on(1);
13627 	}
13628 		break;
13629 	case HW_VAR_SEC_CFG: {
13630 		u16 reg_scr_ori;
13631 		u16 reg_scr;
13632 
13633 		reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
13634 		reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
13635 
13636 		if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
13637 			reg_scr |= SCR_CHK_BMC;
13638 
13639 		if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
13640 			reg_scr |= SCR_NoSKMC;
13641 
13642 		if (reg_scr != reg_scr_ori)
13643 			rtw_write16(adapter, REG_SECCFG, reg_scr);
13644 	}
13645 		break;
13646 	case HW_VAR_SEC_DK_CFG: {
13647 		struct security_priv *sec = &adapter->securitypriv;
13648 		u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
13649 
13650 		if (val) { /* Enable default key related setting */
13651 			reg_scr |= SCR_TXBCUSEDK;
13652 			if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
13653 				reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
13654 		} else /* Disable default key related setting */
13655 			reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
13656 
13657 		rtw_write8(adapter, REG_SECCFG, reg_scr);
13658 	}
13659 		break;
13660 
13661 	case HW_VAR_ASIX_IOT:
13662 		/* enable  ASIX IOT function */
13663 		if (*((u8 *)val) == _TRUE) {
13664 			/* 0xa2e[0]=0 (disable rake receiver) */
13665 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
13666 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
13667 			/* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
13668 			rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
13669 		} else {
13670 			/* restore reg:0xa2e,   reg:0xa1c */
13671 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
13672 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
13673 			rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
13674 		}
13675 		break;
13676 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
13677 	case HW_VAR_WOWLAN: {
13678 		struct wowlan_ioctl_param *poidparam;
13679 
13680 		poidparam = (struct wowlan_ioctl_param *)val;
13681 		switch (poidparam->subcode) {
13682 #ifdef CONFIG_WOWLAN
13683 		case WOWLAN_PATTERN_CLEAN:
13684 			rtw_hal_dl_pattern(adapter, 2);
13685 			break;
13686 		case WOWLAN_ENABLE:
13687 			rtw_hal_wow_enable(adapter);
13688 			break;
13689 		case WOWLAN_DISABLE:
13690 			rtw_hal_wow_disable(adapter);
13691 			break;
13692 #endif /*CONFIG_WOWLAN*/
13693 #ifdef CONFIG_AP_WOWLAN
13694 		case WOWLAN_AP_ENABLE:
13695 			rtw_hal_ap_wow_enable(adapter);
13696 			break;
13697 		case WOWLAN_AP_DISABLE:
13698 			rtw_hal_ap_wow_disable(adapter);
13699 			break;
13700 #endif /*CONFIG_AP_WOWLAN*/
13701 		default:
13702 			break;
13703 		}
13704 	}
13705 		break;
13706 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
13707 
13708 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
13709 	case HW_VAR_BCN_FUNC:
13710 		hw_var_set_bcn_func(adapter, *val);
13711 		break;
13712 #endif
13713 
13714 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
13715 	case HW_VAR_MLME_DISCONNECT:
13716 		hw_var_set_mlme_disconnect(adapter);
13717 		break;
13718 #endif
13719 
13720 	case HW_VAR_MLME_SITESURVEY:
13721 		hw_var_set_mlme_sitesurvey(adapter, *val);
13722 		#ifdef CONFIG_BT_COEXIST
13723 		if (hal_data->EEPROMBluetoothCoexist == 1)
13724 			rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
13725 		#endif
13726 		break;
13727 
13728 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
13729 	case HW_VAR_MLME_JOIN:
13730 		hw_var_set_mlme_join(adapter, *val);
13731 		break;
13732 #endif
13733 
13734 	case HW_VAR_EN_HW_UPDATE_TSF:
13735 		rtw_hal_set_hw_update_tsf(adapter);
13736 		break;
13737 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
13738 	case HW_VAR_CORRECT_TSF:
13739 		hw_var_set_correct_tsf(adapter, *val);
13740 		break;
13741 #endif
13742 
13743 #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
13744 	case HW_VAR_TSF_AUTO_SYNC:
13745 		if (*val == _TRUE)
13746 			hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
13747 		else
13748 			hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
13749 		break;
13750 #endif
13751 	case HW_VAR_APFM_ON_MAC:
13752 		hal_data->bMacPwrCtrlOn = *val;
13753 		RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
13754 		break;
13755 #ifdef CONFIG_WMMPS_STA
13756 	case  HW_VAR_UAPSD_TID:
13757 		rtw_hal_update_uapsd_tid(adapter);
13758 		break;
13759 #endif /* CONFIG_WMMPS_STA */
13760 #ifdef CONFIG_LPS_PG
13761 	case HW_VAR_LPS_PG_HANDLE:
13762 		rtw_hal_lps_pg_handler(adapter, *val);
13763 		break;
13764 #endif
13765 #ifdef CONFIG_LPS_LCLK_WD_TIMER
13766 	case HW_VAR_DM_IN_LPS_LCLK:
13767 		rtw_phydm_wd_lps_lclk_hdl(adapter);
13768 		break;
13769 #endif
13770 	case HW_VAR_ENABLE_RX_BAR:
13771 		if (*val == _TRUE) {
13772 			/* enable RX BAR */
13773 			u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
13774 
13775 			val16 |= BIT(8);
13776 			rtw_write16(adapter, REG_RXFLTMAP1, val16);
13777 		} else {
13778 			/* disable RX BAR */
13779 			u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
13780 
13781 			val16 &= (~BIT(8));
13782 			rtw_write16(adapter, REG_RXFLTMAP1, val16);
13783 		}
13784 		RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
13785 			REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
13786 		break;
13787 	case HW_VAR_HCI_SUS_STATE:
13788 		hal_data->hci_sus_state = *(u8 *)val;
13789 		RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
13790 		break;
13791 #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
13792 		case HW_VAR_BCN_HEAD_SEL:
13793 		{
13794 			u8 vap_id = *(u8 *)val;
13795 
13796 			if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
13797 				RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
13798 				rtw_warn_on(1);
13799 			}
13800 			if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
13801 				u16 drv_pg_bndy = 0, bcn_addr = 0;
13802 				u32 page_size = 0;
13803 
13804 				/*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
13805 				rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
13806 				rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
13807 
13808 				if (vap_id != 0xFF)
13809 					bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
13810 				else
13811 					bcn_addr = drv_pg_bndy;
13812 				RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
13813 					ADPT_ARG(adapter), vap_id, bcn_addr);
13814 				rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
13815 					(bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
13816 			}
13817 		}
13818 		break;
13819 #endif
13820 	case HW_VAR_LPS_STATE_CHK :
13821 		rtw_lps_state_chk(adapter, *(u8 *)val);
13822 		break;
13823 
13824 #ifdef CONFIG_RTS_FULL_BW
13825 	case HW_VAR_SET_RTS_BW:
13826 	{
13827 		#ifdef RTW_HALMAC
13828 			rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
13829 		#else
13830 			u8 temp;
13831 			if(*val)
13832 				temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
13833 			else
13834 				temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
13835 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
13836 			/*RTW_INFO("HW_VAR_SET_RTS_BW	val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
13837 		#endif
13838 	}
13839 	break;
13840 #endif/*CONFIG_RTS_FULL_BW*/
13841 #if defined(CONFIG_PCI_HCI)
13842 	case HW_VAR_ENSWBCN:
13843 	if (*val == _TRUE) {
13844 		rtw_write8(adapter, REG_CR + 1,
13845 			   rtw_read8(adapter, REG_CR + 1) | BIT(0));
13846 	} else
13847 		rtw_write8(adapter, REG_CR + 1,
13848 			   rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
13849 	break;
13850 #endif
13851 	case HW_VAR_BCN_EARLY_C2H_RPT:
13852 		rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(adapter, *(u8 *)val);
13853 		break;
13854 	default:
13855 		if (0)
13856 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
13857 				  FUNC_ADPT_ARG(adapter), variable);
13858 		ret = _FAIL;
13859 		break;
13860 	}
13861 
13862 	return ret;
13863 }
13864 
GetHwReg(_adapter * adapter,u8 variable,u8 * val)13865 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
13866 {
13867 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13868 	u64 val64;
13869 
13870 
13871 	switch (variable) {
13872 	case HW_VAR_MAC_ADDR:
13873 		#ifndef CONFIG_MI_WITH_MBSSID_CAM
13874 		rtw_hal_get_macaddr_port(adapter, val);
13875 		#endif
13876 		break;
13877 	case HW_VAR_BASIC_RATE:
13878 		*((u16 *)val) = hal_data->BasicRateSet;
13879 		break;
13880 	case HW_VAR_MEDIA_STATUS:
13881 		rtw_hal_get_msr(adapter, val);
13882 		break;
13883 	case HW_VAR_DO_IQK:
13884 		*val = hal_data->bNeedIQK;
13885 		break;
13886 	case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
13887 		if (hal_is_band_support(adapter, BAND_ON_5G))
13888 			*val = _TRUE;
13889 		else
13890 			*val = _FALSE;
13891 		break;
13892 	case HW_VAR_APFM_ON_MAC:
13893 		*val = hal_data->bMacPwrCtrlOn;
13894 		break;
13895 	case HW_VAR_RCR:
13896 		hw_var_rcr_get(adapter, (u32 *)val);
13897 		break;
13898 	case HW_VAR_FWLPS_RF_ON:
13899 		/* When we halt NIC, we should check if FW LPS is leave. */
13900 		if (rtw_is_surprise_removed(adapter)
13901 			|| (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
13902 		) {
13903 			/*
13904 			 * If it is in HW/SW Radio OFF or IPS state,
13905 			 * we do not check Fw LPS Leave,
13906 			 * because Fw is unload.
13907 			 */
13908 			*val = _TRUE;
13909 		} else {
13910 			u32 rcr = 0;
13911 
13912 			rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
13913 			if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
13914 				*val = _FALSE;
13915 			else
13916 				*val = _TRUE;
13917 		}
13918 		break;
13919 
13920 	case HW_VAR_HCI_SUS_STATE:
13921 		*((u8 *)val) = hal_data->hci_sus_state;
13922 		break;
13923 
13924 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
13925 	case HW_VAR_BCN_CTRL_ADDR:
13926 		*((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
13927 		break;
13928 #endif
13929 
13930 #ifdef CONFIG_WAPI_SUPPORT
13931 	case HW_VAR_CAM_EMPTY_ENTRY: {
13932 		u8	ucIndex = *((u8 *)val);
13933 		u8	i;
13934 		u32	ulCommand = 0;
13935 		u32	ulContent = 0;
13936 		u32	ulEncAlgo = CAM_AES;
13937 
13938 		for (i = 0; i < CAM_CONTENT_COUNT; i++) {
13939 			/* filled id in CAM config 2 byte */
13940 			if (i == 0)
13941 				ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
13942 			else
13943 				ulContent = 0;
13944 			/* polling bit, and No Write enable, and address */
13945 			ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
13946 			ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
13947 			/* write content 0 is equall to mark invalid */
13948 			rtw_write32(adapter, REG_CAMWRITE, ulContent);  /* delay_ms(40); */
13949 			rtw_write32(adapter, REG_CAMCMD, ulCommand);  /* delay_ms(40); */
13950 		}
13951 	}
13952 #endif
13953 
13954 	default:
13955 		if (0)
13956 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
13957 				  FUNC_ADPT_ARG(adapter), variable);
13958 		break;
13959 	}
13960 
13961 }
13962 
_get_page_size(struct _ADAPTER * a)13963 static u32 _get_page_size(struct _ADAPTER *a)
13964 {
13965 #ifdef RTW_HALMAC
13966 	struct dvobj_priv *d;
13967 	u32 size = 0;
13968 	int err = 0;
13969 
13970 
13971 	d = adapter_to_dvobj(a);
13972 
13973 	err = rtw_halmac_get_page_size(d, &size);
13974 	if (!err)
13975 		return size;
13976 
13977 	RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
13978 		 FUNC_ADPT_ARG(a), err);
13979 #endif /* RTW_HALMAC */
13980 
13981 	return PAGE_SIZE_128;
13982 }
13983 
13984 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13985 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13986 {
13987 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13988 	u8 bResult = _SUCCESS;
13989 
13990 	switch (variable) {
13991 
13992 	case HAL_DEF_DBG_DUMP_RXPKT:
13993 		hal_data->bDumpRxPkt = *((u8 *)value);
13994 		break;
13995 	case HAL_DEF_DBG_DUMP_TXPKT:
13996 		hal_data->bDumpTxPkt = *((u8 *)value);
13997 		break;
13998 	case HAL_DEF_ANT_DETECT:
13999 		hal_data->AntDetection = *((u8 *)value);
14000 		break;
14001 	default:
14002 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
14003 		bResult = _FAIL;
14004 		break;
14005 	}
14006 
14007 	return bResult;
14008 }
14009 
14010 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)14011 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
14012 {
14013 	struct registry_priv	*pregistrypriv = &adapter->registrypriv;
14014 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
14015 
14016 	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)))
14017 		return pregistrypriv->beamformer_rf_num;
14018 	else if (IS_HARDWARE_TYPE_8814AE(adapter)
14019 #if 0
14020 #if defined(CONFIG_USB_HCI)
14021 		|| (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2))  /* for USB3.0 */
14022 #endif
14023 #endif
14024 		) {
14025 		/*BF cap provided by Yu Chen, Sean, 2015, 01 */
14026 		if (hal_data->rf_type == RF_3T3R)
14027 			return 2;
14028 		else if (hal_data->rf_type == RF_4T4R)
14029 			return 3;
14030 		else
14031 			return 1;
14032 	} else
14033 		return 1;
14034 
14035 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)14036 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
14037 {
14038 	struct registry_priv		*pregistrypriv = &adapter->registrypriv;
14039 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
14040 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14041 
14042 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
14043 
14044 	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)))
14045 		return pregistrypriv->beamformee_rf_num;
14046 	else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
14047 		if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
14048 			return 2;
14049 		else
14050 			return 2;/*TODO: May be 3 in the future, by ChenYu. */
14051 	} else
14052 		return 1;
14053 
14054 }
14055 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_hal_beamforming_config_csirate(PADAPTER adapter)14056 void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
14057 {
14058 	struct dm_struct *p_dm_odm;
14059 	struct beamforming_info *bf_info;
14060 	u8 fix_rate_enable = 0;
14061 	u8 new_csi_rate_idx;
14062 	u8 rrsr_54_en;
14063 	u32 temp_rrsr;
14064 
14065 	/* Acting as BFee */
14066 	if (IS_BEAMFORMEE(adapter)) {
14067 	#if 0
14068 		/* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
14069 		if (IS_HARDWARE_TYPE_8821C(Adapter))
14070 			FixRateEnable = 1;	/* Support after 8821C */
14071 	#endif
14072 
14073 		p_dm_odm = adapter_to_phydm(adapter);
14074 		bf_info = GET_BEAMFORM_INFO(adapter);
14075 
14076 		rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
14077 				p_dm_odm->rssi_min,
14078 				bf_info->cur_csi_rpt_rate,
14079 				fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
14080 
14081 		temp_rrsr = rtw_read32(adapter, REG_RRSR);
14082 		if (rrsr_54_en == 1)
14083 			temp_rrsr |= RRSR_54M;
14084 		else if (rrsr_54_en == 0)
14085 			temp_rrsr &= ~RRSR_54M;
14086 		rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
14087 
14088 		if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
14089 			bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
14090 	}
14091 }
14092 #endif
14093 #endif
14094 
14095 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)14096 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
14097 {
14098 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
14099 	u8 bResult = _SUCCESS;
14100 
14101 	switch (variable) {
14102 	case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
14103 		struct mlme_priv *pmlmepriv;
14104 		struct sta_priv *pstapriv;
14105 		struct sta_info *psta;
14106 
14107 		pmlmepriv = &adapter->mlmepriv;
14108 		pstapriv = &adapter->stapriv;
14109 		psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
14110 		if (psta)
14111 			*((int *)value) = psta->cmn.rssi_stat.rssi;
14112 	}
14113 	break;
14114 	case HAL_DEF_DBG_DUMP_RXPKT:
14115 		*((u8 *)value) = hal_data->bDumpRxPkt;
14116 		break;
14117 	case HAL_DEF_DBG_DUMP_TXPKT:
14118 		*((u8 *)value) = hal_data->bDumpTxPkt;
14119 		break;
14120 	case HAL_DEF_ANT_DETECT:
14121 		*((u8 *)value) = hal_data->AntDetection;
14122 		break;
14123 	case HAL_DEF_TX_PAGE_SIZE:
14124 		*((u32 *)value) = _get_page_size(adapter);
14125 		break;
14126 	case HAL_DEF_TX_STBC:
14127 		#ifdef CONFIG_ALPHA_SMART_ANTENNA
14128 		*(u8 *)value = 0;
14129 		#else
14130 		*(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
14131 		#endif
14132 		break;
14133 	case HAL_DEF_EXPLICIT_BEAMFORMER:
14134 	case HAL_DEF_EXPLICIT_BEAMFORMEE:
14135 	case HAL_DEF_VHT_MU_BEAMFORMER:
14136 	case HAL_DEF_VHT_MU_BEAMFORMEE:
14137 		*(u8 *)value = _FALSE;
14138 		break;
14139 #ifdef CONFIG_BEAMFORMING
14140 	case HAL_DEF_BEAMFORMER_CAP:
14141 		*(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
14142 		break;
14143 	case HAL_DEF_BEAMFORMEE_CAP:
14144 		*(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
14145 		break;
14146 #endif
14147 	default:
14148 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
14149 		bResult = _FAIL;
14150 		break;
14151 	}
14152 
14153 	return bResult;
14154 }
14155 
14156 /*
14157  *	Description:
14158  *		Translate a character to hex digit.
14159  *   */
14160 u32
MapCharToHexDigit(char chTmp)14161 MapCharToHexDigit(
14162 			char		chTmp
14163 )
14164 {
14165 	if (chTmp >= '0' && chTmp <= '9')
14166 		return chTmp - '0';
14167 	else if (chTmp >= 'a' && chTmp <= 'f')
14168 		return 10 + (chTmp - 'a');
14169 	else if (chTmp >= 'A' && chTmp <= 'F')
14170 		return 10 + (chTmp - 'A');
14171 	else
14172 		return 0;
14173 }
14174 
14175 
14176 
14177 /*
14178  *	Description:
14179  *		Parse hex number from the string pucStr.
14180  *   */
14181 BOOLEAN
GetHexValueFromString(char * szStr,u32 * pu4bVal,u32 * pu4bMove)14182 GetHexValueFromString(
14183 		char			*szStr,
14184 		u32			*pu4bVal,
14185 		u32			*pu4bMove
14186 )
14187 {
14188 	char		*szScan = szStr;
14189 
14190 	/* Check input parameter. */
14191 	if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
14192 		RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
14193 		return _FALSE;
14194 	}
14195 
14196 	/* Initialize output. */
14197 	*pu4bMove = 0;
14198 	*pu4bVal = 0;
14199 
14200 	/* Skip leading space. */
14201 	while (*szScan != '\0' &&
14202 	       (*szScan == ' ' || *szScan == '\t')) {
14203 		szScan++;
14204 		(*pu4bMove)++;
14205 	}
14206 
14207 	/* Skip leading '0x' or '0X'. */
14208 	if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
14209 		szScan += 2;
14210 		(*pu4bMove) += 2;
14211 	}
14212 
14213 	/* Check if szScan is now pointer to a character for hex digit, */
14214 	/* if not, it means this is not a valid hex number. */
14215 	if (!IsHexDigit(*szScan))
14216 		return _FALSE;
14217 
14218 	/* Parse each digit. */
14219 	do {
14220 		(*pu4bVal) <<= 4;
14221 		*pu4bVal += MapCharToHexDigit(*szScan);
14222 
14223 		szScan++;
14224 		(*pu4bMove)++;
14225 	} while (IsHexDigit(*szScan));
14226 
14227 	return _TRUE;
14228 }
14229 
14230 BOOLEAN
GetFractionValueFromString(char * szStr,u8 * pInteger,u8 * pFraction,u32 * pu4bMove)14231 GetFractionValueFromString(
14232 		char			*szStr,
14233 		u8				*pInteger,
14234 		u8				*pFraction,
14235 		u32			*pu4bMove
14236 )
14237 {
14238 	char	*szScan = szStr;
14239 
14240 	/* Initialize output. */
14241 	*pu4bMove = 0;
14242 	*pInteger = 0;
14243 	*pFraction = 0;
14244 
14245 	/* Skip leading space. */
14246 	while (*szScan != '\0' &&	(*szScan == ' ' || *szScan == '\t')) {
14247 		++szScan;
14248 		++(*pu4bMove);
14249 	}
14250 
14251 	if (*szScan < '0' || *szScan > '9')
14252 		return _FALSE;
14253 
14254 	/* Parse each digit. */
14255 	do {
14256 		(*pInteger) *= 10;
14257 		*pInteger += (*szScan - '0');
14258 
14259 		++szScan;
14260 		++(*pu4bMove);
14261 
14262 		if (*szScan == '.') {
14263 			++szScan;
14264 			++(*pu4bMove);
14265 
14266 			if (*szScan < '0' || *szScan > '9')
14267 				return _FALSE;
14268 
14269 			*pFraction += (*szScan - '0') * 10;
14270 			++szScan;
14271 			++(*pu4bMove);
14272 
14273 			if (*szScan >= '0' && *szScan <= '9') {
14274 				*pFraction += *szScan - '0';
14275 				++szScan;
14276 				++(*pu4bMove);
14277 			}
14278 			return _TRUE;
14279 		}
14280 	} while (*szScan >= '0' && *szScan <= '9');
14281 
14282 	return _TRUE;
14283 }
14284 
14285 /*
14286  *	Description:
14287  * Return TRUE if szStr is comment out with leading " */ /* ".
14288  *   */
14289 BOOLEAN
IsCommentString(char * szStr)14290 IsCommentString(
14291 		char			*szStr
14292 )
14293 {
14294 	if (*szStr == '/' && *(szStr + 1) == '/')
14295 		return _TRUE;
14296 	else
14297 		return _FALSE;
14298 }
14299 
14300 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)14301 GetU1ByteIntegerFromStringInDecimal(
14302 		char	*Str,
14303 		u8		*pInt
14304 )
14305 {
14306 	u16 i = 0;
14307 	*pInt = 0;
14308 
14309 	while (Str[i] != '\0') {
14310 		if (Str[i] >= '0' && Str[i] <= '9') {
14311 			*pInt *= 10;
14312 			*pInt += (Str[i] - '0');
14313 		} else
14314 			return _FALSE;
14315 		++i;
14316 	}
14317 
14318 	return _TRUE;
14319 }
14320 
14321 /* <20121004, Kordan> For example,
14322  * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
14323  * If RightQualifier does not exist, it will hang on in the while loop */
14324 BOOLEAN
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)14325 ParseQualifiedString(
14326 			char	*In,
14327 			u32	*Start,
14328 			char	*Out,
14329 			char		LeftQualifier,
14330 			char		RightQualifier
14331 )
14332 {
14333 	u32	i = 0, j = 0;
14334 	char	c = In[(*Start)++];
14335 
14336 	if (c != LeftQualifier)
14337 		return _FALSE;
14338 
14339 	i = (*Start);
14340 	c = In[(*Start)++];
14341 	while (c != RightQualifier && c != '\0')
14342 		c = In[(*Start)++];
14343 
14344 	if (c == '\0')
14345 		return _FALSE;
14346 
14347 	j = (*Start) - 2;
14348 	strncpy((char *)Out, (const char *)(In + i), j - i + 1);
14349 
14350 	return _TRUE;
14351 }
14352 
14353 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)14354 isAllSpaceOrTab(
14355 	u8	*data,
14356 	u8	size
14357 )
14358 {
14359 	u8	cnt = 0, NumOfSpaceAndTab = 0;
14360 
14361 	while (size > cnt) {
14362 		if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
14363 			++NumOfSpaceAndTab;
14364 
14365 		++cnt;
14366 	}
14367 
14368 	return size == NumOfSpaceAndTab;
14369 }
14370 
14371 
rtw_hal_check_rxfifo_full(_adapter * adapter)14372 void rtw_hal_check_rxfifo_full(_adapter *adapter)
14373 {
14374 	struct dvobj_priv *psdpriv = adapter->dvobj;
14375 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
14376 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
14377 	struct registry_priv *regsty = &adapter->registrypriv;
14378 	int save_cnt = _FALSE;
14379 
14380 	if (regsty->check_hw_status == 1) {
14381 		/* switch counter to RX fifo */
14382 		if (IS_8188E(pHalData->version_id) ||
14383 		    IS_8188F(pHalData->version_id) ||
14384 		    IS_8188GTV(pHalData->version_id) ||
14385 		    IS_8812_SERIES(pHalData->version_id) ||
14386 		    IS_8821_SERIES(pHalData->version_id) ||
14387 		    IS_8723B_SERIES(pHalData->version_id) ||
14388 		    IS_8192E(pHalData->version_id) ||
14389 		    IS_8703B_SERIES(pHalData->version_id) ||
14390 		    IS_8723D_SERIES(pHalData->version_id) ||
14391 		    IS_8192F_SERIES(pHalData->version_id) ||
14392 		    IS_8822C_SERIES(pHalData->version_id)) {
14393 			rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
14394 			save_cnt = _TRUE;
14395 		} else {
14396 			/* todo: other chips */
14397 		}
14398 
14399 
14400 		if (save_cnt) {
14401 			pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
14402 			pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
14403 			pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
14404 		} else {
14405 			/* special value to indicate no implementation */
14406 			pdbgpriv->dbg_rx_fifo_last_overflow = 1;
14407 			pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
14408 			pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
14409 		}
14410 	}
14411 }
14412 
linked_info_dump(_adapter * padapter,u8 benable)14413 void linked_info_dump(_adapter *padapter, u8 benable)
14414 {
14415 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
14416 
14417 	if (padapter->bLinkInfoDump == benable)
14418 		return;
14419 
14420 	RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
14421 
14422 	if (benable) {
14423 #ifdef CONFIG_LPS
14424 		pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
14425 		rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
14426 #endif
14427 
14428 #ifdef CONFIG_IPS
14429 		pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
14430 		rtw_pm_set_ips(padapter, IPS_NONE);
14431 #endif
14432 	} else {
14433 #ifdef CONFIG_IPS
14434 		rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
14435 #endif /* CONFIG_IPS */
14436 
14437 #ifdef CONFIG_LPS
14438 		rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
14439 #endif /* CONFIG_LPS */
14440 	}
14441 	padapter->bLinkInfoDump = benable ;
14442 }
14443 
14444 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)14445 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
14446 {
14447 	u8 isCCKrate, rf_path;
14448 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14449 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14450 	RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
14451 		HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
14452 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14453 
14454 	if (isCCKrate)
14455 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
14456 
14457 	for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14458 		if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14459 			continue;
14460 		RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
14461 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
14462 
14463 		if (!isCCKrate) {
14464 			RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
14465 				psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
14466 		}
14467 	}
14468 }
14469 
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)14470 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
14471 {
14472 	u8 isCCKrate, rf_path;
14473 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14474 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14475 	_RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
14476 	_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);
14477 
14478 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14479 
14480 	if (isCCKrate)
14481 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
14482 
14483 	for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14484 		if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14485 			continue;
14486 		_RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
14487 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
14488 
14489 		if (!isCCKrate)
14490 			_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]);
14491 		else
14492 			_RTW_PRINT_SEL(sel , "\n");
14493 
14494 	}
14495 }
14496 #endif
14497 
14498 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)14499 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
14500 {
14501 #define DBG_RX_DFRAME_RAW_DATA_UC		0
14502 #define DBG_RX_DFRAME_RAW_DATA_BMC		1
14503 #define DBG_RX_DFRAME_RAW_DATA_TYPES	2
14504 
14505 	_irqL irqL;
14506 	u8 isCCKrate, rf_path;
14507 	struct recv_priv *precvpriv = &(padapter->recvpriv);
14508 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14509 	struct sta_priv *pstapriv = &padapter->stapriv;
14510 	struct sta_info *psta;
14511 	struct sta_recv_dframe_info *psta_dframe_info;
14512 	int i, j;
14513 	_list	*plist, *phead;
14514 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14515 	u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14516 
14517 	if (precvpriv->store_law_data_flag) {
14518 
14519 		_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
14520 
14521 		for (i = 0; i < NUM_STA; i++) {
14522 			phead = &(pstapriv->sta_hash[i]);
14523 			plist = get_next(phead);
14524 
14525 			while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
14526 
14527 				psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
14528 				plist = get_next(plist);
14529 
14530 				if (psta) {
14531 					if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN)  !=   _TRUE)
14532 					    && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN)  !=  _TRUE)
14533 					    && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN)  !=  _TRUE)) {
14534 
14535 						RTW_PRINT_SEL(sel, "==============================\n");
14536 						RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
14537 
14538 						for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
14539 							if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
14540 								psta_dframe_info = &psta->sta_dframe_info;
14541 								RTW_PRINT_SEL(sel, "\n");
14542 								RTW_PRINT_SEL(sel, "Unicast:\n");
14543 							} else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
14544 								psta_dframe_info = &psta->sta_dframe_info_bmc;
14545 								RTW_PRINT_SEL(sel, "\n");
14546 								RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
14547 							}
14548 
14549 							isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14550 
14551 							RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
14552 							RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
14553 
14554 							for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14555 								if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14556 									continue;
14557 								if (!isCCKrate) {
14558 									RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
14559 									_RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
14560 								} else
14561 									RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
14562 							}
14563 						}
14564 
14565 					}
14566 				}
14567 			}
14568 		}
14569 		_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
14570 	}
14571 }
14572 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)14573 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
14574 {
14575 	u8 isCCKrate, rf_path , dframe_type;
14576 	u8 *ptr;
14577 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14578 #ifdef DBG_RX_DFRAME_RAW_DATA
14579 	struct sta_recv_dframe_info *psta_dframe_info;
14580 #endif
14581 	struct recv_priv *precvpriv = &(padapter->recvpriv);
14582 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14583 	struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
14584 	struct sta_info *psta = prframe->u.hdr.psta;
14585 	struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
14586 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14587 	psample_pkt_rssi->data_rate = pattrib->data_rate;
14588 	ptr = prframe->u.hdr.rx_data;
14589 	dframe_type = GetFrameType(ptr);
14590 	/*RTW_INFO("=>%s\n", __FUNCTION__);*/
14591 
14592 
14593 	if (precvpriv->store_law_data_flag) {
14594 		isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14595 
14596 		psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
14597 		psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
14598 
14599 		for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14600 			psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
14601 			psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
14602 			if (!isCCKrate) {
14603 				psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
14604 				psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
14605 			}
14606 		}
14607 #ifdef DBG_RX_DFRAME_RAW_DATA
14608 		if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
14609 
14610 			/*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
14611 			if (psta) {
14612 				if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
14613 					psta_dframe_info = &psta->sta_dframe_info_bmc;
14614 				else
14615 					psta_dframe_info = &psta->sta_dframe_info;
14616 				/*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
14617 					__FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
14618 				if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
14619 					psta_dframe_info->sta_data_rate = pattrib->data_rate;
14620 					psta_dframe_info->sta_sgi = pattrib->sgi;
14621 					psta_dframe_info->sta_bw_mode = pattrib->bw;
14622 					for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14623 
14624 						psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
14625 
14626 						if (!isCCKrate) {
14627 							psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
14628 							psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
14629 						}
14630 					}
14631 				}
14632 			}
14633 		}
14634 #endif
14635 	}
14636 
14637 }
14638 
hal_efuse_macaddr_offset(_adapter * adapter)14639 int hal_efuse_macaddr_offset(_adapter *adapter)
14640 {
14641 	u8 interface_type = 0;
14642 	int addr_offset = -1;
14643 
14644 	interface_type = rtw_get_intf_type(adapter);
14645 
14646 	switch (rtw_get_chip_type(adapter)) {
14647 #ifdef CONFIG_RTL8723B
14648 	case RTL8723B:
14649 		if (interface_type == RTW_USB)
14650 			addr_offset = EEPROM_MAC_ADDR_8723BU;
14651 		else if (interface_type == RTW_SDIO)
14652 			addr_offset = EEPROM_MAC_ADDR_8723BS;
14653 		else if (interface_type == RTW_PCIE)
14654 			addr_offset = EEPROM_MAC_ADDR_8723BE;
14655 		break;
14656 #endif
14657 #ifdef CONFIG_RTL8703B
14658 	case RTL8703B:
14659 		if (interface_type == RTW_USB)
14660 			addr_offset = EEPROM_MAC_ADDR_8703BU;
14661 		else if (interface_type == RTW_SDIO)
14662 			addr_offset = EEPROM_MAC_ADDR_8703BS;
14663 		break;
14664 #endif
14665 #ifdef CONFIG_RTL8723D
14666 	case RTL8723D:
14667 		if (interface_type == RTW_USB)
14668 			addr_offset = EEPROM_MAC_ADDR_8723DU;
14669 		else if (interface_type == RTW_SDIO)
14670 			addr_offset = EEPROM_MAC_ADDR_8723DS;
14671 		else if (interface_type == RTW_PCIE)
14672 			addr_offset = EEPROM_MAC_ADDR_8723DE;
14673 		break;
14674 #endif
14675 
14676 #ifdef CONFIG_RTL8188E
14677 	case RTL8188E:
14678 		if (interface_type == RTW_USB)
14679 			addr_offset = EEPROM_MAC_ADDR_88EU;
14680 		else if (interface_type == RTW_SDIO)
14681 			addr_offset = EEPROM_MAC_ADDR_88ES;
14682 		else if (interface_type == RTW_PCIE)
14683 			addr_offset = EEPROM_MAC_ADDR_88EE;
14684 		break;
14685 #endif
14686 #ifdef CONFIG_RTL8188F
14687 	case RTL8188F:
14688 		if (interface_type == RTW_USB)
14689 			addr_offset = EEPROM_MAC_ADDR_8188FU;
14690 		else if (interface_type == RTW_SDIO)
14691 			addr_offset = EEPROM_MAC_ADDR_8188FS;
14692 		break;
14693 #endif
14694 #ifdef CONFIG_RTL8188GTV
14695 	case RTL8188GTV:
14696 		if (interface_type == RTW_USB)
14697 			addr_offset = EEPROM_MAC_ADDR_8188GTVU;
14698 		else if (interface_type == RTW_SDIO)
14699 			addr_offset = EEPROM_MAC_ADDR_8188GTVS;
14700 		break;
14701 #endif
14702 #ifdef CONFIG_RTL8812A
14703 	case RTL8812:
14704 		if (interface_type == RTW_USB)
14705 			addr_offset = EEPROM_MAC_ADDR_8812AU;
14706 		else if (interface_type == RTW_PCIE)
14707 			addr_offset = EEPROM_MAC_ADDR_8812AE;
14708 		break;
14709 #endif
14710 #ifdef CONFIG_RTL8821A
14711 	case RTL8821:
14712 		if (interface_type == RTW_USB)
14713 			addr_offset = EEPROM_MAC_ADDR_8821AU;
14714 		else if (interface_type == RTW_SDIO)
14715 			addr_offset = EEPROM_MAC_ADDR_8821AS;
14716 		else if (interface_type == RTW_PCIE)
14717 			addr_offset = EEPROM_MAC_ADDR_8821AE;
14718 		break;
14719 #endif
14720 #ifdef CONFIG_RTL8192E
14721 	case RTL8192E:
14722 		if (interface_type == RTW_USB)
14723 			addr_offset = EEPROM_MAC_ADDR_8192EU;
14724 		else if (interface_type == RTW_SDIO)
14725 			addr_offset = EEPROM_MAC_ADDR_8192ES;
14726 		else if (interface_type == RTW_PCIE)
14727 			addr_offset = EEPROM_MAC_ADDR_8192EE;
14728 		break;
14729 #endif
14730 #ifdef CONFIG_RTL8814A
14731 	case RTL8814A:
14732 		if (interface_type == RTW_USB)
14733 			addr_offset = EEPROM_MAC_ADDR_8814AU;
14734 		else if (interface_type == RTW_PCIE)
14735 			addr_offset = EEPROM_MAC_ADDR_8814AE;
14736 		break;
14737 #endif
14738 
14739 #ifdef CONFIG_RTL8822B
14740 	case RTL8822B:
14741 		if (interface_type == RTW_USB)
14742 			addr_offset = EEPROM_MAC_ADDR_8822BU;
14743 		else if (interface_type == RTW_SDIO)
14744 			addr_offset = EEPROM_MAC_ADDR_8822BS;
14745 		else if (interface_type == RTW_PCIE)
14746 			addr_offset = EEPROM_MAC_ADDR_8822BE;
14747 		break;
14748 #endif /* CONFIG_RTL8822B */
14749 
14750 #ifdef CONFIG_RTL8821C
14751 	case RTL8821C:
14752 		if (interface_type == RTW_USB)
14753 			addr_offset = EEPROM_MAC_ADDR_8821CU;
14754 		else if (interface_type == RTW_SDIO)
14755 			addr_offset = EEPROM_MAC_ADDR_8821CS;
14756 		else if (interface_type == RTW_PCIE)
14757 			addr_offset = EEPROM_MAC_ADDR_8821CE;
14758 		break;
14759 #endif /* CONFIG_RTL8821C */
14760 
14761 #ifdef CONFIG_RTL8710B
14762 	case RTL8710B:
14763 		if (interface_type == RTW_USB)
14764 			addr_offset = EEPROM_MAC_ADDR_8710B;
14765 		break;
14766 #endif
14767 
14768 #ifdef CONFIG_RTL8192F
14769 	case RTL8192F:
14770 		if (interface_type == RTW_USB)
14771 			addr_offset = EEPROM_MAC_ADDR_8192FU;
14772 		else if (interface_type == RTW_SDIO)
14773 			addr_offset = EEPROM_MAC_ADDR_8192FS;
14774 		else if (interface_type == RTW_PCIE)
14775 			addr_offset = EEPROM_MAC_ADDR_8192FE;
14776 		break;
14777 #endif /* CONFIG_RTL8192F */
14778 
14779 #ifdef CONFIG_RTL8822C
14780 	case RTL8822C:
14781 		if (interface_type == RTW_USB)
14782 			addr_offset = EEPROM_MAC_ADDR_8822CU;
14783 		else if (interface_type == RTW_SDIO)
14784 			addr_offset = EEPROM_MAC_ADDR_8822CS;
14785 		else if (interface_type == RTW_PCIE)
14786 			addr_offset = EEPROM_MAC_ADDR_8822CE;
14787 		break;
14788 #endif /* CONFIG_RTL8822C */
14789 
14790 #ifdef CONFIG_RTL8814B
14791 	case RTL8814B:
14792 		if (interface_type == RTW_USB)
14793 			addr_offset = EEPROM_MAC_ADDR_8814BU;
14794 		else if (interface_type == RTW_PCIE)
14795 			addr_offset = EEPROM_MAC_ADDR_8814BE;
14796 		break;
14797 #endif /* CONFIG_RTL8814B */
14798 
14799 #ifdef CONFIG_RTL8723F
14800 	case RTL8723F:
14801 		if (interface_type == RTW_USB)
14802 			addr_offset = EEPROM_MAC_ADDR_8723FU;
14803 		else if (interface_type == RTW_SDIO)
14804 			addr_offset = EEPROM_MAC_ADDR_8723FS;
14805 		break;
14806 #endif /* CONFIG_RTL8723F */
14807 	}
14808 
14809 	if (addr_offset == -1) {
14810 		RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
14811 			, __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
14812 	}
14813 
14814 	return addr_offset;
14815 }
14816 
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)14817 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
14818 {
14819 	int ret = _FAIL;
14820 	int addr_offset;
14821 
14822 	addr_offset = hal_efuse_macaddr_offset(padapter);
14823 	if (addr_offset == -1)
14824 		goto exit;
14825 
14826 	ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
14827 
14828 exit:
14829 	return ret;
14830 }
14831 
rtw_dump_cur_efuse(PADAPTER padapter)14832 void rtw_dump_cur_efuse(PADAPTER padapter)
14833 {
14834 	int mapsize =0;
14835 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14836 
14837 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
14838 
14839 	if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
14840 		RTW_ERR("wrong map size %d\n", mapsize);
14841 		return;
14842 	}
14843 
14844 #ifdef CONFIG_RTW_DEBUG
14845 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14846 		RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
14847 	else {
14848 #ifdef CONFIG_MP_INCLUDED
14849 		if (rtw_mp_mode_check(padapter) && GET_EFUSE_UPDATE_ON(padapter))
14850 			RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "FAKE EFUSE", hal_data->efuse_eeprom_data, mapsize);
14851 		else
14852 #endif
14853 			RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
14854 	}
14855 #endif
14856 }
14857 
14858 
14859 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)14860 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
14861 {
14862 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14863 	u32 ret = _FALSE;
14864 	u32 maplen = 0;
14865 #ifdef CONFIG_MP_INCLUDED
14866 		struct mp_priv *pmp_priv = &padapter->mppriv;
14867 #endif
14868 
14869 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
14870 
14871 	if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
14872 		RTW_ERR("eFuse length error :%d\n", maplen);
14873 		return _FALSE;
14874 	}
14875 #ifdef CONFIG_MP_INCLUDED
14876 	if (pmp_priv->efuse_update_file == _TRUE && (rtw_mp_mode_check(padapter))) {
14877 		RTW_INFO("%s, eFuse read from file :%s\n", __func__, pmp_priv->efuse_file_path);
14878 		ret = rtw_read_efuse_from_file(pmp_priv->efuse_file_path, hal_data->efuse_eeprom_data, maplen);
14879 		pmp_priv->efuse_update_file = _FALSE;
14880 	} else
14881 #endif
14882 	{
14883 		ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
14884 	}
14885 
14886 	hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
14887 
14888 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14889 		rtw_dump_cur_efuse(padapter);
14890 
14891 	return ret;
14892 }
14893 
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)14894 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
14895 {
14896 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14897 	u32 ret = _FAIL;
14898 
14899 	if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
14900 		&& rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
14901 	) {
14902 		hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
14903 		ret = _SUCCESS;
14904 	} else
14905 		hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
14906 
14907 	return ret;
14908 }
14909 #endif /* CONFIG_EFUSE_CONFIG_FILE */
14910 
hal_config_macaddr(_adapter * adapter,bool autoload_fail)14911 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
14912 {
14913 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
14914 	u8 addr[ETH_ALEN];
14915 	int addr_offset = hal_efuse_macaddr_offset(adapter);
14916 	u8 *hw_addr = NULL;
14917 	int ret = _SUCCESS;
14918 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
14919 	u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
14920 #endif
14921 
14922 	if (autoload_fail)
14923 		goto bypass_hw_pg;
14924 
14925 	if (addr_offset != -1)
14926 		hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
14927 
14928 #ifdef CONFIG_EFUSE_CONFIG_FILE
14929 	/* if the hw_addr is written by efuse file, set to NULL */
14930 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14931 		hw_addr = NULL;
14932 #endif
14933 
14934 	if (!hw_addr) {
14935 		/* try getting hw pg data */
14936 		if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
14937 			hw_addr = addr;
14938 	}
14939 
14940 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
14941 	if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
14942 		hw_addr[0] = 0xff;
14943 #endif
14944 
14945 	/* check hw pg data */
14946 	if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
14947 		_rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
14948 		goto exit;
14949 	}
14950 
14951 bypass_hw_pg:
14952 
14953 #ifdef CONFIG_EFUSE_CONFIG_FILE
14954 	/* check wifi mac file */
14955 	if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
14956 		_rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
14957 		goto exit;
14958 	}
14959 #endif
14960 
14961 	_rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
14962 	ret = _FAIL;
14963 
14964 exit:
14965 	return ret;
14966 }
14967 
14968 #ifdef CONFIG_RF_POWER_TRIM
14969 u32 Array_kfreemap[] = {
14970 	0x08, 0xe,
14971 	0x06, 0xc,
14972 	0x04, 0xa,
14973 	0x02, 0x8,
14974 	0x00, 0x6,
14975 	0x03, 0x4,
14976 	0x05, 0x2,
14977 	0x07, 0x0,
14978 	0x09, 0x0,
14979 	0x0c, 0x0,
14980 };
14981 
rtw_bb_rf_gain_offset(_adapter * padapter)14982 void rtw_bb_rf_gain_offset(_adapter *padapter)
14983 {
14984 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14985 	struct registry_priv  *registry_par = &padapter->registrypriv;
14986 	struct kfree_data_t *kfree_data = &pHalData->kfree_data;
14987 	u8		value = pHalData->EEPROMRFGainOffset;
14988 	u8		tmp = 0x3e;
14989 	u32		res, i = 0;
14990 	u32		ArrayLen	= sizeof(Array_kfreemap) / sizeof(u32);
14991 	u32		*Array = Array_kfreemap;
14992 	u32		v1 = 0, v2 = 0, GainValue = 0, target = 0;
14993 
14994 	if (registry_par->RegPwrTrimEnable == 2) {
14995 		RTW_INFO("Registry kfree default force disable.\n");
14996 		return;
14997 	}
14998 
14999 #if defined(CONFIG_RTL8723B)
15000 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
15001 		RTW_INFO("Offset RF Gain.\n");
15002 		RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
15003 
15004 		if (pHalData->EEPROMRFGainVal != 0xff) {
15005 
15006 			if (pHalData->ant_path == RF_PATH_A)
15007 				GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
15008 
15009 			else
15010 				GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
15011 			RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
15012 
15013 			for (i = 0; i < ArrayLen; i += 2) {
15014 				/* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
15015 				v1 = Array[i];
15016 				v2 = Array[i + 1];
15017 				if (v1 == GainValue) {
15018 					RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
15019 					target = v2;
15020 					break;
15021 				}
15022 			}
15023 			RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
15024 
15025 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
15026 			RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
15027 			phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
15028 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
15029 
15030 			RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
15031 
15032 		} else
15033 
15034 			RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x	!= 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
15035 	} else
15036 		RTW_INFO("Using the default RF gain.\n");
15037 
15038 #elif defined(CONFIG_RTL8188E)
15039 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
15040 		RTW_INFO("8188ES Offset RF Gain.\n");
15041 		RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
15042 			 pHalData->EEPROMRFGainVal);
15043 
15044 		if (pHalData->EEPROMRFGainVal != 0xff) {
15045 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
15046 					 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
15047 
15048 			RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
15049 			res &= 0xfff87fff;
15050 
15051 			res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
15052 			RTW_INFO("Offset RF Gain. res=0x%x\n", res);
15053 
15054 			rtw_hal_write_rfreg(padapter, RF_PATH_A,
15055 					    REG_RF_BB_GAIN_OFFSET,
15056 					    RF_GAIN_OFFSET_MASK, res);
15057 		} else {
15058 			RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
15059 				 pHalData->EEPROMRFGainVal);
15060 		}
15061 	} else
15062 		RTW_INFO("Using the default RF gain.\n");
15063 #else
15064 	/* TODO: call this when channel switch */
15065 	if (kfree_data->flag & KFREE_FLAG_ON)
15066 		rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
15067 #endif
15068 
15069 }
15070 #endif /*CONFIG_RF_POWER_TRIM */
15071 
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)15072 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
15073 {
15074 #ifdef CONFIG_RF_POWER_TRIM
15075 	int i, j;
15076 
15077 	for (i = 0; i < BB_GAIN_NUM; i++)
15078 		for (j = 0; j < RF_PATH_MAX; j++)
15079 			if (data->bb_gain[i][j] != 0)
15080 				return 0;
15081 #endif
15082 	return 1;
15083 }
15084 
15085 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)15086 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
15087 {
15088 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
15089 	if (cur_wireless_mode < WIRELESS_11_24N
15090 	    && cur_wireless_mode > 0) { /* ABG mode */
15091 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
15092 		u32 remainder = 0;
15093 		u8 quotient = 0;
15094 
15095 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
15096 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
15097 
15098 		if (quotient > 5) {
15099 			pHalData->rxagg_usb_size = 0x6;
15100 			pHalData->rxagg_usb_timeout = 0x10;
15101 		} else {
15102 			if (remainder >= 2048) {
15103 				pHalData->rxagg_usb_size = quotient;
15104 				pHalData->rxagg_usb_timeout = 0x10;
15105 			} else {
15106 				pHalData->rxagg_usb_size = (quotient - 1);
15107 				pHalData->rxagg_usb_timeout = 0x10;
15108 			}
15109 		}
15110 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
15111 		if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
15112 			pHalData->rxagg_usb_size = 0x6;
15113 			pHalData->rxagg_usb_timeout = 0x10;
15114 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
15115 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
15116 		}
15117 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
15118 
15119 	} else if (cur_wireless_mode >= WIRELESS_11_24N
15120 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
15121 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
15122 		u32 remainder = 0;
15123 		u8 quotient = 0;
15124 
15125 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
15126 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
15127 
15128 		if (quotient > 5) {
15129 			pHalData->rxagg_usb_size = 0x5;
15130 			pHalData->rxagg_usb_timeout = 0x20;
15131 		} else {
15132 			if (remainder >= 2048) {
15133 				pHalData->rxagg_usb_size = quotient;
15134 				pHalData->rxagg_usb_timeout = 0x10;
15135 			} else {
15136 				pHalData->rxagg_usb_size = (quotient - 1);
15137 				pHalData->rxagg_usb_timeout = 0x10;
15138 			}
15139 		}
15140 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
15141 		if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
15142 			pHalData->rxagg_usb_size = 0x5;
15143 			pHalData->rxagg_usb_timeout = 0x20;
15144 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
15145 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
15146 		}
15147 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
15148 
15149 	} else {
15150 		/* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
15151 	}
15152 }
15153 
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)15154 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
15155 {
15156 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
15157 
15158 	if (cur_wireless_mode < WIRELESS_11_24N
15159 	    && cur_wireless_mode > 0) { /* ABG mode */
15160 		if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
15161 		    || 0x10 != pHalData->rxagg_usb_timeout) {
15162 			pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
15163 			pHalData->rxagg_usb_timeout = 0x10;
15164 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
15165 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
15166 		}
15167 	} else if (cur_wireless_mode >= WIRELESS_11_24N
15168 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
15169 		if (UsbDmaSize != pHalData->rxagg_usb_size
15170 		    || 0x20 != pHalData->rxagg_usb_timeout) {
15171 			pHalData->rxagg_usb_size = UsbDmaSize;
15172 			pHalData->rxagg_usb_timeout = 0x20;
15173 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
15174 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
15175 		}
15176 	} else {
15177 		/* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
15178 	}
15179 }
15180 
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)15181 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
15182 {
15183 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
15184 	rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
15185 	return;
15186 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
15187 
15188 	rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
15189 }
15190 #endif /* CONFIG_USB_RX_AGGREGATION */
15191 
15192 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)15193 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
15194 {
15195 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
15196 	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
15197 	struct registry_priv *registry_par = &padapter->registrypriv;
15198 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
15199 	u8 cur_wireless_mode = WIRELESS_INVALID;
15200 
15201 #ifdef CONFIG_USB_RX_AGGREGATION
15202 	if (!registry_par->dynamic_agg_enable)
15203 		return;
15204 
15205 #ifdef RTW_HALMAC
15206 	if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter)
15207 		|| IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter)
15208 		|| IS_HARDWARE_TYPE_8723FU(padapter))
15209 		rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
15210 #else /* !RTW_HALMAC */
15211 	if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
15212 		/* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
15213 		if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) {
15214 			if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
15215 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
15216 			else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
15217 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
15218 			else
15219 				rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
15220 
15221 			/* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
15222 		}
15223 	} else if (IS_HARDWARE_TYPE_8812(padapter)) {
15224 #ifdef CONFIG_CONCURRENT_MODE
15225 		u8 i;
15226 		_adapter *iface;
15227 		u8 bassocaed = _FALSE;
15228 		struct mlme_ext_priv *mlmeext;
15229 
15230 		for (i = 0; i < pdvobjpriv->iface_nums; i++) {
15231 			iface = pdvobjpriv->padapters[i];
15232 			mlmeext = &iface->mlmeextpriv;
15233 			if (rtw_linked_check(iface) == _TRUE) {
15234 				if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
15235 					cur_wireless_mode = mlmeext->cur_wireless_mode;
15236 				bassocaed = _TRUE;
15237 			}
15238 		}
15239 		if (bassocaed)
15240 #endif
15241 			rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
15242 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
15243 	} else {
15244 		rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
15245 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
15246 	}
15247 #endif /* RTW_HALMAC */
15248 #endif /* CONFIG_USB_RX_AGGREGATION */
15249 
15250 }
15251 
15252 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)15253 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
15254 {
15255 #ifdef CONFIG_AP_MODE
15256 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
15257 	u8 chk_rst = _SUCCESS;
15258 
15259 	if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
15260 		return chk_rst;
15261 
15262 	/* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
15263 	/*	return chk_rst; */
15264 
15265 	if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
15266 	    && (pre_qsel != next_qsel)) {
15267 		/* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
15268 		/*	pre_qsel,next_qsel); */
15269 		chk_rst = _FAIL;
15270 	}
15271 	return chk_rst;
15272 #else
15273 	return _SUCCESS;
15274 #endif /* CONFIG_AP_MODE */
15275 }
15276 
15277 #ifdef CONFIG_WOWLAN
15278 /*
15279  * Description:
15280  * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
15281  * contant.
15282  *
15283  * Input:
15284  * adapter: adapter pointer.
15285  * page_num: The max. page number that user want to dump.
15286  * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
15287  */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)15288 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
15289 {
15290 
15291 	int i;
15292 	u8 val = 0;
15293 	u8 base = 0;
15294 	u32 addr = 0;
15295 	u32 count = (page_size / 8);
15296 
15297 	if (page_num <= 0) {
15298 		RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
15299 		return;
15300 	}
15301 
15302 	if (page_size < 128 || page_size > 512) {
15303 		RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
15304 		return;
15305 	}
15306 
15307 	RTW_INFO("+%s+\n", __func__);
15308 	val = rtw_read8(padapter, 0x106);
15309 	rtw_write8(padapter, 0x106, 0x69);
15310 	RTW_INFO("0x106: 0x%02x\n", val);
15311 	base = rtw_read8(padapter, 0x209);
15312 	RTW_INFO("0x209: 0x%02x\n", base);
15313 
15314 	addr = ((base)*page_size) / 8;
15315 	for (i = 0 ; i < page_num * count ; i += 2) {
15316 		rtw_write32(padapter, 0x140, addr + i);
15317 		printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
15318 		rtw_write32(padapter, 0x140, addr + i + 1);
15319 		printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
15320 	}
15321 }
15322 #endif
15323 
15324 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)15325 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
15326 {
15327 	u8 value = 0;
15328 	u8 direction = 0;
15329 	u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
15330 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
15331 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
15332 	u8 gpio_num_to_set = gpio_num;
15333 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
15334 
15335 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15336 		return value;
15337 
15338 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15339 
15340 	RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
15341 	LeaveAllPowerSaveModeDirect(adapter);
15342 
15343 	if (gpio_num > 7) {
15344 		gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
15345 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
15346 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
15347 		gpio_num_to_set = gpio_num - 8;
15348 	}
15349 
15350 	/* Read GPIO Direction */
15351 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15352 
15353 	/* According the direction to read register value */
15354 	if (direction)
15355 		value =  (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15356 	else
15357 		value =  (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15358 
15359 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15360 	RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
15361 
15362 	return value;
15363 }
15364 
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)15365 int  rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
15366 {
15367 	u8 direction = 0;
15368 	u8 res = -1;
15369 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
15370 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
15371 	u8 gpio_num_to_set = gpio_num;
15372 
15373 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15374 		return -1;
15375 
15376 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15377 
15378 	LeaveAllPowerSaveModeDirect(adapter);
15379 
15380 	if (gpio_num > 7) {
15381 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
15382 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
15383 		gpio_num_to_set = gpio_num - 8;
15384 	}
15385 
15386 	/* Read GPIO direction */
15387 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15388 
15389 	/* If GPIO is output direction, setting value. */
15390 	if (direction) {
15391 		if (isHigh)
15392 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
15393 		else
15394 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
15395 
15396 		RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
15397 		res = 0;
15398 	} else {
15399 		RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
15400 		res = -1;
15401 	}
15402 
15403 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15404 	return res;
15405 }
15406 
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)15407 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
15408 {
15409 	u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
15410 	u8 gpio_num_to_set = gpio_num;
15411 
15412 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15413 		return -1;
15414 
15415 	RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
15416 
15417 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15418 
15419 	LeaveAllPowerSaveModeDirect(adapter);
15420 
15421 	rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
15422 
15423 	if (gpio_num > 7) {
15424 		gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
15425 		gpio_num_to_set = gpio_num - 8;
15426 	}
15427 
15428 	if (isOutput)
15429 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
15430 	else
15431 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
15432 
15433 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15434 
15435 	return 0;
15436 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))15437 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
15438 {
15439 	u8 value;
15440 	u8 direction;
15441 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
15442 
15443 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
15444 		if (gpio_num > 7 || gpio_num < 4) {
15445 			RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
15446 			return -1;
15447 		}
15448 	}
15449 
15450 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15451 
15452 	LeaveAllPowerSaveModeDirect(adapter);
15453 
15454 	/* Read GPIO direction */
15455 	direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
15456 	if (direction) {
15457 		RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
15458 		return -1;
15459 	}
15460 
15461 	/* Config GPIO Mode */
15462 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
15463 
15464 	/* Register GPIO interrupt handler*/
15465 	adapter->gpiointpriv.callback[gpio_num] = callback;
15466 
15467 	/* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
15468 	value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
15469 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
15470 	rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
15471 
15472 	/* Enable GPIO interrupt */
15473 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
15474 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
15475 
15476 	rtw_hal_update_hisr_hsisr_ind(adapter, 1);
15477 
15478 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15479 
15480 	return 0;
15481 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)15482 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
15483 {
15484 	u8 value;
15485 	u8 direction;
15486 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
15487 
15488 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
15489 		if (gpio_num > 7 || gpio_num < 4) {
15490 			RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
15491 			return -1;
15492 		}
15493 	}
15494 
15495 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
15496 
15497 	LeaveAllPowerSaveModeDirect(adapter);
15498 
15499 	/* Config GPIO Mode */
15500 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
15501 
15502 	/* Unregister GPIO interrupt handler*/
15503 	adapter->gpiointpriv.callback[gpio_num] = NULL;
15504 
15505 	/* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
15506 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
15507 	rtw_write8(adapter, REG_GPIO_INTM, 0x00);
15508 
15509 	/* Disable GPIO interrupt */
15510 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
15511 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
15512 
15513 	if (!adapter->gpiointpriv.interrupt_enable_mask)
15514 		rtw_hal_update_hisr_hsisr_ind(adapter, 0);
15515 
15516 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15517 
15518 	return 0;
15519 }
15520 #endif
15521 
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)15522 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
15523 {
15524 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15525 	u8 i;
15526 
15527 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
15528 		if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
15529 			if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
15530 			    && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
15531 				return i;
15532 		}
15533 	}
15534 
15535 	return -1;
15536 }
15537 
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)15538 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
15539 {
15540 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15541 	s8 res;
15542 	u8 i;
15543 
15544 	/* If it's an existed record, overwrite it */
15545 	res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
15546 	if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
15547 		rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
15548 		return;
15549 	}
15550 
15551 	/* Search for the empty record to use */
15552 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
15553 		if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
15554 			rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
15555 			return;
15556 		}
15557 	}
15558 
15559 	/* Else, overwrite the oldest record */
15560 	for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
15561 		_rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
15562 
15563 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
15564 }
15565 
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)15566 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
15567 {
15568 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
15569 }
15570 
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15571 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15572 {
15573 	u32	mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
15574 	u32	mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
15575 	u32	mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
15576 	u32	DropPacket = 0;
15577 
15578 	if (!rx_counter) {
15579 		rtw_warn_on(1);
15580 		return;
15581 	}
15582 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
15583 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15584 
15585 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
15586 	mac_cck_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	  */
15587 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
15588 	mac_ofdm_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15589 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
15590 	mac_ht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15591 	mac_vht_ok	= 0;
15592 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15593 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
15594 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
15595 		mac_vht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
15596 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15597 	}
15598 
15599 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
15600 	mac_cck_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15601 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
15602 	mac_ofdm_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15603 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
15604 	mac_ht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
15605 	mac_vht_err	= 0;
15606 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15607 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
15608 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
15609 		mac_vht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
15610 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15611 	}
15612 
15613 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
15614 	mac_cck_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15615 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
15616 	mac_ofdm_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
15617 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
15618 	mac_ht_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
15619 
15620 	/* Mac_DropPacket */
15621 	rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
15622 	DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
15623 
15624 	rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
15625 	rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
15626 	rx_counter->rx_cck_fa = mac_cck_fa;
15627 	rx_counter->rx_ofdm_fa = mac_ofdm_fa;
15628 	rx_counter->rx_ht_fa = mac_ht_fa;
15629 	rx_counter->rx_pkt_drop = DropPacket;
15630 }
rtw_reset_mac_rx_counters(_adapter * padapter)15631 void rtw_reset_mac_rx_counters(_adapter *padapter)
15632 {
15633 
15634 	/* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
15635 	if (IS_HARDWARE_TYPE_8703B(padapter) ||
15636 		IS_HARDWARE_TYPE_8723D(padapter) ||
15637 		IS_HARDWARE_TYPE_8188F(padapter) ||
15638 		IS_HARDWARE_TYPE_8188GTV(padapter) ||
15639 		IS_HARDWARE_TYPE_8192F(padapter) ||
15640 		IS_HARDWARE_TYPE_8822C(padapter))
15641 		phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
15642 
15643 	/* reset mac counter */
15644 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
15645 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
15646 }
15647 
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15648 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15649 {
15650 	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;
15651 	if (!rx_counter) {
15652 		rtw_warn_on(1);
15653 		return;
15654 	}
15655 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15656 		cckok	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF);	     /* [13:0] */
15657 		ofdmok	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF);	     /* [13:0] */
15658 		htok		= phy_query_bb_reg(padapter, 0xF10, 0x3FFF);     /* [13:0] */
15659 		vht_ok	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF);     /* [13:0] */
15660 		cckcrc	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16]	 */
15661 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
15662 		htcrc	= phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
15663 		vht_err	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
15664 		CCK_FA	= phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
15665 		OFDM_FA	= phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
15666 	} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
15667 		cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
15668 		ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
15669 		htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
15670 		vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
15671 		cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
15672 		ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
15673 		htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
15674 		vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
15675 		CCK_FA	= phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
15676 		OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
15677 	} else if(IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)){
15678 		cckok = phy_query_bb_reg(padapter, 0x2aac, 0xffff);
15679 		ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
15680 		htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
15681 		cckcrc = phy_query_bb_reg(padapter, 0x2aac, 0xffff0000);
15682 		ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
15683 		htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
15684 		CCK_FA	= phy_query_bb_reg(padapter, 0x2aa8, 0xffff0000) + phy_query_bb_reg(padapter, 0x2aa8, 0x0000ffff);
15685 		OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
15686 	} else {
15687 		cckok	= phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
15688 		ofdmok	= phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
15689 		htok		= phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
15690 		vht_ok	= 0;
15691 		cckcrc	= phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
15692 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
15693 		htcrc	= phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
15694 		vht_err	= 0;
15695 		OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF0, bMaskHWord) +
15696 			phy_query_bb_reg(padapter, 0xDA0, bMaskHWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
15697 			phy_query_bb_reg(padapter, 0xDA4, bMaskHWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
15698 
15699 		CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
15700 	}
15701 
15702 	rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
15703 	rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
15704 	rx_counter->rx_ofdm_fa = OFDM_FA;
15705 	rx_counter->rx_cck_fa = CCK_FA;
15706 
15707 }
15708 
rtw_reset_phy_trx_ok_counters(_adapter * padapter)15709 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
15710 {
15711 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15712 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
15713 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
15714 	} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) {
15715 		phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
15716 		phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
15717 	} else {
15718 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
15719 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
15720 	}
15721 }
15722 
rtw_reset_phy_rx_counters(_adapter * padapter)15723 void rtw_reset_phy_rx_counters(_adapter *padapter)
15724 {
15725 	/* reset phy counter */
15726 	if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
15727 		/* reset CCK FA counter */
15728 		phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
15729 		phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
15730 
15731 		/* reset CCK CCA counter */
15732 		phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
15733 		phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
15734 		rtw_reset_phy_trx_ok_counters(padapter);
15735 
15736 	} else if (IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) {
15737 		/* reset CCK FA and CCK CCA counter */
15738 		phy_set_bb_reg(padapter, 0x2a44, BIT21, 0);
15739 		phy_set_bb_reg(padapter, 0x2a44, BIT21, 1);
15740 		rtw_reset_phy_trx_ok_counters(padapter);
15741 
15742 	} else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15743 		rtw_reset_phy_trx_ok_counters(padapter);
15744 
15745 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset  OFDA FA counter */
15746 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
15747 
15748 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
15749 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
15750 	} else {
15751 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
15752 		rtw_msleep_os(10);
15753 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
15754 
15755 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset  OFDA FA counter */
15756 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset  OFDA FA counter */
15757 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
15758 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
15759 
15760 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
15761 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
15762 	}
15763 }
15764 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15765 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15766 {
15767 	struct recv_priv *precvpriv = &padapter->recvpriv;
15768 	if (!rx_counter) {
15769 		rtw_warn_on(1);
15770 		return;
15771 	}
15772 	rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
15773 	rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
15774 	rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
15775 }
rtw_reset_drv_rx_counters(_adapter * padapter)15776 void rtw_reset_drv_rx_counters(_adapter *padapter)
15777 {
15778 	struct recv_priv *precvpriv = &padapter->recvpriv;
15779 	padapter->drv_rx_cnt_ok = 0;
15780 	padapter->drv_rx_cnt_crcerror = 0;
15781 	padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
15782 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)15783 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
15784 {
15785 	u8 initialgain;
15786 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15787 
15788 	if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
15789 		rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
15790 		RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
15791 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
15792 		/*disable dynamic functions, such as high power, DIG*/
15793 		rtw_phydm_ability_backup(padapter);
15794 		rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
15795 	} else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
15796 		/* turn on phy-dynamic functions */
15797 		rtw_phydm_ability_restore(padapter);
15798 		initialgain = 0xff; /* restore RX GAIN */
15799 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
15800 
15801 	}
15802 }
15803 
rtw_dump_rx_counters(_adapter * padapter)15804 void rtw_dump_rx_counters(_adapter *padapter)
15805 {
15806 	struct dbg_rx_counter rx_counter;
15807 
15808 	if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
15809 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15810 		rtw_dump_drv_rx_counters(padapter, &rx_counter);
15811 		RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
15812 			rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
15813 		rtw_reset_drv_rx_counters(padapter);
15814 	}
15815 
15816 	if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
15817 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15818 		rtw_dump_mac_rx_counters(padapter, &rx_counter);
15819 		RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
15820 			 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
15821 			rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
15822 			 rx_counter.rx_pkt_drop);
15823 		rtw_reset_mac_rx_counters(padapter);
15824 	}
15825 
15826 	if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
15827 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15828 		rtw_dump_phy_rx_counters(padapter, &rx_counter);
15829 		/* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
15830 		/* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
15831 		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,
15832 			 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
15833 		rtw_reset_phy_rx_counters(padapter);
15834 	}
15835 }
15836 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)15837 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
15838 {
15839 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15840 	u8 curr_tx_sgi = 0;
15841 	struct ra_sta_info *ra_info;
15842 
15843 	if (!psta)
15844 		return curr_tx_sgi;
15845 
15846 	if (padapter->fix_rate == 0xff) {
15847 #if defined(CONFIG_RTL8188E)
15848 #if (RATE_ADAPTIVE_SUPPORT == 1)
15849 		curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
15850 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
15851 #else
15852 		ra_info = &psta->cmn.ra_info;
15853 		curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
15854 #endif
15855 	} else {
15856 		curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
15857 	}
15858 
15859 	return curr_tx_sgi;
15860 }
15861 
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)15862 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
15863 {
15864 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15865 	u8 rate_id = 0;
15866 	struct ra_sta_info *ra_info;
15867 
15868 	if (!psta)
15869 		return rate_id;
15870 
15871 	if (padapter->fix_rate == 0xff) {
15872 #if defined(CONFIG_RTL8188E)
15873 #if (RATE_ADAPTIVE_SUPPORT == 1)
15874 		rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
15875 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
15876 #else
15877 		ra_info = &psta->cmn.ra_info;
15878 		rate_id = ra_info->curr_tx_rate & 0x7f;
15879 #endif
15880 	} else {
15881 		rate_id = padapter->fix_rate & 0x7f;
15882 	}
15883 
15884 	return rate_id;
15885 }
15886 
update_IOT_info(_adapter * padapter)15887 void update_IOT_info(_adapter *padapter)
15888 {
15889 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
15890 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
15891 
15892 	switch (pmlmeinfo->assoc_AP_vendor) {
15893 	case HT_IOT_PEER_MARVELL:
15894 		pmlmeinfo->turboMode_cts2self = 1;
15895 		pmlmeinfo->turboMode_rtsen = 0;
15896 		break;
15897 
15898 	case HT_IOT_PEER_RALINK:
15899 		pmlmeinfo->turboMode_cts2self = 0;
15900 		pmlmeinfo->turboMode_rtsen = 1;
15901 		break;
15902 	case HT_IOT_PEER_REALTEK:
15903 		/* rtw_write16(padapter, 0x4cc, 0xffff); */
15904 		/* rtw_write16(padapter, 0x546, 0x01c0); */
15905 		break;
15906 	default:
15907 		pmlmeinfo->turboMode_cts2self = 0;
15908 		pmlmeinfo->turboMode_rtsen = 1;
15909 		break;
15910 	}
15911 
15912 }
15913 #ifdef CONFIG_RTS_FULL_BW
15914 /*
15915 8188E: not support full RTS BW feature(mac REG no define 480[5])
15916 */
rtw_set_rts_bw(_adapter * padapter)15917 void rtw_set_rts_bw(_adapter *padapter) {
15918 	int i;
15919 	u8 enable = 1;
15920 	bool connect_to_8812 = _FALSE;
15921 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
15922 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
15923 	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
15924 	struct sta_info *station = NULL;
15925 
15926 	for (i = 0; i < macid_ctl->num; i++) {
15927 		if (rtw_macid_is_used(macid_ctl, i)) {
15928 
15929 			station = NULL;
15930 			station = macid_ctl->sta[i];
15931 			if(station) {
15932 
15933 				 _adapter *sta_adapter =station->padapter;
15934 				struct mlme_ext_priv	*pmlmeext = &(sta_adapter->mlmeextpriv);
15935 				struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
15936 
15937 				if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
15938 					if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) !=  _TRUE) {
15939 						if (  macid_ctl->sta[i]->vendor_8812) {
15940 							connect_to_8812 = _TRUE;
15941 							enable = 0;
15942 						}
15943 					}
15944 				}
15945 			}
15946 		}
15947 
15948 		if(connect_to_8812)
15949 			break;
15950 	}
15951 
15952 		RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
15953 		rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
15954 }
15955 #endif/*CONFIG_RTS_FULL_BW*/
15956 
hal_spec_init(_adapter * adapter)15957 int hal_spec_init(_adapter *adapter)
15958 {
15959 	u8 interface_type = 0;
15960 	int ret = _SUCCESS;
15961 
15962 	interface_type = rtw_get_intf_type(adapter);
15963 
15964 	switch (rtw_get_chip_type(adapter)) {
15965 #ifdef CONFIG_RTL8723B
15966 	case RTL8723B:
15967 		init_hal_spec_8723b(adapter);
15968 		break;
15969 #endif
15970 #ifdef CONFIG_RTL8703B
15971 	case RTL8703B:
15972 		init_hal_spec_8703b(adapter);
15973 		break;
15974 #endif
15975 #ifdef CONFIG_RTL8723D
15976 	case RTL8723D:
15977 		init_hal_spec_8723d(adapter);
15978 		break;
15979 #endif
15980 #ifdef CONFIG_RTL8188E
15981 	case RTL8188E:
15982 		init_hal_spec_8188e(adapter);
15983 		break;
15984 #endif
15985 #ifdef CONFIG_RTL8188F
15986 	case RTL8188F:
15987 		init_hal_spec_8188f(adapter);
15988 		break;
15989 #endif
15990 #ifdef CONFIG_RTL8188GTV
15991 	case RTL8188GTV:
15992 		init_hal_spec_8188gtv(adapter);
15993 		break;
15994 #endif
15995 #ifdef CONFIG_RTL8812A
15996 	case RTL8812:
15997 		init_hal_spec_8812a(adapter);
15998 		break;
15999 #endif
16000 #ifdef CONFIG_RTL8821A
16001 	case RTL8821:
16002 		init_hal_spec_8821a(adapter);
16003 		break;
16004 #endif
16005 #ifdef CONFIG_RTL8192E
16006 	case RTL8192E:
16007 		init_hal_spec_8192e(adapter);
16008 		break;
16009 #endif
16010 #ifdef CONFIG_RTL8814A
16011 	case RTL8814A:
16012 		init_hal_spec_8814a(adapter);
16013 		break;
16014 #endif
16015 #ifdef CONFIG_RTL8822B
16016 	case RTL8822B:
16017 		rtl8822b_init_hal_spec(adapter);
16018 		break;
16019 #endif
16020 #ifdef CONFIG_RTL8821C
16021 	case RTL8821C:
16022 		init_hal_spec_rtl8821c(adapter);
16023 		break;
16024 #endif
16025 #ifdef CONFIG_RTL8710B
16026 	case RTL8710B:
16027 		init_hal_spec_8710b(adapter);
16028 		break;
16029 #endif
16030 #ifdef CONFIG_RTL8192F
16031 	case RTL8192F:
16032 		init_hal_spec_8192f(adapter);
16033 		break;
16034 #endif
16035 #ifdef CONFIG_RTL8822C
16036 	case RTL8822C:
16037 		rtl8822c_init_hal_spec(adapter);
16038 		break;
16039 #endif
16040 #ifdef CONFIG_RTL8814B
16041 	case RTL8814B:
16042 		rtl8814b_init_hal_spec(adapter);
16043 		break;
16044 #endif
16045 #ifdef CONFIG_RTL8723F
16046 	case RTL8723F:
16047 		rtl8723f_init_hal_spec(adapter);
16048 		break;
16049 #endif
16050 	default:
16051 		RTW_ERR("%s: unknown chip_type:%u\n"
16052 			, __func__, rtw_get_chip_type(adapter));
16053 		ret = _FAIL;
16054 		break;
16055 	}
16056 
16057 	return ret;
16058 }
16059 
16060 static const char *const _band_cap_str[] = {
16061 	/* BIT0 */"2G",
16062 	/* BIT1 */"5G",
16063 };
16064 
16065 static const char *const _bw_cap_str[] = {
16066 	/* BIT0 */"5M",
16067 	/* BIT1 */"10M",
16068 	/* BIT2 */"20M",
16069 	/* BIT3 */"40M",
16070 	/* BIT4 */"80M",
16071 	/* BIT5 */"160M",
16072 	/* BIT6 */"80_80M",
16073 };
16074 
16075 static const char *const _proto_cap_str[] = {
16076 	/* BIT0 */"b",
16077 	/* BIT1 */"g",
16078 	/* BIT2 */"n",
16079 	/* BIT3 */"ac",
16080 };
16081 
16082 static const char *const _wl_func_str[] = {
16083 	/* BIT0 */"P2P",
16084 	/* BIT1 */"MIRACAST",
16085 	/* BIT2 */"TDLS",
16086 	/* BIT3 */"FTM",
16087 };
16088 
dump_hal_spec(void * sel,_adapter * adapter)16089 void dump_hal_spec(void *sel, _adapter *adapter)
16090 {
16091 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16092 	int i;
16093 
16094 	RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
16095 	RTW_PRINT_SEL(sel, "macid_cap:%u\n", hal_spec->macid_cap);
16096 	RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
16097 	RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
16098 
16099 	RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
16100 	RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
16101 	RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
16102 	RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num);
16103 	RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp);
16104 	RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
16105 
16106 	RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
16107 	RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
16108 
16109 	RTW_PRINT_SEL(sel, "band_cap:");
16110 	for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
16111 		if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
16112 			_RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
16113 	}
16114 	_RTW_PRINT_SEL(sel, "\n");
16115 
16116 	RTW_PRINT_SEL(sel, "bw_cap:");
16117 	for (i = 0; i < BW_CAP_BIT_NUM; i++) {
16118 		if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
16119 			_RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
16120 	}
16121 	_RTW_PRINT_SEL(sel, "\n");
16122 
16123 	RTW_PRINT_SEL(sel, "proto_cap:");
16124 	for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
16125 		if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
16126 			_RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
16127 	}
16128 	_RTW_PRINT_SEL(sel, "\n");
16129 
16130 	RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
16131 	RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
16132 
16133 	RTW_PRINT_SEL(sel, "wl_func:");
16134 	for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
16135 		if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
16136 			_RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
16137 	}
16138 	_RTW_PRINT_SEL(sel, "\n");
16139 
16140 #if CONFIG_TX_AC_LIFETIME
16141 	RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
16142 		, hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
16143 #endif
16144 
16145 	RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
16146 
16147 	RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
16148 	RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
16149 }
16150 
hal_chk_band_cap(_adapter * adapter,u8 cap)16151 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
16152 {
16153 	return GET_HAL_SPEC(adapter)->band_cap & cap;
16154 }
16155 
hal_chk_bw_cap(_adapter * adapter,u8 cap)16156 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
16157 {
16158 	return GET_HAL_SPEC(adapter)->bw_cap & cap;
16159 }
16160 
hal_chk_proto_cap(_adapter * adapter,u8 cap)16161 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
16162 {
16163 	return GET_HAL_SPEC(adapter)->proto_cap & cap;
16164 }
16165 
hal_chk_wl_func(_adapter * adapter,u8 func)16166 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
16167 {
16168 	return GET_HAL_SPEC(adapter)->wl_func & func;
16169 }
16170 
hal_is_band_support(_adapter * adapter,u8 band)16171 inline bool hal_is_band_support(_adapter *adapter, u8 band)
16172 {
16173 	return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
16174 }
16175 
hal_is_bw_support(_adapter * adapter,u8 bw)16176 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
16177 {
16178 	return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
16179 }
16180 
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)16181 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
16182 {
16183 	u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
16184 
16185 	if (mode == WIRELESS_11B)
16186 		if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
16187 			return 1;
16188 
16189 	if (mode == WIRELESS_11G)
16190 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
16191 			return 1;
16192 
16193 	if (mode == WIRELESS_11A)
16194 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
16195 			return 1;
16196 
16197 	if (mode == WIRELESS_11_24N)
16198 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
16199 			return 1;
16200 
16201 	if (mode == WIRELESS_11_5N)
16202 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
16203 			return 1;
16204 
16205 	if (mode == WIRELESS_11AC)
16206 		if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
16207 			return 1;
16208 
16209 	return 0;
16210 }
hal_is_mimo_support(_adapter * adapter)16211 inline bool hal_is_mimo_support(_adapter *adapter)
16212 {
16213 	if ((GET_HAL_TX_NSS(adapter) == 1) &&
16214 		(GET_HAL_RX_NSS(adapter) == 1))
16215 		return 0;
16216 	return 1;
16217 }
16218 
16219 /*
16220 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
16221 * @adapter:
16222 * @in_bw: starting bw, value of enum channel_width
16223 *
16224 * Returns: value of enum channel_width
16225 */
hal_largest_bw(_adapter * adapter,u8 in_bw)16226 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
16227 {
16228 	for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
16229 		if (hal_is_bw_support(adapter, in_bw))
16230 			break;
16231 	}
16232 
16233 	if (!hal_is_bw_support(adapter, in_bw))
16234 		rtw_warn_on(1);
16235 
16236 	return in_bw;
16237 }
16238 
16239 #ifndef CONFIG_HAS_TX_BEACON_PAUSE
ResumeTxBeacon(_adapter * padapter)16240 void ResumeTxBeacon(_adapter *padapter)
16241 {
16242 	RTW_DBG("ResumeTxBeacon\n");
16243 	#ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE
16244 	rtw_write8(padapter, REG_TXPAUSE,
16245 		rtw_read8(padapter, REG_TXPAUSE) & (~BIT6));
16246 	#else
16247 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
16248 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
16249 	#endif
16250 
16251 #ifdef RTW_HALMAC
16252 	/* Add this for driver using HALMAC because driver doesn't have setup time init by self */
16253 	/* TBTT setup time */
16254 	rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
16255 #endif
16256 	/* TBTT hold time: 0x540[19:8] */
16257 #ifdef	CONFIG_NARROWBAND_SUPPORTING
16258 	if (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
16259 		rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0xc8);
16260 	else
16261 #endif
16262 		rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
16263 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
16264 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
16265 }
16266 
StopTxBeacon(_adapter * padapter)16267 void StopTxBeacon(_adapter *padapter)
16268 {
16269 	RTW_DBG("StopTxBeacon\n");
16270 	#ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE
16271 	rtw_write8(padapter, REG_TXPAUSE,
16272 	rtw_read8(padapter, REG_TXPAUSE) | BIT6);
16273 	#else
16274 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
16275 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
16276 	#endif
16277 
16278 	/* TBTT hold time: 0x540[19:8] */
16279 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
16280 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
16281 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
16282 }
16283 #endif /* CONFIG_HAS_TX_BEACON_PAUSE */
16284 
16285 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
16286 
16287 #ifdef CONFIG_CLIENT_PORT_CFG
16288 const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
16289 	CLT_PORT0,
16290 	CLT_PORT1,
16291 	CLT_PORT2,
16292 	CLT_PORT3
16293 };
16294 
rtw_clt_port_init(struct clt_port_t * cltp)16295 void rtw_clt_port_init(struct clt_port_t  *cltp)
16296 {
16297 	cltp->bmp = 0;
16298 	cltp->num = 0;
16299 	_rtw_spinlock_init(&cltp->lock);
16300 }
rtw_clt_port_deinit(struct clt_port_t * cltp)16301 void rtw_clt_port_deinit(struct clt_port_t *cltp)
16302 {
16303 	_rtw_spinlock_free(&cltp->lock);
16304 }
_hw_client_port_alloc(_adapter * adapter)16305 static void _hw_client_port_alloc(_adapter *adapter)
16306 {
16307 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
16308 	struct clt_port_t  *cltp = &dvobj->clt_port;
16309 	_irqL irql;
16310 	int i;
16311 
16312 	#if 0
16313 	if (cltp->num > MAX_CLIENT_PORT_NUM) {
16314 		RTW_ERR(ADPT_FMT" cann't  alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
16315 		rtw_warn_on(1);
16316 		return;
16317 	}
16318 	#endif
16319 
16320 	if (adapter->client_id !=  MAX_CLIENT_PORT_NUM) {
16321 		RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
16322 			ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
16323 		return;
16324 	}
16325 	_enter_critical_bh(&cltp->lock, &irql);
16326 	for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
16327 		if (!(cltp->bmp & BIT(i)))
16328 			break;
16329 	}
16330 
16331 	if (i < MAX_CLIENT_PORT_NUM) {
16332 		adapter->client_id = i;
16333 		cltp->bmp |= BIT(i);
16334 		adapter->client_port = _clt_port_id[i];
16335 	}
16336 	cltp->num++;
16337 	_exit_critical_bh(&cltp->lock, &irql);
16338 	RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
16339 		__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
16340 }
_hw_client_port_free(_adapter * adapter)16341 static void _hw_client_port_free(_adapter *adapter)
16342 {
16343 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
16344 	struct clt_port_t  *cltp = &dvobj->clt_port;
16345 	_irqL irql;
16346 
16347 	#if 0
16348 	if (adapter->client_id >=  MAX_CLIENT_PORT_NUM) {
16349 		RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
16350 		/*rtw_warn_on(1);*/
16351 	}
16352 	#endif
16353 
16354 	RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
16355 		__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
16356 
16357 	_enter_critical_bh(&cltp->lock, &irql);
16358 	if (adapter->client_id !=  MAX_CLIENT_PORT_NUM) {
16359 		cltp->bmp &= ~ BIT(adapter->client_id);
16360 		adapter->client_id = MAX_CLIENT_PORT_NUM;
16361 		adapter->client_port = CLT_PORT_INVALID;
16362 	}
16363 	cltp->num--;
16364 	if (cltp->num < 0)
16365 		cltp->num = 0;
16366 	_exit_critical_bh(&cltp->lock, &irql);
16367 }
rtw_hw_client_port_allocate(_adapter * adapter)16368 void rtw_hw_client_port_allocate(_adapter *adapter)
16369 {
16370 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16371 
16372 	if (hal_spec->port_num != 5)
16373 		return;
16374 
16375 	_hw_client_port_alloc(adapter);
16376 }
rtw_hw_client_port_release(_adapter * adapter)16377 void rtw_hw_client_port_release(_adapter *adapter)
16378 {
16379 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16380 
16381 	if (hal_spec->port_num != 5)
16382 		return;
16383 
16384 	_hw_client_port_free(adapter);
16385 }
16386 #endif /*CONFIG_CLIENT_PORT_CFG*/
16387 
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)16388 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
16389 {
16390 	RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
16391 
16392 	rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
16393 
16394 	/* set net_type */
16395 	Set_MSR(Adapter, mode);
16396 
16397 	if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
16398 		if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
16399 			StopTxBeacon(Adapter);
16400 	} else if (mode == _HW_STATE_ADHOC_)
16401 		ResumeTxBeacon(Adapter);
16402 	else if (mode == _HW_STATE_AP_)
16403 		/* enable rx ps-poll */
16404 		rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
16405 
16406 	/* enable rx data frame */
16407 	rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
16408 
16409 #ifdef CONFIG_CLIENT_PORT_CFG
16410 	if (mode == _HW_STATE_STATION_)
16411 		rtw_hw_client_port_allocate(Adapter);
16412 	else
16413 		rtw_hw_client_port_release(Adapter);
16414 #endif
16415 #if defined(CONFIG_RTL8192F)
16416 		rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
16417 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
16418 #endif
16419 }
16420 #endif
16421 
16422 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)16423 u8	rtw_hal_antdiv_before_linked(_adapter *padapter)
16424 {
16425 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16426 	u8 cur_ant, change_ant;
16427 
16428 	if (!pHalData->AntDivCfg)
16429 		return _FALSE;
16430 
16431 	if (pHalData->sw_antdiv_bl_state == 0) {
16432 		pHalData->sw_antdiv_bl_state = 1;
16433 
16434 		rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
16435 		change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
16436 
16437 		return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
16438 	}
16439 
16440 	pHalData->sw_antdiv_bl_state = 0;
16441 	return _FALSE;
16442 }
16443 
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)16444 void	rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
16445 {
16446 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16447 
16448 	if (pHalData->AntDivCfg) {
16449 		/*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
16450 		/*select optimum_antenna for before linked =>For antenna diversity*/
16451 		if (dst->Rssi >=  src->Rssi) {/*keep org parameter*/
16452 			src->Rssi = dst->Rssi;
16453 			src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
16454 		}
16455 	}
16456 }
16457 #endif
16458 
16459 #ifdef CONFIG_PROC_DEBUG
16460 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)16461 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
16462 {
16463 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
16464 	struct phy_spec_t *phy_spec = &pHalData->phy_spec;
16465 
16466 	RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
16467 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
16468 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
16469 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index	[15:8]*/
16470 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index	[7:0]*/
16471 
16472 	RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
16473 	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]*/
16474 	/*VHT STBC Rx [23:16]
16475 	0 = not support
16476 	1 = support for 1 spatial stream
16477 	2 = support for 1 or 2 spatial streams
16478 	3 = support for 1 or 2 or 3 spatial streams
16479 	4 = support for 1 or 2 or 3 or 4 spatial streams*/
16480 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
16481 	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]*/
16482 	/*HT STBC Rx [7:0]
16483 	0 = not support
16484 	1 = support for 1 spatial stream
16485 	2 = support for 1 or 2 spatial streams
16486 	3 = support for 1 or 2 or 3 spatial streams*/
16487 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
16488 
16489 	RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
16490 	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]*/
16491 	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]*/
16492 	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]*/
16493 	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]*/
16494 	#ifdef CONFIG_BEAMFORMING
16495 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
16496 	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]*/
16497 	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]*/
16498 	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]*/
16499 	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]*/
16500 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF)  ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
16501 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
16502 
16503 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
16504 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
16505 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
16506 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
16507 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
16508 	#endif
16509 }
16510 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)16511 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
16512 {
16513 	u8 phy_cap = _FALSE;
16514 
16515 	/* STBC */
16516 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
16517 	RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16518 
16519 	phy_cap = _FALSE;
16520 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
16521 	RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16522 
16523 	/* LDPC support */
16524 	phy_cap = _FALSE;
16525 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
16526 	RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16527 
16528 	phy_cap = _FALSE;
16529 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
16530 	RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16531 
16532 	#ifdef CONFIG_BEAMFORMING
16533 	phy_cap = _FALSE;
16534 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
16535 	RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16536 
16537 	phy_cap = _FALSE;
16538 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
16539 	RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16540 
16541 	phy_cap = _FALSE;
16542 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
16543 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16544 
16545 	phy_cap = _FALSE;
16546 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
16547 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16548 	#endif
16549 }
16550 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)16551 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
16552 {
16553 	RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
16554 #ifdef CONFIG_PHY_CAPABILITY_QUERY
16555 	rtw_dump_phy_cap_by_phydmapi(sel, adapter);
16556 #else
16557 	rtw_dump_phy_cap_by_hal(sel, adapter);
16558 #endif
16559 }
16560 #endif
16561 
translate_dbm_to_percentage(s16 signal)16562 inline s16 translate_dbm_to_percentage(s16 signal)
16563 {
16564 	if ((signal <= -100) || (signal >= 20))
16565 		return	0;
16566 	else if (signal >= 0)
16567 		return	100;
16568 	else
16569 		return 100 + signal;
16570 }
16571 
16572 #ifdef CONFIG_SWTIMER_BASED_TXBCN
16573 #ifdef CONFIG_BCN_RECOVERY
16574 #define REG_CPU_MGQ_INFO	0x041C
16575 #define BIT_BCN_POLL			BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)16576 u8 rtw_ap_bcn_recovery(_adapter *padapter)
16577 {
16578 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
16579 
16580 	if (hal_data->issue_bcn_fail >= 2) {
16581 		RTW_ERR("%s ISSUE BCN Fail\n", __func__);
16582 		rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
16583 		hal_data->issue_bcn_fail = 0;
16584 	}
16585 	return _SUCCESS;
16586 }
16587 #endif /*CONFIG_BCN_RECOVERY*/
16588 
16589 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)16590 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
16591 {
16592 	u32 start_time = rtw_get_current_time();
16593 	u8 bcn_queue_empty = _FALSE;
16594 
16595 	do {
16596 		if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
16597 			bcn_queue_empty = _TRUE;
16598 			break;
16599 		}
16600 	} while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
16601 
16602 	if (bcn_queue_empty == _FALSE)
16603 		RTW_ERR("%s BCN queue not empty\n", __func__);
16604 
16605 	return bcn_queue_empty;
16606 }
16607 #endif /*CONFIG_BCN_XMIT_PROTECT*/
16608 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
16609 
16610 /**
16611  * rtw_hal_get_trx_path() - Get RF path related information
16612  * @d:		struct dvobj_priv*
16613  * @type:	RF type, nTnR
16614  * @tx:		Tx path
16615  * @rx:		Rx path
16616  *
16617  * Get RF type, TX path and RX path information.
16618  */
rtw_hal_get_trx_path(struct dvobj_priv * d,enum rf_type * type,enum bb_path * tx,enum bb_path * rx)16619 void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
16620 			 enum bb_path *tx, enum bb_path *rx)
16621 {
16622 	struct _ADAPTER *a = dvobj_get_primary_adapter(d);
16623 	enum rf_type t = GET_HAL_RFPATH(a);
16624 
16625 	if (type)
16626 		*type = t;
16627 
16628 	if (tx || rx) {
16629 		u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
16630 		u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
16631 
16632 		if (!tx_bmp && !rx_bmp)
16633 			rf_type_to_default_trx_bmp(t, tx, rx);
16634 		else {
16635 			if (tx)
16636 				*tx = GET_HAL_TX_PATH_BMP(a);
16637 			if (rx)
16638 				*rx = GET_HAL_RX_PATH_BMP(a);
16639 		}
16640 	}
16641 }
16642 
16643 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
rtw_hal_switch_chnl_and_set_bw_offload(_adapter * adapter,u8 central_ch,u8 pri_ch_idx,u8 bw)16644 void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
16645 {
16646 	u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
16647 	PHAL_DATA_TYPE hal;
16648 	struct submit_ctx *chsw_sctx;
16649 
16650 	hal = GET_HAL_DATA(adapter);
16651 	chsw_sctx = &hal->chsw_sctx;
16652 
16653 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
16654 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
16655 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
16656 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_IQK_UPDATE_EN(h2c, 1);
16657 
16658 	rtw_sctx_init(chsw_sctx, 10);
16659 	rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
16660 	rtw_sctx_wait(chsw_sctx, __func__);
16661 }
16662 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
16663 
phy_get_capable_tx_num(_adapter * adapter,enum MGN_RATE rate)16664 u8 phy_get_capable_tx_num(_adapter *adapter, enum MGN_RATE rate)
16665 {
16666 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16667 	u8 tx_num = 0;
16668 
16669 	if (IS_1T_RATE(rate))
16670 		tx_num = hal_data->txpath_cap_num_nss[0];
16671 	else if (IS_2T_RATE(rate))
16672 		tx_num = hal_data->txpath_cap_num_nss[1];
16673 	else if (IS_3T_RATE(rate))
16674 		tx_num = hal_data->txpath_cap_num_nss[2];
16675 	else if (IS_4T_RATE(rate))
16676 		tx_num = hal_data->txpath_cap_num_nss[3];
16677 	else
16678 		rtw_warn_on(1);
16679 
16680 	return tx_num == 0 ? RF_1TX : tx_num - 1;
16681 }
16682 
phy_get_current_tx_num(_adapter * adapter,enum MGN_RATE rate)16683 u8 phy_get_current_tx_num(_adapter *adapter, enum MGN_RATE rate)
16684 {
16685 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16686 	u8 tx_num = 0;
16687 
16688 	if (IS_1T_RATE(rate))
16689 		tx_num = hal_data->txpath_num_nss[0];
16690 	else if (IS_2T_RATE(rate))
16691 		tx_num = hal_data->txpath_num_nss[1];
16692 	else if (IS_3T_RATE(rate))
16693 		tx_num = hal_data->txpath_num_nss[2];
16694 	else if (IS_4T_RATE(rate))
16695 		tx_num = hal_data->txpath_num_nss[3];
16696 	else
16697 		rtw_warn_on(1);
16698 
16699 	return tx_num == 0 ? RF_1TX : tx_num - 1;
16700 }
16701 
16702 #ifdef CONFIG_RTL8812A
rtw_hal_set_8812a_vendor_ie(_adapter * padapter,u8 * pframe,uint * frlen)16703 u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
16704 	int vender_len = 7;
16705 	unsigned char	vendor_info[vender_len];
16706 	unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
16707 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
16708 
16709 	if( !IS_HARDWARE_TYPE_8812(padapter) )
16710 		return pframe;
16711 
16712 	_rtw_memset(vendor_info,0,vender_len);
16713 	_rtw_memcpy(vendor_info, REALTEK_OUI, 3);
16714 	vendor_info[4] =2;
16715 	if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
16716 		vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
16717 	else
16718 		vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
16719 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
16720 
16721 	return pframe;
16722 }
16723 #endif /*CONFIG_RTL8812A*/
16724 
rtw_enter_protsel(struct protsel * protsel,u32 sel)16725 static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
16726 {
16727 	int refcnt;
16728 
16729 	_enter_critical_mutex(&protsel->mutex, NULL);
16730 
16731 	refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
16732 
16733 	WARN_ON(refcnt > 1 && protsel->sel != sel);
16734 
16735 	protsel->sel = sel;
16736 
16737 	_exit_critical_mutex(&protsel->mutex, NULL);
16738 }
16739 
rtw_leave_protsel(struct protsel * protsel)16740 static inline void rtw_leave_protsel(struct protsel *protsel)
16741 {
16742 	int refcnt;
16743 
16744 	_enter_critical_mutex(&protsel->mutex, NULL);
16745 
16746 	refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
16747 
16748 	_exit_critical_mutex(&protsel->mutex, NULL);
16749 
16750 	WARN_ON(refcnt < 0);
16751 }
16752 
rtw_assert_protsel(struct protsel * protsel)16753 static inline bool rtw_assert_protsel(struct protsel *protsel)
16754 {
16755 	int refcnt = ATOMIC_READ(&protsel->refcnt);
16756 
16757 	if (refcnt > 0)
16758 		return true;
16759 
16760 	return false;
16761 }
16762 
16763 #ifdef CONFIG_PROTSEL_PORT
rtw_enter_protsel_port(_adapter * padapter,u8 port_sel)16764 void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
16765 {
16766 	u8 val8;
16767 
16768 	rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
16769 
16770 	val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
16771 	val8 &= ~BIT_MASK_PORT_CTRL_SEL;
16772 	val8 |= BIT_PORT_CTRL_SEL(port_sel);
16773 	rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
16774 }
16775 
rtw_assert_protsel_port(_adapter * padapter,u32 addr,u8 len)16776 bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
16777 {
16778 	if (!padapter->bup)	/* don't assert before IF up */
16779 		return true;
16780 
16781 	return rtw_assert_protsel(&padapter->dvobj->protsel_port);
16782 }
16783 
rtw_leave_protsel_port(_adapter * padapter)16784 void rtw_leave_protsel_port(_adapter *padapter)
16785 {
16786 	rtw_leave_protsel(&padapter->dvobj->protsel_port);
16787 }
16788 #endif
16789 
16790 #ifdef CONFIG_PROTSEL_ATIMDTIM
rtw_enter_protsel_atimdtim(_adapter * padapter,u8 port_sel)16791 void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
16792 {
16793 	/* 0~15 is for port 0 MBSSID setting
16794 	 * 16 is for port 1 setting
16795 	 * 17 is for port 2 setting
16796 	 * 18 is for port 3 setting
16797 	 * 19 is for port 4 setting
16798 	 */
16799 	u8 val8;
16800 
16801 	if (port_sel >= 1 && port_sel <= 4)
16802 		port_sel += 15;
16803 
16804 	rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
16805 
16806 	val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
16807 	val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
16808 	val8 |= BIT_ATIM_DTIM_SEL(port_sel);
16809 	rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
16810 }
16811 
rtw_assert_protsel_atimdtim(_adapter * padapter,u32 addr,u8 len)16812 bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
16813 {
16814 	return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
16815 }
16816 
rtw_leave_protsel_atimdtim(_adapter * padapter)16817 void rtw_leave_protsel_atimdtim(_adapter *padapter)
16818 {
16819 	rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
16820 }
16821 #endif
16822 
16823 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_enter_protsel_macsleep(_adapter * padapter,u8 sel)16824 void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
16825 {
16826 	u32 val32;
16827 
16828 	rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
16829 
16830 	val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
16831 	val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
16832 	val32 |= BIT_MACID_SLEEP_SEL(sel);
16833 	rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
16834 }
16835 
rtw_assert_protsel_macsleep(_adapter * padapter,u32 addr,u8 len)16836 bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
16837 {
16838 	return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
16839 }
16840 
rtw_leave_protsel_macsleep(_adapter * padapter)16841 void rtw_leave_protsel_macsleep(_adapter *padapter)
16842 {
16843 	rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
16844 }
16845 #endif
16846 
rtw_hal_bcn_early_rpt_c2h_handler(_adapter * padapter)16847 void rtw_hal_bcn_early_rpt_c2h_handler(_adapter *padapter)
16848 {
16849 	if(0)
16850 		RTW_INFO("Recv Bcn Early report!!\n");
16851 
16852 #ifdef CONFIG_AP_MODE
16853 	rtw_mi_update_csa(padapter);
16854 #endif
16855 
16856 #ifdef CONFIG_TDLS
16857 #ifdef CONFIG_TDLS_CH_SW
16858 	if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
16859 		rtw_tdls_ch_sw_back_to_base_chnl(padapter);
16860 #endif
16861 #endif
16862 }
16863 
16864 #ifndef RTW_HALMAC
rtw_hal_init_sifs_backup(_adapter * adapter)16865 void rtw_hal_init_sifs_backup(_adapter *adapter)
16866 {
16867 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16868 
16869 	hal_data->init_reg_0x428 = rtw_read16(adapter, 0x428);
16870 	hal_data->init_reg_0x514 = rtw_read32(adapter, 0x514);
16871 	hal_data->init_reg_0x63a = rtw_read16(adapter, 0x63a);
16872 	hal_data->init_reg_0x63c = rtw_read32(adapter, 0x63c);
16873 
16874 #ifndef RTW_SIFS_INIT_CHK
16875 #define RTW_SIFS_INIT_CHK 1
16876 #endif
16877 
16878 #if RTW_SIFS_INIT_CHK
16879 /*
16880 the expected initial values:
16881 0x428[15:0]=0x100A
16882 0x514[31:0]=0x0E0A0E0A
16883 0x63A[15:0]=0x100A
16884 0x63C[31:0]=0x0E0E0A0A
16885 */
16886 #define INIT_REG_0x428 0x100A
16887 #define INIT_REG_0x514 0x0E0A0E0A
16888 #define INIT_REG_0x63A 0x100A
16889 #define INIT_REG_0x63C 0x0E0E0A0A
16890 
16891 	if (hal_data->init_reg_0x428 != INIT_REG_0x428) {
16892 		RTW_WARN("init_reg_0x428:0x%04x != 0x%04x\n", hal_data->init_reg_0x428, INIT_REG_0x428);
16893 		#if RTW_SIFS_INIT_CHK > 1
16894 		hal_data->init_reg_0x428 = INIT_REG_0x428;
16895 		rtw_write16(adapter, 0x428, hal_data->init_reg_0x428);
16896 		#endif
16897 	}
16898 	if (hal_data->init_reg_0x514 != INIT_REG_0x514) {
16899 		RTW_WARN("init_reg_0x514:0x%08x != 0x%08x\n", hal_data->init_reg_0x514, INIT_REG_0x514);
16900 		#if RTW_SIFS_INIT_CHK > 1
16901 		hal_data->init_reg_0x514 = INIT_REG_0x514;
16902 		rtw_write32(adapter, 0x514, hal_data->init_reg_0x514);
16903 		#endif
16904 	}
16905 	if (hal_data->init_reg_0x63a != INIT_REG_0x63A) {
16906 		RTW_WARN("init_reg_0x63a:0x%04x != 0x%04x\n", hal_data->init_reg_0x63a, INIT_REG_0x63A);
16907 		#if RTW_SIFS_INIT_CHK > 1
16908 		hal_data->init_reg_0x63a = INIT_REG_0x63A;
16909 		rtw_write16(adapter, 0x63a, hal_data->init_reg_0x63a);
16910 		#endif
16911 	}
16912 	if (hal_data->init_reg_0x63c != INIT_REG_0x63C) {
16913 		RTW_WARN("init_reg_0x63c:0x%08x != 0x%08x\n", hal_data->init_reg_0x63c, INIT_REG_0x63C);
16914 		#if RTW_SIFS_INIT_CHK > 1
16915 		hal_data->init_reg_0x63c = INIT_REG_0x63C;
16916 		rtw_write32(adapter, 0x63c, hal_data->init_reg_0x63c);
16917 		#endif
16918 	}
16919 #endif
16920 }
16921 #endif
16922