xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8822be/hal/hal_com.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _HAL_COM_C_
21 
22 #include <drv_types.h>
23 #include "hal_com_h2c.h"
24 
25 #include "hal_data.h"
26 
27 /* #define CONFIG_GTK_OL_DBG */
28 
29 /*#define DBG_SEC_CAM_MOVE*/
30 #ifdef DBG_SEC_CAM_MOVE
rtw_hal_move_sta_gk_to_dk(_adapter * adapter)31 void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
32 {
33 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
34 	int cam_id, index = 0;
35 	u8 *addr = NULL;
36 
37 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
38 		return;
39 
40 	addr = get_bssid(pmlmepriv);
41 
42 	if (addr == NULL) {
43 		RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
44 		return;
45 	}
46 
47 	rtw_clean_dk_section(adapter);
48 
49 	do {
50 		cam_id = rtw_camid_search(adapter, addr, index, 1);
51 
52 		if (cam_id == -1)
53 			RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
54 		else
55 			rtw_sec_cam_swap(adapter, cam_id, index);
56 
57 		index++;
58 	} while (index < 4);
59 
60 }
61 
rtw_hal_read_sta_dk_key(_adapter * adapter,u8 key_id)62 void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
63 {
64 	struct security_priv *psecuritypriv = &adapter->securitypriv;
65 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
66 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
67 	_irqL irqL;
68 	u8 get_key[16];
69 
70 	_rtw_memset(get_key, 0, sizeof(get_key));
71 
72 	if (key_id > 4) {
73 		RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
74 		rtw_warn_on(1);
75 		return;
76 	}
77 	rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
78 
79 	/*update key into related sw variable*/
80 	_enter_critical_bh(&cam_ctl->lock, &irqL);
81 	if (_rtw_camid_is_gk(adapter, key_id)) {
82 		RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
83 		RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
84 	}
85 	_exit_critical_bh(&cam_ctl->lock, &irqL);
86 
87 }
88 #endif
89 
90 
91 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
92 	char	rtw_phy_para_file_path[PATH_LENGTH_MAX];
93 #endif
94 
dump_chip_info(HAL_VERSION ChipVersion)95 void dump_chip_info(HAL_VERSION	ChipVersion)
96 {
97 	int cnt = 0;
98 	u8 buf[128] = {0};
99 
100 	if (IS_8188E(ChipVersion))
101 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
102 	else if (IS_8188F(ChipVersion))
103 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
104 	else if (IS_8812_SERIES(ChipVersion))
105 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
106 	else if (IS_8192E(ChipVersion))
107 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
108 	else if (IS_8821_SERIES(ChipVersion))
109 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
110 	else if (IS_8723B_SERIES(ChipVersion))
111 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
112 	else if (IS_8703B_SERIES(ChipVersion))
113 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
114 	else if (IS_8723D_SERIES(ChipVersion))
115 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
116 	else if (IS_8814A_SERIES(ChipVersion))
117 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
118 	else if (IS_8822B_SERIES(ChipVersion))
119 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
120 	else if (IS_8821C_SERIES(ChipVersion))
121 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
122 	else
123 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
124 
125 	cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(ChipVersion) ? "Normal_Chip" : "Test_Chip");
126 	if (IS_CHIP_VENDOR_TSMC(ChipVersion))
127 		cnt += sprintf((buf + cnt), "%s_", "TSMC");
128 	else if (IS_CHIP_VENDOR_UMC(ChipVersion))
129 		cnt += sprintf((buf + cnt), "%s_", "UMC");
130 	else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
131 		cnt += sprintf((buf + cnt), "%s_", "SMIC");
132 
133 	if (IS_A_CUT(ChipVersion))
134 		cnt += sprintf((buf + cnt), "A_CUT_");
135 	else if (IS_B_CUT(ChipVersion))
136 		cnt += sprintf((buf + cnt), "B_CUT_");
137 	else if (IS_C_CUT(ChipVersion))
138 		cnt += sprintf((buf + cnt), "C_CUT_");
139 	else if (IS_D_CUT(ChipVersion))
140 		cnt += sprintf((buf + cnt), "D_CUT_");
141 	else if (IS_E_CUT(ChipVersion))
142 		cnt += sprintf((buf + cnt), "E_CUT_");
143 	else if (IS_F_CUT(ChipVersion))
144 		cnt += sprintf((buf + cnt), "F_CUT_");
145 	else if (IS_I_CUT(ChipVersion))
146 		cnt += sprintf((buf + cnt), "I_CUT_");
147 	else if (IS_J_CUT(ChipVersion))
148 		cnt += sprintf((buf + cnt), "J_CUT_");
149 	else if (IS_K_CUT(ChipVersion))
150 		cnt += sprintf((buf + cnt), "K_CUT_");
151 	else
152 		cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion);
153 
154 	if (IS_1T1R(ChipVersion))
155 		cnt += sprintf((buf + cnt), "1T1R_");
156 	else if (IS_1T2R(ChipVersion))
157 		cnt += sprintf((buf + cnt), "1T2R_");
158 	else if (IS_2T2R(ChipVersion))
159 		cnt += sprintf((buf + cnt), "2T2R_");
160 	else if (IS_3T3R(ChipVersion))
161 		cnt += sprintf((buf + cnt), "3T3R_");
162 	else if (IS_3T4R(ChipVersion))
163 		cnt += sprintf((buf + cnt), "3T4R_");
164 	else if (IS_4T4R(ChipVersion))
165 		cnt += sprintf((buf + cnt), "4T4R_");
166 	else
167 		cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
168 
169 	cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
170 
171 	RTW_INFO("%s", buf);
172 }
rtw_hal_config_rftype(PADAPTER padapter)173 void rtw_hal_config_rftype(PADAPTER  padapter)
174 {
175 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
176 
177 	if (IS_1T1R(pHalData->VersionID)) {
178 		pHalData->rf_type = RF_1T1R;
179 		pHalData->NumTotalRFPath = 1;
180 	} else if (IS_2T2R(pHalData->VersionID)) {
181 		pHalData->rf_type = RF_2T2R;
182 		pHalData->NumTotalRFPath = 2;
183 	} else if (IS_1T2R(pHalData->VersionID)) {
184 		pHalData->rf_type = RF_1T2R;
185 		pHalData->NumTotalRFPath = 2;
186 	} else if (IS_3T3R(pHalData->VersionID)) {
187 		pHalData->rf_type = RF_3T3R;
188 		pHalData->NumTotalRFPath = 3;
189 	} else if (IS_4T4R(pHalData->VersionID)) {
190 		pHalData->rf_type = RF_4T4R;
191 		pHalData->NumTotalRFPath = 4;
192 	} else {
193 		pHalData->rf_type = RF_1T1R;
194 		pHalData->NumTotalRFPath = 1;
195 	}
196 
197 	RTW_INFO("%s RF_Type is %d TotalTxPath is %d\n", __FUNCTION__, pHalData->rf_type, pHalData->NumTotalRFPath);
198 }
199 
200 #define	EEPROM_CHANNEL_PLAN_BY_HW_MASK	0x80
201 
202 /*
203  * Description:
204  *	Use hardware(efuse), driver parameter(registry) and default channel plan
205  *	to decide which one should be used.
206  *
207  * Parameters:
208  *	padapter			pointer of adapter
209  *	hw_alpha2		country code from HW (efuse/eeprom/mapfile)
210  *	hw_chplan		channel plan from HW (efuse/eeprom/mapfile)
211  *						BIT[7] software configure mode; 0:Enable, 1:disable
212  *						BIT[6:0] Channel Plan
213  *	sw_alpha2		country code from HW (registry/module param)
214  *	sw_chplan		channel plan from SW (registry/module param)
215  *	def_chplan		channel plan used when HW/SW both invalid
216  *	AutoLoadFail		efuse autoload fail or not
217  *
218  * Return:
219  *	Final channel plan decision
220  *
221  */
hal_com_config_channel_plan(IN PADAPTER padapter,IN char * hw_alpha2,IN u8 hw_chplan,IN char * sw_alpha2,IN u8 sw_chplan,IN u8 def_chplan,IN BOOLEAN AutoLoadFail)222 u8 hal_com_config_channel_plan(
223 	IN	PADAPTER padapter,
224 	IN	char *hw_alpha2,
225 	IN	u8 hw_chplan,
226 	IN	char *sw_alpha2,
227 	IN	u8 sw_chplan,
228 	IN	u8 def_chplan,
229 	IN	BOOLEAN AutoLoadFail
230 )
231 {
232 	PHAL_DATA_TYPE	pHalData;
233 	u8 force_hw_chplan = _FALSE;
234 	int chplan = -1;
235 	const struct country_chplan *country_ent = NULL, *ent;
236 
237 	pHalData = GET_HAL_DATA(padapter);
238 
239 	/* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
240 	if (hw_chplan == 0xFF)
241 		goto chk_hw_country_code;
242 
243 	if (AutoLoadFail == _TRUE)
244 		goto chk_sw_config;
245 
246 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
247 	if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
248 		force_hw_chplan = _TRUE;
249 #endif
250 
251 	hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
252 
253 chk_hw_country_code:
254 	if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
255 		ent = rtw_get_chplan_from_country(hw_alpha2);
256 		if (ent) {
257 			/* get chplan from hw country code, by pass hw chplan setting */
258 			country_ent = ent;
259 			chplan = ent->chplan;
260 			goto chk_sw_config;
261 		} else
262 			RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
263 	}
264 
265 	if (rtw_is_channel_plan_valid(hw_chplan))
266 		chplan = hw_chplan;
267 	else if (force_hw_chplan == _TRUE) {
268 		RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
269 		/* hw infomaton invalid, refer to sw information */
270 		force_hw_chplan = _FALSE;
271 	}
272 
273 chk_sw_config:
274 	if (force_hw_chplan == _TRUE)
275 		goto done;
276 
277 	if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
278 		ent = rtw_get_chplan_from_country(sw_alpha2);
279 		if (ent) {
280 			/* get chplan from sw country code, by pass sw chplan setting */
281 			country_ent = ent;
282 			chplan = ent->chplan;
283 			goto done;
284 		} else
285 			RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
286 	}
287 
288 	if (rtw_is_channel_plan_valid(sw_chplan)) {
289 		/* cancel hw_alpha2 because chplan is specified by sw_chplan*/
290 		country_ent = NULL;
291 		chplan = sw_chplan;
292 	} else if (sw_chplan != RTW_CHPLAN_MAX)
293 		RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
294 
295 done:
296 	if (chplan == -1) {
297 		RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
298 		chplan = def_chplan;
299 	} else if (country_ent) {
300 		RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
301 			, country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
302 	} else
303 		RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
304 
305 	padapter->mlmepriv.country_ent = country_ent;
306 	pHalData->bDisableSWChannelPlan = force_hw_chplan;
307 
308 	return chplan;
309 }
310 
311 BOOLEAN
HAL_IsLegalChannel(IN PADAPTER Adapter,IN u32 Channel)312 HAL_IsLegalChannel(
313 	IN	PADAPTER	Adapter,
314 	IN	u32			Channel
315 )
316 {
317 	BOOLEAN bLegalChannel = _TRUE;
318 
319 	if (Channel > 14) {
320 		if (IsSupported5G(Adapter->registrypriv.wireless_mode) == _FALSE) {
321 			bLegalChannel = _FALSE;
322 			RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
323 		}
324 	} else if ((Channel <= 14) && (Channel >= 1)) {
325 		if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
326 			bLegalChannel = _FALSE;
327 			RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
328 		}
329 	} else {
330 		bLegalChannel = _FALSE;
331 		RTW_INFO("Channel is Invalid !!!\n");
332 	}
333 
334 	return bLegalChannel;
335 }
336 
MRateToHwRate(u8 rate)337 u8	MRateToHwRate(u8 rate)
338 {
339 	u8	ret = DESC_RATE1M;
340 
341 	switch (rate) {
342 	case MGN_1M:
343 		ret = DESC_RATE1M;
344 		break;
345 	case MGN_2M:
346 		ret = DESC_RATE2M;
347 		break;
348 	case MGN_5_5M:
349 		ret = DESC_RATE5_5M;
350 		break;
351 	case MGN_11M:
352 		ret = DESC_RATE11M;
353 		break;
354 	case MGN_6M:
355 		ret = DESC_RATE6M;
356 		break;
357 	case MGN_9M:
358 		ret = DESC_RATE9M;
359 		break;
360 	case MGN_12M:
361 		ret = DESC_RATE12M;
362 		break;
363 	case MGN_18M:
364 		ret = DESC_RATE18M;
365 		break;
366 	case MGN_24M:
367 		ret = DESC_RATE24M;
368 		break;
369 	case MGN_36M:
370 		ret = DESC_RATE36M;
371 		break;
372 	case MGN_48M:
373 		ret = DESC_RATE48M;
374 		break;
375 	case MGN_54M:
376 		ret = DESC_RATE54M;
377 		break;
378 
379 	case MGN_MCS0:
380 		ret = DESC_RATEMCS0;
381 		break;
382 	case MGN_MCS1:
383 		ret = DESC_RATEMCS1;
384 		break;
385 	case MGN_MCS2:
386 		ret = DESC_RATEMCS2;
387 		break;
388 	case MGN_MCS3:
389 		ret = DESC_RATEMCS3;
390 		break;
391 	case MGN_MCS4:
392 		ret = DESC_RATEMCS4;
393 		break;
394 	case MGN_MCS5:
395 		ret = DESC_RATEMCS5;
396 		break;
397 	case MGN_MCS6:
398 		ret = DESC_RATEMCS6;
399 		break;
400 	case MGN_MCS7:
401 		ret = DESC_RATEMCS7;
402 		break;
403 	case MGN_MCS8:
404 		ret = DESC_RATEMCS8;
405 		break;
406 	case MGN_MCS9:
407 		ret = DESC_RATEMCS9;
408 		break;
409 	case MGN_MCS10:
410 		ret = DESC_RATEMCS10;
411 		break;
412 	case MGN_MCS11:
413 		ret = DESC_RATEMCS11;
414 		break;
415 	case MGN_MCS12:
416 		ret = DESC_RATEMCS12;
417 		break;
418 	case MGN_MCS13:
419 		ret = DESC_RATEMCS13;
420 		break;
421 	case MGN_MCS14:
422 		ret = DESC_RATEMCS14;
423 		break;
424 	case MGN_MCS15:
425 		ret = DESC_RATEMCS15;
426 		break;
427 	case MGN_MCS16:
428 		ret = DESC_RATEMCS16;
429 		break;
430 	case MGN_MCS17:
431 		ret = DESC_RATEMCS17;
432 		break;
433 	case MGN_MCS18:
434 		ret = DESC_RATEMCS18;
435 		break;
436 	case MGN_MCS19:
437 		ret = DESC_RATEMCS19;
438 		break;
439 	case MGN_MCS20:
440 		ret = DESC_RATEMCS20;
441 		break;
442 	case MGN_MCS21:
443 		ret = DESC_RATEMCS21;
444 		break;
445 	case MGN_MCS22:
446 		ret = DESC_RATEMCS22;
447 		break;
448 	case MGN_MCS23:
449 		ret = DESC_RATEMCS23;
450 		break;
451 	case MGN_MCS24:
452 		ret = DESC_RATEMCS24;
453 		break;
454 	case MGN_MCS25:
455 		ret = DESC_RATEMCS25;
456 		break;
457 	case MGN_MCS26:
458 		ret = DESC_RATEMCS26;
459 		break;
460 	case MGN_MCS27:
461 		ret = DESC_RATEMCS27;
462 		break;
463 	case MGN_MCS28:
464 		ret = DESC_RATEMCS28;
465 		break;
466 	case MGN_MCS29:
467 		ret = DESC_RATEMCS29;
468 		break;
469 	case MGN_MCS30:
470 		ret = DESC_RATEMCS30;
471 		break;
472 	case MGN_MCS31:
473 		ret = DESC_RATEMCS31;
474 		break;
475 
476 	case MGN_VHT1SS_MCS0:
477 		ret = DESC_RATEVHTSS1MCS0;
478 		break;
479 	case MGN_VHT1SS_MCS1:
480 		ret = DESC_RATEVHTSS1MCS1;
481 		break;
482 	case MGN_VHT1SS_MCS2:
483 		ret = DESC_RATEVHTSS1MCS2;
484 		break;
485 	case MGN_VHT1SS_MCS3:
486 		ret = DESC_RATEVHTSS1MCS3;
487 		break;
488 	case MGN_VHT1SS_MCS4:
489 		ret = DESC_RATEVHTSS1MCS4;
490 		break;
491 	case MGN_VHT1SS_MCS5:
492 		ret = DESC_RATEVHTSS1MCS5;
493 		break;
494 	case MGN_VHT1SS_MCS6:
495 		ret = DESC_RATEVHTSS1MCS6;
496 		break;
497 	case MGN_VHT1SS_MCS7:
498 		ret = DESC_RATEVHTSS1MCS7;
499 		break;
500 	case MGN_VHT1SS_MCS8:
501 		ret = DESC_RATEVHTSS1MCS8;
502 		break;
503 	case MGN_VHT1SS_MCS9:
504 		ret = DESC_RATEVHTSS1MCS9;
505 		break;
506 	case MGN_VHT2SS_MCS0:
507 		ret = DESC_RATEVHTSS2MCS0;
508 		break;
509 	case MGN_VHT2SS_MCS1:
510 		ret = DESC_RATEVHTSS2MCS1;
511 		break;
512 	case MGN_VHT2SS_MCS2:
513 		ret = DESC_RATEVHTSS2MCS2;
514 		break;
515 	case MGN_VHT2SS_MCS3:
516 		ret = DESC_RATEVHTSS2MCS3;
517 		break;
518 	case MGN_VHT2SS_MCS4:
519 		ret = DESC_RATEVHTSS2MCS4;
520 		break;
521 	case MGN_VHT2SS_MCS5:
522 		ret = DESC_RATEVHTSS2MCS5;
523 		break;
524 	case MGN_VHT2SS_MCS6:
525 		ret = DESC_RATEVHTSS2MCS6;
526 		break;
527 	case MGN_VHT2SS_MCS7:
528 		ret = DESC_RATEVHTSS2MCS7;
529 		break;
530 	case MGN_VHT2SS_MCS8:
531 		ret = DESC_RATEVHTSS2MCS8;
532 		break;
533 	case MGN_VHT2SS_MCS9:
534 		ret = DESC_RATEVHTSS2MCS9;
535 		break;
536 	case MGN_VHT3SS_MCS0:
537 		ret = DESC_RATEVHTSS3MCS0;
538 		break;
539 	case MGN_VHT3SS_MCS1:
540 		ret = DESC_RATEVHTSS3MCS1;
541 		break;
542 	case MGN_VHT3SS_MCS2:
543 		ret = DESC_RATEVHTSS3MCS2;
544 		break;
545 	case MGN_VHT3SS_MCS3:
546 		ret = DESC_RATEVHTSS3MCS3;
547 		break;
548 	case MGN_VHT3SS_MCS4:
549 		ret = DESC_RATEVHTSS3MCS4;
550 		break;
551 	case MGN_VHT3SS_MCS5:
552 		ret = DESC_RATEVHTSS3MCS5;
553 		break;
554 	case MGN_VHT3SS_MCS6:
555 		ret = DESC_RATEVHTSS3MCS6;
556 		break;
557 	case MGN_VHT3SS_MCS7:
558 		ret = DESC_RATEVHTSS3MCS7;
559 		break;
560 	case MGN_VHT3SS_MCS8:
561 		ret = DESC_RATEVHTSS3MCS8;
562 		break;
563 	case MGN_VHT3SS_MCS9:
564 		ret = DESC_RATEVHTSS3MCS9;
565 		break;
566 	case MGN_VHT4SS_MCS0:
567 		ret = DESC_RATEVHTSS4MCS0;
568 		break;
569 	case MGN_VHT4SS_MCS1:
570 		ret = DESC_RATEVHTSS4MCS1;
571 		break;
572 	case MGN_VHT4SS_MCS2:
573 		ret = DESC_RATEVHTSS4MCS2;
574 		break;
575 	case MGN_VHT4SS_MCS3:
576 		ret = DESC_RATEVHTSS4MCS3;
577 		break;
578 	case MGN_VHT4SS_MCS4:
579 		ret = DESC_RATEVHTSS4MCS4;
580 		break;
581 	case MGN_VHT4SS_MCS5:
582 		ret = DESC_RATEVHTSS4MCS5;
583 		break;
584 	case MGN_VHT4SS_MCS6:
585 		ret = DESC_RATEVHTSS4MCS6;
586 		break;
587 	case MGN_VHT4SS_MCS7:
588 		ret = DESC_RATEVHTSS4MCS7;
589 		break;
590 	case MGN_VHT4SS_MCS8:
591 		ret = DESC_RATEVHTSS4MCS8;
592 		break;
593 	case MGN_VHT4SS_MCS9:
594 		ret = DESC_RATEVHTSS4MCS9;
595 		break;
596 	default:
597 		break;
598 	}
599 
600 	return ret;
601 }
602 
HwRateToMRate(u8 rate)603 u8	HwRateToMRate(u8 rate)
604 {
605 	u8	ret_rate = MGN_1M;
606 
607 	switch (rate) {
608 
609 	case DESC_RATE1M:
610 		ret_rate = MGN_1M;
611 		break;
612 	case DESC_RATE2M:
613 		ret_rate = MGN_2M;
614 		break;
615 	case DESC_RATE5_5M:
616 		ret_rate = MGN_5_5M;
617 		break;
618 	case DESC_RATE11M:
619 		ret_rate = MGN_11M;
620 		break;
621 	case DESC_RATE6M:
622 		ret_rate = MGN_6M;
623 		break;
624 	case DESC_RATE9M:
625 		ret_rate = MGN_9M;
626 		break;
627 	case DESC_RATE12M:
628 		ret_rate = MGN_12M;
629 		break;
630 	case DESC_RATE18M:
631 		ret_rate = MGN_18M;
632 		break;
633 	case DESC_RATE24M:
634 		ret_rate = MGN_24M;
635 		break;
636 	case DESC_RATE36M:
637 		ret_rate = MGN_36M;
638 		break;
639 	case DESC_RATE48M:
640 		ret_rate = MGN_48M;
641 		break;
642 	case DESC_RATE54M:
643 		ret_rate = MGN_54M;
644 		break;
645 	case DESC_RATEMCS0:
646 		ret_rate = MGN_MCS0;
647 		break;
648 	case DESC_RATEMCS1:
649 		ret_rate = MGN_MCS1;
650 		break;
651 	case DESC_RATEMCS2:
652 		ret_rate = MGN_MCS2;
653 		break;
654 	case DESC_RATEMCS3:
655 		ret_rate = MGN_MCS3;
656 		break;
657 	case DESC_RATEMCS4:
658 		ret_rate = MGN_MCS4;
659 		break;
660 	case DESC_RATEMCS5:
661 		ret_rate = MGN_MCS5;
662 		break;
663 	case DESC_RATEMCS6:
664 		ret_rate = MGN_MCS6;
665 		break;
666 	case DESC_RATEMCS7:
667 		ret_rate = MGN_MCS7;
668 		break;
669 	case DESC_RATEMCS8:
670 		ret_rate = MGN_MCS8;
671 		break;
672 	case DESC_RATEMCS9:
673 		ret_rate = MGN_MCS9;
674 		break;
675 	case DESC_RATEMCS10:
676 		ret_rate = MGN_MCS10;
677 		break;
678 	case DESC_RATEMCS11:
679 		ret_rate = MGN_MCS11;
680 		break;
681 	case DESC_RATEMCS12:
682 		ret_rate = MGN_MCS12;
683 		break;
684 	case DESC_RATEMCS13:
685 		ret_rate = MGN_MCS13;
686 		break;
687 	case DESC_RATEMCS14:
688 		ret_rate = MGN_MCS14;
689 		break;
690 	case DESC_RATEMCS15:
691 		ret_rate = MGN_MCS15;
692 		break;
693 	case DESC_RATEMCS16:
694 		ret_rate = MGN_MCS16;
695 		break;
696 	case DESC_RATEMCS17:
697 		ret_rate = MGN_MCS17;
698 		break;
699 	case DESC_RATEMCS18:
700 		ret_rate = MGN_MCS18;
701 		break;
702 	case DESC_RATEMCS19:
703 		ret_rate = MGN_MCS19;
704 		break;
705 	case DESC_RATEMCS20:
706 		ret_rate = MGN_MCS20;
707 		break;
708 	case DESC_RATEMCS21:
709 		ret_rate = MGN_MCS21;
710 		break;
711 	case DESC_RATEMCS22:
712 		ret_rate = MGN_MCS22;
713 		break;
714 	case DESC_RATEMCS23:
715 		ret_rate = MGN_MCS23;
716 		break;
717 	case DESC_RATEMCS24:
718 		ret_rate = MGN_MCS24;
719 		break;
720 	case DESC_RATEMCS25:
721 		ret_rate = MGN_MCS25;
722 		break;
723 	case DESC_RATEMCS26:
724 		ret_rate = MGN_MCS26;
725 		break;
726 	case DESC_RATEMCS27:
727 		ret_rate = MGN_MCS27;
728 		break;
729 	case DESC_RATEMCS28:
730 		ret_rate = MGN_MCS28;
731 		break;
732 	case DESC_RATEMCS29:
733 		ret_rate = MGN_MCS29;
734 		break;
735 	case DESC_RATEMCS30:
736 		ret_rate = MGN_MCS30;
737 		break;
738 	case DESC_RATEMCS31:
739 		ret_rate = MGN_MCS31;
740 		break;
741 	case DESC_RATEVHTSS1MCS0:
742 		ret_rate = MGN_VHT1SS_MCS0;
743 		break;
744 	case DESC_RATEVHTSS1MCS1:
745 		ret_rate = MGN_VHT1SS_MCS1;
746 		break;
747 	case DESC_RATEVHTSS1MCS2:
748 		ret_rate = MGN_VHT1SS_MCS2;
749 		break;
750 	case DESC_RATEVHTSS1MCS3:
751 		ret_rate = MGN_VHT1SS_MCS3;
752 		break;
753 	case DESC_RATEVHTSS1MCS4:
754 		ret_rate = MGN_VHT1SS_MCS4;
755 		break;
756 	case DESC_RATEVHTSS1MCS5:
757 		ret_rate = MGN_VHT1SS_MCS5;
758 		break;
759 	case DESC_RATEVHTSS1MCS6:
760 		ret_rate = MGN_VHT1SS_MCS6;
761 		break;
762 	case DESC_RATEVHTSS1MCS7:
763 		ret_rate = MGN_VHT1SS_MCS7;
764 		break;
765 	case DESC_RATEVHTSS1MCS8:
766 		ret_rate = MGN_VHT1SS_MCS8;
767 		break;
768 	case DESC_RATEVHTSS1MCS9:
769 		ret_rate = MGN_VHT1SS_MCS9;
770 		break;
771 	case DESC_RATEVHTSS2MCS0:
772 		ret_rate = MGN_VHT2SS_MCS0;
773 		break;
774 	case DESC_RATEVHTSS2MCS1:
775 		ret_rate = MGN_VHT2SS_MCS1;
776 		break;
777 	case DESC_RATEVHTSS2MCS2:
778 		ret_rate = MGN_VHT2SS_MCS2;
779 		break;
780 	case DESC_RATEVHTSS2MCS3:
781 		ret_rate = MGN_VHT2SS_MCS3;
782 		break;
783 	case DESC_RATEVHTSS2MCS4:
784 		ret_rate = MGN_VHT2SS_MCS4;
785 		break;
786 	case DESC_RATEVHTSS2MCS5:
787 		ret_rate = MGN_VHT2SS_MCS5;
788 		break;
789 	case DESC_RATEVHTSS2MCS6:
790 		ret_rate = MGN_VHT2SS_MCS6;
791 		break;
792 	case DESC_RATEVHTSS2MCS7:
793 		ret_rate = MGN_VHT2SS_MCS7;
794 		break;
795 	case DESC_RATEVHTSS2MCS8:
796 		ret_rate = MGN_VHT2SS_MCS8;
797 		break;
798 	case DESC_RATEVHTSS2MCS9:
799 		ret_rate = MGN_VHT2SS_MCS9;
800 		break;
801 	case DESC_RATEVHTSS3MCS0:
802 		ret_rate = MGN_VHT3SS_MCS0;
803 		break;
804 	case DESC_RATEVHTSS3MCS1:
805 		ret_rate = MGN_VHT3SS_MCS1;
806 		break;
807 	case DESC_RATEVHTSS3MCS2:
808 		ret_rate = MGN_VHT3SS_MCS2;
809 		break;
810 	case DESC_RATEVHTSS3MCS3:
811 		ret_rate = MGN_VHT3SS_MCS3;
812 		break;
813 	case DESC_RATEVHTSS3MCS4:
814 		ret_rate = MGN_VHT3SS_MCS4;
815 		break;
816 	case DESC_RATEVHTSS3MCS5:
817 		ret_rate = MGN_VHT3SS_MCS5;
818 		break;
819 	case DESC_RATEVHTSS3MCS6:
820 		ret_rate = MGN_VHT3SS_MCS6;
821 		break;
822 	case DESC_RATEVHTSS3MCS7:
823 		ret_rate = MGN_VHT3SS_MCS7;
824 		break;
825 	case DESC_RATEVHTSS3MCS8:
826 		ret_rate = MGN_VHT3SS_MCS8;
827 		break;
828 	case DESC_RATEVHTSS3MCS9:
829 		ret_rate = MGN_VHT3SS_MCS9;
830 		break;
831 	case DESC_RATEVHTSS4MCS0:
832 		ret_rate = MGN_VHT4SS_MCS0;
833 		break;
834 	case DESC_RATEVHTSS4MCS1:
835 		ret_rate = MGN_VHT4SS_MCS1;
836 		break;
837 	case DESC_RATEVHTSS4MCS2:
838 		ret_rate = MGN_VHT4SS_MCS2;
839 		break;
840 	case DESC_RATEVHTSS4MCS3:
841 		ret_rate = MGN_VHT4SS_MCS3;
842 		break;
843 	case DESC_RATEVHTSS4MCS4:
844 		ret_rate = MGN_VHT4SS_MCS4;
845 		break;
846 	case DESC_RATEVHTSS4MCS5:
847 		ret_rate = MGN_VHT4SS_MCS5;
848 		break;
849 	case DESC_RATEVHTSS4MCS6:
850 		ret_rate = MGN_VHT4SS_MCS6;
851 		break;
852 	case DESC_RATEVHTSS4MCS7:
853 		ret_rate = MGN_VHT4SS_MCS7;
854 		break;
855 	case DESC_RATEVHTSS4MCS8:
856 		ret_rate = MGN_VHT4SS_MCS8;
857 		break;
858 	case DESC_RATEVHTSS4MCS9:
859 		ret_rate = MGN_VHT4SS_MCS9;
860 		break;
861 
862 	default:
863 		RTW_INFO("HwRateToMRate(): Non supported Rate [%x]!!!\n", rate);
864 		break;
865 	}
866 
867 	return ret_rate;
868 }
869 
HalSetBrateCfg(IN PADAPTER Adapter,IN u8 * mBratesOS,OUT u16 * pBrateCfg)870 void	HalSetBrateCfg(
871 	IN PADAPTER		Adapter,
872 	IN u8			*mBratesOS,
873 	OUT u16			*pBrateCfg)
874 {
875 	u8	i, is_brate, brate;
876 
877 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
878 		is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
879 		brate = mBratesOS[i] & 0x7f;
880 
881 		if (is_brate) {
882 			switch (brate) {
883 			case IEEE80211_CCK_RATE_1MB:
884 				*pBrateCfg |= RATE_1M;
885 				break;
886 			case IEEE80211_CCK_RATE_2MB:
887 				*pBrateCfg |= RATE_2M;
888 				break;
889 			case IEEE80211_CCK_RATE_5MB:
890 				*pBrateCfg |= RATE_5_5M;
891 				break;
892 			case IEEE80211_CCK_RATE_11MB:
893 				*pBrateCfg |= RATE_11M;
894 				break;
895 			case IEEE80211_OFDM_RATE_6MB:
896 				*pBrateCfg |= RATE_6M;
897 				break;
898 			case IEEE80211_OFDM_RATE_9MB:
899 				*pBrateCfg |= RATE_9M;
900 				break;
901 			case IEEE80211_OFDM_RATE_12MB:
902 				*pBrateCfg |= RATE_12M;
903 				break;
904 			case IEEE80211_OFDM_RATE_18MB:
905 				*pBrateCfg |= RATE_18M;
906 				break;
907 			case IEEE80211_OFDM_RATE_24MB:
908 				*pBrateCfg |= RATE_24M;
909 				break;
910 			case IEEE80211_OFDM_RATE_36MB:
911 				*pBrateCfg |= RATE_36M;
912 				break;
913 			case IEEE80211_OFDM_RATE_48MB:
914 				*pBrateCfg |= RATE_48M;
915 				break;
916 			case IEEE80211_OFDM_RATE_54MB:
917 				*pBrateCfg |= RATE_54M;
918 				break;
919 			}
920 		}
921 	}
922 }
923 
924 static VOID
_OneOutPipeMapping(IN PADAPTER pAdapter)925 _OneOutPipeMapping(
926 	IN	PADAPTER	pAdapter
927 )
928 {
929 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
930 
931 	pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
932 	pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
933 	pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
934 	pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
935 
936 	pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
937 	pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
938 	pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
939 	pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
940 }
941 
942 static VOID
_TwoOutPipeMapping(IN PADAPTER pAdapter,IN BOOLEAN bWIFICfg)943 _TwoOutPipeMapping(
944 	IN	PADAPTER	pAdapter,
945 	IN	BOOLEAN		bWIFICfg
946 )
947 {
948 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
949 
950 	if (bWIFICfg) { /* WMM */
951 
952 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
953 		/* {  0, 	1, 	0, 	1, 	0, 	0, 	0, 	0, 		0	}; */
954 		/* 0:ep_0 num, 1:ep_1 num */
955 
956 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
957 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
958 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
959 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
960 
961 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
962 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
963 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
964 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
965 
966 	} else { /* typical setting */
967 
968 
969 		/* BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA */
970 		/* {  1, 	1, 	0, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
971 		/* 0:ep_0 num, 1:ep_1 num */
972 
973 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
974 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
975 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
976 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
977 
978 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
979 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
980 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
981 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
982 
983 	}
984 
985 }
986 
_ThreeOutPipeMapping(IN PADAPTER pAdapter,IN BOOLEAN bWIFICfg)987 static VOID _ThreeOutPipeMapping(
988 	IN	PADAPTER	pAdapter,
989 	IN	BOOLEAN		bWIFICfg
990 )
991 {
992 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
993 
994 	if (bWIFICfg) { /* for WMM */
995 
996 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
997 		/* {  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	}; */
998 		/* 0:H, 1:N, 2:L */
999 
1000 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1001 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1002 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1003 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1004 
1005 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1006 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1007 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1008 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1009 
1010 	} else { /* typical setting */
1011 
1012 
1013 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1014 		/* {  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
1015 		/* 0:H, 1:N, 2:L */
1016 
1017 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1018 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1019 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1020 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1021 
1022 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1023 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1024 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1025 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
1026 	}
1027 
1028 }
_FourOutPipeMapping(IN PADAPTER pAdapter,IN BOOLEAN bWIFICfg)1029 static VOID _FourOutPipeMapping(
1030 	IN	PADAPTER	pAdapter,
1031 	IN	BOOLEAN		bWIFICfg
1032 )
1033 {
1034 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
1035 
1036 	if (bWIFICfg) { /* for WMM */
1037 
1038 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1039 		/* {  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	}; */
1040 		/* 0:H, 1:N, 2:L ,3:E */
1041 
1042 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1043 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1044 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1045 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1046 
1047 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1048 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1049 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1050 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1051 
1052 	} else { /* typical setting */
1053 
1054 
1055 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1056 		/* {  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
1057 		/* 0:H, 1:N, 2:L */
1058 
1059 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1060 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1061 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1062 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1063 
1064 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1065 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1066 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1067 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
1068 	}
1069 
1070 }
1071 BOOLEAN
Hal_MappingOutPipe(IN PADAPTER pAdapter,IN u8 NumOutPipe)1072 Hal_MappingOutPipe(
1073 	IN	PADAPTER	pAdapter,
1074 	IN	u8		NumOutPipe
1075 )
1076 {
1077 	struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1078 
1079 	BOOLEAN	 bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1080 
1081 	BOOLEAN result = _TRUE;
1082 
1083 	switch (NumOutPipe) {
1084 	case 2:
1085 		_TwoOutPipeMapping(pAdapter, bWIFICfg);
1086 		break;
1087 	case 3:
1088 	case 4:
1089 		_ThreeOutPipeMapping(pAdapter, bWIFICfg);
1090 		break;
1091 	case 1:
1092 		_OneOutPipeMapping(pAdapter);
1093 		break;
1094 	default:
1095 		result = _FALSE;
1096 		break;
1097 	}
1098 
1099 	return result;
1100 
1101 }
1102 
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1103 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1104 {
1105 	if (padapter->HalFunc.reqtxrpt)
1106 		padapter->HalFunc.reqtxrpt(padapter, macid);
1107 }
1108 
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1109 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1110 {
1111 	int i;
1112 	_adapter *iface;
1113 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1114 	u8 mac_addr[ETH_ALEN];
1115 
1116 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1117 	rtw_mbid_cam_dump(sel, __func__, adapter);
1118 #else
1119 	for (i = 0; i < dvobj->iface_nums; i++) {
1120 		iface = dvobj->padapters[i];
1121 		if (iface) {
1122 			rtw_hal_get_macaddr_port(iface, mac_addr);
1123 			RTW_PRINT_SEL(sel, ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",
1124 				ADPT_ARG(iface), iface->hw_port, MAC_ARG(mac_addr));
1125 		}
1126 	}
1127 #endif
1128 }
1129 
rtw_restore_mac_addr(_adapter * adapter)1130 void rtw_restore_mac_addr(_adapter *adapter)
1131 {
1132 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1133 	_adapter *iface;
1134 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1135 
1136 	rtw_mbid_cam_restore(adapter);
1137 #else
1138 	int i;
1139 	_adapter *iface;
1140 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1141 
1142 	for (i = 0; i < dvobj->iface_nums; i++) {
1143 		iface = dvobj->padapters[i];
1144 		if (iface)
1145 			rtw_hal_set_macaddr_port(iface, adapter_mac_addr(iface));
1146 	}
1147 #endif
1148 	if (1)
1149 		rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1150 }
1151 
rtw_init_hal_com_default_value(PADAPTER Adapter)1152 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1153 {
1154 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
1155 	struct registry_priv *regsty = adapter_to_regsty(Adapter);
1156 
1157 	pHalData->AntDetection = 1;
1158 	pHalData->antenna_test = _FALSE;
1159 	pHalData->u1ForcedIgiLb = regsty->force_igi_lb;
1160 }
1161 
1162 /*
1163 * C2H event format:
1164 * Field	 TRIGGER		CONTENT	   CMD_SEQ	CMD_LEN		 CMD_ID
1165 * BITS	 [127:120]	[119:16]      [15:8]		  [7:4]		   [3:0]
1166 */
1167 
c2h_evt_clear(_adapter * adapter)1168 void c2h_evt_clear(_adapter *adapter)
1169 {
1170 	rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1171 }
1172 
c2h_evt_read(_adapter * adapter,u8 * buf)1173 s32 c2h_evt_read(_adapter *adapter, u8 *buf)
1174 {
1175 	s32 ret = _FAIL;
1176 	struct c2h_evt_hdr *c2h_evt;
1177 	int i;
1178 	u8 trigger;
1179 
1180 	if (buf == NULL)
1181 		goto exit;
1182 
1183 #if defined(CONFIG_RTL8188E)
1184 
1185 	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1186 
1187 	if (trigger == C2H_EVT_HOST_CLOSE) {
1188 		goto exit; /* Not ready */
1189 	} else if (trigger != C2H_EVT_FW_CLOSE) {
1190 		goto clear_evt; /* Not a valid value */
1191 	}
1192 
1193 	c2h_evt = (struct c2h_evt_hdr *)buf;
1194 
1195 	_rtw_memset(c2h_evt, 0, 16);
1196 
1197 	*buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1198 	*(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
1199 
1200 	RTW_DBG_DUMP("c2h_evt_read(): ",
1201 		     &c2h_evt , sizeof(c2h_evt));
1202 
1203 	if (0) {
1204 		RTW_INFO("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__
1205 			 , c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger);
1206 	}
1207 
1208 	/* Read the content */
1209 	for (i = 0; i < c2h_evt->plen; i++)
1210 		c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1211 
1212 	RTW_DBG_DUMP("c2h_evt_read(): Command Content:\n",
1213 		     c2h_evt->payload, c2h_evt->plen);
1214 
1215 	ret = _SUCCESS;
1216 
1217 clear_evt:
1218 	/*
1219 	* Clear event to notify FW we have read the command.
1220 	* If this field isn't clear, the FW won't update the next command message.
1221 	*/
1222 	c2h_evt_clear(adapter);
1223 #endif
1224 exit:
1225 	return ret;
1226 }
1227 
1228 /*
1229 * C2H event format:
1230 * Field    TRIGGER    CMD_LEN    CONTENT    CMD_SEQ    CMD_ID
1231 * BITS    [127:120]   [119:112]    [111:16]	     [15:8]         [7:0]
1232 */
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1233 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1234 {
1235 	s32 ret = _FAIL;
1236 	struct c2h_evt_hdr_88xx *c2h_evt;
1237 	int i;
1238 	u8 trigger;
1239 
1240 	if (buf == NULL)
1241 		goto exit;
1242 
1243 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
1244 	|| defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8723B) \
1245 	|| defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D)
1246 
1247 	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1248 
1249 	if (trigger == C2H_EVT_HOST_CLOSE) {
1250 		goto exit; /* Not ready */
1251 	} else if (trigger != C2H_EVT_FW_CLOSE) {
1252 		goto clear_evt; /* Not a valid value */
1253 	}
1254 
1255 	c2h_evt = (struct c2h_evt_hdr_88xx *)buf;
1256 
1257 	_rtw_memset(c2h_evt, 0, 16);
1258 
1259 	c2h_evt->id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1260 	c2h_evt->seq = rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX);
1261 	c2h_evt->plen = rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX);
1262 
1263 	RTW_DBG_DUMP("c2h_evt_read(): ",
1264 		     &c2h_evt , sizeof(c2h_evt));
1265 
1266 	if (0) {
1267 		RTW_INFO("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__
1268 			 , c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger);
1269 	}
1270 
1271 	/* Read the content */
1272 	for (i = 0; i < c2h_evt->plen; i++)
1273 		c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1274 
1275 	RTW_DBG_DUMP("c2h_evt_read(): Command Content:\n",
1276 		     c2h_evt->payload, c2h_evt->plen);
1277 
1278 	ret = _SUCCESS;
1279 
1280 clear_evt:
1281 	/*
1282 	* Clear event to notify FW we have read the command.
1283 	* If this field isn't clear, the FW won't update the next command message.
1284 	*/
1285 	c2h_evt_clear(adapter);
1286 #endif
1287 exit:
1288 	return ret;
1289 }
1290 
1291 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1292 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1293 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1294 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data)			LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1295 #define	GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1296 #define	GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 4)
1297 #define	GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1298 #define	GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1299 #define	GET_C2H_MAC_HIDDEN_RPT_BW(_data)				LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1300 #define	GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1301 #define	GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1302 #define	GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1303 
1304 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1305 	#define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1306 #endif
1307 
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1308 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1309 {
1310 	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
1311 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1312 	int ret = _FAIL;
1313 
1314 	u32 uuid;
1315 	u8 uuid_x;
1316 	u8 uuid_y;
1317 	u8 uuid_z;
1318 	u16 uuid_crc;
1319 
1320 	u8 hci_type;
1321 	u8 package_type;
1322 	u8 wl_func;
1323 	u8 hw_stype;
1324 	u8 bw;
1325 	u8 ant_num;
1326 	u8 protocol;
1327 	u8 nic;
1328 
1329 	int i;
1330 
1331 	if (len < MAC_HIDDEN_RPT_LEN) {
1332 		RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1333 		goto exit;
1334 	}
1335 
1336 	uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1337 	uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1338 	uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1339 	uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1340 
1341 	hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1342 	package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1343 
1344 	wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1345 	hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1346 
1347 	bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1348 	ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1349 
1350 	protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1351 	nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1352 
1353 	if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1354 		for (i = 0; i < len; i++)
1355 			RTW_INFO("%s: 0x%02X\n", __func__, *(data + i));
1356 
1357 		RTW_INFO("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1358 		RTW_INFO("hci_type:0x%x\n", hci_type);
1359 		RTW_INFO("package_type:0x%x\n", package_type);
1360 		RTW_INFO("wl_func:0x%x\n", wl_func);
1361 		RTW_INFO("hw_stype:0x%x\n", hw_stype);
1362 		RTW_INFO("bw:0x%x\n", bw);
1363 		RTW_INFO("ant_num:0x%x\n", ant_num);
1364 		RTW_INFO("protocol:0x%x\n", protocol);
1365 		RTW_INFO("nic:0x%x\n", nic);
1366 	}
1367 
1368 	hal_data->PackageType = package_type;
1369 	hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1370 	hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1371 	hal_spec->nss_num = rtw_min(hal_spec->nss_num, ant_num);
1372 	hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1373 
1374 	ret = _SUCCESS;
1375 
1376 exit:
1377 	return ret;
1378 }
1379 
hal_read_mac_hidden_rpt(_adapter * adapter)1380 int hal_read_mac_hidden_rpt(_adapter *adapter)
1381 {
1382 	int ret = _FAIL;
1383 	int ret_fwdl;
1384 	u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN] = {0};
1385 	u32 start = rtw_get_current_time();
1386 	u32 cnt = 0;
1387 	u32 timeout_ms = 800;
1388 	u32 min_cnt = 10;
1389 	u8 id = C2H_MAC_HIDDEN_RPT + 1;
1390 	int i;
1391 
1392 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1393 	u8 hci_type = rtw_get_intf_type(adapter);
1394 
1395 	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1396 	    && !rtw_is_hw_init_completed(adapter))
1397 		rtw_hal_power_on(adapter);
1398 #endif
1399 
1400 	/* clear data ready */
1401 	rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, id);
1402 
1403 	/* download FW */
1404 	ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1405 	if (ret_fwdl != _SUCCESS)
1406 		goto mac_hidden_rpt_hdl;
1407 
1408 	/* polling for data ready */
1409 	start = rtw_get_current_time();
1410 	do {
1411 		cnt++;
1412 		id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1413 		if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1414 			break;
1415 		rtw_msleep_os(10);
1416 	} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1417 
1418 	if (id == C2H_MAC_HIDDEN_RPT) {
1419 		/* read data */
1420 		for (i = 0; i < MAC_HIDDEN_RPT_LEN; i++)
1421 			mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1422 	}
1423 
1424 mac_hidden_rpt_hdl:
1425 	c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1426 
1427 	if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1428 		ret = _SUCCESS;
1429 
1430 exit:
1431 
1432 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1433 	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1434 	    && !rtw_is_hw_init_completed(adapter))
1435 		rtw_hal_power_off(adapter);
1436 #endif
1437 
1438 	RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1439 		, (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1440 
1441 	return ret;
1442 }
1443 
rtw_hal_networktype_to_raid(_adapter * adapter,struct sta_info * psta)1444 u8  rtw_hal_networktype_to_raid(_adapter *adapter, struct sta_info *psta)
1445 {
1446 	if (IS_NEW_GENERATION_IC(adapter))
1447 		return networktype_to_raid_ex(adapter, psta);
1448 	else
1449 		return networktype_to_raid(adapter, psta);
1450 
1451 }
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)1452 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
1453 {
1454 
1455 	u8 raid;
1456 	if (IS_NEW_GENERATION_IC(adapter)) {
1457 
1458 		raid = (network_type & WIRELESS_11B)	? RATEID_IDX_B
1459 		       : RATEID_IDX_G;
1460 	} else {
1461 		raid = (network_type & WIRELESS_11B)	? RATR_INX_WIRELESS_B
1462 		       : RATR_INX_WIRELESS_G;
1463 	}
1464 	return raid;
1465 }
1466 
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)1467 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
1468 {
1469 	u8	i, rf_type, limit;
1470 	u64	tx_ra_bitmap;
1471 
1472 	if (psta == NULL)
1473 		return;
1474 
1475 	tx_ra_bitmap = 0;
1476 
1477 	/* b/g mode ra_bitmap  */
1478 	for (i = 0; i < sizeof(psta->bssrateset); i++) {
1479 		if (psta->bssrateset[i])
1480 			tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
1481 	}
1482 
1483 #ifdef CONFIG_80211N_HT
1484 #ifdef CONFIG_80211AC_VHT
1485 	/* AC mode ra_bitmap */
1486 	if (psta->vhtpriv.vht_option)
1487 		tx_ra_bitmap |= (rtw_vht_rate_to_bitmap(psta->vhtpriv.vht_mcs_map) << 12);
1488 	else
1489 #endif /* CONFIG_80211AC_VHT */
1490 	{
1491 		/* n mode ra_bitmap */
1492 		if (psta->htpriv.ht_option) {
1493 			rf_type = RF_1T1R;
1494 			rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1495 			if (rf_type == RF_2T2R)
1496 				limit = 16; /* 2R */
1497 			else if (rf_type == RF_3T3R)
1498 				limit = 24; /* 3R */
1499 			else
1500 				limit = 8; /* 1R */
1501 
1502 
1503 			/* Handling SMPS mode for AP MODE only*/
1504 			if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
1505 				/*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
1506 				if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
1507 					/*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
1508 					limit = 8;/*  1R*/
1509 				}
1510 			}
1511 
1512 			for (i = 0; i < limit; i++) {
1513 				if (psta->htpriv.ht_cap.supp_mcs_set[i / 8] & BIT(i % 8))
1514 					tx_ra_bitmap |= BIT(i + 12);
1515 			}
1516 		}
1517 	}
1518 #endif /* CONFIG_80211N_HT */
1519 	RTW_INFO("supp_mcs_set = %02x, %02x, %02x, rf_type=%d, tx_ra_bitmap=%016llx\n"
1520 		, psta->htpriv.ht_cap.supp_mcs_set[0], psta->htpriv.ht_cap.supp_mcs_set[1], psta->htpriv.ht_cap.supp_mcs_set[2], rf_type, tx_ra_bitmap);
1521 	psta->ra_mask = tx_ra_bitmap;
1522 	psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
1523 }
1524 
1525 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
1526 	#define SEC_CAM_ACCESS_TIMEOUT_MS 200
1527 #endif
1528 
1529 #ifndef DBG_SEC_CAM_ACCESS
1530 	#define DBG_SEC_CAM_ACCESS 0
1531 #endif
1532 
rtw_sec_read_cam(_adapter * adapter,u8 addr)1533 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
1534 {
1535 	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
1536 	u32 rdata;
1537 	u32 cnt = 0;
1538 	u32 start = 0, end = 0;
1539 	u8 timeout = 0;
1540 	u8 sr = 0;
1541 
1542 	_enter_critical_mutex(mutex, NULL);
1543 
1544 	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
1545 
1546 	start = rtw_get_current_time();
1547 	while (1) {
1548 		if (rtw_is_surprise_removed(adapter)) {
1549 			sr = 1;
1550 			break;
1551 		}
1552 
1553 		cnt++;
1554 		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
1555 			break;
1556 
1557 		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
1558 			timeout = 1;
1559 			break;
1560 		}
1561 	}
1562 	end = rtw_get_current_time();
1563 
1564 	rdata = rtw_read32(adapter, REG_CAMREAD);
1565 
1566 	_exit_critical_mutex(mutex, NULL);
1567 
1568 	if (DBG_SEC_CAM_ACCESS || timeout) {
1569 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
1570 			, FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
1571 	}
1572 
1573 	return rdata;
1574 }
1575 
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)1576 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
1577 {
1578 	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
1579 	u32 cnt = 0;
1580 	u32 start = 0, end = 0;
1581 	u8 timeout = 0;
1582 	u8 sr = 0;
1583 
1584 	_enter_critical_mutex(mutex, NULL);
1585 
1586 	rtw_write32(adapter, REG_CAMWRITE, wdata);
1587 	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
1588 
1589 	start = rtw_get_current_time();
1590 	while (1) {
1591 		if (rtw_is_surprise_removed(adapter)) {
1592 			sr = 1;
1593 			break;
1594 		}
1595 
1596 		cnt++;
1597 		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
1598 			break;
1599 
1600 		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
1601 			timeout = 1;
1602 			break;
1603 		}
1604 	}
1605 	end = rtw_get_current_time();
1606 
1607 	_exit_critical_mutex(mutex, NULL);
1608 
1609 	if (DBG_SEC_CAM_ACCESS || timeout) {
1610 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
1611 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
1612 	}
1613 }
1614 
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)1615 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
1616 {
1617 	unsigned int val, addr;
1618 	u8 i;
1619 	u32 rdata;
1620 	u8 begin = 0;
1621 	u8 end = 5; /* TODO: consider other key length accordingly */
1622 
1623 	if (!ctrl && !mac && !key) {
1624 		rtw_warn_on(1);
1625 		goto exit;
1626 	}
1627 
1628 	/* TODO: check id range */
1629 
1630 	if (!ctrl && !mac)
1631 		begin = 2; /* read from key */
1632 
1633 	if (!key && !mac)
1634 		end = 0; /* read to ctrl */
1635 	else if (!key)
1636 		end = 2; /* read to mac */
1637 
1638 	for (i = begin; i <= end; i++) {
1639 		rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
1640 
1641 		switch (i) {
1642 		case 0:
1643 			if (ctrl)
1644 				_rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
1645 			if (mac)
1646 				_rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
1647 			break;
1648 		case 1:
1649 			if (mac)
1650 				_rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
1651 			break;
1652 		default:
1653 			if (key)
1654 				_rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
1655 			break;
1656 		}
1657 	}
1658 
1659 exit:
1660 	return;
1661 }
1662 
1663 
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)1664 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
1665 {
1666 	unsigned int i;
1667 	int j;
1668 	u8 addr;
1669 	u32 wdata;
1670 
1671 	/* TODO: consider other key length accordingly */
1672 #if 0
1673 	switch ((ctrl & 0x1c) >> 2) {
1674 	case _WEP40_:
1675 	case _TKIP_:
1676 	case _AES_:
1677 	case _WEP104_:
1678 
1679 	}
1680 #else
1681 	j = 5;
1682 #endif
1683 
1684 	for (; j >= 0; j--) {
1685 		switch (j) {
1686 		case 0:
1687 			wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
1688 			break;
1689 		case 1:
1690 			wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
1691 			break;
1692 		default:
1693 			i = (j - 2) << 2;
1694 			wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
1695 			break;
1696 		}
1697 
1698 		addr = (id << 3) + j;
1699 
1700 		rtw_sec_write_cam(adapter, addr, wdata);
1701 	}
1702 }
1703 
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)1704 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
1705 {
1706 	u8 addr;
1707 
1708 	addr = (id << 3);
1709 	rtw_sec_write_cam(adapter, addr, 0);
1710 }
1711 
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)1712 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
1713 {
1714 	bool res;
1715 	u16 ctrl;
1716 
1717 	rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
1718 
1719 	res = (ctrl & BIT6) ? _TRUE : _FALSE;
1720 	return res;
1721 }
1722 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)1723 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
1724 {
1725 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1726 
1727 	_rtw_spinlock_init(&mbid_cam_ctl->lock);
1728 	mbid_cam_ctl->bitmap = 0;
1729 	ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
1730 	_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
1731 }
1732 
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)1733 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
1734 {
1735 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1736 
1737 	_rtw_spinlock_free(&mbid_cam_ctl->lock);
1738 }
1739 
rtw_mbid_cam_reset(_adapter * adapter)1740 void rtw_mbid_cam_reset(_adapter *adapter)
1741 {
1742 	_irqL irqL;
1743 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1744 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1745 
1746 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1747 	mbid_cam_ctl->bitmap = 0;
1748 	_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
1749 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1750 
1751 	ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
1752 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)1753 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
1754 {
1755 	u8 i;
1756 	u8 cam_id = INVALID_CAM_ID;
1757 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1758 
1759 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
1760 		if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
1761 			cam_id = i;
1762 			break;
1763 		}
1764 	}
1765 
1766 	RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
1767 	return cam_id;
1768 }
1769 
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)1770 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
1771 {
1772 	_irqL irqL;
1773 
1774 	u8 cam_id = INVALID_CAM_ID;
1775 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1776 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1777 
1778 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1779 	cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
1780 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1781 
1782 	return cam_id;
1783 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)1784 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
1785 {
1786 	u8 i;
1787 	u8 cam_id = INVALID_CAM_ID;
1788 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1789 
1790 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
1791 		if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
1792 			cam_id = i;
1793 			break;
1794 		}
1795 	}
1796 	if (cam_id != INVALID_CAM_ID)
1797 		RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
1798 			__func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
1799 
1800 	return cam_id;
1801 }
1802 
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)1803 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
1804 {
1805 	_irqL irqL;
1806 	u8 cam_id = INVALID_CAM_ID;
1807 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1808 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1809 
1810 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1811 	cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
1812 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1813 
1814 	return cam_id;
1815 }
rtw_get_max_mbid_cam_id(_adapter * adapter)1816 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
1817 {
1818 	_irqL irqL;
1819 	s8 i;
1820 	u8 cam_id = INVALID_CAM_ID;
1821 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1822 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1823 
1824 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1825 	for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
1826 		if (mbid_cam_ctl->bitmap & BIT(i)) {
1827 			cam_id = i;
1828 			break;
1829 		}
1830 	}
1831 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1832 	/*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
1833 	return cam_id;
1834 }
1835 
rtw_get_mbid_cam_entry_num(_adapter * adapter)1836 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
1837 {
1838 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1839 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1840 
1841 	return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
1842 }
1843 
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)1844 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
1845 {
1846 	if (adapter && pmbid_cam && mac_addr) {
1847 		_rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
1848 		pmbid_cam->iface_id = adapter->iface_id;
1849 	}
1850 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)1851 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
1852 {
1853 	if (pmbid_cam) {
1854 		_rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
1855 		pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
1856 	}
1857 }
1858 
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)1859 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
1860 {
1861 	_irqL irqL;
1862 	u8 cam_id = INVALID_CAM_ID, i;
1863 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1864 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1865 	u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
1866 
1867 	if (entry_num >= TOTAL_MBID_CAM_NUM) {
1868 		RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
1869 		rtw_warn_on(1);
1870 	}
1871 
1872 	if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
1873 		goto exit;
1874 
1875 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1876 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
1877 		if (!(mbid_cam_ctl->bitmap & BIT(i))) {
1878 			mbid_cam_ctl->bitmap |= BIT(i);
1879 			cam_id = i;
1880 			break;
1881 		}
1882 	}
1883 	if ((cam_id != INVALID_CAM_ID) && (mac_addr))
1884 		mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
1885 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1886 
1887 	if (cam_id != INVALID_CAM_ID) {
1888 		ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
1889 		RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
1890 #ifdef DBG_MBID_CAM_DUMP
1891 		rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
1892 #endif
1893 	} else
1894 		RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
1895 exit:
1896 	return cam_id;
1897 }
1898 
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)1899 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
1900 {
1901 	_irqL irqL;
1902 	u8 entry_id = INVALID_CAM_ID;
1903 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1904 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1905 
1906 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1907 	entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
1908 	if (entry_id != INVALID_CAM_ID)
1909 		mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
1910 
1911 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1912 
1913 	return entry_id;
1914 }
1915 
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)1916 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
1917 {
1918 	_irqL irqL;
1919 	u8 ret = _FALSE;
1920 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1921 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1922 
1923 	if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
1924 		RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
1925 		rtw_warn_on(1);
1926 	}
1927 	if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
1928 		goto exit;
1929 
1930 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1931 	if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
1932 		if (mac_addr) {
1933 			mbid_cam_ctl->bitmap |= BIT(camid);
1934 			mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
1935 			ret = _TRUE;
1936 		}
1937 	}
1938 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1939 
1940 	if (ret == _TRUE) {
1941 		ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
1942 		RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
1943 #ifdef DBG_MBID_CAM_DUMP
1944 		rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
1945 #endif
1946 	} else
1947 		RTW_INFO("%s  [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
1948 
1949 exit:
1950 	return ret;
1951 }
1952 
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)1953 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
1954 {
1955 	_irqL irqL;
1956 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1957 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1958 
1959 	if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
1960 		RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
1961 		rtw_warn_on(1);
1962 	}
1963 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1964 	mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
1965 	mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
1966 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1967 	ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
1968 	RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
1969 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)1970 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
1971 {
1972 	_irqL irqL;
1973 	u8 i;
1974 	_adapter *iface;
1975 	u8 iface_id;
1976 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1977 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1978 	u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
1979 	u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
1980 
1981 	RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
1982 
1983 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1984 	RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
1985 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
1986 		RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
1987 
1988 		if (mbid_cam_ctl->bitmap & BIT(i)) {
1989 			iface_id = dvobj->mbid_cam_cache[i].iface_id;
1990 			RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
1991 			RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
1992 
1993 			iface = dvobj->padapters[iface_id];
1994 			if (iface) {
1995 				if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE)
1996 					RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
1997 				else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE)
1998 					RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
1999 				else
2000 					RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2001 			}
2002 
2003 		} else
2004 			RTW_PRINT_SEL(sel, "N/A\n");
2005 	}
2006 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2007 	return 0;
2008 }
2009 
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2010 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2011 {
2012 	u8 poll = 1;
2013 	u8 cam_ready = _FALSE;
2014 	u32 cam_data1 = 0;
2015 	u16 cam_data2 = 0;
2016 
2017 	if (RTW_CANNOT_RUN(padapter))
2018 		return;
2019 
2020 	rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2021 
2022 	do {
2023 		if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2024 			cam_ready = _TRUE;
2025 			break;
2026 		}
2027 		poll++;
2028 	} while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2029 
2030 	if (cam_ready) {
2031 		cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2032 		mac[0] = cam_data1 & 0xFF;
2033 		mac[1] = (cam_data1 >> 8) & 0xFF;
2034 		mac[2] = (cam_data1 >> 16) & 0xFF;
2035 		mac[3] = (cam_data1 >> 24) & 0xFF;
2036 
2037 		cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
2038 		mac[4] = cam_data2 & 0xFF;
2039 		mac[5] = (cam_data2 >> 8) & 0xFF;
2040 	}
2041 
2042 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)2043 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
2044 {
2045 	/*_irqL irqL;*/
2046 	u8 i;
2047 	u8 mac_addr[ETH_ALEN];
2048 
2049 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2050 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2051 
2052 	RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
2053 
2054 	/*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2055 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2056 		RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2057 		_rtw_memset(mac_addr, 0, ETH_ALEN);
2058 		read_mbssid_cam(adapter, i, mac_addr);
2059 		RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
2060 	}
2061 	/*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2062 	return 0;
2063 }
2064 
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2065 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2066 {
2067 	u32	cam_val[2] = {0};
2068 
2069 	cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
2070 	cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT)  | (mac[5] << 8) | mac[4];
2071 
2072 	rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
2073 }
2074 
clear_mbssid_cam(_adapter * padapter,u8 cam_addr)2075 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
2076 {
2077 	rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
2078 }
enable_mbssid_cam(_adapter * adapter)2079 static void enable_mbssid_cam(_adapter *adapter)
2080 {
2081 	u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2082 	/*enable MBSSID*/
2083 	rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) | RCR_ENMBID);
2084 	if (max_cam_id != INVALID_CAM_ID) {
2085 		rtw_write8(adapter, REG_MBID_NUM,
2086 			((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | (max_cam_id & 0x07)));
2087 	}
2088 }
rtw_mbid_cam_restore(_adapter * adapter)2089 void rtw_mbid_cam_restore(_adapter *adapter)
2090 {
2091 	u8 i;
2092 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2093 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2094 
2095 #ifdef DBG_MBID_CAM_DUMP
2096 	rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2097 #endif
2098 
2099 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2100 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2101 			write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
2102 			RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2103 		}
2104 	}
2105 	enable_mbssid_cam(adapter);
2106 }
2107 #endif /*CONFIG_MBSSID_CAM*/
2108 
2109 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)2110 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
2111 {
2112 
2113 #if 0 /*TODO - modify for more flexible*/
2114 	u8 idx = 0;
2115 
2116 	if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
2117 	    (adapter_to_dvobj(adapter)->iface_state.sta_num == 1)) {
2118 		for (idx = 0; idx < 6; idx++)
2119 			rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
2120 	}  else {
2121 		/*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
2122 		u8 entry_id;
2123 
2124 		if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
2125 		    (adapter_to_dvobj(adapter)->iface_state.ap_num == 1)) {
2126 			entry_id = 0;
2127 			if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
2128 				RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
2129 				write_mbssid_cam(adapter, entry_id, val);
2130 			}
2131 		} else {
2132 			entry_id = rtw_mbid_camid_alloc(adapter, val);
2133 			if (entry_id != INVALID_CAM_ID)
2134 				write_mbssid_cam(adapter, entry_id, val);
2135 		}
2136 	}
2137 #else
2138 	{
2139 		/*
2140 			MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
2141 		*/
2142 		u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
2143 
2144 
2145 		if (entry_id != INVALID_CAM_ID) {
2146 			write_mbssid_cam(adapter, entry_id, mac_addr);
2147 			enable_mbssid_cam(adapter);
2148 		}
2149 	}
2150 #endif
2151 }
2152 
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)2153 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
2154 {
2155 	u8 idx = 0;
2156 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2157 	u8 entry_id;
2158 
2159 	if (!mac_addr) {
2160 		rtw_warn_on(1);
2161 		return;
2162 	}
2163 
2164 
2165 	entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
2166 
2167 	if (entry_id != INVALID_CAM_ID)
2168 		write_mbssid_cam(adapter, entry_id, mac_addr);
2169 }
2170 
2171 
2172 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
2173 
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * val)2174 void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *val)
2175 {
2176 	u8 idx = 0;
2177 	u32 reg_macid = 0;
2178 
2179 	if (val == NULL)
2180 		return;
2181 
2182 	RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
2183 		 ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(val));
2184 
2185 	switch (adapter->hw_port) {
2186 	case HW_PORT0:
2187 	default:
2188 		reg_macid = REG_MACID;
2189 		break;
2190 	case HW_PORT1:
2191 		reg_macid = REG_MACID1;
2192 		break;
2193 #if defined(CONFIG_RTL8814A)
2194 	case HW_PORT2:
2195 		reg_macid = REG_MACID2;
2196 		break;
2197 	case HW_PORT3:
2198 		reg_macid = REG_MACID3;
2199 		break;
2200 	case HW_PORT4:
2201 		reg_macid = REG_MACID4;
2202 		break;
2203 #endif/*defined(CONFIG_RTL8814A)*/
2204 	}
2205 
2206 	for (idx = 0; idx < 6; idx++)
2207 		rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx), val[idx]);
2208 }
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)2209 void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
2210 {
2211 	u8 idx = 0;
2212 	u32 reg_macid = 0;
2213 
2214 	if (mac_addr == NULL)
2215 		return;
2216 
2217 	_rtw_memset(mac_addr, 0, ETH_ALEN);
2218 	switch (adapter->hw_port) {
2219 	case HW_PORT0:
2220 	default:
2221 		reg_macid = REG_MACID;
2222 		break;
2223 	case HW_PORT1:
2224 		reg_macid = REG_MACID1;
2225 		break;
2226 #if defined(CONFIG_RTL8814A)
2227 	case HW_PORT2:
2228 		reg_macid = REG_MACID2;
2229 		break;
2230 	case HW_PORT3:
2231 		reg_macid = REG_MACID3;
2232 		break;
2233 	case HW_PORT4:
2234 		reg_macid = REG_MACID4;
2235 		break;
2236 #endif /*defined(CONFIG_RTL8814A)*/
2237 	}
2238 
2239 	for (idx = 0; idx < 6; idx++)
2240 		mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx));
2241 
2242 	RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
2243 		 ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(mac_addr));
2244 }
2245 
rtw_hal_set_bssid(_adapter * adapter,u8 * val)2246 void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
2247 {
2248 	u8	idx = 0;
2249 	u32 reg_bssid = 0;
2250 
2251 	switch (adapter->hw_port) {
2252 	case HW_PORT0:
2253 	default:
2254 		reg_bssid = REG_BSSID;
2255 		break;
2256 	case HW_PORT1:
2257 		reg_bssid = REG_BSSID1;
2258 		break;
2259 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)
2260 	case HW_PORT2:
2261 		reg_bssid = REG_BSSID2;
2262 		break;
2263 	case HW_PORT3:
2264 		reg_bssid = REG_BSSID3;
2265 		break;
2266 	case HW_PORT4:
2267 		reg_bssid = REG_BSSID4;
2268 		break;
2269 #endif/*defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)*/
2270 	}
2271 
2272 	for (idx = 0 ; idx < 6; idx++)
2273 		rtw_write8(adapter, (reg_bssid + idx), val[idx]);
2274 
2275 	RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n", __func__, ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(val));
2276 }
2277 
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2278 void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2279 {
2280 	switch (adapter->hw_port) {
2281 	case HW_PORT0:
2282 		/*REG_CR - BIT[17:16]-Network Type for port 1*/
2283 		*net_type = rtw_read8(adapter, MSR) & 0x03;
2284 		break;
2285 	case HW_PORT1:
2286 		/*REG_CR - BIT[19:18]-Network Type for port 1*/
2287 		*net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2288 		break;
2289 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)
2290 	case HW_PORT2:
2291 		/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2292 		*net_type = rtw_read8(adapter, MSR1) & 0x03;
2293 		break;
2294 	case HW_PORT3:
2295 		/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2296 		*net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2297 		break;
2298 	case HW_PORT4:
2299 		/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2300 		*net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2301 		break;
2302 #endif /*#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)*/
2303 	default:
2304 		RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2305 			 ADPT_ARG(adapter), adapter->hw_port);
2306 		rtw_warn_on(1);
2307 		break;
2308 	}
2309 }
2310 
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2311 void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2312 {
2313 	u8 val8 = 0;
2314 
2315 	switch (adapter->hw_port) {
2316 	case HW_PORT0:
2317 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
2318 		if (rtw_get_mbid_cam_entry_num(adapter)) {
2319 			if (net_type != _HW_STATE_NOLINK_)
2320 				net_type = _HW_STATE_AP_;
2321 		}
2322 #endif
2323 		/*REG_CR - BIT[17:16]-Network Type for port 0*/
2324 		val8 = rtw_read8(adapter, MSR) & 0x0C;
2325 		val8 |= net_type;
2326 		rtw_write8(adapter, MSR, val8);
2327 		break;
2328 	case HW_PORT1:
2329 		/*REG_CR - BIT[19:18]-Network Type for port 1*/
2330 		val8 = rtw_read8(adapter, MSR) & 0x03;
2331 		val8 |= net_type << 2;
2332 		rtw_write8(adapter, MSR, val8);
2333 		break;
2334 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)
2335 	case HW_PORT2:
2336 		/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2337 		val8 = rtw_read8(adapter, MSR1) & 0xFC;
2338 		val8 |= net_type;
2339 		rtw_write8(adapter, MSR1, val8);
2340 		break;
2341 	case HW_PORT3:
2342 		/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2343 		val8 = rtw_read8(adapter, MSR1) & 0xF3;
2344 		val8 |= net_type << 2;
2345 		rtw_write8(adapter, MSR1, val8);
2346 		break;
2347 	case HW_PORT4:
2348 		/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2349 		val8 = rtw_read8(adapter, MSR1) & 0xCF;
2350 		val8 |= net_type << 4;
2351 		rtw_write8(adapter, MSR1, val8);
2352 		break;
2353 #endif /* CONFIG_RTL8814A | CONFIG_RTL8822B */
2354 	default:
2355 		RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2356 			 ADPT_ARG(adapter), adapter->hw_port);
2357 		rtw_warn_on(1);
2358 		break;
2359 	}
2360 }
2361 
rtw_hal_port_reconfig(_adapter * adapter,u8 port)2362 void rtw_hal_port_reconfig(_adapter *adapter, u8 port)
2363 {
2364 #ifdef CONFIG_CONCURRENT_MODE
2365 	u8 hal_port_num = 0;
2366 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2367 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2368 
2369 	if (port > (hal_spec->port_num - 1)) {
2370 		RTW_INFO("[WARN] "ADPT_FMT"- hw_port : %d,will switch to invalid port-%d\n",
2371 			 ADPT_ARG(adapter), adapter->hw_port, port);
2372 		rtw_warn_on(1);
2373 	}
2374 
2375 	RTW_PRINT(ADPT_FMT"- hw_port : %d,will switch to port-%d\n",
2376 		  ADPT_ARG(adapter), adapter->hw_port, port);
2377 
2378 #endif
2379 
2380 }
2381 
2382 
hw_var_port_switch(_adapter * adapter)2383 void hw_var_port_switch(_adapter *adapter)
2384 {
2385 #ifdef CONFIG_CONCURRENT_MODE
2386 #ifdef CONFIG_RUNTIME_PORT_SWITCH
2387 	/*
2388 	0x102: MSR
2389 	0x550: REG_BCN_CTRL
2390 	0x551: REG_BCN_CTRL_1
2391 	0x55A: REG_ATIMWND
2392 	0x560: REG_TSFTR
2393 	0x568: REG_TSFTR1
2394 	0x570: REG_ATIMWND_1
2395 	0x610: REG_MACID
2396 	0x618: REG_BSSID
2397 	0x700: REG_MACID1
2398 	0x708: REG_BSSID1
2399 	*/
2400 
2401 	int i;
2402 	u8 msr;
2403 	u8 bcn_ctrl;
2404 	u8 bcn_ctrl_1;
2405 	u8 atimwnd[2];
2406 	u8 atimwnd_1[2];
2407 	u8 tsftr[8];
2408 	u8 tsftr_1[8];
2409 	u8 macid[6];
2410 	u8 bssid[6];
2411 	u8 macid_1[6];
2412 	u8 bssid_1[6];
2413 
2414 	u8 hw_port;
2415 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2416 	_adapter *iface = NULL;
2417 
2418 	msr = rtw_read8(adapter, MSR);
2419 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
2420 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
2421 
2422 	for (i = 0; i < 2; i++)
2423 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
2424 	for (i = 0; i < 2; i++)
2425 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
2426 
2427 	for (i = 0; i < 8; i++)
2428 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
2429 	for (i = 0; i < 8; i++)
2430 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
2431 
2432 	for (i = 0; i < 6; i++)
2433 		macid[i] = rtw_read8(adapter, REG_MACID + i);
2434 
2435 	for (i = 0; i < 6; i++)
2436 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
2437 
2438 	for (i = 0; i < 6; i++)
2439 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
2440 
2441 	for (i = 0; i < 6; i++)
2442 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
2443 
2444 #ifdef DBG_RUNTIME_PORT_SWITCH
2445 	RTW_INFO(FUNC_ADPT_FMT" before switch\n"
2446 		 "msr:0x%02x\n"
2447 		 "bcn_ctrl:0x%02x\n"
2448 		 "bcn_ctrl_1:0x%02x\n"
2449 		 "atimwnd:0x%04x\n"
2450 		 "atimwnd_1:0x%04x\n"
2451 		 "tsftr:%llu\n"
2452 		 "tsftr1:%llu\n"
2453 		 "macid:"MAC_FMT"\n"
2454 		 "bssid:"MAC_FMT"\n"
2455 		 "macid_1:"MAC_FMT"\n"
2456 		 "bssid_1:"MAC_FMT"\n"
2457 		 , FUNC_ADPT_ARG(adapter)
2458 		 , msr
2459 		 , bcn_ctrl
2460 		 , bcn_ctrl_1
2461 		 , *((u16 *)atimwnd)
2462 		 , *((u16 *)atimwnd_1)
2463 		 , *((u64 *)tsftr)
2464 		 , *((u64 *)tsftr_1)
2465 		 , MAC_ARG(macid)
2466 		 , MAC_ARG(bssid)
2467 		 , MAC_ARG(macid_1)
2468 		 , MAC_ARG(bssid_1)
2469 		);
2470 #endif /* DBG_RUNTIME_PORT_SWITCH */
2471 
2472 	/* disable bcn function, disable update TSF */
2473 	rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
2474 	rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
2475 
2476 	/* switch msr */
2477 	msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
2478 	rtw_write8(adapter, MSR, msr);
2479 
2480 	/* write port0 */
2481 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
2482 	for (i = 0; i < 2; i++)
2483 		rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
2484 	for (i = 0; i < 8; i++)
2485 		rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
2486 	for (i = 0; i < 6; i++)
2487 		rtw_write8(adapter, REG_MACID + i, macid_1[i]);
2488 	for (i = 0; i < 6; i++)
2489 		rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
2490 
2491 	/* write port1 */
2492 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
2493 	for (i = 0; i < 2; i++)
2494 		rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
2495 	for (i = 0; i < 8; i++)
2496 		rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
2497 	for (i = 0; i < 6; i++)
2498 		rtw_write8(adapter, REG_MACID1 + i, macid[i]);
2499 	for (i = 0; i < 6; i++)
2500 		rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
2501 
2502 	/* write bcn ctl */
2503 #ifdef CONFIG_BT_COEXIST
2504 	/* always enable port0 beacon function for PSTDMA */
2505 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
2506 	    || IS_HARDWARE_TYPE_8723D(adapter))
2507 		bcn_ctrl_1 |= EN_BCN_FUNCTION;
2508 	/* always disable port1 beacon function for PSTDMA */
2509 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
2510 		bcn_ctrl &= ~EN_BCN_FUNCTION;
2511 #endif
2512 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
2513 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
2514 
2515 	if (adapter->iface_id == IFACE_ID0)
2516 		iface = dvobj->padapters[IFACE_ID1];
2517 	else if (adapter->iface_id == IFACE_ID1)
2518 		iface = dvobj->padapters[IFACE_ID0];
2519 
2520 
2521 	if (adapter->hw_port == HW_PORT0) {
2522 		adapter->hw_port = HW_PORT1;
2523 		iface->hw_port = HW_PORT0;
2524 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
2525 			  ADPT_ARG(iface), ADPT_ARG(adapter));
2526 	} else {
2527 		adapter->hw_port = HW_PORT0;
2528 		iface->hw_port = HW_PORT1;
2529 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
2530 			  ADPT_ARG(adapter), ADPT_ARG(iface));
2531 	}
2532 
2533 #ifdef DBG_RUNTIME_PORT_SWITCH
2534 	msr = rtw_read8(adapter, MSR);
2535 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
2536 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
2537 
2538 	for (i = 0; i < 2; i++)
2539 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
2540 	for (i = 0; i < 2; i++)
2541 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
2542 
2543 	for (i = 0; i < 8; i++)
2544 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
2545 	for (i = 0; i < 8; i++)
2546 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
2547 
2548 	for (i = 0; i < 6; i++)
2549 		macid[i] = rtw_read8(adapter, REG_MACID + i);
2550 
2551 	for (i = 0; i < 6; i++)
2552 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
2553 
2554 	for (i = 0; i < 6; i++)
2555 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
2556 
2557 	for (i = 0; i < 6; i++)
2558 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
2559 
2560 	RTW_INFO(FUNC_ADPT_FMT" after switch\n"
2561 		 "msr:0x%02x\n"
2562 		 "bcn_ctrl:0x%02x\n"
2563 		 "bcn_ctrl_1:0x%02x\n"
2564 		 "atimwnd:%u\n"
2565 		 "atimwnd_1:%u\n"
2566 		 "tsftr:%llu\n"
2567 		 "tsftr1:%llu\n"
2568 		 "macid:"MAC_FMT"\n"
2569 		 "bssid:"MAC_FMT"\n"
2570 		 "macid_1:"MAC_FMT"\n"
2571 		 "bssid_1:"MAC_FMT"\n"
2572 		 , FUNC_ADPT_ARG(adapter)
2573 		 , msr
2574 		 , bcn_ctrl
2575 		 , bcn_ctrl_1
2576 		 , *((u16 *)atimwnd)
2577 		 , *((u16 *)atimwnd_1)
2578 		 , *((u64 *)tsftr)
2579 		 , *((u64 *)tsftr_1)
2580 		 , MAC_ARG(macid)
2581 		 , MAC_ARG(bssid)
2582 		 , MAC_ARG(macid_1)
2583 		 , MAC_ARG(bssid_1)
2584 		);
2585 #endif /* DBG_RUNTIME_PORT_SWITCH */
2586 
2587 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
2588 #endif /* CONFIG_CONCURRENT_MODE */
2589 }
2590 
2591 const char *const _h2c_msr_role_str[] = {
2592 	"RSVD",
2593 	"STA",
2594 	"AP",
2595 	"GC",
2596 	"GO",
2597 	"TDLS",
2598 	"ADHOC",
2599 	"INVALID",
2600 };
2601 
2602 /*
2603 * rtw_hal_set_FwMediaStatusRpt_cmd -
2604 *
2605 * @adapter:
2606 * @opmode:  0:disconnect, 1:connect
2607 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
2608 * @miracast_sink: 0:source. 1:sink
2609 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
2610 * @macid:
2611 * @macid_ind:  0:update Media Status to macid.  1:update Media Status from macid to macid_end
2612 * @macid_end:
2613 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)2614 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)
2615 {
2616 	struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
2617 	u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
2618 	int i;
2619 	s32 ret;
2620 
2621 	SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
2622 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
2623 	SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
2624 	SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
2625 	SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
2626 	SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
2627 	SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
2628 
2629 	RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
2630 
2631 #ifdef CONFIG_DFS_MASTER
2632 	/* workaround for TXPAUSE cleared issue by FW's MediaStatusRpt handling */
2633 	if (macid_ind == 0 && macid == 1) {
2634 		u8 parm0_bak = parm[0];
2635 
2636 		SET_H2CCMD_MSRRPT_PARM_MACID_IND(&parm0_bak, 0);
2637 		if (macid_ctl->h2c_msr[macid] == parm0_bak) {
2638 			ret = _SUCCESS;
2639 			goto post_action;
2640 		}
2641 	}
2642 #endif
2643 
2644 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
2645 	if (ret != _SUCCESS)
2646 		goto exit;
2647 
2648 #ifdef CONFIG_DFS_MASTER
2649 post_action:
2650 #endif
2651 
2652 #if defined(CONFIG_RTL8188E)
2653 	if (rtw_get_chip_type(adapter) == RTL8188E) {
2654 		HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2655 
2656 		/* 8188E FW doesn't set macid no link, driver does it by self */
2657 		if (opmode)
2658 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
2659 		else
2660 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
2661 
2662 		/* for 8188E RA */
2663 #if (RATE_ADAPTIVE_SUPPORT == 1)
2664 		if (hal_data->fw_ractrl == _FALSE) {
2665 			u8 max_macid;
2666 
2667 			max_macid = rtw_search_max_mac_id(adapter);
2668 			rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
2669 		}
2670 #endif
2671 	}
2672 #endif
2673 
2674 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
2675 	/* TODO: this should move to IOT issue area */
2676 	if (rtw_get_chip_type(adapter) == RTL8812
2677 	    || rtw_get_chip_type(adapter) == RTL8821
2678 	   ) {
2679 		if (MLME_IS_STA(adapter))
2680 			Hal_PatchwithJaguar_8812(adapter, opmode);
2681 	}
2682 #endif
2683 
2684 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
2685 	if (macid_ind == 0)
2686 		macid_end = macid;
2687 
2688 	for (i = macid; macid <= macid_end; macid++)
2689 		rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
2690 
2691 exit:
2692 	return ret;
2693 }
2694 
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)2695 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
2696 {
2697 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
2698 }
2699 
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)2700 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
2701 {
2702 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
2703 }
2704 
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)2705 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
2706 {
2707 	struct	hal_ops *pHalFunc = &padapter->HalFunc;
2708 	u8	u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
2709 	u8	ret = 0;
2710 
2711 	RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
2712 		 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
2713 		 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
2714 		 rsvdpageloc->LocBTQosNull);
2715 
2716 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
2717 	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
2718 	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
2719 	SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
2720 	SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
2721 
2722 	ret = rtw_hal_fill_h2c_cmd(padapter,
2723 				   H2C_RSVD_PAGE,
2724 				   H2C_RSVDPAGE_LOC_LEN,
2725 				   u1H2CRsvdPageParm);
2726 
2727 }
2728 
2729 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)2730 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
2731 {
2732 	/*
2733 	* Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
2734 	* It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
2735 	* and implement HAL function.
2736 	* TODO: GPIO_8 multi function?
2737 	*/
2738 	if (index == 13 || index == 14)
2739 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
2740 }
2741 
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)2742 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
2743 {
2744 	if (index <= 7) {
2745 		/* config GPIO mode */
2746 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
2747 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
2748 
2749 		/* config GPIO Sel */
2750 		/* 0: input */
2751 		/* 1: output */
2752 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
2753 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
2754 
2755 		/* set output value */
2756 		if (outputval) {
2757 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
2758 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
2759 		} else {
2760 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
2761 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
2762 		}
2763 	} else if (index <= 15) {
2764 		/* 88C Series: */
2765 		/* index: 11~8 transform to 3~0 */
2766 		/* 8723 Series: */
2767 		/* index: 12~8 transform to 4~0 */
2768 
2769 		index -= 8;
2770 
2771 		/* config GPIO mode */
2772 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
2773 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
2774 
2775 		/* config GPIO Sel */
2776 		/* 0: input */
2777 		/* 1: output */
2778 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
2779 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
2780 
2781 		/* set output value */
2782 		if (outputval) {
2783 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
2784 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
2785 		} else {
2786 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
2787 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
2788 		}
2789 	} else {
2790 		RTW_INFO("%s: invalid GPIO%d=%d\n",
2791 			 __FUNCTION__, index, outputval);
2792 	}
2793 }
2794 #endif
2795 
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)2796 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
2797 {
2798 	struct	hal_ops *pHalFunc = &padapter->HalFunc;
2799 	struct	pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
2800 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
2801 	u8	res = 0, count = 0, ret = 0;
2802 #ifdef CONFIG_WOWLAN
2803 	u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
2804 
2805 	RTW_INFO("AOACRsvdPageLoc: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n",
2806 		 rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp,
2807 		 rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp,
2808 		 rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq,
2809 		 rsvdpageloc->LocNetList);
2810 
2811 	if (check_fwstate(pmlmepriv, _FW_LINKED)) {
2812 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
2813 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
2814 		/* SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv); */
2815 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
2816 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
2817 #ifdef CONFIG_GTK_OL
2818 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
2819 #endif /* CONFIG_GTK_OL */
2820 		ret = rtw_hal_fill_h2c_cmd(padapter,
2821 					   H2C_AOAC_RSVD_PAGE,
2822 					   H2C_AOAC_RSVDPAGE_LOC_LEN,
2823 					   u1H2CAoacRsvdPageParm);
2824 	}
2825 #ifdef CONFIG_PNO_SUPPORT
2826 	else {
2827 
2828 		if (!pwrpriv->pno_in_resume) {
2829 			RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
2830 			_rtw_memset(&u1H2CAoacRsvdPageParm, 0,
2831 				    sizeof(u1H2CAoacRsvdPageParm));
2832 			SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
2833 						      rsvdpageloc->LocPNOInfo);
2834 			ret = rtw_hal_fill_h2c_cmd(padapter,
2835 						   H2C_AOAC_RSVDPAGE3,
2836 						   H2C_AOAC_RSVDPAGE_LOC_LEN,
2837 						   u1H2CAoacRsvdPageParm);
2838 		}
2839 	}
2840 #endif /* CONFIG_PNO_SUPPORT */
2841 #endif /* CONFIG_WOWLAN */
2842 }
2843 
2844 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)2845 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
2846 {
2847 	RTW_INFO("%s: Set 0x690=0x00\n", __func__);
2848 	rtw_write8(adapter, REG_WOW_CTRL,
2849 		   (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
2850 	RTW_PRINT("%s: Release RXDMA\n", __func__);
2851 	rtw_write32(adapter, REG_RXPKT_NUM,
2852 		    (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
2853 }
2854 
rtw_hal_disable_tx_report(_adapter * adapter)2855 static void rtw_hal_disable_tx_report(_adapter *adapter)
2856 {
2857 	rtw_write8(adapter, REG_TX_RPT_CTRL,
2858 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
2859 	RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
2860 }
2861 
rtw_hal_enable_tx_report(_adapter * adapter)2862 static void rtw_hal_enable_tx_report(_adapter *adapter)
2863 {
2864 	rtw_write8(adapter, REG_TX_RPT_CTRL,
2865 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
2866 	RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
2867 }
2868 
rtw_hal_release_rx_dma(_adapter * adapter)2869 static void rtw_hal_release_rx_dma(_adapter *adapter)
2870 {
2871 	u32 val32 = 0;
2872 
2873 	val32 = rtw_read32(adapter, REG_RXPKT_NUM);
2874 
2875 	rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
2876 
2877 	RTW_INFO("%s, [0x%04x]: 0x%08x\n",
2878 		 __func__, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
2879 }
2880 
rtw_hal_pause_rx_dma(_adapter * adapter)2881 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
2882 {
2883 	u8 ret = 0;
2884 	s8 trycnt = 100;
2885 	u16 len = 0;
2886 	u32 tmp = 0;
2887 	int res = 0;
2888 	/* RX DMA stop */
2889 	RTW_PRINT("Pause DMA\n");
2890 	rtw_write32(adapter, REG_RXPKT_NUM,
2891 		    (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
2892 	do {
2893 		if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
2894 			RTW_PRINT("RX_DMA_IDLE is true\n");
2895 			ret = _SUCCESS;
2896 			break;
2897 		}
2898 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2899 		else {
2900 			/* If RX_DMA is not idle, receive one pkt from DMA */
2901 			res = sdio_local_read(adapter,
2902 				      SDIO_REG_RX0_REQ_LEN, 4, (u8 *)&tmp);
2903 			len = le16_to_cpu(tmp);
2904 			RTW_PRINT("RX len:%d\n", len);
2905 
2906 			if (len > 0)
2907 				res = RecvOnePkt(adapter, len);
2908 			else
2909 				RTW_PRINT("read length fail %d\n", len);
2910 
2911 			RTW_PRINT("RecvOnePkt Result: %d\n", res);
2912 		}
2913 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
2914 #ifdef CONFIG_USB_HCI
2915 		else {
2916 			rtw_intf_start(adapter);
2917 
2918 			tmp = rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE;
2919 			if (tmp) {
2920 				rtw_intf_stop(adapter);
2921 				RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
2922 				RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
2923 			}
2924 		}
2925 #endif
2926 	} while (trycnt--);
2927 
2928 	if (trycnt < 0) {
2929 		tmp = rtw_read16(adapter, REG_RXPKT_NUM + 3);
2930 
2931 		RTW_PRINT("Stop RX DMA failed......\n");
2932 		RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
2933 			  __func__, tmp);
2934 		tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
2935 		if (tmp & BIT(3))
2936 			RTW_PRINT("%s, RX DMA has req\n",
2937 				  __func__);
2938 		else
2939 			RTW_PRINT("%s, RX DMA no req\n",
2940 				  __func__);
2941 		ret = _FAIL;
2942 	}
2943 
2944 	return ret;
2945 }
2946 
2947 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
rtw_hal_enable_cpwm2(_adapter * adapter)2948 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
2949 {
2950 	u8 ret = 0;
2951 	int res = 0;
2952 	u32 tmp = 0;
2953 
2954 	RTW_PRINT("%s\n", __func__);
2955 
2956 	res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
2957 	if (!res)
2958 		RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
2959 	else
2960 		RTW_INFO("sdio_local_read fail\n");
2961 
2962 	tmp = SDIO_HIMR_CPWM2_MSK;
2963 
2964 	res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
2965 
2966 	if (!res) {
2967 		res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
2968 		RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
2969 		ret = _SUCCESS;
2970 	} else {
2971 		RTW_INFO("sdio_local_write fail\n");
2972 		ret = _FAIL;
2973 	}
2974 
2975 	return ret;
2976 }
2977 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
2978 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
2979 
2980 #ifdef CONFIG_WOWLAN
2981 /*
2982  * rtw_hal_check_wow_ctrl
2983  * chk_type: _TRUE means to check enable, if 0x690 & bit1, WOW enable successful
2984  *		     _FALSE means to check disable, if 0x690 & bit1, WOW disable fail
2985  */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)2986 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
2987 {
2988 	u8 mstatus = 0;
2989 	u8 trycnt = 25;
2990 	u8 res = _FALSE;
2991 
2992 	mstatus = rtw_read8(adapter, REG_WOW_CTRL);
2993 	RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
2994 
2995 	if (chk_type) {
2996 		while (!(mstatus & BIT1) && trycnt > 1) {
2997 			mstatus = rtw_read8(adapter, REG_WOW_CTRL);
2998 			RTW_PRINT("Loop index: %d :0x%02x\n",
2999 				  trycnt, mstatus);
3000 			trycnt--;
3001 			rtw_msleep_os(20);
3002 		}
3003 		if (mstatus & BIT1)
3004 			res = _TRUE;
3005 		else
3006 			res = _FALSE;
3007 	} else {
3008 		while (mstatus & BIT1 && trycnt > 1) {
3009 			mstatus = rtw_read8(adapter, REG_WOW_CTRL);
3010 			RTW_PRINT("Loop index: %d :0x%02x\n",
3011 				  trycnt, mstatus);
3012 			trycnt--;
3013 			rtw_msleep_os(20);
3014 		}
3015 
3016 		if (mstatus & BIT1)
3017 			res = _FALSE;
3018 		else
3019 			res = _TRUE;
3020 	}
3021 	RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
3022 		  __func__, chk_type, res, (25 - trycnt));
3023 	return res;
3024 }
3025 
3026 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)3027 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
3028 {
3029 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
3030 	u8 res = 0, count = 0;
3031 	u8 ret = _FALSE;
3032 
3033 	if (ppwrpriv->wowlan_pno_enable && ppwrpriv->pno_in_resume == _FALSE) {
3034 		res = rtw_read8(adapter, REG_PNO_STATUS);
3035 		while (!(res & BIT(7)) && count < 25) {
3036 			RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
3037 				 count, res);
3038 			res = rtw_read8(adapter, REG_PNO_STATUS);
3039 			count++;
3040 			rtw_msleep_os(2);
3041 		}
3042 		if (res & BIT(7))
3043 			ret = _TRUE;
3044 		else
3045 			ret = _FALSE;
3046 		RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
3047 	}
3048 	return ret;
3049 }
3050 #endif
3051 
rtw_hal_backup_rate(_adapter * adapter)3052 static void rtw_hal_backup_rate(_adapter *adapter)
3053 {
3054 	RTW_INFO("%s\n", __func__);
3055 	/* backup data rate to register 0x8b for wowlan FW */
3056 	rtw_write8(adapter, 0x8d, 1);
3057 	rtw_write8(adapter, 0x8c, 0);
3058 	rtw_write8(adapter, 0x8f, 0x40);
3059 	rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
3060 }
3061 
3062 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)3063 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
3064 {
3065 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3066 	int cam_id, index = 0;
3067 	u8 *addr = NULL;
3068 
3069 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3070 		return;
3071 
3072 	addr = get_bssid(pmlmepriv);
3073 
3074 	if (addr == NULL) {
3075 		RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
3076 		return;
3077 	}
3078 
3079 	rtw_clean_dk_section(adapter);
3080 
3081 	do {
3082 		cam_id = rtw_camid_search(adapter, addr, index, 1);
3083 
3084 		if (cam_id == -1)
3085 			RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
3086 		else
3087 			rtw_sec_cam_swap(adapter, cam_id, index);
3088 
3089 		index++;
3090 	} while (index < 4);
3091 
3092 	rtw_write8(adapter, REG_SECCFG, 0xcc);
3093 }
3094 
3095 #ifndef CONFIG_WOW_PATTERN_HW_CAM
rtw_hal_update_gtk_offload_info(_adapter * adapter)3096 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
3097 {
3098 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3099 	struct security_priv *psecuritypriv = &adapter->securitypriv;
3100 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3101 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
3102 	_irqL irqL;
3103 	u8 get_key[16];
3104 	u8 gtk_keyindex = 0;
3105 
3106 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3107 		return;
3108 
3109 	_rtw_memset(get_key, 0, sizeof(get_key));
3110 
3111 	if (psecuritypriv->binstallKCK_KEK == _TRUE) {
3112 
3113 		/*read gtk key index*/
3114 		gtk_keyindex = rtw_read8(adapter, 0x48c);
3115 
3116 		if (gtk_keyindex > 4) {
3117 			RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, gtk_keyindex);
3118 			rtw_warn_on(1);
3119 			return;
3120 		}
3121 		/*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
3122 		rtw_sec_read_cam_ent(adapter, gtk_keyindex, NULL, NULL, get_key);
3123 
3124 		/*update key into related sw variable and sec-cam cache*/
3125 		psecuritypriv->dot118021XGrpKeyid = gtk_keyindex;
3126 		_rtw_memcpy(psecuritypriv->dot118021XGrpKey[gtk_keyindex].skey, get_key, 16);
3127 
3128 		rtw_clean_hw_dk_cam(adapter);
3129 		if (_rtw_camid_is_gk(adapter, gtk_keyindex)) {
3130 			_enter_critical_bh(&cam_ctl->lock, &irqL);
3131 			_rtw_memcpy(&dvobj->cam_cache[gtk_keyindex].key, get_key, 16);
3132 			_exit_critical_bh(&cam_ctl->lock, &irqL);
3133 		} else {
3134 			struct setkey_parm aes_gtk;
3135 
3136 			aes_gtk.algorithm = _AES_;
3137 			aes_gtk.keyid = gtk_keyindex;
3138 			_rtw_memcpy(aes_gtk.key, get_key, 16);
3139 			setkey_hdl(adapter, (u8 *)&aes_gtk);
3140 		}
3141 		rtw_clean_dk_section(adapter);
3142 
3143 		RTW_PRINT("GTK (%d) "KEY_FMT"\n",
3144 			  gtk_keyindex,
3145 			KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_keyindex].skey));
3146 
3147 		rtw_write8(adapter, REG_SECCFG, 0x0c);
3148 
3149 		#ifdef CONFIG_GTK_OL_DBG
3150 		/* if (gtk_keyindex != 5) */
3151 		dump_sec_cam(RTW_DBGDUMP, adapter);
3152 		dump_sec_cam_cache(RTW_DBGDUMP, adapter);
3153 		#endif
3154 	}
3155 }
3156 #else
rtw_hal_update_gtk_offload_info(_adapter * adapter)3157 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
3158 {
3159 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3160 	struct security_priv *psecuritypriv = &adapter->securitypriv;
3161 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3162 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
3163 	struct aoac_report *aoac_rpt = &pwrctl->wowlan_aoac_rpt;
3164 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
3165 	_irqL irqL;
3166 	u8 gtk_keyindex = aoac_rpt->key_index;
3167 
3168 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3169 		return;
3170 
3171 	if (psecuritypriv->binstallKCK_KEK == _TRUE) {
3172 
3173 		if (gtk_keyindex > 4) {
3174 			RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, gtk_keyindex);
3175 			rtw_warn_on(1);
3176 			return;
3177 		}
3178 
3179 		/*update key into related sw variable and sec-cam cache*/
3180 		psecuritypriv->dot118021XGrpKeyid = gtk_keyindex;
3181 		_rtw_memcpy(psecuritypriv->dot118021XGrpKey[gtk_keyindex].skey, aoac_rpt->group_key, 16);
3182 		rtw_clean_hw_dk_cam(adapter);
3183 		if (_rtw_camid_is_gk(adapter, gtk_keyindex)) {
3184 			_enter_critical_bh(&cam_ctl->lock, &irqL);
3185 			_rtw_memcpy(&dvobj->cam_cache[gtk_keyindex].key, aoac_rpt->group_key, 16);
3186 			_exit_critical_bh(&cam_ctl->lock, &irqL);
3187 		} else {
3188 			struct setkey_parm aes_gtk;
3189 
3190 			aes_gtk.algorithm = aoac_rpt->scurity_type;
3191 			aes_gtk.keyid = gtk_keyindex;
3192 			_rtw_memcpy(aes_gtk.key, aoac_rpt->group_key, 16);
3193 			setkey_hdl(adapter, (u8 *)&aes_gtk);
3194 		}
3195 		rtw_clean_dk_section(adapter);
3196 
3197 		RTW_PRINT("GTK (%d) "KEY_FMT"\n",
3198 			  gtk_keyindex,
3199 			KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_keyindex].skey));
3200 
3201 		rtw_write8(adapter, REG_SECCFG, 0x0c);
3202 
3203 		#ifdef CONFIG_GTK_OL_DBG
3204 		/* if (gtk_keyindex != 5) */
3205 		dump_sec_cam(RTW_DBGDUMP, adapter);
3206 		dump_sec_cam_cache(RTW_DBGDUMP, adapter);
3207 		#endif
3208 	}
3209 }
3210 
3211 #endif /*CONFIG_WOW_PATTERN_HW_CAM*/
3212 
3213 #endif /*CONFIG_GTK_OL*/
3214 
3215 #ifndef CONFIG_WOW_PATTERN_HW_CAM
rtw_hal_update_tx_iv(_adapter * adapter)3216 static void rtw_hal_update_tx_iv(_adapter *adapter)
3217 {
3218 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
3219 	u64 iv_low = 0, iv_high = 0;
3220 
3221 	/* 3.1 read fw iv */
3222 	iv_low = rtw_read32(adapter, REG_TXPKTBUF_IV_LOW);
3223 	/* only low two bytes is PN, check AES_IV macro for detail */
3224 	iv_low &= 0xffff;
3225 	iv_high = rtw_read32(adapter, REG_TXPKTBUF_IV_HIGH);
3226 	/* get the real packet number */
3227 	pwrctl->wowlan_fw_iv = iv_high << 16 | iv_low;
3228 	RTW_PRINT("fw_iv: 0x%016llx\n", pwrctl->wowlan_fw_iv);
3229 	/* Update TX iv data. */
3230 	rtw_set_sec_pn(adapter);
3231 }
3232 #else
3233 #define DBG_AOAC_RPT
rtw_parse_aoac_rpt(_adapter * adapter,u8 * buffer,struct aoac_report * paoac_rpt)3234 void rtw_parse_aoac_rpt(_adapter *adapter, u8 *buffer, struct aoac_report *paoac_rpt)
3235 {
3236 	if ((!buffer) && (!paoac_rpt))
3237 		return;
3238 
3239 	_rtw_memcpy(paoac_rpt->iv, buffer, 8);
3240 	_rtw_memcpy(paoac_rpt->replay_counter_eapol_key, buffer + 8, 8);
3241 	_rtw_memcpy(paoac_rpt->group_key, buffer + 16, 32);
3242 	paoac_rpt->key_index = *(buffer + 48);
3243 	paoac_rpt->scurity_type = *(buffer + 49);
3244 
3245 	#ifdef DBG_AOAC_RPT
3246 	RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
3247 	RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ", paoac_rpt->replay_counter_eapol_key, 8);
3248 	RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
3249 	RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
3250 	RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->scurity_type);
3251 	#endif
3252 }
3253 
rtw_hal_update_tx_iv(_adapter * adapter)3254 static void rtw_hal_update_tx_iv(_adapter *adapter)
3255 {
3256 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
3257 	struct aoac_report *aoac_rpt = &pwrctl->wowlan_aoac_rpt;
3258 	u32 page_offset, page_number;
3259 	u32 page_size = 0;
3260 	u8 *buffer = NULL;
3261 	u32 buf_size = 0;
3262 	int ret = -1;
3263 
3264 	/* read fw iv from rsvd page */
3265 	page_offset = pwrctl->wowlan_aoac_rpt_loc;
3266 	page_number = 1;
3267 
3268 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
3269 	buf_size = page_size * page_number;
3270 
3271 	buffer = rtw_zvmalloc(buf_size);
3272 
3273 	if (NULL == buffer) {
3274 		RTW_ERR("%s buffer allocate failed size(%d)\n", __func__, buf_size);
3275 		return;
3276 	}
3277 
3278 	RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
3279 	ret = rtw_hal_get_rsvd_page(adapter, page_offset, page_number, buffer, buf_size);
3280 	if (ret) {
3281 		RTW_ERR("%s get aoac report failed\n", __func__);
3282 		rtw_warn_on(1);
3283 		goto _exit;
3284 	}
3285 
3286 	_rtw_memset(aoac_rpt, 0, sizeof(struct aoac_report));
3287 	rtw_parse_aoac_rpt(adapter, buffer, aoac_rpt);
3288 
3289 	_rtw_memcpy(&pwrctl->wowlan_fw_iv, aoac_rpt->iv, 8);
3290 
3291 	RTW_PRINT("fw_iv: 0x%016llx\n", pwrctl->wowlan_fw_iv);
3292 	/* Update TX iv data. */
3293 	rtw_set_sec_pn(adapter);
3294 
3295 _exit:
3296 	if (buffer)
3297 		rtw_vmfree(buffer, buf_size);
3298 }
3299 #endif
3300 
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)3301 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
3302 {
3303 	struct hal_ops *pHalFunc = &adapter->HalFunc;
3304 
3305 	u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
3306 	u8 adopt = 1, check_period = 5;
3307 	u8 ret = _FAIL;
3308 
3309 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
3310 	SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
3311 	SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
3312 	SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
3313 	SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
3314 
3315 	ret = rtw_hal_fill_h2c_cmd(adapter,
3316 				   H2C_KEEP_ALIVE,
3317 				   H2C_KEEP_ALIVE_CTRL_LEN,
3318 				   u1H2CKeepAliveParm);
3319 
3320 	return ret;
3321 }
3322 
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)3323 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
3324 {
3325 	struct hal_ops *pHalFunc = &adapter->HalFunc;
3326 	u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
3327 	u8 adopt = 1, check_period = 10, trypkt_num = 0;
3328 	u8 ret = _FAIL;
3329 
3330 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
3331 	SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
3332 	SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
3333 	SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
3334 	SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
3335 
3336 	ret = rtw_hal_fill_h2c_cmd(adapter,
3337 				   H2C_DISCON_DECISION,
3338 				   H2C_DISCON_DECISION_LEN,
3339 				   u1H2CDisconDecisionParm);
3340 	return ret;
3341 }
3342 
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)3343 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
3344 {
3345 	struct security_priv *psecpriv = &adapter->securitypriv;
3346 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
3347 	struct hal_ops *pHalFunc = &adapter->HalFunc;
3348 
3349 	u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
3350 	u8 discont_wake = 1, gpionum = 0, gpio_dur = 0;
3351 	u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
3352 	u8 sdio_wakeup_enable = 1;
3353 	u8 gpio_high_active = 0;
3354 	u8 magic_pkt = 0;
3355 	u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
3356 	u8 ret = _FAIL;
3357 
3358 #ifdef CONFIG_GPIO_WAKEUP
3359 	gpio_high_active = ppwrpriv->is_high_active;
3360 	gpionum = WAKEUP_GPIO_IDX;
3361 	sdio_wakeup_enable = 0;
3362 #endif /* CONFIG_GPIO_WAKEUP */
3363 
3364 	if (!ppwrpriv->wowlan_pno_enable)
3365 		magic_pkt = enable;
3366 
3367 	if (psecpriv->dot11PrivacyAlgrthm == _WEP40_ || psecpriv->dot11PrivacyAlgrthm == _WEP104_)
3368 		hw_unicast = 1;
3369 	else
3370 		hw_unicast = 0;
3371 
3372 	RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
3373 		 enable, change_unit);
3374 
3375 	/* time = (gpio_dur/2) * gpio_unit, default:256 ms */
3376 	if (enable && change_unit) {
3377 		gpio_dur = 0x40;
3378 		gpio_unit = 1;
3379 		gpio_pulse_en = 1;
3380 	}
3381 
3382 #ifdef CONFIG_PLATFORM_ARM_RK3188
3383 	if (enable) {
3384 		gpio_pulse_en = 1;
3385 		gpio_pulse_cnt = 0x04;
3386 	}
3387 #endif
3388 
3389 	SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
3390 	SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
3391 	SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
3392 	SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
3393 	SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
3394 	SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
3395 
3396 #ifdef CONFIG_GTK_OL
3397 	if (enable == _TRUE) {
3398 		/* GTK rekey only for AES, if GTK rekey is TKIP, then wake up*/
3399 		if (psecpriv->dot118021XGrpPrivacy == _AES_)
3400 			SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
3401 		else if (psecpriv->dot118021XGrpPrivacy == _TKIP_)
3402 			SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
3403 	}
3404 #else
3405 	SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
3406 #endif
3407 	SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
3408 	SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
3409 	SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
3410 
3411 	SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
3412 	SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
3413 
3414 	SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
3415 	SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
3416 
3417 	ret = rtw_hal_fill_h2c_cmd(adapter,
3418 				   H2C_WOWLAN,
3419 				   H2C_WOWLAN_LEN,
3420 				   u1H2CWoWlanCtrlParm);
3421 	return ret;
3422 }
3423 
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)3424 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
3425 {
3426 	struct hal_ops *pHalFunc = &adapter->HalFunc;
3427 	struct security_priv *psecuritypriv = &(adapter->securitypriv);
3428 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
3429 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
3430 	u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
3431 	u8 ret = _FAIL, count = 0;
3432 
3433 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
3434 
3435 	if (!ppwrpriv->wowlan_pno_enable) {
3436 		SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
3437 			u1H2CRemoteWakeCtrlParm, enable);
3438 		SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
3439 			u1H2CRemoteWakeCtrlParm, 1);
3440 #ifdef CONFIG_GTK_OL
3441 		if (psecuritypriv->binstallKCK_KEK == _TRUE &&
3442 		    psecuritypriv->dot11PrivacyAlgrthm == _AES_ &&
3443 		    psecuritypriv->dot118021XGrpPrivacy == _AES_) {
3444 			SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
3445 				u1H2CRemoteWakeCtrlParm, 1);
3446 		} else {
3447 			RTW_INFO("no kck or security is not AES\n");
3448 			SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
3449 				u1H2CRemoteWakeCtrlParm, 0);
3450 		}
3451 #endif /* CONFIG_GTK_OL */
3452 
3453 		if (pregistrypriv->default_patterns_en == _FALSE) {
3454 			SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
3455 				u1H2CRemoteWakeCtrlParm, enable);
3456 			/*
3457 			 * filter NetBios name service pkt to avoid being waked-up
3458 			 * by this kind of unicast pkt this exceptional modification
3459 			 * is used for match competitor's behavior
3460 			 */
3461 			SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
3462 				u1H2CRemoteWakeCtrlParm, enable);
3463 		}
3464 
3465 		if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
3466 		    (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
3467 			SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
3468 				u1H2CRemoteWakeCtrlParm, 0);
3469 		} else {
3470 			SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
3471 				u1H2CRemoteWakeCtrlParm, 1);
3472 		}
3473 
3474 		SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
3475 			u1H2CRemoteWakeCtrlParm, 1);
3476 	}
3477 #ifdef CONFIG_PNO_SUPPORT
3478 	else {
3479 		SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
3480 			u1H2CRemoteWakeCtrlParm, enable);
3481 		SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
3482 			u1H2CRemoteWakeCtrlParm, enable);
3483 	}
3484 #endif
3485 
3486 #ifdef CONFIG_P2P_WOWLAN
3487 	if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
3488 		RTW_INFO("P2P OFFLOAD ENABLE\n");
3489 		SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
3490 	} else {
3491 		RTW_INFO("P2P OFFLOAD DISABLE\n");
3492 		SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
3493 	}
3494 #endif /* CONFIG_P2P_WOWLAN */
3495 
3496 
3497 	ret = rtw_hal_fill_h2c_cmd(adapter,
3498 				   H2C_REMOTE_WAKE_CTRL,
3499 				   H2C_REMOTE_WAKE_CTRL_LEN,
3500 				   u1H2CRemoteWakeCtrlParm);
3501 	return ret;
3502 }
3503 
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)3504 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
3505 {
3506 	struct hal_ops *pHalFunc = &adapter->HalFunc;
3507 	u8 ret = _FAIL;
3508 	u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
3509 
3510 	RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
3511 		 __func__, group_alg, pairwise_alg);
3512 	SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
3513 			pairwise_alg);
3514 	SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
3515 			group_alg);
3516 
3517 	ret = rtw_hal_fill_h2c_cmd(adapter,
3518 				   H2C_AOAC_GLOBAL_INFO,
3519 				   H2C_AOAC_GLOBAL_INFO_LEN,
3520 				   u1H2CAOACGlobalInfoParm);
3521 
3522 	return ret;
3523 }
3524 
3525 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)3526 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
3527 		PRSVDPAGE_LOC rsvdpageloc, u8 enable)
3528 {
3529 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
3530 	struct hal_ops *pHalFunc = &adapter->HalFunc;
3531 
3532 	u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
3533 	u8 res = 0, count = 0, ret = _FAIL;
3534 
3535 	RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
3536 		 __func__, rsvdpageloc->LocProbePacket,
3537 		 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
3538 
3539 	SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
3540 	SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
3541 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
3542 					       rsvdpageloc->LocScanInfo);
3543 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
3544 			rsvdpageloc->LocProbePacket);
3545 	/*
3546 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
3547 				rsvdpageloc->LocSSIDInfo);
3548 	*/
3549 	ret = rtw_hal_fill_h2c_cmd(adapter,
3550 				   H2C_D0_SCAN_OFFLOAD_INFO,
3551 				   H2C_SCAN_OFFLOAD_CTRL_LEN,
3552 				   u1H2CScanOffloadInfoParm);
3553 	return ret;
3554 }
3555 #endif /* CONFIG_PNO_SUPPORT */
3556 
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)3557 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
3558 {
3559 	struct security_priv *psecpriv = &padapter->securitypriv;
3560 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
3561 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
3562 	struct sta_info *psta = NULL;
3563 	u16 media_status_rpt;
3564 	u8	pkt_type = 0;
3565 	u8 ret = _SUCCESS;
3566 
3567 	RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
3568 	_func_enter_;
3569 
3570 	rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
3571 
3572 	if (enable) {
3573 		rtw_hal_set_global_info_cmd(padapter,
3574 					    psecpriv->dot118021XGrpPrivacy,
3575 					    psecpriv->dot11PrivacyAlgrthm);
3576 
3577 		if (!(ppwrpriv->wowlan_pno_enable)) {
3578 			rtw_hal_set_disconnect_decision_cmd(padapter, enable);
3579 #ifdef CONFIG_ARP_KEEP_ALIVE
3580 			if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
3581 			    (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
3582 				pkt_type = 0;
3583 			else
3584 				pkt_type = 1;
3585 #else
3586 			pkt_type = 0;
3587 #endif /* CONFIG_ARP_KEEP_ALIVE */
3588 			rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
3589 		}
3590 		rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
3591 #ifdef CONFIG_PNO_SUPPORT
3592 		rtw_hal_check_pno_enabled(padapter);
3593 #endif /* CONFIG_PNO_SUPPORT */
3594 	} else {
3595 #if 0
3596 		{
3597 			u32 PageSize = 0;
3598 			rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
3599 			dump_TX_FIFO(padapter, 4, PageSize);
3600 		}
3601 #endif
3602 
3603 		rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
3604 	}
3605 	_func_exit_;
3606 	RTW_PRINT("-%s()-\n", __func__);
3607 }
3608 #endif /* CONFIG_WOWLAN */
3609 
3610 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)3611 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
3612 {
3613 	struct security_priv *psecpriv = &adapter->securitypriv;
3614 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
3615 	struct hal_ops *pHalFunc = &adapter->HalFunc;
3616 
3617 	u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
3618 	u8 gpionum = 0, gpio_dur = 0;
3619 	u8 gpio_pulse = enable;
3620 	u8 sdio_wakeup_enable = 1;
3621 	u8 gpio_high_active = 0;
3622 	u8 ret = _FAIL;
3623 
3624 #ifdef CONFIG_GPIO_WAKEUP
3625 	gpio_high_active = ppwrpriv->is_high_active;
3626 	gpionum = WAKEUP_GPIO_IDX;
3627 	sdio_wakeup_enable = 0;
3628 #endif /*CONFIG_GPIO_WAKEUP*/
3629 
3630 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
3631 
3632 	SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
3633 					  gpionum);
3634 	SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
3635 					 gpio_pulse);
3636 	SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
3637 						gpio_high_active);
3638 	SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
3639 				       enable);
3640 	SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
3641 					     gpio_dur);
3642 
3643 	ret = rtw_hal_fill_h2c_cmd(adapter,
3644 				   H2C_AP_WOW_GPIO_CTRL,
3645 				   H2C_AP_WOW_GPIO_CTRL_LEN,
3646 				   u1H2CAPWoWlanCtrlParm);
3647 
3648 	return ret;
3649 }
3650 
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)3651 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
3652 {
3653 	struct hal_ops *pHalFunc = &adapter->HalFunc;
3654 	u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
3655 	u8 ret = _FAIL;
3656 
3657 	RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
3658 
3659 	SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
3660 
3661 	ret = rtw_hal_fill_h2c_cmd(adapter,
3662 				   H2C_AP_OFFLOAD,
3663 				   H2C_AP_OFFLOAD_LEN,
3664 				   u1H2CAPOffloadCtrlParm);
3665 
3666 	return ret;
3667 }
3668 
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)3669 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
3670 {
3671 	struct hal_ops *pHalFunc = &adapter->HalFunc;
3672 	u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
3673 	u8 ret = _FAIL;
3674 
3675 	RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
3676 
3677 	SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
3678 #ifndef CONFIG_USB_HCI
3679 	SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
3680 #endif /*CONFIG_USB_HCI*/
3681 	SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
3682 
3683 	if (enable)
3684 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
3685 	else
3686 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
3687 
3688 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
3689 				   H2C_AP_PS_LEN, ap_ps_parm);
3690 
3691 	return ret;
3692 }
3693 
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)3694 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
3695 		PRSVDPAGE_LOC rsvdpageloc)
3696 {
3697 	struct hal_ops *pHalFunc = &padapter->HalFunc;
3698 	u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
3699 	u8 ret = _FAIL, header = 0;
3700 
3701 	if (pHalFunc->fill_h2c_cmd == NULL) {
3702 		RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
3703 		return;
3704 	}
3705 
3706 	header = rtw_read8(padapter, REG_BCNQ_BDNY);
3707 
3708 	RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
3709 		 rsvdpageloc->LocApOffloadBCN,
3710 		 rsvdpageloc->LocProbeRsp,
3711 		 header);
3712 
3713 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
3714 				      rsvdpageloc->LocApOffloadBCN + header);
3715 
3716 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
3717 				   H2C_BCN_RSVDPAGE_LEN, rsvdparm);
3718 
3719 	if (ret == _FAIL)
3720 		RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
3721 
3722 	rtw_msleep_os(10);
3723 
3724 	_rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
3725 
3726 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
3727 			rsvdpageloc->LocProbeRsp + header);
3728 
3729 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
3730 				   H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
3731 
3732 	if (ret == _FAIL)
3733 		RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
3734 
3735 	rtw_msleep_os(10);
3736 }
3737 
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)3738 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
3739 {
3740 	rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
3741 	rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
3742 	rtw_hal_set_ap_ps_cmd(padapter, enable);
3743 }
3744 
rtw_hal_ap_wow_enable(_adapter * padapter)3745 static void rtw_hal_ap_wow_enable(_adapter *padapter)
3746 {
3747 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
3748 	struct security_priv *psecuritypriv = &padapter->securitypriv;
3749 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3750 	struct hal_ops *pHalFunc = &padapter->HalFunc;
3751 	struct sta_info *psta = NULL;
3752 #ifdef DBG_CHECK_FW_PS_STATE
3753 	struct dvobj_priv *psdpriv = padapter->dvobj;
3754 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
3755 #endif /*DBG_CHECK_FW_PS_STATE*/
3756 	int res;
3757 	u16 media_status_rpt;
3758 
3759 	RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
3760 #ifdef DBG_CHECK_FW_PS_STATE
3761 	if (rtw_fw_ps_state(padapter) == _FAIL) {
3762 		pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
3763 		RTW_PRINT("wowlan enable no leave 32k\n");
3764 	}
3765 #endif /*DBG_CHECK_FW_PS_STATE*/
3766 
3767 	/* 1. Download WOWLAN FW*/
3768 	rtw_hal_fw_dl(padapter, _TRUE);
3769 
3770 	media_status_rpt = RT_MEDIA_CONNECT;
3771 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
3772 			  (u8 *)&media_status_rpt);
3773 
3774 	issue_beacon(padapter, 0);
3775 
3776 	rtw_msleep_os(2);
3777 
3778 	if (IS_HARDWARE_TYPE_8188E(padapter))
3779 		rtw_hal_disable_tx_report(padapter);
3780 
3781 	/* RX DMA stop */
3782 	res = rtw_hal_pause_rx_dma(padapter);
3783 	if (res == _FAIL)
3784 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
3785 
3786 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3787 	/* Enable CPWM2 only. */
3788 	res = rtw_hal_enable_cpwm2(padapter);
3789 	if (res == _FAIL)
3790 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
3791 #endif
3792 
3793 #ifdef CONFIG_GPIO_WAKEUP
3794 	rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE);
3795 #endif
3796 	/* 5. Set Enable WOWLAN H2C command. */
3797 	RTW_PRINT("Set Enable AP WOWLan cmd\n");
3798 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
3799 
3800 	rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
3801 #ifdef CONFIG_USB_HCI
3802 	rtw_mi_intf_stop(padapter);
3803 	/* Invoid SE0 reset signal during suspending*/
3804 	rtw_write8(padapter, REG_RSV_CTRL, 0x20);
3805 	rtw_write8(padapter, REG_RSV_CTRL, 0x60);
3806 #endif /*CONFIG_USB_HCI*/
3807 }
3808 
rtw_hal_ap_wow_disable(_adapter * padapter)3809 static void rtw_hal_ap_wow_disable(_adapter *padapter)
3810 {
3811 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
3812 	struct hal_ops *pHalFunc = &padapter->HalFunc;
3813 #ifdef DBG_CHECK_FW_PS_STATE
3814 	struct dvobj_priv *psdpriv = padapter->dvobj;
3815 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
3816 #endif /*DBG_CHECK_FW_PS_STATE*/
3817 	u16 media_status_rpt;
3818 	u8 val8;
3819 
3820 	RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
3821 	/* 1. Read wakeup reason*/
3822 	pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
3823 
3824 	RTW_PRINT("wakeup_reason: 0x%02x\n",
3825 		  pwrctl->wowlan_wake_reason);
3826 
3827 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
3828 
3829 	rtw_msleep_os(2);
3830 #ifdef DBG_CHECK_FW_PS_STATE
3831 	if (rtw_fw_ps_state(padapter) == _FAIL) {
3832 		pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
3833 		RTW_PRINT("wowlan enable no leave 32k\n");
3834 	}
3835 #endif /*DBG_CHECK_FW_PS_STATE*/
3836 
3837 	if (IS_HARDWARE_TYPE_8188E(padapter))
3838 		rtw_hal_enable_tx_report(padapter);
3839 
3840 	rtw_hal_force_enable_rxdma(padapter);
3841 
3842 	rtw_hal_fw_dl(padapter, _FALSE);
3843 
3844 #ifdef CONFIG_GPIO_WAKEUP
3845 	val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
3846 	RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
3847 	rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8);
3848 #endif
3849 	media_status_rpt = RT_MEDIA_CONNECT;
3850 
3851 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
3852 			  (u8 *)&media_status_rpt);
3853 
3854 	issue_beacon(padapter, 0);
3855 }
3856 #endif /*CONFIG_AP_WOWLAN*/
3857 
3858 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)3859 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
3860 {
3861 	u8 *ssid_ie;
3862 	sint ssid_len_ori;
3863 	int len_diff = 0;
3864 
3865 	ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
3866 
3867 	/* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
3868 
3869 	if (ssid_ie && ssid_len_ori > 0) {
3870 		switch (hidden_ssid_mode) {
3871 		case 1: {
3872 			u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
3873 			u32 remain_len = 0;
3874 
3875 			remain_len = ies_len - (next_ie - ies);
3876 
3877 			ssid_ie[1] = 0;
3878 			_rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
3879 			len_diff -= ssid_len_ori;
3880 
3881 			break;
3882 		}
3883 		case 2:
3884 			_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
3885 			break;
3886 		default:
3887 			break;
3888 		}
3889 	}
3890 
3891 	return len_diff;
3892 }
3893 
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)3894 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
3895 {
3896 	/* struct xmit_frame	*pmgntframe; */
3897 	/* struct pkt_attrib	*pattrib; */
3898 	/* unsigned char	*pframe; */
3899 	struct rtw_ieee80211_hdr *pwlanhdr;
3900 	unsigned short *fctrl;
3901 	unsigned int	rate_len;
3902 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
3903 	u32	pktlen;
3904 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
3905 	/*	_irqL irqL;
3906 	 *	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3907 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
3908 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3909 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
3910 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3911 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
3912 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3913 #ifdef CONFIG_P2P
3914 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
3915 #endif /* CONFIG_P2P */
3916 
3917 	/* for debug */
3918 	u8 *dbgbuf = pframe;
3919 	u8 dbgbufLen = 0, index = 0;
3920 
3921 	RTW_INFO("%s\n", __FUNCTION__);
3922 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
3923 	/*	_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
3924 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
3925 
3926 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3927 
3928 
3929 	fctrl = &(pwlanhdr->frame_ctl);
3930 	*(fctrl) = 0;
3931 
3932 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
3933 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
3934 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
3935 
3936 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
3937 	/* pmlmeext->mgnt_seq++; */
3938 	SetFrameSubType(pframe, WIFI_BEACON);
3939 
3940 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3941 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3942 
3943 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3944 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
3945 #ifdef CONFIG_P2P
3946 		/* for P2P : Primary Device Type & Device Name */
3947 		u32 wpsielen = 0, insert_len = 0;
3948 		u8 *wpsie = NULL;
3949 		wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
3950 
3951 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
3952 			uint wps_offset, remainder_ielen;
3953 			u8 *premainder_ie, *pframe_wscie;
3954 
3955 			wps_offset = (uint)(wpsie - cur_network->IEs);
3956 
3957 			premainder_ie = wpsie + wpsielen;
3958 
3959 			remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
3960 
3961 #ifdef CONFIG_IOCTL_CFG80211
3962 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
3963 				if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
3964 					_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
3965 					pframe += wps_offset;
3966 					pktlen += wps_offset;
3967 
3968 					_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
3969 					pframe += pmlmepriv->wps_beacon_ie_len;
3970 					pktlen += pmlmepriv->wps_beacon_ie_len;
3971 
3972 					/* copy remainder_ie to pframe */
3973 					_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
3974 					pframe += remainder_ielen;
3975 					pktlen += remainder_ielen;
3976 				} else {
3977 					_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
3978 					pframe += cur_network->IELength;
3979 					pktlen += cur_network->IELength;
3980 				}
3981 			} else
3982 #endif /* CONFIG_IOCTL_CFG80211 */
3983 			{
3984 				pframe_wscie = pframe + wps_offset;
3985 				_rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
3986 				pframe += (wps_offset + wpsielen);
3987 				pktlen += (wps_offset + wpsielen);
3988 
3989 				/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
3990 				/*	Primary Device Type */
3991 				/*	Type: */
3992 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
3993 				insert_len += 2;
3994 
3995 				/*	Length: */
3996 				*(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
3997 				insert_len += 2;
3998 
3999 				/*	Value: */
4000 				/*	Category ID */
4001 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4002 				insert_len += 2;
4003 
4004 				/*	OUI */
4005 				*(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
4006 				insert_len += 4;
4007 
4008 				/*	Sub Category ID */
4009 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4010 				insert_len += 2;
4011 
4012 
4013 				/*	Device Name */
4014 				/*	Type: */
4015 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4016 				insert_len += 2;
4017 
4018 				/*	Length: */
4019 				*(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
4020 				insert_len += 2;
4021 
4022 				/*	Value: */
4023 				_rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
4024 				insert_len += pwdinfo->device_name_len;
4025 
4026 
4027 				/* update wsc ie length */
4028 				*(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
4029 
4030 				/* pframe move to end */
4031 				pframe += insert_len;
4032 				pktlen += insert_len;
4033 
4034 				/* copy remainder_ie to pframe */
4035 				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
4036 				pframe += remainder_ielen;
4037 				pktlen += remainder_ielen;
4038 			}
4039 		} else
4040 #endif /* CONFIG_P2P */
4041 		{
4042 			int len_diff;
4043 			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
4044 			len_diff = update_hidden_ssid(
4045 					   pframe + _BEACON_IE_OFFSET_
4046 				   , cur_network->IELength - _BEACON_IE_OFFSET_
4047 					   , pmlmeinfo->hidden_ssid_mode
4048 				   );
4049 			pframe += (cur_network->IELength + len_diff);
4050 			pktlen += (cur_network->IELength + len_diff);
4051 		}
4052 #if 0
4053 		{
4054 			u8 *wps_ie;
4055 			uint wps_ielen;
4056 			u8 sr = 0;
4057 			wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
4058 				pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
4059 			if (wps_ie && wps_ielen > 0)
4060 				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
4061 			if (sr != 0)
4062 				set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
4063 			else
4064 				_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
4065 		}
4066 #endif
4067 #ifdef CONFIG_P2P
4068 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
4069 			u32 len;
4070 #ifdef CONFIG_IOCTL_CFG80211
4071 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
4072 				len = pmlmepriv->p2p_beacon_ie_len;
4073 				if (pmlmepriv->p2p_beacon_ie && len > 0)
4074 					_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
4075 			} else
4076 #endif /* CONFIG_IOCTL_CFG80211 */
4077 			{
4078 				len = build_beacon_p2p_ie(pwdinfo, pframe);
4079 			}
4080 
4081 			pframe += len;
4082 			pktlen += len;
4083 
4084 #ifdef CONFIG_WFD
4085 			len = rtw_append_beacon_wfd_ie(padapter, pframe);
4086 			pframe += len;
4087 			pktlen += len;
4088 #endif
4089 
4090 		}
4091 #endif /* CONFIG_P2P */
4092 
4093 		goto _issue_bcn;
4094 
4095 	}
4096 
4097 	/* below for ad-hoc mode */
4098 
4099 	/* timestamp will be inserted by hardware */
4100 	pframe += 8;
4101 	pktlen += 8;
4102 
4103 	/* beacon interval: 2 bytes */
4104 
4105 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
4106 
4107 	pframe += 2;
4108 	pktlen += 2;
4109 
4110 	/* capability info: 2 bytes */
4111 
4112 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
4113 
4114 	pframe += 2;
4115 	pktlen += 2;
4116 
4117 	/* SSID */
4118 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
4119 
4120 	/* supported rates... */
4121 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
4122 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
4123 
4124 	/* DS parameter set */
4125 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
4126 
4127 	/* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
4128 	{
4129 		u8 erpinfo = 0;
4130 		u32 ATIMWindow;
4131 		/* IBSS Parameter Set... */
4132 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
4133 		ATIMWindow = 0;
4134 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
4135 
4136 		/* ERP IE */
4137 		pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
4138 	}
4139 
4140 
4141 	/* EXTERNDED SUPPORTED RATE */
4142 	if (rate_len > 8)
4143 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
4144 
4145 
4146 	/* todo:HT for adhoc */
4147 
4148 _issue_bcn:
4149 
4150 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
4151 	/*	pmlmepriv->update_bcn = _FALSE;
4152 	 *
4153 	 *	_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
4154 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
4155 
4156 	*pLength = pktlen;
4157 #if 0
4158 	/* printf dbg msg */
4159 	dbgbufLen = pktlen;
4160 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
4161 
4162 	for (index = 0; index < dbgbufLen; index++)
4163 		printk("%x ", *(dbgbuf + index));
4164 
4165 	printk("\n");
4166 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
4167 
4168 #endif
4169 }
4170 
get_reg_classes_full_count(struct p2p_channels channel_list)4171 static int get_reg_classes_full_count(struct p2p_channels channel_list)
4172 {
4173 	int cnt = 0;
4174 	int i;
4175 
4176 	for (i = 0; i < channel_list.reg_classes; i++)
4177 		cnt += channel_list.reg_class[i].channels;
4178 
4179 	return cnt;
4180 }
4181 
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)4182 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
4183 {
4184 	/* struct xmit_frame			*pmgntframe; */
4185 	/* struct pkt_attrib			*pattrib; */
4186 	/* unsigned char					*pframe; */
4187 	struct rtw_ieee80211_hdr	*pwlanhdr;
4188 	unsigned short				*fctrl;
4189 	unsigned char					*mac;
4190 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
4191 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
4192 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4193 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4194 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
4195 	u16					beacon_interval = 100;
4196 	u16					capInfo = 0;
4197 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4198 	u8					wpsie[255] = { 0x00 };
4199 	u32					wpsielen = 0, p2pielen = 0;
4200 	u32					pktlen;
4201 #ifdef CONFIG_WFD
4202 	u32					wfdielen = 0;
4203 #endif
4204 #ifdef CONFIG_INTEL_WIDI
4205 	u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
4206 #endif /* CONFIG_INTEL_WIDI */
4207 
4208 	/* for debug */
4209 	u8 *dbgbuf = pframe;
4210 	u8 dbgbufLen = 0, index = 0;
4211 
4212 	RTW_INFO("%s\n", __FUNCTION__);
4213 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4214 
4215 	mac = adapter_mac_addr(padapter);
4216 
4217 	fctrl = &(pwlanhdr->frame_ctl);
4218 	*(fctrl) = 0;
4219 
4220 	/* DA filled by FW */
4221 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
4222 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
4223 
4224 	/*	Use the device address for BSSID field.	 */
4225 	_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
4226 
4227 	SetSeqNum(pwlanhdr, 0);
4228 	SetFrameSubType(fctrl, WIFI_PROBERSP);
4229 
4230 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4231 	pframe += pktlen;
4232 
4233 
4234 	/* timestamp will be inserted by hardware */
4235 	pframe += 8;
4236 	pktlen += 8;
4237 
4238 	/* beacon interval: 2 bytes */
4239 	_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
4240 	pframe += 2;
4241 	pktlen += 2;
4242 
4243 	/*	capability info: 2 bytes */
4244 	/*	ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
4245 	capInfo |= cap_ShortPremble;
4246 	capInfo |= cap_ShortSlot;
4247 
4248 	_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
4249 	pframe += 2;
4250 	pktlen += 2;
4251 
4252 
4253 	/* SSID */
4254 	pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
4255 
4256 	/* supported rates... */
4257 	/*	Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
4258 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
4259 
4260 	/* DS parameter set */
4261 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
4262 
4263 #ifdef CONFIG_IOCTL_CFG80211
4264 	if (pwdinfo->driver_interface == DRIVER_CFG80211) {
4265 		if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
4266 			/* WPS IE */
4267 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
4268 			pktlen += pmlmepriv->wps_probe_resp_ie_len;
4269 			pframe += pmlmepriv->wps_probe_resp_ie_len;
4270 
4271 			/* P2P IE */
4272 			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
4273 			pktlen += pmlmepriv->p2p_probe_resp_ie_len;
4274 			pframe += pmlmepriv->p2p_probe_resp_ie_len;
4275 		}
4276 	} else
4277 #endif /* CONFIG_IOCTL_CFG80211		 */
4278 	{
4279 
4280 		/*	Todo: WPS IE */
4281 		/*	Noted by Albert 20100907 */
4282 		/*	According to the WPS specification, all the WPS attribute is presented by Big Endian. */
4283 
4284 		wpsielen = 0;
4285 		/*	WPS OUI */
4286 		*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
4287 		wpsielen += 4;
4288 
4289 		/*	WPS version */
4290 		/*	Type: */
4291 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
4292 		wpsielen += 2;
4293 
4294 		/*	Length: */
4295 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4296 		wpsielen += 2;
4297 
4298 		/*	Value: */
4299 		wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
4300 
4301 #ifdef CONFIG_INTEL_WIDI
4302 		/*	Commented by Kurt */
4303 		/*	Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext. */
4304 		if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
4305 		    || pmlmepriv->num_p2p_sdt != 0) {
4306 			/* Sec dev type */
4307 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SEC_DEV_TYPE_LIST);
4308 			wpsielen += 2;
4309 
4310 			/*	Length: */
4311 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
4312 			wpsielen += 2;
4313 
4314 			/*	Value: */
4315 			/*	Category ID */
4316 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_DISPLAYS);
4317 			wpsielen += 2;
4318 
4319 			/*	OUI */
4320 			*(u32 *)(wpsie + wpsielen) = cpu_to_be32(INTEL_DEV_TYPE_OUI);
4321 			wpsielen += 4;
4322 
4323 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_WIDI_CONSUMER_SINK);
4324 			wpsielen += 2;
4325 
4326 			if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE) {
4327 				/*	Vendor Extension */
4328 				_rtw_memcpy(wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN);
4329 				wpsielen += L2SDTA_SERVICE_VE_LEN;
4330 			}
4331 		}
4332 #endif /* CONFIG_INTEL_WIDI */
4333 
4334 		/*	WiFi Simple Config State */
4335 		/*	Type: */
4336 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
4337 		wpsielen += 2;
4338 
4339 		/*	Length: */
4340 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4341 		wpsielen += 2;
4342 
4343 		/*	Value: */
4344 		wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;	/*	Not Configured. */
4345 
4346 		/*	Response Type */
4347 		/*	Type: */
4348 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
4349 		wpsielen += 2;
4350 
4351 		/*	Length: */
4352 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4353 		wpsielen += 2;
4354 
4355 		/*	Value: */
4356 		wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
4357 
4358 		/*	UUID-E */
4359 		/*	Type: */
4360 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
4361 		wpsielen += 2;
4362 
4363 		/*	Length: */
4364 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
4365 		wpsielen += 2;
4366 
4367 		/*	Value: */
4368 		if (pwdinfo->external_uuid == 0) {
4369 			_rtw_memset(wpsie + wpsielen, 0x0, 16);
4370 			_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
4371 		} else
4372 			_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
4373 		wpsielen += 0x10;
4374 
4375 		/*	Manufacturer */
4376 		/*	Type: */
4377 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
4378 		wpsielen += 2;
4379 
4380 		/*	Length: */
4381 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
4382 		wpsielen += 2;
4383 
4384 		/*	Value: */
4385 		_rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
4386 		wpsielen += 7;
4387 
4388 		/*	Model Name */
4389 		/*	Type: */
4390 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
4391 		wpsielen += 2;
4392 
4393 		/*	Length: */
4394 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
4395 		wpsielen += 2;
4396 
4397 		/*	Value: */
4398 		_rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
4399 		wpsielen += 6;
4400 
4401 		/*	Model Number */
4402 		/*	Type: */
4403 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
4404 		wpsielen += 2;
4405 
4406 		/*	Length: */
4407 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4408 		wpsielen += 2;
4409 
4410 		/*	Value: */
4411 		wpsie[wpsielen++] = 0x31;		/*	character 1 */
4412 
4413 		/*	Serial Number */
4414 		/*	Type: */
4415 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
4416 		wpsielen += 2;
4417 
4418 		/*	Length: */
4419 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
4420 		wpsielen += 2;
4421 
4422 		/*	Value: */
4423 		_rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
4424 		wpsielen += ETH_ALEN;
4425 
4426 		/*	Primary Device Type */
4427 		/*	Type: */
4428 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
4429 		wpsielen += 2;
4430 
4431 		/*	Length: */
4432 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
4433 		wpsielen += 2;
4434 
4435 		/*	Value: */
4436 		/*	Category ID */
4437 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4438 		wpsielen += 2;
4439 
4440 		/*	OUI */
4441 		*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
4442 		wpsielen += 4;
4443 
4444 		/*	Sub Category ID */
4445 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4446 		wpsielen += 2;
4447 
4448 		/*	Device Name */
4449 		/*	Type: */
4450 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4451 		wpsielen += 2;
4452 
4453 		/*	Length: */
4454 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
4455 		wpsielen += 2;
4456 
4457 		/*	Value: */
4458 		_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
4459 		wpsielen += pwdinfo->device_name_len;
4460 
4461 		/*	Config Method */
4462 		/*	Type: */
4463 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
4464 		wpsielen += 2;
4465 
4466 		/*	Length: */
4467 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
4468 		wpsielen += 2;
4469 
4470 		/*	Value: */
4471 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
4472 		wpsielen += 2;
4473 
4474 
4475 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
4476 
4477 
4478 		p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
4479 		pframe += p2pielen;
4480 		pktlen += p2pielen;
4481 	}
4482 
4483 #ifdef CONFIG_WFD
4484 	wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
4485 	pframe += wfdielen;
4486 	pktlen += wfdielen;
4487 #endif
4488 
4489 	*pLength = pktlen;
4490 
4491 #if 0
4492 	/* printf dbg msg */
4493 	dbgbufLen = pktlen;
4494 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
4495 
4496 	for (index = 0; index < dbgbufLen; index++)
4497 		printk("%x ", *(dbgbuf + index));
4498 
4499 	printk("\n");
4500 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
4501 #endif
4502 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)4503 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
4504 {
4505 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4506 	u8			action = P2P_PUB_ACTION_ACTION;
4507 	u32			p2poui = cpu_to_be32(P2POUI);
4508 	u8			oui_subtype = P2P_GO_NEGO_RESP;
4509 	u8			wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
4510 	u8			p2pielen = 0, i;
4511 	uint			wpsielen = 0;
4512 	u16			wps_devicepassword_id = 0x0000;
4513 	uint			wps_devicepassword_id_len = 0;
4514 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
4515 	u16			len_channellist_attr = 0;
4516 	u32			pktlen;
4517 	u8			dialogToken = 0;
4518 
4519 	/* struct xmit_frame			*pmgntframe; */
4520 	/* struct pkt_attrib			*pattrib; */
4521 	/* unsigned char					*pframe; */
4522 	struct rtw_ieee80211_hdr	*pwlanhdr;
4523 	unsigned short				*fctrl;
4524 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
4525 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
4526 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4527 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4528 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
4529 
4530 #ifdef CONFIG_WFD
4531 	u32					wfdielen = 0;
4532 #endif
4533 
4534 	/* for debug */
4535 	u8 *dbgbuf = pframe;
4536 	u8 dbgbufLen = 0, index = 0;
4537 
4538 	RTW_INFO("%s\n", __FUNCTION__);
4539 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4540 
4541 	fctrl = &(pwlanhdr->frame_ctl);
4542 	*(fctrl) = 0;
4543 
4544 	/* RA, filled by FW */
4545 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
4546 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4547 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4548 
4549 	SetSeqNum(pwlanhdr, 0);
4550 	SetFrameSubType(pframe, WIFI_ACTION);
4551 
4552 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4553 	pframe += pktlen;
4554 
4555 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
4556 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
4557 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
4558 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
4559 
4560 	/* dialog token, filled by FW */
4561 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
4562 
4563 	_rtw_memset(wpsie, 0x00, 255);
4564 	wpsielen = 0;
4565 
4566 	/*	WPS Section */
4567 	wpsielen = 0;
4568 	/*	WPS OUI */
4569 	*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
4570 	wpsielen += 4;
4571 
4572 	/*	WPS version */
4573 	/*	Type: */
4574 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
4575 	wpsielen += 2;
4576 
4577 	/*	Length: */
4578 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4579 	wpsielen += 2;
4580 
4581 	/*	Value: */
4582 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
4583 
4584 	/*	Device Password ID */
4585 	/*	Type: */
4586 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
4587 	wpsielen += 2;
4588 
4589 	/*	Length: */
4590 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
4591 	wpsielen += 2;
4592 
4593 	/*	Value: */
4594 	if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
4595 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
4596 	else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
4597 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
4598 	else
4599 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
4600 	wpsielen += 2;
4601 
4602 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
4603 
4604 
4605 	/*	P2P IE Section. */
4606 
4607 	/*	P2P OUI */
4608 	p2pielen = 0;
4609 	p2pie[p2pielen++] = 0x50;
4610 	p2pie[p2pielen++] = 0x6F;
4611 	p2pie[p2pielen++] = 0x9A;
4612 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
4613 
4614 	/*	Commented by Albert 20100908 */
4615 	/*	According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
4616 	/*	1. Status */
4617 	/*	2. P2P Capability */
4618 	/*	3. Group Owner Intent */
4619 	/*	4. Configuration Timeout */
4620 	/*	5. Operating Channel */
4621 	/*	6. Intended P2P Interface Address */
4622 	/*	7. Channel List */
4623 	/*	8. Device Info */
4624 	/*	9. Group ID	( Only GO ) */
4625 
4626 
4627 	/*	ToDo: */
4628 
4629 	/*	P2P Status */
4630 	/*	Type: */
4631 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
4632 
4633 	/*	Length: */
4634 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4635 	p2pielen += 2;
4636 
4637 	/*	Value, filled by FW */
4638 	p2pie[p2pielen++] = 1;
4639 
4640 	/*	P2P Capability */
4641 	/*	Type: */
4642 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
4643 
4644 	/*	Length: */
4645 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4646 	p2pielen += 2;
4647 
4648 	/*	Value: */
4649 	/*	Device Capability Bitmap, 1 byte */
4650 
4651 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
4652 		/*	Commented by Albert 2011/03/08 */
4653 		/*	According to the P2P specification */
4654 		/*	if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
4655 		p2pie[p2pielen++] = 0;
4656 	} else {
4657 		/*	Be group owner or meet the error case */
4658 		p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
4659 	}
4660 
4661 	/*	Group Capability Bitmap, 1 byte */
4662 	if (pwdinfo->persistent_supported)
4663 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4664 	else
4665 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
4666 
4667 	/*	Group Owner Intent */
4668 	/*	Type: */
4669 	p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
4670 
4671 	/*	Length: */
4672 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4673 	p2pielen += 2;
4674 
4675 	/*	Value: */
4676 	if (pwdinfo->peer_intent & 0x01) {
4677 		/*	Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
4678 		p2pie[p2pielen++] = (pwdinfo->intent << 1);
4679 	} else {
4680 		/*	Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
4681 		p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
4682 	}
4683 
4684 
4685 	/*	Configuration Timeout */
4686 	/*	Type: */
4687 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
4688 
4689 	/*	Length: */
4690 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4691 	p2pielen += 2;
4692 
4693 	/*	Value: */
4694 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
4695 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
4696 
4697 	/*	Operating Channel */
4698 	/*	Type: */
4699 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
4700 
4701 	/*	Length: */
4702 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4703 	p2pielen += 2;
4704 
4705 	/*	Value: */
4706 	/*	Country String */
4707 	p2pie[p2pielen++] = 'X';
4708 	p2pie[p2pielen++] = 'X';
4709 
4710 	/*	The third byte should be set to 0x04. */
4711 	/*	Described in the "Operating Channel Attribute" section. */
4712 	p2pie[p2pielen++] = 0x04;
4713 
4714 	/*	Operating Class */
4715 	if (pwdinfo->operating_channel <= 14) {
4716 		/*	Operating Class */
4717 		p2pie[p2pielen++] = 0x51;
4718 	} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
4719 		/*	Operating Class */
4720 		p2pie[p2pielen++] = 0x73;
4721 	} else {
4722 		/*	Operating Class */
4723 		p2pie[p2pielen++] = 0x7c;
4724 	}
4725 
4726 	/*	Channel Number */
4727 	p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
4728 
4729 	/*	Intended P2P Interface Address	 */
4730 	/*	Type: */
4731 	p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR;
4732 
4733 	/*	Length: */
4734 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
4735 	p2pielen += 2;
4736 
4737 	/*	Value: */
4738 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4739 	p2pielen += ETH_ALEN;
4740 
4741 	/*	Channel List */
4742 	/*	Type: */
4743 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
4744 
4745 	/* Country String(3) */
4746 	/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
4747 	/* + number of channels in all classes */
4748 	len_channellist_attr = 3
4749 		       + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4750 		       + get_reg_classes_full_count(pmlmeext->channel_list);
4751 
4752 #ifdef CONFIG_CONCURRENT_MODE
4753 	if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED))
4754 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
4755 	else
4756 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4757 
4758 #else
4759 
4760 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4761 
4762 #endif
4763 	p2pielen += 2;
4764 
4765 	/*	Value: */
4766 	/*	Country String */
4767 	p2pie[p2pielen++] = 'X';
4768 	p2pie[p2pielen++] = 'X';
4769 
4770 	/*	The third byte should be set to 0x04. */
4771 	/*	Described in the "Operating Channel Attribute" section. */
4772 	p2pie[p2pielen++] = 0x04;
4773 
4774 	/*	Channel Entry List */
4775 
4776 #ifdef CONFIG_CONCURRENT_MODE
4777 	if (rtw_mi_check_status(padapter, MI_LINKED)) {
4778 		u8 union_ch = rtw_mi_get_union_chan(padapter);
4779 
4780 		/*	Operating Class */
4781 		if (union_ch > 14) {
4782 			if (union_ch >= 149)
4783 				p2pie[p2pielen++] = 0x7c;
4784 			else
4785 				p2pie[p2pielen++] = 0x73;
4786 		} else
4787 			p2pie[p2pielen++] = 0x51;
4788 
4789 
4790 		/*	Number of Channels */
4791 		/*	Just support 1 channel and this channel is AP's channel */
4792 		p2pie[p2pielen++] = 1;
4793 
4794 		/*	Channel List */
4795 		p2pie[p2pielen++] = union_ch;
4796 	} else {
4797 		int i, j;
4798 		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4799 			/*	Operating Class */
4800 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4801 
4802 			/*	Number of Channels */
4803 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4804 
4805 			/*	Channel List */
4806 			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
4807 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4808 		}
4809 	}
4810 #else /* CONFIG_CONCURRENT_MODE */
4811 	{
4812 		int i, j;
4813 		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4814 			/*	Operating Class */
4815 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4816 
4817 			/*	Number of Channels */
4818 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4819 
4820 			/*	Channel List */
4821 			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
4822 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4823 		}
4824 	}
4825 #endif /* CONFIG_CONCURRENT_MODE */
4826 
4827 
4828 	/*	Device Info */
4829 	/*	Type: */
4830 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
4831 
4832 	/*	Length: */
4833 	/*	21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
4834 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
4835 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
4836 	p2pielen += 2;
4837 
4838 	/*	Value: */
4839 	/*	P2P Device Address */
4840 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4841 	p2pielen += ETH_ALEN;
4842 
4843 	/*	Config Method */
4844 	/*	This field should be big endian. Noted by P2P specification. */
4845 
4846 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
4847 
4848 	p2pielen += 2;
4849 
4850 	/*	Primary Device Type */
4851 	/*	Category ID */
4852 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4853 	p2pielen += 2;
4854 
4855 	/*	OUI */
4856 	*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
4857 	p2pielen += 4;
4858 
4859 	/*	Sub Category ID */
4860 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4861 	p2pielen += 2;
4862 
4863 	/*	Number of Secondary Device Types */
4864 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
4865 
4866 	/*	Device Name */
4867 	/*	Type: */
4868 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4869 	p2pielen += 2;
4870 
4871 	/*	Length: */
4872 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
4873 	p2pielen += 2;
4874 
4875 	/*	Value: */
4876 	_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
4877 	p2pielen += pwdinfo->device_name_len;
4878 
4879 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
4880 		/*	Group ID Attribute */
4881 		/*	Type: */
4882 		p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
4883 
4884 		/*	Length: */
4885 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
4886 		p2pielen += 2;
4887 
4888 		/*	Value: */
4889 		/*	p2P Device Address */
4890 		_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
4891 		p2pielen += ETH_ALEN;
4892 
4893 		/*	SSID */
4894 		_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
4895 		p2pielen += pwdinfo->nego_ssidlen;
4896 
4897 	}
4898 
4899 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
4900 
4901 #ifdef CONFIG_WFD
4902 	wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
4903 	pframe += wfdielen;
4904 	pktlen += wfdielen;
4905 #endif
4906 
4907 	*pLength = pktlen;
4908 #if 0
4909 	/* printf dbg msg */
4910 	dbgbufLen = pktlen;
4911 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
4912 
4913 	for (index = 0; index < dbgbufLen; index++)
4914 		printk("%x ", *(dbgbuf + index));
4915 
4916 	printk("\n");
4917 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
4918 #endif
4919 }
4920 
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)4921 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
4922 {
4923 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4924 	u8			action = P2P_PUB_ACTION_ACTION;
4925 	u32			p2poui = cpu_to_be32(P2POUI);
4926 	u8			oui_subtype = P2P_INVIT_RESP;
4927 	u8			p2pie[255] = { 0x00 };
4928 	u8			p2pielen = 0, i;
4929 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
4930 	u16			len_channellist_attr = 0;
4931 	u32			pktlen;
4932 	u8			dialogToken = 0;
4933 #ifdef CONFIG_WFD
4934 	u32					wfdielen = 0;
4935 #endif
4936 
4937 	/* struct xmit_frame			*pmgntframe; */
4938 	/* struct pkt_attrib			*pattrib; */
4939 	/* unsigned char					*pframe; */
4940 	struct rtw_ieee80211_hdr	*pwlanhdr;
4941 	unsigned short				*fctrl;
4942 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
4943 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
4944 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4945 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4946 
4947 	/* for debug */
4948 	u8 *dbgbuf = pframe;
4949 	u8 dbgbufLen = 0, index = 0;
4950 
4951 
4952 	RTW_INFO("%s\n", __FUNCTION__);
4953 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4954 
4955 	fctrl = &(pwlanhdr->frame_ctl);
4956 	*(fctrl) = 0;
4957 
4958 	/* RA fill by FW */
4959 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
4960 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4961 
4962 	/* BSSID fill by FW */
4963 	_rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
4964 
4965 	SetSeqNum(pwlanhdr, 0);
4966 	SetFrameSubType(pframe, WIFI_ACTION);
4967 
4968 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4969 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4970 
4971 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
4972 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
4973 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
4974 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
4975 
4976 	/* dialog token, filled by FW */
4977 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
4978 
4979 	/*	P2P IE Section. */
4980 
4981 	/*	P2P OUI */
4982 	p2pielen = 0;
4983 	p2pie[p2pielen++] = 0x50;
4984 	p2pie[p2pielen++] = 0x6F;
4985 	p2pie[p2pielen++] = 0x9A;
4986 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
4987 
4988 	/*	Commented by Albert 20101005 */
4989 	/*	According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
4990 	/*	1. Status */
4991 	/*	2. Configuration Timeout */
4992 	/*	3. Operating Channel	( Only GO ) */
4993 	/*	4. P2P Group BSSID	( Only GO ) */
4994 	/*	5. Channel List */
4995 
4996 	/*	P2P Status */
4997 	/*	Type: */
4998 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
4999 
5000 	/*	Length: */
5001 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5002 	p2pielen += 2;
5003 
5004 	/*	Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
5005 	p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5006 
5007 	/*	Configuration Timeout */
5008 	/*	Type: */
5009 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5010 
5011 	/*	Length: */
5012 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5013 	p2pielen += 2;
5014 
5015 	/*	Value: */
5016 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
5017 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
5018 
5019 	/* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
5020 #if 0
5021 	if (status_code == P2P_STATUS_SUCCESS) {
5022 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5023 			/*	The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
5024 			/*	In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
5025 			/*	First one is operating channel attribute. */
5026 			/*	Second one is P2P Group BSSID attribute. */
5027 
5028 			/*	Operating Channel */
5029 			/*	Type: */
5030 			p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5031 
5032 			/*	Length: */
5033 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5034 			p2pielen += 2;
5035 
5036 			/*	Value: */
5037 			/*	Country String */
5038 			p2pie[p2pielen++] = 'X';
5039 			p2pie[p2pielen++] = 'X';
5040 
5041 			/*	The third byte should be set to 0x04. */
5042 			/*	Described in the "Operating Channel Attribute" section. */
5043 			p2pie[p2pielen++] = 0x04;
5044 
5045 			/*	Operating Class */
5046 			p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
5047 
5048 			/*	Channel Number */
5049 			p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
5050 
5051 
5052 			/*	P2P Group BSSID */
5053 			/*	Type: */
5054 			p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
5055 
5056 			/*	Length: */
5057 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5058 			p2pielen += 2;
5059 
5060 			/*	Value: */
5061 			/*	P2P Device Address for GO */
5062 			_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5063 			p2pielen += ETH_ALEN;
5064 
5065 		}
5066 
5067 		/*	Channel List */
5068 		/*	Type: */
5069 		p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5070 
5071 		/*	Length: */
5072 		/* Country String(3) */
5073 		/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5074 		/* + number of channels in all classes */
5075 		len_channellist_attr = 3
5076 			+ (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5077 			+ get_reg_classes_full_count(pmlmeext->channel_list);
5078 
5079 #ifdef CONFIG_CONCURRENT_MODE
5080 		if (rtw_mi_check_status(padapter, MI_LINKED))
5081 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5082 		else
5083 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5084 
5085 #else
5086 
5087 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5088 
5089 #endif
5090 		p2pielen += 2;
5091 
5092 		/*	Value: */
5093 		/*	Country String */
5094 		p2pie[p2pielen++] = 'X';
5095 		p2pie[p2pielen++] = 'X';
5096 
5097 		/*	The third byte should be set to 0x04. */
5098 		/*	Described in the "Operating Channel Attribute" section. */
5099 		p2pie[p2pielen++] = 0x04;
5100 
5101 		/*	Channel Entry List */
5102 #ifdef CONFIG_CONCURRENT_MODE
5103 		if (rtw_mi_check_status(padapter, MI_LINKED)) {
5104 			u8 union_ch = rtw_mi_get_union_chan(padapter);
5105 
5106 			/*	Operating Class */
5107 			if (union_ch > 14) {
5108 				if (union_ch >= 149)
5109 					p2pie[p2pielen++] = 0x7c;
5110 				else
5111 					p2pie[p2pielen++] = 0x73;
5112 
5113 			} else
5114 				p2pie[p2pielen++] = 0x51;
5115 
5116 
5117 			/*	Number of Channels */
5118 			/*	Just support 1 channel and this channel is AP's channel */
5119 			p2pie[p2pielen++] = 1;
5120 
5121 			/*	Channel List */
5122 			p2pie[p2pielen++] = union_ch;
5123 		} else {
5124 			int i, j;
5125 			for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5126 				/*	Operating Class */
5127 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5128 
5129 				/*	Number of Channels */
5130 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5131 
5132 				/*	Channel List */
5133 				for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
5134 					p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5135 			}
5136 		}
5137 #else /* CONFIG_CONCURRENT_MODE */
5138 		{
5139 			int i, j;
5140 			for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5141 				/*	Operating Class */
5142 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5143 
5144 				/*	Number of Channels */
5145 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5146 
5147 				/*	Channel List */
5148 				for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
5149 					p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5150 			}
5151 		}
5152 #endif /* CONFIG_CONCURRENT_MODE */
5153 	}
5154 #endif
5155 
5156 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
5157 
5158 #ifdef CONFIG_WFD
5159 	wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
5160 	pframe += wfdielen;
5161 	pktlen += wfdielen;
5162 #endif
5163 
5164 	*pLength = pktlen;
5165 
5166 #if 0
5167 	/* printf dbg msg */
5168 	dbgbufLen = pktlen;
5169 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
5170 
5171 	for (index = 0; index < dbgbufLen; index++)
5172 		printk("%x ", *(dbgbuf + index));
5173 
5174 	printk("\n");
5175 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
5176 #endif
5177 }
5178 
5179 
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)5180 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
5181 {
5182 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5183 	u8			action = P2P_PUB_ACTION_ACTION;
5184 	u8			dialogToken = 0;
5185 	u32			p2poui = cpu_to_be32(P2POUI);
5186 	u8			oui_subtype = P2P_PROVISION_DISC_RESP;
5187 	u8			wpsie[100] = { 0x00 };
5188 	u8			wpsielen = 0;
5189 	u32			pktlen;
5190 #ifdef CONFIG_WFD
5191 	u32					wfdielen = 0;
5192 #endif
5193 
5194 	/* struct xmit_frame			*pmgntframe; */
5195 	/* struct pkt_attrib			*pattrib; */
5196 	/* unsigned char					*pframe; */
5197 	struct rtw_ieee80211_hdr	*pwlanhdr;
5198 	unsigned short				*fctrl;
5199 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
5200 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5201 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5202 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5203 
5204 	/* for debug */
5205 	u8 *dbgbuf = pframe;
5206 	u8 dbgbufLen = 0, index = 0;
5207 
5208 	RTW_INFO("%s\n", __FUNCTION__);
5209 
5210 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5211 
5212 	fctrl = &(pwlanhdr->frame_ctl);
5213 	*(fctrl) = 0;
5214 
5215 	/* RA filled by FW */
5216 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
5217 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5218 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
5219 
5220 	SetSeqNum(pwlanhdr, 0);
5221 	SetFrameSubType(pframe, WIFI_ACTION);
5222 
5223 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5224 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5225 
5226 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
5227 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
5228 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
5229 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
5230 	/* dialog token, filled by FW */
5231 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
5232 
5233 	wpsielen = 0;
5234 	/*	WPS OUI */
5235 	/* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
5236 	RTW_PUT_BE32(wpsie, WPSOUI);
5237 	wpsielen += 4;
5238 
5239 #if 0
5240 	/*	WPS version */
5241 	/*	Type: */
5242 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5243 	wpsielen += 2;
5244 
5245 	/*	Length: */
5246 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5247 	wpsielen += 2;
5248 
5249 	/*	Value: */
5250 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
5251 #endif
5252 
5253 	/*	Config Method */
5254 	/*	Type: */
5255 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
5256 	RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
5257 	wpsielen += 2;
5258 
5259 	/*	Length: */
5260 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
5261 	RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
5262 	wpsielen += 2;
5263 
5264 	/*	Value: filled by FW, default value is PBC */
5265 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
5266 	RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
5267 	wpsielen += 2;
5268 
5269 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
5270 
5271 #ifdef CONFIG_WFD
5272 	wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
5273 	pframe += wfdielen;
5274 	pktlen += wfdielen;
5275 #endif
5276 
5277 	*pLength = pktlen;
5278 
5279 	/* printf dbg msg */
5280 #if 0
5281 	dbgbufLen = pktlen;
5282 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT  ProvisionDis Rsp\n");
5283 
5284 	for (index = 0; index < dbgbufLen; index++)
5285 		printk("%x ", *(dbgbuf + index));
5286 
5287 	printk("\n");
5288 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
5289 #endif
5290 }
5291 
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)5292 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
5293 {
5294 	u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
5295 	struct hal_ops *pHalFunc = &adapter->HalFunc;
5296 	u8 ret = _FAIL;
5297 
5298 	RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
5299 		 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
5300 		 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
5301 		 rsvdpageloc->LocPDRsp);
5302 
5303 	SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
5304 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
5305 	SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
5306 	SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
5307 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
5308 
5309 	/* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
5310 	ret = rtw_hal_fill_h2c_cmd(adapter,
5311 				   H2C_P2P_OFFLOAD_RSVD_PAGE,
5312 				   H2C_P2PRSVDPAGE_LOC_LEN,
5313 				   u1H2CP2PRsvdPageParm);
5314 
5315 	return ret;
5316 }
5317 
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)5318 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
5319 {
5320 
5321 	u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
5322 	struct wifidirect_info	*pwdinfo = &(adapter->wdinfo);
5323 	struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
5324 	struct hal_ops *pHalFunc = &adapter->HalFunc;
5325 	u8 ret = _FAIL;
5326 
5327 	_rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
5328 	RTW_INFO("%s\n", __func__);
5329 	switch (pwdinfo->role) {
5330 	case P2P_ROLE_DEVICE:
5331 		RTW_INFO("P2P_ROLE_DEVICE\n");
5332 		p2p_wowlan_offload->role = 0;
5333 		break;
5334 	case P2P_ROLE_CLIENT:
5335 		RTW_INFO("P2P_ROLE_CLIENT\n");
5336 		p2p_wowlan_offload->role = 1;
5337 		break;
5338 	case P2P_ROLE_GO:
5339 		RTW_INFO("P2P_ROLE_GO\n");
5340 		p2p_wowlan_offload->role = 2;
5341 		break;
5342 	default:
5343 		RTW_INFO("P2P_ROLE_DISABLE\n");
5344 		break;
5345 	}
5346 	p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
5347 	p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
5348 	offload_cmd = (u8 *)p2p_wowlan_offload;
5349 	RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
5350 
5351 	ret = rtw_hal_fill_h2c_cmd(adapter,
5352 				   H2C_P2P_OFFLOAD,
5353 				   H2C_P2P_OFFLOAD_LEN,
5354 				   offload_cmd);
5355 	return ret;
5356 
5357 	/* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
5358 }
5359 #endif /* CONFIG_P2P_WOWLAN */
5360 
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)5361 static void rtw_hal_construct_beacon(_adapter *padapter,
5362 				     u8 *pframe, u32 *pLength)
5363 {
5364 	struct rtw_ieee80211_hdr	*pwlanhdr;
5365 	u16					*fctrl;
5366 	u32					rate_len, pktlen;
5367 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5368 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5369 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
5370 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5371 
5372 
5373 	/* RTW_INFO("%s\n", __FUNCTION__); */
5374 
5375 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5376 
5377 	fctrl = &(pwlanhdr->frame_ctl);
5378 	*(fctrl) = 0;
5379 
5380 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
5381 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5382 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
5383 
5384 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
5385 	/* pmlmeext->mgnt_seq++; */
5386 	SetFrameSubType(pframe, WIFI_BEACON);
5387 
5388 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5389 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5390 
5391 	/* timestamp will be inserted by hardware */
5392 	pframe += 8;
5393 	pktlen += 8;
5394 
5395 	/* beacon interval: 2 bytes */
5396 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
5397 
5398 	pframe += 2;
5399 	pktlen += 2;
5400 
5401 	/* capability info: 2 bytes */
5402 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
5403 
5404 	pframe += 2;
5405 	pktlen += 2;
5406 
5407 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
5408 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
5409 		pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
5410 		_rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
5411 
5412 		goto _ConstructBeacon;
5413 	}
5414 
5415 	/* below for ad-hoc mode */
5416 
5417 	/* SSID */
5418 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
5419 
5420 	/* supported rates... */
5421 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
5422 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
5423 
5424 	/* DS parameter set */
5425 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
5426 
5427 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
5428 		u32 ATIMWindow;
5429 		/* IBSS Parameter Set... */
5430 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
5431 		ATIMWindow = 0;
5432 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
5433 	}
5434 
5435 
5436 	/* todo: ERP IE */
5437 
5438 
5439 	/* EXTERNDED SUPPORTED RATE */
5440 	if (rate_len > 8)
5441 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
5442 
5443 
5444 	/* todo:HT for adhoc */
5445 
5446 _ConstructBeacon:
5447 
5448 	if ((pktlen + TXDESC_SIZE) > 512) {
5449 		RTW_INFO("beacon frame too large\n");
5450 		return;
5451 	}
5452 
5453 	*pLength = pktlen;
5454 
5455 	/* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
5456 
5457 }
5458 
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)5459 static void rtw_hal_construct_PSPoll(_adapter *padapter,
5460 				     u8 *pframe, u32 *pLength)
5461 {
5462 	struct rtw_ieee80211_hdr	*pwlanhdr;
5463 	u16					*fctrl;
5464 	u32					pktlen;
5465 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5466 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5467 
5468 	/* RTW_INFO("%s\n", __FUNCTION__); */
5469 
5470 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5471 
5472 	/* Frame control. */
5473 	fctrl = &(pwlanhdr->frame_ctl);
5474 	*(fctrl) = 0;
5475 	SetPwrMgt(fctrl);
5476 	SetFrameSubType(pframe, WIFI_PSPOLL);
5477 
5478 	/* AID. */
5479 	SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
5480 
5481 	/* BSSID. */
5482 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5483 
5484 	/* TA. */
5485 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5486 
5487 	*pLength = 16;
5488 }
5489 
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * StaAddr,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)5490 void rtw_hal_construct_NullFunctionData(
5491 	PADAPTER padapter,
5492 	u8		*pframe,
5493 	u32		*pLength,
5494 	u8		*StaAddr,
5495 	u8		bQoS,
5496 	u8		AC,
5497 	u8		bEosp,
5498 	u8		bForcePowerSave)
5499 {
5500 	struct rtw_ieee80211_hdr	*pwlanhdr;
5501 	u16						*fctrl;
5502 	u32						pktlen;
5503 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
5504 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
5505 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5506 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5507 
5508 
5509 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
5510 
5511 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5512 
5513 	fctrl = &pwlanhdr->frame_ctl;
5514 	*(fctrl) = 0;
5515 	if (bForcePowerSave)
5516 		SetPwrMgt(fctrl);
5517 
5518 	switch (cur_network->network.InfrastructureMode) {
5519 	case Ndis802_11Infrastructure:
5520 		SetToDs(fctrl);
5521 		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5522 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5523 		_rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
5524 		break;
5525 	case Ndis802_11APMode:
5526 		SetFrDs(fctrl);
5527 		_rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
5528 		_rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5529 		_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
5530 		break;
5531 	case Ndis802_11IBSS:
5532 	default:
5533 		_rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
5534 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5535 		_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5536 		break;
5537 	}
5538 
5539 	SetSeqNum(pwlanhdr, 0);
5540 
5541 	if (bQoS == _TRUE) {
5542 		struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
5543 
5544 		SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
5545 
5546 		pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
5547 		SetPriority(&pwlanqoshdr->qc, AC);
5548 		SetEOSP(&pwlanqoshdr->qc, bEosp);
5549 
5550 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
5551 	} else {
5552 		SetFrameSubType(pframe, WIFI_DATA_NULL);
5553 
5554 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5555 	}
5556 
5557 	*pLength = pktlen;
5558 }
5559 
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,u8 * StaAddr,BOOLEAN bHideSSID)5560 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
5561 				u8 *StaAddr, BOOLEAN bHideSSID)
5562 {
5563 	struct rtw_ieee80211_hdr	*pwlanhdr;
5564 	u16					*fctrl;
5565 	u8					*mac, *bssid;
5566 	u32					pktlen;
5567 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5568 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5569 	WLAN_BSSID_EX  *cur_network = &(pmlmeinfo->network);
5570 
5571 	/*RTW_INFO("%s\n", __FUNCTION__);*/
5572 
5573 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5574 
5575 	mac = adapter_mac_addr(padapter);
5576 	bssid = cur_network->MacAddress;
5577 
5578 	fctrl = &(pwlanhdr->frame_ctl);
5579 	*(fctrl) = 0;
5580 	_rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
5581 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5582 	_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
5583 
5584 	SetSeqNum(pwlanhdr, 0);
5585 	SetFrameSubType(fctrl, WIFI_PROBERSP);
5586 
5587 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5588 	pframe += pktlen;
5589 
5590 	if (cur_network->IELength > MAX_IE_SZ)
5591 		return;
5592 
5593 	_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
5594 	pframe += cur_network->IELength;
5595 	pktlen += cur_network->IELength;
5596 
5597 	*pLength = pktlen;
5598 }
5599 
5600 #ifdef CONFIG_WOWLAN
5601 /*
5602  * Description:
5603  *	Construct the ARP response packet to support ARP offload.
5604  *   */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)5605 static void rtw_hal_construct_ARPRsp(
5606 	PADAPTER padapter,
5607 	u8			*pframe,
5608 	u32			*pLength,
5609 	u8			*pIPAddress
5610 )
5611 {
5612 	struct rtw_ieee80211_hdr	*pwlanhdr;
5613 	u16	*fctrl;
5614 	u32	pktlen;
5615 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
5616 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
5617 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5618 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5619 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
5620 	static u8	ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
5621 	u8	*pARPRspPkt = pframe;
5622 	/* for TKIP Cal MIC */
5623 	u8	*payload = pframe;
5624 	u8	EncryptionHeadOverhead = 0;
5625 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
5626 
5627 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5628 
5629 	fctrl = &pwlanhdr->frame_ctl;
5630 	*(fctrl) = 0;
5631 
5632 	/* ------------------------------------------------------------------------- */
5633 	/* MAC Header. */
5634 	/* ------------------------------------------------------------------------- */
5635 	SetFrameType(fctrl, WIFI_DATA);
5636 	/* SetFrameSubType(fctrl, 0); */
5637 	SetToDs(fctrl);
5638 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5639 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5640 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5641 
5642 	SetSeqNum(pwlanhdr, 0);
5643 	SetDuration(pwlanhdr, 0);
5644 	/* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
5645 	/* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
5646 	/* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
5647 	/* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
5648 	/* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
5649 	/* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
5650 
5651 	/* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
5652 	/* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
5653 #ifdef CONFIG_WAPI_SUPPORT
5654 	*pLength = sMacHdrLng;
5655 #else
5656 	*pLength = 24;
5657 #endif
5658 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
5659 	case _WEP40_:
5660 	case _WEP104_:
5661 		EncryptionHeadOverhead = 4;
5662 		break;
5663 	case _TKIP_:
5664 		EncryptionHeadOverhead = 8;
5665 		break;
5666 	case _AES_:
5667 		EncryptionHeadOverhead = 8;
5668 		break;
5669 #ifdef CONFIG_WAPI_SUPPORT
5670 	case _SMS4_:
5671 		EncryptionHeadOverhead = 18;
5672 		break;
5673 #endif
5674 	default:
5675 		EncryptionHeadOverhead = 0;
5676 	}
5677 
5678 	if (EncryptionHeadOverhead > 0) {
5679 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
5680 		*pLength += EncryptionHeadOverhead;
5681 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
5682 		SetPrivacy(fctrl);
5683 	}
5684 
5685 	/* ------------------------------------------------------------------------- */
5686 	/* Frame Body. */
5687 	/* ------------------------------------------------------------------------- */
5688 	pARPRspPkt = (u8 *)(pframe + *pLength);
5689 	payload = pARPRspPkt; /* Get Payload pointer */
5690 	/* LLC header */
5691 	_rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
5692 	*pLength += 8;
5693 
5694 	/* ARP element */
5695 	pARPRspPkt += 8;
5696 	SET_ARP_PKT_HW(pARPRspPkt, 0x0100);
5697 	SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008);	/* IP protocol */
5698 	SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);
5699 	SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);
5700 	SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200);	/* ARP response */
5701 	SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
5702 	SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
5703 #ifdef CONFIG_ARP_KEEP_ALIVE
5704 	if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
5705 		SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
5706 		SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
5707 	} else
5708 #endif
5709 	{
5710 		SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt,
5711 				    get_my_bssid(&(pmlmeinfo->network)));
5712 		SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt,
5713 					   pIPAddress);
5714 		RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
5715 			 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
5716 		RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
5717 			 IP_ARG(pIPAddress));
5718 	}
5719 
5720 	*pLength += 28;
5721 
5722 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
5723 		u8	mic[8];
5724 		struct mic_data	micdata;
5725 		struct sta_info	*psta = NULL;
5726 		u8	priority[4] = {0x0, 0x0, 0x0, 0x0};
5727 		u8	null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
5728 
5729 		RTW_INFO("%s(): Add MIC\n", __FUNCTION__);
5730 
5731 		psta = rtw_get_stainfo(&padapter->stapriv,
5732 				       get_my_bssid(&(pmlmeinfo->network)));
5733 		if (psta != NULL) {
5734 			if (_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
5735 					null_key, 16) == _TRUE) {
5736 				RTW_INFO("%s(): STA dot11tkiptxmickey==0\n",
5737 					 __func__);
5738 			}
5739 			/* start to calculate the mic code */
5740 			rtw_secmicsetkey(&micdata,
5741 					 &psta->dot11tkiptxmickey.skey[0]);
5742 		}
5743 
5744 		rtw_secmicappend(&micdata, pwlanhdr->addr3, 6);  /* DA */
5745 
5746 		rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
5747 
5748 		priority[0] = 0;
5749 
5750 		rtw_secmicappend(&micdata, &priority[0], 4);
5751 
5752 		rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
5753 
5754 		rtw_secgetmic(&micdata, &(mic[0]));
5755 
5756 		pARPRspPkt += 28;
5757 		_rtw_memcpy(pARPRspPkt, &(mic[0]), 8);
5758 
5759 		*pLength += 8;
5760 	}
5761 }
5762 
5763 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)5764 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
5765 				       u32 *pLength, pno_ssid_t *ssid)
5766 {
5767 	struct rtw_ieee80211_hdr	*pwlanhdr;
5768 	u16				*fctrl;
5769 	u32				pktlen;
5770 	unsigned char			*mac;
5771 	unsigned char			bssrate[NumRates];
5772 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
5773 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5774 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5775 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5776 	int	bssrate_len = 0;
5777 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5778 
5779 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5780 	mac = adapter_mac_addr(padapter);
5781 
5782 	fctrl = &(pwlanhdr->frame_ctl);
5783 	*(fctrl) = 0;
5784 
5785 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
5786 	_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
5787 
5788 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5789 
5790 	SetSeqNum(pwlanhdr, 0);
5791 	SetFrameSubType(pframe, WIFI_PROBEREQ);
5792 
5793 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5794 	pframe += pktlen;
5795 
5796 	if (ssid == NULL)
5797 		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
5798 	else {
5799 		/* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
5800 		pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
5801 	}
5802 
5803 	get_rate_set(padapter, bssrate, &bssrate_len);
5804 
5805 	if (bssrate_len > 8) {
5806 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
5807 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
5808 	} else
5809 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
5810 
5811 	*pLength = pktlen;
5812 }
5813 
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)5814 static void rtw_hal_construct_PNO_info(_adapter *padapter,
5815 				       u8 *pframe, u32 *pLength)
5816 {
5817 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
5818 	int i;
5819 
5820 	u8	*pPnoInfoPkt = pframe;
5821 	pPnoInfoPkt = (u8 *)(pframe + *pLength);
5822 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
5823 
5824 	pPnoInfoPkt += 1;
5825 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
5826 
5827 	pPnoInfoPkt += 3;
5828 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
5829 
5830 	pPnoInfoPkt += 4;
5831 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
5832 
5833 	pPnoInfoPkt += 4;
5834 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
5835 
5836 	pPnoInfoPkt += 4;
5837 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
5838 
5839 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
5840 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
5841 
5842 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
5843 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
5844 
5845 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
5846 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
5847 
5848 	pPnoInfoPkt += MAX_HIDDEN_AP;
5849 
5850 	/*
5851 	SSID is located at 128th Byte in NLO info Page
5852 	*/
5853 
5854 	*pLength += 128;
5855 	pPnoInfoPkt = pframe + 128;
5856 
5857 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
5858 		_rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
5859 			    pwrctl->pnlo_info->ssid_length[i]);
5860 		*pLength += WLAN_SSID_MAXLEN;
5861 		pPnoInfoPkt += WLAN_SSID_MAXLEN;
5862 	}
5863 }
5864 
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)5865 static void rtw_hal_construct_ssid_list(_adapter *padapter,
5866 					u8 *pframe, u32 *pLength)
5867 {
5868 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
5869 	u8 *pSSIDListPkt = pframe;
5870 	int i;
5871 
5872 	pSSIDListPkt = (u8 *)(pframe + *pLength);
5873 
5874 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
5875 		_rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
5876 			    pwrctl->pnlo_info->ssid_length[i]);
5877 
5878 		*pLength += WLAN_SSID_MAXLEN;
5879 		pSSIDListPkt += WLAN_SSID_MAXLEN;
5880 	}
5881 }
5882 
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)5883 static void rtw_hal_construct_scan_info(_adapter *padapter,
5884 					u8 *pframe, u32 *pLength)
5885 {
5886 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
5887 	u8 *pScanInfoPkt = pframe;
5888 	int i;
5889 
5890 	pScanInfoPkt = (u8 *)(pframe + *pLength);
5891 
5892 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
5893 
5894 	*pLength += 1;
5895 	pScanInfoPkt += 1;
5896 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
5897 
5898 
5899 	*pLength += 1;
5900 	pScanInfoPkt += 1;
5901 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
5902 
5903 
5904 	*pLength += 1;
5905 	pScanInfoPkt += 1;
5906 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
5907 
5908 	*pLength += 1;
5909 	pScanInfoPkt += 1;
5910 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
5911 
5912 	*pLength += 1;
5913 	pScanInfoPkt += 1;
5914 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
5915 
5916 	*pLength += 1;
5917 	pScanInfoPkt += 1;
5918 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
5919 
5920 	*pLength += 1;
5921 	pScanInfoPkt += 1;
5922 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
5923 
5924 	*pLength += 1;
5925 	pScanInfoPkt += 1;
5926 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
5927 
5928 	*pLength += 8;
5929 	pScanInfoPkt += 8;
5930 
5931 	for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
5932 		_rtw_memcpy(pScanInfoPkt,
5933 			    &pwrctl->pscan_info->ssid_channel_info[i], 4);
5934 		*pLength += 4;
5935 		pScanInfoPkt += 4;
5936 	}
5937 }
5938 #endif /* CONFIG_PNO_SUPPORT */
5939 
5940 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)5941 static void rtw_hal_construct_GTKRsp(
5942 	PADAPTER	padapter,
5943 	u8		*pframe,
5944 	u32		*pLength
5945 )
5946 {
5947 	struct rtw_ieee80211_hdr	*pwlanhdr;
5948 	u16	*fctrl;
5949 	u32	pktlen;
5950 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
5951 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
5952 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5953 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5954 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
5955 	static u8	LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
5956 	static u8	GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
5957 	u8	*pGTKRspPkt = pframe;
5958 	u8	EncryptionHeadOverhead = 0;
5959 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
5960 
5961 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5962 
5963 	fctrl = &pwlanhdr->frame_ctl;
5964 	*(fctrl) = 0;
5965 
5966 	/* ------------------------------------------------------------------------- */
5967 	/* MAC Header. */
5968 	/* ------------------------------------------------------------------------- */
5969 	SetFrameType(fctrl, WIFI_DATA);
5970 	/* SetFrameSubType(fctrl, 0); */
5971 	SetToDs(fctrl);
5972 
5973 	_rtw_memcpy(pwlanhdr->addr1,
5974 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5975 
5976 	_rtw_memcpy(pwlanhdr->addr2,
5977 		    adapter_mac_addr(padapter), ETH_ALEN);
5978 
5979 	_rtw_memcpy(pwlanhdr->addr3,
5980 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5981 
5982 	SetSeqNum(pwlanhdr, 0);
5983 	SetDuration(pwlanhdr, 0);
5984 
5985 #ifdef CONFIG_WAPI_SUPPORT
5986 	*pLength = sMacHdrLng;
5987 #else
5988 	*pLength = 24;
5989 #endif /* CONFIG_WAPI_SUPPORT */
5990 
5991 	/* ------------------------------------------------------------------------- */
5992 	/* Security Header: leave space for it if necessary. */
5993 	/* ------------------------------------------------------------------------- */
5994 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
5995 	case _WEP40_:
5996 	case _WEP104_:
5997 		EncryptionHeadOverhead = 4;
5998 		break;
5999 	case _TKIP_:
6000 		EncryptionHeadOverhead = 8;
6001 		break;
6002 	case _AES_:
6003 		EncryptionHeadOverhead = 8;
6004 		break;
6005 #ifdef CONFIG_WAPI_SUPPORT
6006 	case _SMS4_:
6007 		EncryptionHeadOverhead = 18;
6008 		break;
6009 #endif /* CONFIG_WAPI_SUPPORT */
6010 	default:
6011 		EncryptionHeadOverhead = 0;
6012 	}
6013 
6014 	if (EncryptionHeadOverhead > 0) {
6015 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
6016 		*pLength += EncryptionHeadOverhead;
6017 		/* SET_80211_HDR_WEP(pGTKRspPkt, 1);  */ /* Suggested by CCW. */
6018 		/* GTK's privacy bit is done by FW */
6019 		/* SetPrivacy(fctrl); */
6020 	}
6021 	/* ------------------------------------------------------------------------- */
6022 	/* Frame Body. */
6023 	/* ------------------------------------------------------------------------- */
6024 	pGTKRspPkt = (u8 *)(pframe + *pLength);
6025 	/* LLC header */
6026 	_rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
6027 	*pLength += 8;
6028 
6029 	/* GTK element */
6030 	pGTKRspPkt += 8;
6031 
6032 	/* GTK frame body after LLC, part 1 */
6033 	_rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
6034 	*pLength += 11;
6035 	pGTKRspPkt += 11;
6036 	/* GTK frame body after LLC, part 2 */
6037 	_rtw_memset(&(pframe[*pLength]), 0, 88);
6038 	*pLength += 88;
6039 	pGTKRspPkt += 88;
6040 
6041 }
6042 #endif /* CONFIG_GTK_OL */
6043 
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)6044 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
6045 		  u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
6046 				  RSVDPAGE_LOC *rsvd_page_loc)
6047 {
6048 	struct security_priv *psecuritypriv = &adapter->securitypriv;
6049 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
6050 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
6051 	struct mlme_ext_priv	*pmlmeext;
6052 	struct mlme_ext_info	*pmlmeinfo;
6053 	u32	ARPLegnth = 0, GTKLegnth = 0, PNOLength = 0, ScanInfoLength = 0;
6054 	u32	SSIDLegnth = 0, ProbeReqLength = 0;
6055 	u8 CurtPktPageNum = 0;
6056 	u8 currentip[4];
6057 	u8 cur_dot11txpn[8];
6058 
6059 #ifdef CONFIG_GTK_OL
6060 	struct sta_priv *pstapriv = &adapter->stapriv;
6061 	struct sta_info *psta;
6062 	u8 kek[RTW_KEK_LEN];
6063 	u8 kck[RTW_KCK_LEN];
6064 #endif /* CONFIG_GTK_OL */
6065 #ifdef CONFIG_PNO_SUPPORT
6066 	int pno_index;
6067 	u8 ssid_num;
6068 #endif /* CONFIG_PNO_SUPPORT */
6069 
6070 	pmlmeext = &adapter->mlmeextpriv;
6071 	pmlmeinfo = &pmlmeext->mlmext_info;
6072 
6073 	if (pwrctl->wowlan_pno_enable == _FALSE) {
6074 		/* ARP RSP * 1 page */
6075 		rtw_get_current_ip_address(adapter, currentip);
6076 
6077 		rsvd_page_loc->LocArpRsp = *page_num;
6078 
6079 		RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
6080 
6081 		rtw_hal_construct_ARPRsp(adapter, &pframe[index],
6082 					 &ARPLegnth, currentip);
6083 
6084 		rtw_hal_fill_fake_txdesc(adapter,
6085 					 &pframe[index - tx_desc],
6086 					 ARPLegnth, _FALSE, _FALSE, _TRUE);
6087 
6088 		CurtPktPageNum = (u8)PageNum(tx_desc + ARPLegnth, page_size);
6089 
6090 		*page_num += CurtPktPageNum;
6091 
6092 		index += (CurtPktPageNum * page_size);
6093 
6094 		/* 3 SEC IV * 1 page */
6095 		rtw_get_sec_iv(adapter, cur_dot11txpn,
6096 			       get_my_bssid(&pmlmeinfo->network));
6097 
6098 		rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
6099 
6100 		RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
6101 
6102 		_rtw_memcpy(pframe + index - tx_desc, cur_dot11txpn, _AES_IV_LEN_);
6103 
6104 		CurtPktPageNum = (u8)PageNum(_AES_IV_LEN_, page_size);
6105 
6106 		*page_num += CurtPktPageNum;
6107 
6108 		*total_pkt_len = index + _AES_IV_LEN_;
6109 #ifdef CONFIG_GTK_OL
6110 		index += (CurtPktPageNum * page_size);
6111 
6112 		/* if the ap staion info. exists, get the kek, kck from staion info. */
6113 		psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
6114 		if (psta == NULL) {
6115 			_rtw_memset(kek, 0, RTW_KEK_LEN);
6116 			_rtw_memset(kck, 0, RTW_KCK_LEN);
6117 			RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
6118 				 __func__);
6119 		} else {
6120 			_rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
6121 			_rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
6122 		}
6123 
6124 		/* 3 KEK, KCK */
6125 		rsvd_page_loc->LocGTKInfo = *page_num;
6126 		RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
6127 
6128 		if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
6129 			struct security_priv *psecpriv = NULL;
6130 
6131 			psecpriv = &adapter->securitypriv;
6132 			_rtw_memcpy(pframe + index - tx_desc,
6133 				    &psecpriv->dot11PrivacyAlgrthm, 1);
6134 			_rtw_memcpy(pframe + index - tx_desc + 1,
6135 				    &psecpriv->dot118021XGrpPrivacy, 1);
6136 			_rtw_memcpy(pframe + index - tx_desc + 2,
6137 				    kck, RTW_KCK_LEN);
6138 			_rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
6139 				    kek, RTW_KEK_LEN);
6140 			CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
6141 		} else {
6142 			_rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
6143 			_rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN, kek, RTW_KEK_LEN);
6144 			CurtPktPageNum = (u8)PageNum(tx_desc + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
6145 		}
6146 
6147 
6148 
6149 #if 0
6150 		{
6151 			int i;
6152 			printk("\ntoFW KCK: ");
6153 			for (i = 0; i < 16; i++)
6154 				printk(" %02x ", kck[i]);
6155 			printk("\ntoFW KEK: ");
6156 			for (i = 0; i < 16; i++)
6157 				printk(" %02x ", kek[i]);
6158 			printk("\n");
6159 		}
6160 
6161 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
6162 			 __FUNCTION__, &pframe[index - tx_desc],
6163 			 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
6164 #endif
6165 
6166 		*page_num += CurtPktPageNum;
6167 
6168 		index += (CurtPktPageNum * page_size);
6169 
6170 		/* 3 GTK Response */
6171 		rsvd_page_loc->LocGTKRsp = *page_num;
6172 		RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
6173 		rtw_hal_construct_GTKRsp(adapter, &pframe[index], &GTKLegnth);
6174 
6175 		rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6176 					 GTKLegnth, _FALSE, _FALSE, _TRUE);
6177 #if 0
6178 		{
6179 			int gj;
6180 			printk("123GTK pkt=>\n");
6181 			for (gj = 0; gj < GTKLegnth + tx_desc; gj++) {
6182 				printk(" %02x ", pframe[index - tx_desc + gj]);
6183 				if ((gj + 1) % 16 == 0)
6184 					printk("\n");
6185 			}
6186 			printk(" <=end\n");
6187 		}
6188 
6189 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
6190 			 __FUNCTION__, &pframe[index - tx_desc],
6191 			 (tx_desc + GTKLegnth));
6192 #endif
6193 
6194 		CurtPktPageNum = (u8)PageNum(tx_desc + GTKLegnth, page_size);
6195 
6196 		*page_num += CurtPktPageNum;
6197 
6198 		index += (CurtPktPageNum * page_size);
6199 
6200 		/* below page is empty for GTK extension memory */
6201 		/* 3(11) GTK EXT MEM */
6202 		rsvd_page_loc->LocGTKEXTMEM = *page_num;
6203 		RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
6204 		CurtPktPageNum = 2;
6205 
6206 		if (page_size >= 256)
6207 			CurtPktPageNum = 1;
6208 
6209 		*page_num += CurtPktPageNum;
6210 		/* extension memory for FW */
6211 		*total_pkt_len = index + (page_size * CurtPktPageNum);
6212 
6213 #endif /* CONFIG_GTK_OL */
6214 	} else {
6215 #ifdef CONFIG_PNO_SUPPORT
6216 		if (pwrctl->pno_in_resume == _FALSE &&
6217 		    pwrctl->pno_inited == _TRUE) {
6218 
6219 			/* Broadcast Probe Request */
6220 			rsvd_page_loc->LocProbePacket = *page_num;
6221 
6222 			RTW_INFO("loc_probe_req: %d\n",
6223 				 rsvd_page_loc->LocProbePacket);
6224 
6225 			rtw_hal_construct_ProbeReq(
6226 				adapter,
6227 				&pframe[index],
6228 				&ProbeReqLength,
6229 				NULL);
6230 
6231 			rtw_hal_fill_fake_txdesc(adapter,
6232 						 &pframe[index - tx_desc],
6233 				 ProbeReqLength, _FALSE, _FALSE, _FALSE);
6234 
6235 			CurtPktPageNum =
6236 				(u8)PageNum(tx_desc + ProbeReqLength, page_size);
6237 
6238 			*page_num += CurtPktPageNum;
6239 
6240 			index += (CurtPktPageNum * page_size);
6241 
6242 			/* Hidden SSID Probe Request */
6243 			ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
6244 
6245 			for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
6246 				pwrctl->pnlo_info->loc_probe_req[pno_index] =
6247 					*page_num;
6248 
6249 				rtw_hal_construct_ProbeReq(
6250 					adapter,
6251 					&pframe[index],
6252 					&ProbeReqLength,
6253 					&pwrctl->pno_ssid_list->node[pno_index]);
6254 
6255 				rtw_hal_fill_fake_txdesc(adapter,
6256 						 &pframe[index - tx_desc],
6257 					ProbeReqLength, _FALSE, _FALSE, _FALSE);
6258 
6259 				CurtPktPageNum =
6260 					(u8)PageNum(tx_desc + ProbeReqLength, page_size);
6261 
6262 				*page_num += CurtPktPageNum;
6263 
6264 				index += (CurtPktPageNum * page_size);
6265 			}
6266 
6267 			/* PNO INFO Page */
6268 			rsvd_page_loc->LocPNOInfo = *page_num;
6269 			RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
6270 			rtw_hal_construct_PNO_info(adapter,
6271 						   &pframe[index - tx_desc],
6272 						   &PNOLength);
6273 
6274 			CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
6275 			*page_num += CurtPktPageNum;
6276 			index += (CurtPktPageNum * page_size);
6277 
6278 			/* Scan Info Page */
6279 			rsvd_page_loc->LocScanInfo = *page_num;
6280 			RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
6281 			rtw_hal_construct_scan_info(adapter,
6282 						    &pframe[index - tx_desc],
6283 						    &ScanInfoLength);
6284 
6285 			CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
6286 			*page_num += CurtPktPageNum;
6287 			*total_pkt_len = index + ScanInfoLength;
6288 			index += (CurtPktPageNum * page_size);
6289 
6290 		}
6291 #endif /* CONFIG_PNO_SUPPORT */
6292 	}
6293 }
6294 
rtw_hal_gate_bb(_adapter * adapter,bool stop)6295 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
6296 {
6297 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6298 	u8 val8 = 0;
6299 	u16 val16 = 0;
6300 
6301 	if (stop) {
6302 		/* Pause TX*/
6303 		pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
6304 		rtw_write8(adapter, REG_TXPAUSE, 0xff);
6305 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
6306 		val8 &= ~BIT(0);
6307 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
6308 		RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
6309 			 __func__,
6310 			 rtw_read8(adapter, REG_SYS_FUNC_EN),
6311 			 pwrpriv->wowlan_txpause_status);
6312 	} else {
6313 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
6314 		val8 |= BIT(0);
6315 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
6316 		RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
6317 			 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
6318 			 pwrpriv->wowlan_txpause_status);
6319 		/* release TX*/
6320 		rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
6321 	}
6322 }
6323 
rtw_hal_reset_mac_rx(_adapter * adapter)6324 static void rtw_hal_reset_mac_rx(_adapter *adapter)
6325 {
6326 	u8 val8 = 0;
6327 	/* Set REG_CR bit1, bit3, bit7 to 0*/
6328 	val8 = rtw_read8(adapter, REG_CR);
6329 	val8 &= 0x75;
6330 	rtw_write8(adapter, REG_CR, val8);
6331 	val8 = rtw_read8(adapter, REG_CR);
6332 	/* Set REG_CR bit1, bit3, bit7 to 1*/
6333 	val8 |= 0x8a;
6334 	rtw_write8(adapter, REG_CR, val8);
6335 	RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
6336 }
6337 
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)6338 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
6339 {
6340 	u8 val8 = 0;
6341 	u16 rxff_bndy = 0;
6342 	u32 rx_dma_buff_sz = 0;
6343 
6344 	val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
6345 	if (val8 != 0)
6346 		RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
6347 			 __func__, (REG_FIFOPAGE + 3));
6348 
6349 	rtw_hal_reset_mac_rx(adapter);
6350 
6351 	if (wow_mode) {
6352 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
6353 				    (u8 *)&rx_dma_buff_sz);
6354 		rxff_bndy = rx_dma_buff_sz - 1;
6355 
6356 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
6357 		RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
6358 			 REG_TRXFF_BNDY + 2,
6359 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
6360 	} else {
6361 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
6362 				    (u8 *)&rx_dma_buff_sz);
6363 		rxff_bndy = rx_dma_buff_sz - 1;
6364 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
6365 		RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
6366 			 REG_TRXFF_BNDY + 2,
6367 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
6368 	}
6369 }
6370 
rtw_hal_set_pattern(_adapter * adapter,u8 * pattern,u8 len,u8 * mask,u8 idx)6371 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
6372 			       u8 len, u8 *mask, u8 idx)
6373 {
6374 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
6375 	struct mlme_ext_priv *pmlmeext = NULL;
6376 	struct mlme_ext_info *pmlmeinfo = NULL;
6377 	struct rtl_wow_pattern wow_pattern;
6378 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
6379 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
6380 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6381 	u8 multicast_addr1[2] = {0x33, 0x33};
6382 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
6383 	u8 res = _FALSE, index = 0, mask_len = 0;
6384 	u8 mac_addr[ETH_ALEN] = {0};
6385 	u16 count = 0;
6386 	int i, j;
6387 
6388 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_NUM) {
6389 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
6390 			 __func__, MAX_WKFM_NUM);
6391 		return _FALSE;
6392 	}
6393 
6394 	pmlmeext = &adapter->mlmeextpriv;
6395 	pmlmeinfo = &pmlmeext->mlmext_info;
6396 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
6397 	_rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
6398 
6399 	mask_len = DIV_ROUND_UP(len, 8);
6400 
6401 	/* 1. setup A1 table */
6402 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
6403 		wow_pattern.type = PATTERN_BROADCAST;
6404 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
6405 		wow_pattern.type = PATTERN_MULTICAST;
6406 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
6407 		wow_pattern.type = PATTERN_MULTICAST;
6408 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
6409 		wow_pattern.type = PATTERN_UNICAST;
6410 	else
6411 		wow_pattern.type = PATTERN_INVALID;
6412 
6413 	/* translate mask from os to mask for hw */
6414 
6415 	/******************************************************************************
6416 	 * pattern from OS uses 'ethenet frame', like this:
6417 
6418 		|    6   |    6   |   2  |     20    |  Variable  |  4  |
6419 		|--------+--------+------+-----------+------------+-----|
6420 		|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
6421 		|   DA   |   SA   | Type |
6422 
6423 	 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
6424 
6425 		|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
6426 		|-------------------+--------+------+-----------+------------+-----|
6427 		| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
6428 				    | Others | Tpye |
6429 
6430 	 * Therefore, we need translate mask_from_OS to mask_to_hw.
6431 	 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
6432 	 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
6433 	 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
6434 	 ******************************************************************************/
6435 	/* Shift 6 bits */
6436 	for (i = 0; i < mask_len - 1; i++) {
6437 		mask_hw[i] = mask[i] >> 6;
6438 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
6439 	}
6440 
6441 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
6442 	/* Set bit 0-5 to zero */
6443 	mask_hw[0] &= 0xC0;
6444 
6445 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
6446 		wow_pattern.mask[i] = mask_hw[i * 4];
6447 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
6448 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
6449 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
6450 	}
6451 
6452 	/* To get the wake up pattern from the mask.
6453 	 * We do not count first 12 bits which means
6454 	 * DA[6] and SA[6] in the pattern to match HW design. */
6455 	count = 0;
6456 	for (i = 12; i < len; i++) {
6457 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
6458 			content[count] = pattern[i];
6459 			count++;
6460 		}
6461 	}
6462 
6463 	wow_pattern.crc = rtw_calc_crc(content, count);
6464 
6465 	if (wow_pattern.crc != 0) {
6466 		if (wow_pattern.type == PATTERN_INVALID)
6467 			wow_pattern.type = PATTERN_VALID;
6468 	}
6469 
6470 	index = idx;
6471 
6472 	if (!pwrctl->bInSuspend)
6473 		index += 2;
6474 
6475 	/* write pattern */
6476 	res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
6477 
6478 	if (res == _FALSE)
6479 		RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
6480 			 __func__, idx);
6481 
6482 	return res;
6483 }
6484 
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)6485 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
6486 {
6487 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
6488 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6489 	int i = 0, total = 0;
6490 
6491 	total = pwrpriv->wowlan_pattern_idx;
6492 
6493 	if (total > MAX_WKFM_NUM)
6494 		total = MAX_WKFM_NUM;
6495 
6496 	rtw_clean_pattern(adapter);
6497 
6498 	switch (mode) {
6499 	case 0:
6500 		RTW_INFO("%s: total patterns: %d\n", __func__, total);
6501 		break;
6502 	case 1:
6503 		rtw_set_default_pattern(adapter);
6504 		for (i = 0 ; i < total ; i++) {
6505 			rtw_hal_set_pattern(adapter,
6506 					    pwrpriv->patterns[i].content,
6507 					    pwrpriv->patterns[i].len,
6508 					    pwrpriv->patterns[i].mask, i);
6509 		}
6510 		rtw_write8(adapter, REG_WKFMCAM_NUM, total);
6511 		RTW_INFO("%s: pattern total: %d downloaded\n",
6512 			 __func__, total);
6513 		break;
6514 	case 2:
6515 		pwrpriv->wowlan_pattern_idx = DEFAULT_PATTERN_NUM;
6516 
6517 		for (i = DEFAULT_PATTERN_NUM ; i < MAX_WKFM_NUM ; i++) {
6518 			_rtw_memset(pwrpriv->patterns[i].content, '\0',
6519 				    sizeof(pwrpriv->patterns[i].content));
6520 			_rtw_memset(pwrpriv->patterns[i].mask, '\0',
6521 				    sizeof(pwrpriv->patterns[i].mask));
6522 			pwrpriv->patterns[i].len = 0;
6523 		}
6524 		RTW_INFO("%s: clean patterns\n", __func__);
6525 		break;
6526 	default:
6527 		RTW_INFO("%s: unknown mode\n", __func__);
6528 		break;
6529 	}
6530 }
6531 
rtw_hal_wow_enable(_adapter * adapter)6532 static void rtw_hal_wow_enable(_adapter *adapter)
6533 {
6534 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
6535 	struct security_priv *psecuritypriv = &adapter->securitypriv;
6536 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
6537 	struct hal_ops *pHalFunc = &adapter->HalFunc;
6538 	struct sta_info *psta = NULL;
6539 	int res;
6540 	u16 media_status_rpt;
6541 
6542 
6543 	RTW_PRINT("%s, WOWLAN_ENABLE\n", __func__);
6544 	rtw_hal_gate_bb(adapter, _TRUE);
6545 #ifdef CONFIG_GTK_OL
6546 	if (psecuritypriv->dot11PrivacyAlgrthm == _AES_ &&
6547 		psecuritypriv->dot118021XGrpPrivacy == _AES_)
6548 		rtw_hal_fw_sync_cam_id(adapter);
6549 #endif
6550 	if (IS_HARDWARE_TYPE_8723B(adapter))
6551 		rtw_hal_backup_rate(adapter);
6552 
6553 	/* RX DMA stop */
6554 	if (IS_HARDWARE_TYPE_8188E(adapter))
6555 		rtw_hal_disable_tx_report(adapter);
6556 
6557 	res = rtw_hal_pause_rx_dma(adapter);
6558 	if (res == _FAIL)
6559 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
6560 
6561 	/* Reconfig RX_FF Boundary */
6562 	rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
6563 
6564 	/* redownload wow pattern */
6565 	rtw_hal_dl_pattern(adapter, 1);
6566 
6567 	rtw_hal_fw_dl(adapter, _TRUE);
6568 	media_status_rpt = RT_MEDIA_CONNECT;
6569 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
6570 			  (u8 *)&media_status_rpt);
6571 
6572 	if (!pwrctl->wowlan_pno_enable) {
6573 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
6574 		if (psta != NULL)
6575 			rtw_sta_media_status_rpt(adapter, psta, 1);
6576 	}
6577 
6578 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6579 	/* Enable CPWM2 only. */
6580 	res = rtw_hal_enable_cpwm2(adapter);
6581 	if (res == _FAIL)
6582 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6583 #endif
6584 #ifdef CONFIG_GPIO_WAKEUP
6585 	rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _TRUE);
6586 #endif
6587 	/* Set WOWLAN H2C command. */
6588 	RTW_PRINT("Set WOWLan cmd\n");
6589 	rtw_hal_set_fw_wow_related_cmd(adapter, 1);
6590 
6591 	res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
6592 
6593 	if (res == _FALSE)
6594 		RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
6595 
6596 	pwrctl->wowlan_wake_reason =
6597 		rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
6598 
6599 	RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
6600 		  pwrctl->wowlan_wake_reason);
6601 #ifdef CONFIG_GTK_OL_DBG
6602 	dump_sec_cam(RTW_DBGDUMP, adapter);
6603 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
6604 #endif
6605 #ifdef CONFIG_USB_HCI
6606 	/* free adapter's resource */
6607 	rtw_mi_intf_stop(adapter);
6608 
6609 	/* Invoid SE0 reset signal during suspending*/
6610 	rtw_write8(adapter, REG_RSV_CTRL, 0x20);
6611 	rtw_write8(adapter, REG_RSV_CTRL, 0x60);
6612 #endif /*CONFIG_USB_HCI*/
6613 
6614 	rtw_hal_gate_bb(adapter, _FALSE);
6615 }
6616 
rtw_hal_wow_disable(_adapter * adapter)6617 static void rtw_hal_wow_disable(_adapter *adapter)
6618 {
6619 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
6620 	struct security_priv *psecuritypriv = &adapter->securitypriv;
6621 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
6622 	struct hal_ops *pHalFunc = &adapter->HalFunc;
6623 	struct sta_info *psta = NULL;
6624 	int res;
6625 	u16 media_status_rpt;
6626 	u8 val8;
6627 
6628 	RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
6629 
6630 	if (!pwrctl->wowlan_pno_enable) {
6631 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
6632 		if (psta != NULL)
6633 			rtw_sta_media_status_rpt(adapter, psta, 0);
6634 		else
6635 			RTW_INFO("%s: psta is null\n", __func__);
6636 	}
6637 
6638 	if (0) {
6639 		RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
6640 		RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
6641 	}
6642 
6643 	pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
6644 
6645 	RTW_PRINT("wakeup_reason: 0x%02x\n",
6646 		  pwrctl->wowlan_wake_reason);
6647 
6648 	rtw_hal_set_fw_wow_related_cmd(adapter, 0);
6649 
6650 	res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
6651 
6652 	if (res == _FALSE) {
6653 		RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
6654 		rtw_hal_force_enable_rxdma(adapter);
6655 	}
6656 
6657 	rtw_hal_gate_bb(adapter, _TRUE);
6658 
6659 	res = rtw_hal_pause_rx_dma(adapter);
6660 	if (res == _FAIL)
6661 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
6662 
6663 	/* clean HW pattern match */
6664 	rtw_hal_dl_pattern(adapter, 0);
6665 
6666 	/* config RXFF boundary to original */
6667 	rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
6668 
6669 	rtw_hal_release_rx_dma(adapter);
6670 
6671 	if (IS_HARDWARE_TYPE_8188E(adapter))
6672 		rtw_hal_enable_tx_report(adapter);
6673 
6674 	rtw_hal_update_tx_iv(adapter);
6675 
6676 #ifdef CONFIG_GTK_OL
6677 	if (psecuritypriv->dot11PrivacyAlgrthm == _AES_ &&
6678 		psecuritypriv->dot118021XGrpPrivacy == _AES_)
6679 		rtw_hal_update_gtk_offload_info(adapter);
6680 #endif /*CONFIG_GTK_OL*/
6681 
6682 	rtw_hal_fw_dl(adapter, _FALSE);
6683 
6684 #ifdef CONFIG_GPIO_WAKEUP
6685 	val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
6686 	RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
6687 	rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, val8);
6688 #endif
6689 
6690 	if ((pwrctl->wowlan_wake_reason != FWDecisionDisconnect) &&
6691 	    (pwrctl->wowlan_wake_reason != Rx_Pairwisekey) &&
6692 	    (pwrctl->wowlan_wake_reason != Rx_DisAssoc) &&
6693 	    (pwrctl->wowlan_wake_reason != Rx_DeAuth)) {
6694 
6695 		media_status_rpt = RT_MEDIA_CONNECT;
6696 		rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
6697 				  (u8 *)&media_status_rpt);
6698 
6699 		if (psta != NULL)
6700 			rtw_sta_media_status_rpt(adapter, psta, 1);
6701 	}
6702 	rtw_hal_gate_bb(adapter, _FALSE);
6703 }
6704 #endif /*CONFIG_WOWLAN*/
6705 
6706 #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)6707 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
6708 	      u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
6709 				      RSVDPAGE_LOC *rsvd_page_loc)
6710 {
6711 	u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
6712 	u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
6713 	u8 CurtPktPageNum = 0;
6714 
6715 	/* P2P Beacon */
6716 	rsvd_page_loc->LocP2PBeacon = *page_num;
6717 	rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
6718 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6719 				 P2PBCNLength, _FALSE, _FALSE, _FALSE);
6720 
6721 #if 0
6722 	RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
6723 		__FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
6724 #endif
6725 
6726 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
6727 
6728 	*page_num += CurtPktPageNum;
6729 
6730 	index += (CurtPktPageNum * page_size);
6731 
6732 	/* P2P Probe rsp */
6733 	rsvd_page_loc->LocP2PProbeRsp = *page_num;
6734 	rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
6735 				      &P2PProbeRspLength);
6736 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6737 				 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
6738 
6739 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",  */
6740 	/*	__FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
6741 
6742 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
6743 
6744 	*page_num += CurtPktPageNum;
6745 
6746 	index += (CurtPktPageNum * page_size);
6747 
6748 	/* P2P nego rsp */
6749 	rsvd_page_loc->LocNegoRsp = *page_num;
6750 	rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
6751 				     &P2PNegoRspLength);
6752 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6753 				 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
6754 
6755 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
6756 	/*	__FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
6757 
6758 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
6759 
6760 	*page_num += CurtPktPageNum;
6761 
6762 	index += (CurtPktPageNum * page_size);
6763 
6764 	/* P2P invite rsp */
6765 	rsvd_page_loc->LocInviteRsp = *page_num;
6766 	rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
6767 				       &P2PInviteRspLength);
6768 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6769 				 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
6770 
6771 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
6772 	/* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
6773 
6774 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
6775 
6776 	*page_num += CurtPktPageNum;
6777 
6778 	index += (CurtPktPageNum * page_size);
6779 
6780 	/* P2P provision discovery rsp */
6781 	rsvd_page_loc->LocPDRsp = *page_num;
6782 	rtw_hal_construct_P2PProvisionDisRsp(adapter,
6783 					     &pframe[index], &P2PPDRspLength);
6784 
6785 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6786 				 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
6787 
6788 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
6789 	/*	__FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
6790 
6791 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
6792 
6793 	*page_num += CurtPktPageNum;
6794 
6795 	*total_pkt_len = index + P2PPDRspLength;
6796 
6797 	index += (CurtPktPageNum * page_size);
6798 
6799 
6800 }
6801 #endif /* CONFIG_P2P_WOWLAN */
6802 
6803 #ifdef CONFIG_LPS_PG
6804 	#define LPSPG_RSVD_PAGE_SET_MACID(_rsvd_pag, _value)		SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x00, 0, 8, _value)/*used macid*/
6805 	#define LPSPG_RSVD_PAGE_SET_MBSSCAMID(_rsvd_pag, _value)	SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x00, 8, 8, _value)/*used BSSID CAM entry*/
6806 	#define LPSPG_RSVD_PAGE_SET_PMC_NUM(_rsvd_pag, _value)		SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x00, 16, 8, _value)/*Max used Pattern Match CAM entry*/
6807 	#define LPSPG_RSVD_PAGE_SET_MU_RAID_GID(_rsvd_pag, _value)	SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x00, 24, 8, _value)/*Max MU rate table Group ID*/
6808 	#define LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(_rsvd_pag, _value)	SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x04, 0, 8, _value)/*used Security CAM entry number*/
6809 	#define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID1(_rsvd_pag, _value)	SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x08, 0, 8, _value)/*used Security CAM entry -1*/
6810 	#define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID2(_rsvd_pag, _value)	SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x08, 8, 8, _value)/*used Security CAM entry -2*/
6811 	#define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID3(_rsvd_pag, _value)	SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x08, 16, 8, _value)/*used Security CAM entry -3*/
6812 	#define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID4(_rsvd_pag, _value)	SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x08, 24, 8, _value)/*used Security CAM entry -4*/
6813 	#define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID5(_rsvd_pag, _value)	SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x0C, 0, 8, _value)/*used Security CAM entry -5*/
6814 	#define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID6(_rsvd_pag, _value)	SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x0C, 8, 8, _value)/*used Security CAM entry -6*/
6815 	#define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID7(_rsvd_pag, _value)	SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x0C, 16, 8, _value)/*used Security CAM entry -7*/
6816 	#define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID8(_rsvd_pag, _value)	SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x0C, 24, 8, _value)/*used Security CAM entry -8*/
6817 #endif
6818 #ifdef CONFIG_LPS_PG
6819 #include "hal_halmac.h"
6820 
6821 #define DBG_LPSPG_SEC_DUMP
6822 #define LPS_PG_INFO_RSVD_LEN	16
6823 
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)6824 static void rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
6825 {
6826 	u8 cur_pag_num = 0;
6827 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6828 	struct sta_info	*psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
6829 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
6830 	u8 lps_pg_info[LPS_PG_INFO_RSVD_LEN] = {0};
6831 #ifdef CONFIG_MBSSID_CAM
6832 	u8 cam_id = INVALID_CAM_ID;
6833 #endif
6834 	u8 *psec_cam_id = lps_pg_info + 8;
6835 	u8 sec_cam_num = 0;
6836 
6837 	if (!psta) {
6838 		RTW_INFO("%s [ERROR] sta is NULL\n", __func__);
6839 		rtw_warn_on(1);
6840 		return;
6841 	}
6842 
6843 	LPSPG_RSVD_PAGE_SET_MACID(lps_pg_info, psta->mac_id);	/*used macid*/
6844 	RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->mac_id);
6845 
6846 #ifdef CONFIG_MBSSID_CAM
6847 	cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
6848 	if (cam_id != INVALID_CAM_ID)
6849 		LPSPG_RSVD_PAGE_SET_MBSSCAMID(lps_pg_info, cam_id);	/*used BSSID CAM entry*/
6850 	RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
6851 #endif
6852 
6853 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
6854 	if (pwrpriv->wowlan_mode == _TRUE &&
6855 	    check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _TRUE) {
6856 		LPSPG_RSVD_PAGE_SET_PMC_NUM(lps_pg_info, pwrpriv->wowlan_pattern_idx);	/*Max used Pattern Match CAM entry*/
6857 		RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", _value);
6858 	}
6859 #endif
6860 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
6861 	LPSPG_RSVD_PAGE_SET_MU_RAID_GID(lps_pg_info, _value);	/*Max MU rate table Group ID*/
6862 	RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", _value);
6863 #endif
6864 
6865 	sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
6866 	if (sec_cam_num < 8)
6867 		LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(lps_pg_info, sec_cam_num);	/*used Security CAM entry number*/
6868 	RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
6869 
6870 #ifdef DBG_LPSPG_SEC_DUMP
6871 	{
6872 		int i;
6873 
6874 		for (i = 0; i < sec_cam_num; i++)
6875 			RTW_INFO("%d = sec_cam_id:%d\n", i, psec_cam_id[i]);
6876 	}
6877 #endif
6878 
6879 #ifdef DBG_LPSPG_INFO_DUMP
6880 	RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
6881 	RTW_INFO("  %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
6882 		*(lps_pg_info), *(lps_pg_info + 1), *(lps_pg_info + 2), *(lps_pg_info + 3),
6883 		*(lps_pg_info + 4), *(lps_pg_info + 5), *(lps_pg_info + 6), *(lps_pg_info + 7));
6884 	RTW_INFO("  %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
6885 		*(lps_pg_info + 8), *(lps_pg_info + 9), *(lps_pg_info + 10), *(lps_pg_info + 11),
6886 		*(lps_pg_info + 12), *(lps_pg_info + 13), *(lps_pg_info + 14), *(lps_pg_info + 15));
6887 	RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
6888 #endif
6889 
6890 	rtw_halmac_download_rsvd_page(dvobj, pwrpriv->lpspg_rsvd_page_locate, lps_pg_info, LPS_PG_INFO_RSVD_LEN);
6891 
6892 }
6893 
6894 #define DBG_LPSPG_INFO_DUMP
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)6895 static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
6896 {
6897 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6898 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
6899 
6900 	u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
6901 	u8 ret = _FAIL;
6902 
6903 	RTW_INFO("%s: loc_lpspg_info:%d\n", __func__, pwrpriv->lpspg_rsvd_page_locate);
6904 
6905 	if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
6906 		SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1);	/*SecurityCAM_En*/
6907 #ifdef CONFIG_MBSSID_CAM
6908 	SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1);		/*BSSIDCAM_En*/
6909 #endif
6910 
6911 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
6912 	if (pwrpriv->wowlan_mode == _TRUE &&
6913 	    check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
6914 
6915 		SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1);	/*PatternMatchCAM_En*/
6916 	}
6917 #endif
6918 
6919 #ifdef CONFIG_MACID_SEARCH
6920 	SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1);	/*MACIDSearch_En*/
6921 #endif
6922 
6923 #ifdef CONFIG_TX_SC
6924 	SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1);	/*TXSC_En*/
6925 #endif
6926 
6927 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
6928 	SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1);	/*MURateTable_En*/
6929 #endif
6930 
6931 	SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_rsvd_page_locate);
6932 
6933 #ifdef DBG_LPSPG_INFO_DUMP
6934 	RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
6935 	RTW_INFO("  H2C_CMD: 0x%02x, H2C_LEN: %d\n", H2C_LPS_PG_INFO, H2C_LPS_PG_INFO_LEN);
6936 	RTW_INFO("  %02X:%02X\n", *(lpspg_info), *(lpspg_info + 1));
6937 	RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
6938 #endif
6939 
6940 	ret = rtw_hal_fill_h2c_cmd(adapter,
6941 				   H2C_LPS_PG_INFO,
6942 				   H2C_LPS_PG_INFO_LEN,
6943 				   lpspg_info);
6944 	return ret;
6945 }
rtw_hal_set_lps_pg_info(_adapter * adapter)6946 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
6947 {
6948 	u8 ret = _FAIL;
6949 
6950 	rtw_hal_set_lps_pg_info_rsvd_page(adapter);
6951 	ret = rtw_hal_set_lps_pg_info_cmd(adapter);
6952 	return ret;
6953 }
6954 #endif /*CONFIG_LPS_PG*/
6955 
6956 /*
6957  * Description: Fill the reserved packets that FW will use to RSVD page.
6958  *			Now we just send 4 types packet to rsvd page.
6959  *			(1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
6960  * Input:
6961  * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
6962  *		    so we need to set the packet length to total lengh.
6963  *	      TRUE: At the second time, we should send the first packet (default:beacon)
6964  *		    to Hw again and set the lengh in descriptor to the real beacon lengh.
6965  * 2009.10.15 by tynli.
6966  *
6967  * Page Size = 128: 8188e, 8723a/b, 8192c/d,
6968  * Page Size = 256: 8192e, 8821a
6969  * Page Size = 512: 8812a
6970  */
6971 
rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished)6972 void rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished)
6973 {
6974 	PHAL_DATA_TYPE pHalData;
6975 	struct xmit_frame	*pcmdframe;
6976 	struct pkt_attrib	*pattrib;
6977 	struct xmit_priv	*pxmitpriv;
6978 	struct mlme_ext_priv	*pmlmeext;
6979 	struct mlme_ext_info	*pmlmeinfo;
6980 	struct pwrctrl_priv *pwrctl;
6981 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
6982 	struct hal_ops *pHalFunc = &adapter->HalFunc;
6983 	u32	BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
6984 	u32	NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
6985 	u32	ProbeReqLength = 0, NullFunctionDataLength = 0;
6986 	u8	TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
6987 	u8	TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
6988 	u8	*ReservedPagePacket;
6989 	u16	BufIndex = 0;
6990 	u32	TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
6991 	RSVDPAGE_LOC	RsvdPageLoc;
6992 
6993 #ifdef DBG_CONFIG_ERROR_DETECT
6994 	struct sreset_priv *psrtpriv;
6995 #endif /* DBG_CONFIG_ERROR_DETECT */
6996 
6997 #ifdef CONFIG_MCC_MODE
6998 	u8 dl_mcc_page = _FAIL;
6999 #endif /* CONFIG_MCC_MODE */
7000 
7001 	pHalData = GET_HAL_DATA(adapter);
7002 #ifdef DBG_CONFIG_ERROR_DETECT
7003 	psrtpriv = &pHalData->srestpriv;
7004 #endif
7005 	pxmitpriv = &adapter->xmitpriv;
7006 	pmlmeext = &adapter->mlmeextpriv;
7007 	pmlmeinfo = &pmlmeext->mlmext_info;
7008 	pwrctl = adapter_to_pwrctl(adapter);
7009 
7010 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
7011 
7012 	if (PageSize == 0) {
7013 		RTW_INFO("[Error]: %s, PageSize is zero!!\n", __func__);
7014 		return;
7015 	}
7016 
7017 	if (pwrctl->wowlan_mode == _TRUE || pwrctl->wowlan_ap_mode == _TRUE)
7018 		RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
7019 	else
7020 		RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
7021 
7022 	RTW_INFO("%s PageSize: %d, RsvdPageNUm: %d\n", __func__, PageSize, RsvdPageNum);
7023 
7024 	MaxRsvdPageBufSize = RsvdPageNum * PageSize;
7025 
7026 	if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
7027 		RTW_INFO("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
7028 			 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
7029 		rtw_warn_on(1);
7030 		return;
7031 	}
7032 
7033 	pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
7034 
7035 	if (pcmdframe == NULL) {
7036 		RTW_INFO("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
7037 		return;
7038 	}
7039 
7040 	ReservedPagePacket = pcmdframe->buf_addr;
7041 	_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
7042 
7043 	/* beacon * 2 pages */
7044 	BufIndex = TxDescOffset;
7045 	rtw_hal_construct_beacon(adapter,
7046 				 &ReservedPagePacket[BufIndex], &BeaconLength);
7047 
7048 	/*
7049 	* When we count the first page size, we need to reserve description size for the RSVD
7050 	* packet, it will be filled in front of the packet in TXPKTBUF.
7051 	*/
7052 	CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
7053 	/* If we don't add 1 more page, ARP offload function will fail at 8723bs.*/
7054 	if (CurtPktPageNum == 1)
7055 		CurtPktPageNum += 1;
7056 
7057 	TotalPageNum += CurtPktPageNum;
7058 
7059 	BufIndex += (CurtPktPageNum * PageSize);
7060 
7061 	if (pwrctl->wowlan_ap_mode == _TRUE) {
7062 		/* (4) probe response*/
7063 		RsvdPageLoc.LocProbeRsp = TotalPageNum;
7064 		rtw_hal_construct_ProbeRsp(
7065 			adapter, &ReservedPagePacket[BufIndex],
7066 			&ProbeRspLength,
7067 			get_my_bssid(&pmlmeinfo->network), _FALSE);
7068 		rtw_hal_fill_fake_txdesc(adapter,
7069 				 &ReservedPagePacket[BufIndex - TxDescLen],
7070 				 ProbeRspLength, _FALSE, _FALSE, _FALSE);
7071 
7072 		CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
7073 		TotalPageNum += CurtPktPageNum;
7074 		TotalPacketLen = BufIndex + ProbeRspLength;
7075 		BufIndex += (CurtPktPageNum * PageSize);
7076 		goto download_page;
7077 	}
7078 
7079 	/* ps-poll * 1 page */
7080 	RsvdPageLoc.LocPsPoll = TotalPageNum;
7081 	RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
7082 	rtw_hal_construct_PSPoll(adapter,
7083 				 &ReservedPagePacket[BufIndex], &PSPollLength);
7084 	rtw_hal_fill_fake_txdesc(adapter,
7085 				 &ReservedPagePacket[BufIndex - TxDescLen],
7086 				 PSPollLength, _TRUE, _FALSE, _FALSE);
7087 
7088 	CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
7089 
7090 	TotalPageNum += CurtPktPageNum;
7091 
7092 	BufIndex += (CurtPktPageNum * PageSize);
7093 
7094 #ifdef CONFIG_BT_COEXIST
7095 	/* BT Qos null data * 1 page */
7096 	RsvdPageLoc.LocBTQosNull = TotalPageNum;
7097 	RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
7098 	rtw_hal_construct_NullFunctionData(
7099 		adapter,
7100 		&ReservedPagePacket[BufIndex],
7101 		&BTQosNullLength,
7102 		get_my_bssid(&pmlmeinfo->network),
7103 		_TRUE, 0, 0, _FALSE);
7104 	rtw_hal_fill_fake_txdesc(adapter,
7105 				 &ReservedPagePacket[BufIndex - TxDescLen],
7106 				 BTQosNullLength, _FALSE, _TRUE, _FALSE);
7107 
7108 	CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength, PageSize);
7109 
7110 	TotalPageNum += CurtPktPageNum;
7111 
7112 	BufIndex += (CurtPktPageNum * PageSize);
7113 #endif /* CONFIG_BT_COEXIT */
7114 
7115 #ifdef CONFIG_MCC_MODE
7116 	if (MCC_EN(adapter)) {
7117 		dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
7118 				&BufIndex, TxDescLen, PageSize,
7119 				&TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
7120 	} else
7121 		dl_mcc_page = _FAIL;
7122 
7123 	if (dl_mcc_page == _FAIL) {
7124 #endif /* CONFIG_MCC_MODE */
7125 
7126 		/* null data * 1 page */
7127 		RsvdPageLoc.LocNullData = TotalPageNum;
7128 		RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
7129 		rtw_hal_construct_NullFunctionData(
7130 			adapter,
7131 			&ReservedPagePacket[BufIndex],
7132 			&NullDataLength,
7133 			get_my_bssid(&pmlmeinfo->network),
7134 			_FALSE, 0, 0, _FALSE);
7135 		rtw_hal_fill_fake_txdesc(adapter,
7136 				 &ReservedPagePacket[BufIndex - TxDescLen],
7137 				 NullDataLength, _FALSE, _FALSE, _FALSE);
7138 
7139 		CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
7140 
7141 		TotalPageNum += CurtPktPageNum;
7142 
7143 		BufIndex += (CurtPktPageNum * PageSize);
7144 #ifdef CONFIG_MCC_MODE
7145 	}
7146 #endif /* CONFIG_MCC_MODE */
7147 
7148 	/* Qos null data * 1 page */
7149 	RsvdPageLoc.LocQosNull = TotalPageNum;
7150 	RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
7151 	rtw_hal_construct_NullFunctionData(
7152 		adapter,
7153 		&ReservedPagePacket[BufIndex],
7154 		&QosNullLength,
7155 		get_my_bssid(&pmlmeinfo->network),
7156 		_TRUE, 0, 0, _FALSE);
7157 	rtw_hal_fill_fake_txdesc(adapter,
7158 				 &ReservedPagePacket[BufIndex - TxDescLen],
7159 				 QosNullLength, _FALSE, _FALSE, _FALSE);
7160 
7161 	CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength, PageSize);
7162 
7163 	TotalPageNum += CurtPktPageNum;
7164 
7165 	TotalPacketLen = BufIndex + QosNullLength;
7166 
7167 	BufIndex += (CurtPktPageNum * PageSize);
7168 
7169 #ifdef CONFIG_WOWLAN
7170 	if (pwrctl->wowlan_mode == _TRUE) {
7171 		rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
7172 					     BufIndex, TxDescLen, PageSize,
7173 			     &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
7174 	}
7175 #endif /* CONFIG_WOWLAN */
7176 
7177 #ifdef CONFIG_P2P_WOWLAN
7178 	if (_TRUE == pwrctl->wowlan_p2p_mode) {
7179 		rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
7180 						 BufIndex, TxDescLen, PageSize,
7181 				 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
7182 	}
7183 #endif /* CONFIG_P2P_WOWLAN */
7184 
7185 #ifdef CONFIG_LPS_PG
7186 	/* must reserved last 1 x page for LPS PG Info*/
7187 	pwrctl->lpspg_rsvd_page_locate = TotalPageNum;
7188 #endif
7189 
7190 download_page:
7191 	/* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
7192 	RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
7193 		 __func__, TotalPageNum, TotalPacketLen);
7194 
7195 	if (TotalPacketLen > MaxRsvdPageBufSize) {
7196 		RTW_INFO("%s(ERROR): rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
7197 			 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
7198 		rtw_warn_on(1);
7199 		goto error;
7200 	} else {
7201 		/* update attribute */
7202 		pattrib = &pcmdframe->attrib;
7203 		update_mgntframe_attrib(adapter, pattrib);
7204 		pattrib->qsel = QSLT_BEACON;
7205 		pattrib->pktlen = TotalPacketLen - TxDescOffset;
7206 		pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
7207 #ifdef CONFIG_PCI_HCI
7208 		dump_mgntframe(adapter, pcmdframe);
7209 #else
7210 		dump_mgntframe_and_wait(adapter, pcmdframe, 100);
7211 #endif
7212 	}
7213 
7214 	RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
7215 		 __func__, TotalPacketLen, TotalPageNum);
7216 
7217 	if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
7218 		rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
7219 		if (pwrctl->wowlan_mode == _TRUE)
7220 			rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
7221 #ifdef CONFIG_AP_WOWLAN
7222 		if (pwrctl->wowlan_ap_mode == _TRUE)
7223 			rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
7224 #endif /* CONFIG_AP_WOWLAN */
7225 	} else if (pwrctl->wowlan_pno_enable) {
7226 #ifdef CONFIG_PNO_SUPPORT
7227 		rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
7228 		if (pwrctl->pno_in_resume)
7229 			rtw_hal_set_scan_offload_info_cmd(adapter,
7230 							  &RsvdPageLoc, 0);
7231 		else
7232 			rtw_hal_set_scan_offload_info_cmd(adapter,
7233 							  &RsvdPageLoc, 1);
7234 #endif /* CONFIG_PNO_SUPPORT */
7235 	}
7236 #ifdef CONFIG_P2P_WOWLAN
7237 	if (_TRUE == pwrctl->wowlan_p2p_mode)
7238 		rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
7239 #endif /* CONFIG_P2P_WOWLAN */
7240 	return;
7241 error:
7242 	rtw_free_xmitframe(pxmitpriv, pcmdframe);
7243 }
rtw_hal_set_hw_update_tsf(PADAPTER padapter)7244 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
7245 {
7246 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7247 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7248 
7249 #if defined(CONFIG_RTL8822B) || defined(CONFIG_MI_WITH_MBSSID_CAM)
7250 	RTW_INFO("[Warn] %s "ADPT_FMT" enter func\n", __func__, ADPT_ARG(padapter));
7251 	rtw_warn_on(1);
7252 	return;
7253 #endif
7254 
7255 	if (!pmlmeext->en_hw_update_tsf)
7256 		return;
7257 
7258 	/* check REG_RCR bit is set */
7259 	if (!(rtw_read32(padapter, REG_RCR) & RCR_CBSSID_BCN))
7260 		return;
7261 
7262 	/* enable hw update tsf function for non-AP */
7263 	if (rtw_linked_check(padapter) &&
7264 	    check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) {
7265 #ifdef CONFIG_CONCURRENT_MODE
7266 		if (padapter->hw_port == HW_PORT1)
7267 			rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~DIS_TSF_UDT));
7268 		else
7269 #endif
7270 			rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~DIS_TSF_UDT));
7271 	}
7272 	pmlmeext->en_hw_update_tsf = _FALSE;
7273 }
7274 
7275 #ifdef CONFIG_TDLS
7276 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)7277 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
7278 {
7279 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
7280 	u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
7281 
7282 
7283 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
7284 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
7285 	switch (bwmode) {
7286 	case CHANNEL_WIDTH_40:
7287 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
7288 		break;
7289 	case CHANNEL_WIDTH_80:
7290 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
7291 		break;
7292 	case CHANNEL_WIDTH_20:
7293 	default:
7294 		break;
7295 	}
7296 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->RFEType);
7297 
7298 	return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
7299 }
7300 #endif
7301 #endif
7302 
7303 #ifdef CONFIG_BT_COEXIST
7304 /* For multi-port support, driver needs to inform the port ID to FW for btc operations */
rtw_hal_set_wifi_port_id_cmd(_adapter * adapter)7305 s32 rtw_hal_set_wifi_port_id_cmd(_adapter *adapter)
7306 {
7307 	u8 port_id = 0;
7308 	u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
7309 
7310 	port_id = get_hw_port(adapter);
7311 
7312 	SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, port_id);
7313 
7314 	return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
7315 }
7316 #endif
7317 
SetHwReg(_adapter * adapter,u8 variable,u8 * val)7318 void SetHwReg(_adapter *adapter, u8 variable, u8 *val)
7319 {
7320 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
7321 	_func_enter_;
7322 
7323 	switch (variable) {
7324 	case HW_VAR_MEDIA_STATUS: {
7325 		u8 net_type = *((u8 *)val);
7326 
7327 		rtw_hal_set_msr(adapter, net_type);
7328 	}
7329 	break;
7330 	case HW_VAR_MAC_ADDR:
7331 #ifdef CONFIG_MI_WITH_MBSSID_CAM
7332 		rtw_hal_set_macaddr_mbid(adapter, val);
7333 #else
7334 		rtw_hal_set_macaddr_port(adapter, val);
7335 #endif
7336 		break;
7337 	case HW_VAR_BSSID:
7338 		rtw_hal_set_bssid(adapter, val);
7339 		break;
7340 #ifdef CONFIG_MBSSID_CAM
7341 	case HW_VAR_MBSSID_CAM_WRITE: {
7342 		u32	cmd = 0;
7343 		u32	*cam_val = (u32 *)val;
7344 
7345 		rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
7346 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
7347 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
7348 	}
7349 	break;
7350 	case HW_VAR_MBSSID_CAM_CLEAR: {
7351 		u32 cmd;
7352 		u8 entry_id = *(u8 *)val;
7353 
7354 		rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
7355 
7356 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
7357 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
7358 	}
7359 	break;
7360 	case HW_VAR_RCR_MBSSID_EN:
7361 		if (*((u8 *)val))
7362 			rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) | RCR_ENMBID);
7363 		else {
7364 			u32	val32;
7365 
7366 			val32 = rtw_read32(adapter, REG_RCR);
7367 			val32 &= ~(RCR_ENMBID);
7368 			rtw_write32(adapter, REG_RCR, val32);
7369 		}
7370 		break;
7371 #endif
7372 	case HW_VAR_PORT_SWITCH:
7373 		hw_var_port_switch(adapter);
7374 		break;
7375 	case HW_VAR_INIT_RTS_RATE: {
7376 		u16 brate_cfg = *((u16 *)val);
7377 		u8 rate_index = 0;
7378 		HAL_VERSION *hal_ver = &hal_data->VersionID;
7379 
7380 		if (IS_8188E(*hal_ver)) {
7381 
7382 			while (brate_cfg > 0x1) {
7383 				brate_cfg = (brate_cfg >> 1);
7384 				rate_index++;
7385 			}
7386 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
7387 		} else
7388 			rtw_warn_on(1);
7389 	}
7390 	break;
7391 	case HW_VAR_SEC_CFG: {
7392 		u16 reg_scr_ori;
7393 		u16 reg_scr;
7394 
7395 		reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
7396 		reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
7397 
7398 		if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
7399 			reg_scr |= SCR_CHK_BMC;
7400 
7401 		if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
7402 			reg_scr |= SCR_NoSKMC;
7403 
7404 		if (reg_scr != reg_scr_ori)
7405 			rtw_write16(adapter, REG_SECCFG, reg_scr);
7406 	}
7407 	break;
7408 	case HW_VAR_SEC_DK_CFG: {
7409 		struct security_priv *sec = &adapter->securitypriv;
7410 		u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
7411 
7412 		if (val) { /* Enable default key related setting */
7413 			reg_scr |= SCR_TXBCUSEDK;
7414 			if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
7415 				reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
7416 		} else /* Disable default key related setting */
7417 			reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
7418 
7419 		rtw_write8(adapter, REG_SECCFG, reg_scr);
7420 	}
7421 	break;
7422 
7423 	case HW_VAR_ASIX_IOT:
7424 		/* enable  ASIX IOT function */
7425 		if (*((u8 *)val) == _TRUE) {
7426 			/* 0xa2e[0]=0 (disable rake receiver) */
7427 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
7428 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
7429 			/* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
7430 			rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
7431 		} else {
7432 			/* restore reg:0xa2e,   reg:0xa1c */
7433 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
7434 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
7435 			rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
7436 		}
7437 		break;
7438 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
7439 	case HW_VAR_WOWLAN: {
7440 		struct wowlan_ioctl_param *poidparam;
7441 
7442 		poidparam = (struct wowlan_ioctl_param *)val;
7443 		switch (poidparam->subcode) {
7444 #ifdef CONFIG_WOWLAN
7445 		case WOWLAN_PATTERN_CLEAN:
7446 			rtw_hal_dl_pattern(adapter, 2);
7447 			break;
7448 		case WOWLAN_ENABLE:
7449 			rtw_hal_wow_enable(adapter);
7450 			break;
7451 		case WOWLAN_DISABLE:
7452 			rtw_hal_wow_disable(adapter);
7453 			break;
7454 #endif /*CONFIG_WOWLAN*/
7455 #ifdef CONFIG_AP_WOWLAN
7456 		case WOWLAN_AP_ENABLE:
7457 			rtw_hal_ap_wow_enable(adapter);
7458 			break;
7459 		case WOWLAN_AP_DISABLE:
7460 			rtw_hal_ap_wow_disable(adapter);
7461 			break;
7462 #endif /*CONFIG_AP_WOWLAN*/
7463 		default:
7464 			break;
7465 		}
7466 	}
7467 	break;
7468 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
7469 
7470 	case HW_VAR_EN_HW_UPDATE_TSF:
7471 		rtw_hal_set_hw_update_tsf(adapter);
7472 		break;
7473 
7474 	default:
7475 		if (0)
7476 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
7477 				  FUNC_ADPT_ARG(adapter), variable);
7478 		break;
7479 	}
7480 
7481 	_func_exit_;
7482 }
7483 
GetHwReg(_adapter * adapter,u8 variable,u8 * val)7484 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
7485 {
7486 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
7487 
7488 	_func_enter_;
7489 
7490 	switch (variable) {
7491 	case HW_VAR_BASIC_RATE:
7492 		*((u16 *)val) = hal_data->BasicRateSet;
7493 		break;
7494 	case HW_VAR_RF_TYPE:
7495 		*((u8 *)val) = hal_data->rf_type;
7496 		break;
7497 	case HW_VAR_MEDIA_STATUS:
7498 		rtw_hal_get_msr(adapter, val);
7499 		break;
7500 	case HW_VAR_DO_IQK:
7501 		*val = hal_data->bNeedIQK;
7502 		break;
7503 	case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
7504 		if (hal_is_band_support(adapter, BAND_ON_5G))
7505 			*val = _TRUE;
7506 		else
7507 			*val = _FALSE;
7508 
7509 		break;
7510 	default:
7511 		if (0)
7512 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
7513 				  FUNC_ADPT_ARG(adapter), variable);
7514 		break;
7515 	}
7516 
7517 	_func_exit_;
7518 }
7519 
7520 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)7521 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
7522 {
7523 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
7524 	u8 bResult = _SUCCESS;
7525 
7526 	switch (variable) {
7527 
7528 	case HAL_DEF_DBG_DUMP_RXPKT:
7529 		hal_data->bDumpRxPkt = *((u8 *)value);
7530 		break;
7531 	case HAL_DEF_DBG_DUMP_TXPKT:
7532 		hal_data->bDumpTxPkt = *((u8 *)value);
7533 		break;
7534 	case HAL_DEF_ANT_DETECT:
7535 		hal_data->AntDetection = *((u8 *)value);
7536 		break;
7537 	case HAL_DEF_DBG_DIS_PWT:
7538 		hal_data->bDisableTXPowerTraining = *((u8 *)value);
7539 		break;
7540 	default:
7541 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
7542 		bResult = _FAIL;
7543 		break;
7544 	}
7545 
7546 	return bResult;
7547 }
7548 
7549 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)7550 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
7551 {
7552 	struct registry_priv	*pregistrypriv = &adapter->registrypriv;
7553 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
7554 
7555 	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)))
7556 		return pregistrypriv->beamformer_rf_num;
7557 	else if (IS_HARDWARE_TYPE_8814AE(adapter)
7558 #if 0
7559 #if defined(CONFIG_USB_HCI)
7560 		|| (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2))  /* for USB3.0 */
7561 #endif
7562 #endif
7563 		) {
7564 		/*BF cap provided by Yu Chen, Sean, 2015, 01 */
7565 		if (hal_data->rf_type == RF_3T3R)
7566 			return 2;
7567 		else if (hal_data->rf_type == RF_4T4R)
7568 			return 3;
7569 		else
7570 			return 1;
7571 	} else
7572 		return 1;
7573 
7574 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)7575 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
7576 {
7577 	struct registry_priv		*pregistrypriv = &adapter->registrypriv;
7578 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
7579 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7580 
7581 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
7582 
7583 	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)))
7584 		return pregistrypriv->beamformee_rf_num;
7585 	else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
7586 		if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
7587 			return 2;
7588 		else
7589 			return 2;/*TODO: May be 3 in the future, by ChenYu. */
7590 	} else
7591 		return 1;
7592 
7593 }
7594 #endif
7595 
7596 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)7597 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
7598 {
7599 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
7600 	u8 bResult = _SUCCESS;
7601 
7602 	switch (variable) {
7603 	case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
7604 		struct mlme_priv *pmlmepriv;
7605 		struct sta_priv *pstapriv;
7606 		struct sta_info *psta;
7607 
7608 		pmlmepriv = &adapter->mlmepriv;
7609 		pstapriv = &adapter->stapriv;
7610 		psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
7611 		if (psta)
7612 			*((int *)value) = psta->rssi_stat.UndecoratedSmoothedPWDB;
7613 	}
7614 	break;
7615 	case HAL_DEF_DBG_DUMP_RXPKT:
7616 		*((u8 *)value) = hal_data->bDumpRxPkt;
7617 		break;
7618 	case HAL_DEF_DBG_DUMP_TXPKT:
7619 		*((u8 *)value) = hal_data->bDumpTxPkt;
7620 		break;
7621 	case HAL_DEF_ANT_DETECT:
7622 		*((u8 *)value) = hal_data->AntDetection;
7623 		break;
7624 	case HAL_DEF_MACID_SLEEP:
7625 		*(u8 *)value = _FALSE;
7626 		break;
7627 	case HAL_DEF_TX_PAGE_SIZE:
7628 		*((u32 *)value) = PAGE_SIZE_128;
7629 		break;
7630 	case HAL_DEF_DBG_DIS_PWT:
7631 		*(u8 *)value = hal_data->bDisableTXPowerTraining;
7632 		break;
7633 	case HAL_DEF_EXPLICIT_BEAMFORMER:
7634 	case HAL_DEF_EXPLICIT_BEAMFORMEE:
7635 	case HAL_DEF_VHT_MU_BEAMFORMER:
7636 	case HAL_DEF_VHT_MU_BEAMFORMEE:
7637 		*(u8 *)value = _FALSE;
7638 		break;
7639 #ifdef CONFIG_BEAMFORMING
7640 	case HAL_DEF_BEAMFORMER_CAP:
7641 		*(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
7642 		break;
7643 	case HAL_DEF_BEAMFORMEE_CAP:
7644 		*(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
7645 		break;
7646 #endif
7647 	default:
7648 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
7649 		bResult = _FAIL;
7650 		break;
7651 	}
7652 
7653 	return bResult;
7654 }
7655 
SetHalODMVar(PADAPTER Adapter,HAL_ODM_VARIABLE eVariable,PVOID pValue1,BOOLEAN bSet)7656 void SetHalODMVar(
7657 	PADAPTER				Adapter,
7658 	HAL_ODM_VARIABLE		eVariable,
7659 	PVOID					pValue1,
7660 	BOOLEAN					bSet)
7661 {
7662 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
7663 	PDM_ODM_T podmpriv = &pHalData->odmpriv;
7664 	/* _irqL irqL; */
7665 	switch (eVariable) {
7666 	case HAL_ODM_STA_INFO: {
7667 		struct sta_info *psta = (struct sta_info *)pValue1;
7668 		if (bSet) {
7669 			RTW_INFO("### Set STA_(%d) info ###\n", psta->mac_id);
7670 			ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta);
7671 		} else {
7672 			RTW_INFO("### Clean STA_(%d) info ###\n", psta->mac_id);
7673 			/* _enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL); */
7674 			ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL);
7675 
7676 			/* _exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL); */
7677 		}
7678 	}
7679 	break;
7680 	case HAL_ODM_P2P_STATE:
7681 		ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
7682 		break;
7683 	case HAL_ODM_WIFI_DISPLAY_STATE:
7684 		ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
7685 		break;
7686 	case HAL_ODM_REGULATION:
7687 		ODM_CmnInfoInit(podmpriv, ODM_CMNINFO_DOMAIN_CODE_2G, pHalData->Regulation2_4G);
7688 		ODM_CmnInfoInit(podmpriv, ODM_CMNINFO_DOMAIN_CODE_5G, pHalData->Regulation5G);
7689 		break;
7690 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
7691 	case HAL_ODM_NOISE_MONITOR: {
7692 		struct noise_info *pinfo = (struct noise_info *)pValue1;
7693 
7694 #ifdef DBG_NOISE_MONITOR
7695 		RTW_INFO("### Noise monitor chan(%d)-bPauseDIG:%d,IGIValue:0x%02x,max_time:%d (ms) ###\n",
7696 			pinfo->chan, pinfo->bPauseDIG, pinfo->IGIValue, pinfo->max_time);
7697 #endif
7698 
7699 		pHalData->noise[pinfo->chan] = ODM_InbandNoise_Monitor(podmpriv, pinfo->bPauseDIG, pinfo->IGIValue, pinfo->max_time);
7700 		RTW_INFO("chan_%d, noise = %d (dBm)\n", pinfo->chan, pHalData->noise[pinfo->chan]);
7701 #ifdef DBG_NOISE_MONITOR
7702 		RTW_INFO("noise_a = %d, noise_b = %d  noise_all:%d\n",
7703 			 podmpriv->noise_level.noise[ODM_RF_PATH_A],
7704 			 podmpriv->noise_level.noise[ODM_RF_PATH_B],
7705 			 podmpriv->noise_level.noise_all);
7706 #endif
7707 	}
7708 	break;
7709 #endif/*#ifdef CONFIG_BACKGROUND_NOISE_MONITOR*/
7710 
7711 	case HAL_ODM_INITIAL_GAIN: {
7712 		u8 rx_gain = *((u8 *)(pValue1));
7713 		/*printk("rx_gain:%x\n",rx_gain);*/
7714 		if (rx_gain == 0xff) {/*restore rx gain*/
7715 			/*ODM_Write_DIG(podmpriv,pDigTable->BackupIGValue);*/
7716 			odm_PauseDIG(podmpriv, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, rx_gain);
7717 		} else {
7718 			/*pDigTable->BackupIGValue = pDigTable->CurIGValue;*/
7719 			/*ODM_Write_DIG(podmpriv,rx_gain);*/
7720 			odm_PauseDIG(podmpriv, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, rx_gain);
7721 		}
7722 	}
7723 	break;
7724 	case HAL_ODM_FA_CNT_DUMP:
7725 		if (*((u8 *)pValue1))
7726 			podmpriv->DebugComponents |= (ODM_COMP_DIG | ODM_COMP_FA_CNT);
7727 		else
7728 			podmpriv->DebugComponents &= ~(ODM_COMP_DIG | ODM_COMP_FA_CNT);
7729 		break;
7730 	case HAL_ODM_DBG_FLAG:
7731 		ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_DBG_COMP, *((u8Byte *)pValue1));
7732 		break;
7733 	case HAL_ODM_DBG_LEVEL:
7734 		ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_DBG_LEVEL, *((u4Byte *)pValue1));
7735 		break;
7736 	case HAL_ODM_RX_INFO_DUMP: {
7737 		PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure(podmpriv , PHYDM_FALSEALMCNT);
7738 		pDIG_T	pDM_DigTable = &podmpriv->DM_DigTable;
7739 		void *sel;
7740 
7741 		sel = pValue1;
7742 
7743 		_RTW_PRINT_SEL(sel , "============ Rx Info dump ===================\n");
7744 		_RTW_PRINT_SEL(sel , "bLinked = %d, RSSI_Min = %d(%%), CurrentIGI = 0x%x\n", podmpriv->bLinked, podmpriv->RSSI_Min, pDM_DigTable->CurIGValue);
7745 		_RTW_PRINT_SEL(sel , "Cnt_Cck_fail = %d, Cnt_Ofdm_fail = %d, Total False Alarm = %d\n", FalseAlmCnt->Cnt_Cck_fail, FalseAlmCnt->Cnt_Ofdm_fail, FalseAlmCnt->Cnt_all);
7746 
7747 		if (podmpriv->bLinked) {
7748 			_RTW_PRINT_SEL(sel , "RxRate = %s", HDATA_RATE(podmpriv->RxRate));
7749 			_RTW_PRINT_SEL(sel , " RSSI_A = %d(%%), RSSI_B = %d(%%)\n", podmpriv->RSSI_A, podmpriv->RSSI_B);
7750 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
7751 			rtw_dump_raw_rssi_info(Adapter, sel);
7752 #endif
7753 		}
7754 	}
7755 	break;
7756 	case HAL_ODM_RX_Dframe_INFO: {
7757 		void *sel;
7758 
7759 		sel = pValue1;
7760 
7761 		/*_RTW_PRINT_SEL(sel , "HAL_ODM_RX_Dframe_INFO\n");*/
7762 #ifdef DBG_RX_DFRAME_RAW_DATA
7763 		rtw_dump_rx_dframe_info(Adapter, sel);
7764 #endif
7765 	}
7766 	break;
7767 
7768 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
7769 	case HAL_ODM_AUTO_CHNL_SEL: {
7770 		ACS_OP	acs_op = *(ACS_OP *)pValue1;
7771 
7772 		rtw_phydm_func_set(Adapter, ODM_BB_NHM_CNT);
7773 
7774 		if (ACS_INIT == acs_op) {
7775 #ifdef DBG_AUTO_CHNL_SEL_NHM
7776 			RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_INIT\n", ADPT_ARG(Adapter));
7777 #endif
7778 			odm_AutoChannelSelectInit(podmpriv);
7779 		} else if (ACS_RESET == acs_op) {
7780 			/* Reset statistics for auto channel selection mechanism.*/
7781 #ifdef DBG_AUTO_CHNL_SEL_NHM
7782 			RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_RESET\n", ADPT_ARG(Adapter));
7783 #endif
7784 			odm_AutoChannelSelectReset(podmpriv);
7785 
7786 		} else if (ACS_SELECT == acs_op) {
7787 			/* Collect NHM measurement result after current channel */
7788 #ifdef DBG_AUTO_CHNL_SEL_NHM
7789 			RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_SELECT, CH(%d)\n", ADPT_ARG(Adapter), rtw_get_acs_channel(Adapter));
7790 #endif
7791 			odm_AutoChannelSelect(podmpriv, rtw_get_acs_channel(Adapter));
7792 		} else
7793 			RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: Unexpected OP\n", ADPT_ARG(Adapter));
7794 
7795 	}
7796 	break;
7797 #endif
7798 #ifdef CONFIG_ANTENNA_DIVERSITY
7799 	case HAL_ODM_ANTDIV_SELECT: {
7800 		u8	antenna = (*(u8 *)pValue1);
7801 
7802 		/*switch antenna*/
7803 		ODM_UpdateRxIdleAnt(&pHalData->odmpriv, antenna);
7804 		/*RTW_INFO("==> HAL_ODM_ANTDIV_SELECT, Ant_(%s)\n", (antenna == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT");*/
7805 
7806 	}
7807 	break;
7808 #endif
7809 
7810 	default:
7811 		break;
7812 	}
7813 }
7814 
GetHalODMVar(PADAPTER Adapter,HAL_ODM_VARIABLE eVariable,PVOID pValue1,PVOID pValue2)7815 void GetHalODMVar(
7816 	PADAPTER				Adapter,
7817 	HAL_ODM_VARIABLE		eVariable,
7818 	PVOID					pValue1,
7819 	PVOID					pValue2)
7820 {
7821 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
7822 	PDM_ODM_T podmpriv = &pHalData->odmpriv;
7823 
7824 	switch (eVariable) {
7825 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
7826 	case HAL_ODM_NOISE_MONITOR: {
7827 		u8 chan = *(u8 *)pValue1;
7828 		*(s16 *)pValue2 = pHalData->noise[chan];
7829 #ifdef DBG_NOISE_MONITOR
7830 		RTW_INFO("### Noise monitor chan(%d)-noise:%d (dBm) ###\n",
7831 			 chan, pHalData->noise[chan]);
7832 #endif
7833 	}
7834 	break;
7835 #endif/*#ifdef CONFIG_BACKGROUND_NOISE_MONITOR*/
7836 	case HAL_ODM_DBG_FLAG:
7837 		*((u8Byte *)pValue1) = podmpriv->DebugComponents;
7838 		break;
7839 	case HAL_ODM_DBG_LEVEL:
7840 		*((u4Byte *)pValue1) = podmpriv->DebugLevel;
7841 		break;
7842 
7843 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
7844 	case HAL_ODM_AUTO_CHNL_SEL: {
7845 #ifdef DBG_AUTO_CHNL_SEL_NHM
7846 		RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: GET_BEST_CHAN\n", ADPT_ARG(Adapter));
7847 #endif
7848 		/* Retrieve better channel from NHM mechanism	*/
7849 		if (IsSupported24G(Adapter->registrypriv.wireless_mode))
7850 			*((u8 *)(pValue1)) = ODM_GetAutoChannelSelectResult(podmpriv, BAND_ON_2_4G);
7851 		if (IsSupported5G(Adapter->registrypriv.wireless_mode))
7852 			*((u8 *)(pValue2)) = ODM_GetAutoChannelSelectResult(podmpriv, BAND_ON_5G);
7853 	}
7854 	break;
7855 #endif
7856 #ifdef CONFIG_ANTENNA_DIVERSITY
7857 	case HAL_ODM_ANTDIV_SELECT: {
7858 		pFAT_T	pDM_FatTable = &podmpriv->DM_FatTable;
7859 		*((u8 *)pValue1) = pDM_FatTable->RxIdleAnt;
7860 	}
7861 	break;
7862 #endif
7863 	case HAL_ODM_INITIAL_GAIN: {
7864 		pDIG_T pDM_DigTable = &podmpriv->DM_DigTable;
7865 		*((u8 *)pValue1) = pDM_DigTable->CurIGValue;
7866 	}
7867 	break;
7868 	default:
7869 		break;
7870 	}
7871 }
7872 
7873 
rtw_phydm_ability_ops(_adapter * adapter,HAL_PHYDM_OPS ops,u32 ability)7874 u32 rtw_phydm_ability_ops(_adapter *adapter, HAL_PHYDM_OPS ops, u32 ability)
7875 {
7876 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
7877 	PDM_ODM_T podmpriv = &pHalData->odmpriv;
7878 	u32 result = 0;
7879 
7880 	switch (ops) {
7881 	case HAL_PHYDM_DIS_ALL_FUNC:
7882 		podmpriv->SupportAbility = DYNAMIC_FUNC_DISABLE;
7883 		break;
7884 	case HAL_PHYDM_FUNC_SET:
7885 		podmpriv->SupportAbility |= ability;
7886 		break;
7887 	case HAL_PHYDM_FUNC_CLR:
7888 		podmpriv->SupportAbility &= ~(ability);
7889 		break;
7890 	case HAL_PHYDM_ABILITY_BK:
7891 		/* dm flag backup*/
7892 		podmpriv->BK_SupportAbility = podmpriv->SupportAbility;
7893 		break;
7894 	case HAL_PHYDM_ABILITY_RESTORE:
7895 		/* restore dm flag */
7896 		podmpriv->SupportAbility = podmpriv->BK_SupportAbility;
7897 		break;
7898 	case HAL_PHYDM_ABILITY_SET:
7899 		podmpriv->SupportAbility = ability;
7900 		break;
7901 	case HAL_PHYDM_ABILITY_GET:
7902 		result = podmpriv->SupportAbility;
7903 		break;
7904 	}
7905 	return result;
7906 }
7907 
7908 
7909 BOOLEAN
eqNByte(u8 * str1,u8 * str2,u32 num)7910 eqNByte(
7911 	u8	*str1,
7912 	u8	*str2,
7913 	u32	num
7914 )
7915 {
7916 	if (num == 0)
7917 		return _FALSE;
7918 	while (num > 0) {
7919 		num--;
7920 		if (str1[num] != str2[num])
7921 			return _FALSE;
7922 	}
7923 	return _TRUE;
7924 }
7925 
7926 /*
7927  *	Description:
7928  *		Translate a character to hex digit.
7929  *   */
7930 u32
MapCharToHexDigit(IN char chTmp)7931 MapCharToHexDigit(
7932 	IN		char		chTmp
7933 )
7934 {
7935 	if (chTmp >= '0' && chTmp <= '9')
7936 		return chTmp - '0';
7937 	else if (chTmp >= 'a' && chTmp <= 'f')
7938 		return 10 + (chTmp - 'a');
7939 	else if (chTmp >= 'A' && chTmp <= 'F')
7940 		return 10 + (chTmp - 'A');
7941 	else
7942 		return 0;
7943 }
7944 
7945 
7946 
7947 /*
7948  *	Description:
7949  *		Parse hex number from the string pucStr.
7950  *   */
7951 BOOLEAN
GetHexValueFromString(IN char * szStr,IN OUT u32 * pu4bVal,IN OUT u32 * pu4bMove)7952 GetHexValueFromString(
7953 	IN		char			*szStr,
7954 	IN OUT	u32			*pu4bVal,
7955 	IN OUT	u32			*pu4bMove
7956 )
7957 {
7958 	char		*szScan = szStr;
7959 
7960 	/* Check input parameter. */
7961 	if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
7962 		RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
7963 		return _FALSE;
7964 	}
7965 
7966 	/* Initialize output. */
7967 	*pu4bMove = 0;
7968 	*pu4bVal = 0;
7969 
7970 	/* Skip leading space. */
7971 	while (*szScan != '\0' &&
7972 	       (*szScan == ' ' || *szScan == '\t')) {
7973 		szScan++;
7974 		(*pu4bMove)++;
7975 	}
7976 
7977 	/* Skip leading '0x' or '0X'. */
7978 	if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
7979 		szScan += 2;
7980 		(*pu4bMove) += 2;
7981 	}
7982 
7983 	/* Check if szScan is now pointer to a character for hex digit, */
7984 	/* if not, it means this is not a valid hex number. */
7985 	if (!IsHexDigit(*szScan))
7986 		return _FALSE;
7987 
7988 	/* Parse each digit. */
7989 	do {
7990 		(*pu4bVal) <<= 4;
7991 		*pu4bVal += MapCharToHexDigit(*szScan);
7992 
7993 		szScan++;
7994 		(*pu4bMove)++;
7995 	} while (IsHexDigit(*szScan));
7996 
7997 	return _TRUE;
7998 }
7999 
8000 BOOLEAN
GetFractionValueFromString(IN char * szStr,IN OUT u8 * pInteger,IN OUT u8 * pFraction,IN OUT u32 * pu4bMove)8001 GetFractionValueFromString(
8002 	IN		char			*szStr,
8003 	IN OUT	u8				*pInteger,
8004 	IN OUT	u8				*pFraction,
8005 	IN OUT	u32			*pu4bMove
8006 )
8007 {
8008 	char	*szScan = szStr;
8009 
8010 	/* Initialize output. */
8011 	*pu4bMove = 0;
8012 	*pInteger = 0;
8013 	*pFraction = 0;
8014 
8015 	/* Skip leading space. */
8016 	while (*szScan != '\0' &&	(*szScan == ' ' || *szScan == '\t')) {
8017 		++szScan;
8018 		++(*pu4bMove);
8019 	}
8020 
8021 	/* Parse each digit. */
8022 	do {
8023 		(*pInteger) *= 10;
8024 		*pInteger += (*szScan - '0');
8025 
8026 		++szScan;
8027 		++(*pu4bMove);
8028 
8029 		if (*szScan == '.') {
8030 			++szScan;
8031 			++(*pu4bMove);
8032 
8033 			if (*szScan < '0' || *szScan > '9')
8034 				return _FALSE;
8035 			else {
8036 				*pFraction = *szScan - '0';
8037 				++szScan;
8038 				++(*pu4bMove);
8039 				return _TRUE;
8040 			}
8041 		}
8042 	} while (*szScan >= '0' && *szScan <= '9');
8043 
8044 	return _TRUE;
8045 }
8046 
8047 /*
8048  *	Description:
8049  * Return TRUE if szStr is comment out with leading " */ /* ".
8050  *   */
8051 BOOLEAN
IsCommentString(IN char * szStr)8052 IsCommentString(
8053 	IN		char			*szStr
8054 )
8055 {
8056 	if (*szStr == '/' && *(szStr + 1) == '/')
8057 		return _TRUE;
8058 	else
8059 		return _FALSE;
8060 }
8061 
8062 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(IN char * Str,IN OUT u8 * pInt)8063 GetU1ByteIntegerFromStringInDecimal(
8064 	IN		char	*Str,
8065 	IN OUT	u8		*pInt
8066 )
8067 {
8068 	u16 i = 0;
8069 	*pInt = 0;
8070 
8071 	while (Str[i] != '\0') {
8072 		if (Str[i] >= '0' && Str[i] <= '9') {
8073 			*pInt *= 10;
8074 			*pInt += (Str[i] - '0');
8075 		} else
8076 			return _FALSE;
8077 		++i;
8078 	}
8079 
8080 	return _TRUE;
8081 }
8082 
8083 /* <20121004, Kordan> For example,
8084  * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
8085  * If RightQualifier does not exist, it will hang on in the while loop */
8086 BOOLEAN
ParseQualifiedString(IN char * In,IN OUT u32 * Start,OUT char * Out,IN char LeftQualifier,IN char RightQualifier)8087 ParseQualifiedString(
8088 	IN		char	*In,
8089 	IN OUT	u32	*Start,
8090 	OUT		char	*Out,
8091 	IN		char		LeftQualifier,
8092 	IN		char		RightQualifier
8093 )
8094 {
8095 	u32	i = 0, j = 0;
8096 	char	c = In[(*Start)++];
8097 
8098 	if (c != LeftQualifier)
8099 		return _FALSE;
8100 
8101 	i = (*Start);
8102 	while ((c = In[(*Start)++]) != RightQualifier)
8103 		; /* find ']' */
8104 	j = (*Start) - 2;
8105 	strncpy((char *)Out, (const char *)(In + i), j - i + 1);
8106 
8107 	return _TRUE;
8108 }
8109 
8110 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)8111 isAllSpaceOrTab(
8112 	u8	*data,
8113 	u8	size
8114 )
8115 {
8116 	u8	cnt = 0, NumOfSpaceAndTab = 0;
8117 
8118 	while (size > cnt) {
8119 		if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
8120 			++NumOfSpaceAndTab;
8121 
8122 		++cnt;
8123 	}
8124 
8125 	return size == NumOfSpaceAndTab;
8126 }
8127 
8128 
rtw_hal_check_rxfifo_full(_adapter * adapter)8129 void rtw_hal_check_rxfifo_full(_adapter *adapter)
8130 {
8131 	struct dvobj_priv *psdpriv = adapter->dvobj;
8132 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
8133 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
8134 	struct registry_priv *regsty = &adapter->registrypriv;
8135 	int save_cnt = _FALSE;
8136 
8137 	if (regsty->check_hw_status == 1) {
8138 		/* switch counter to RX fifo */
8139 		if (IS_8188E(pHalData->VersionID) ||
8140 		    IS_8188F(pHalData->VersionID) ||
8141 		    IS_8812_SERIES(pHalData->VersionID) ||
8142 		    IS_8821_SERIES(pHalData->VersionID) ||
8143 		    IS_8723B_SERIES(pHalData->VersionID) ||
8144 		    IS_8192E(pHalData->VersionID) ||
8145 		    IS_8703B_SERIES(pHalData->VersionID) ||
8146 		    IS_8723D_SERIES(pHalData->VersionID)) {
8147 			rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
8148 			save_cnt = _TRUE;
8149 		} else {
8150 			/* todo: other chips */
8151 		}
8152 
8153 
8154 		if (save_cnt) {
8155 			pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
8156 			pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
8157 			pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
8158 		} else {
8159 			/* special value to indicate no implementation */
8160 			pdbgpriv->dbg_rx_fifo_last_overflow = 1;
8161 			pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
8162 			pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
8163 		}
8164 	}
8165 }
8166 
linked_info_dump(_adapter * padapter,u8 benable)8167 void linked_info_dump(_adapter *padapter, u8 benable)
8168 {
8169 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
8170 
8171 	if (padapter->bLinkInfoDump == benable)
8172 		return;
8173 
8174 	RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
8175 
8176 	if (benable) {
8177 #ifdef CONFIG_LPS
8178 		pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
8179 		rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
8180 #endif
8181 
8182 #ifdef CONFIG_IPS
8183 		pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
8184 		rtw_pm_set_ips(padapter, IPS_NONE);
8185 #endif
8186 	} else {
8187 #ifdef CONFIG_IPS
8188 		rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
8189 #endif /* CONFIG_IPS */
8190 
8191 #ifdef CONFIG_LPS
8192 		rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
8193 #endif /* CONFIG_LPS */
8194 	}
8195 	padapter->bLinkInfoDump = benable ;
8196 }
8197 
8198 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)8199 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
8200 {
8201 	u8 isCCKrate, rf_path;
8202 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
8203 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
8204 	RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
8205 		HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
8206 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
8207 
8208 	if (isCCKrate)
8209 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
8210 
8211 	for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
8212 		RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
8213 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
8214 
8215 		if (!isCCKrate) {
8216 			RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
8217 				psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
8218 		}
8219 	}
8220 }
8221 
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)8222 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
8223 {
8224 	u8 isCCKrate, rf_path;
8225 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
8226 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
8227 	_RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
8228 	_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);
8229 
8230 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
8231 
8232 	if (isCCKrate)
8233 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
8234 
8235 	for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
8236 		_RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
8237 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
8238 
8239 		if (!isCCKrate)
8240 			_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]);
8241 		else
8242 			_RTW_PRINT_SEL(sel , "\n");
8243 
8244 	}
8245 }
8246 #endif
8247 
8248 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)8249 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
8250 {
8251 	_irqL irqL;
8252 	u8 isCCKrate, rf_path;
8253 	struct recv_priv *precvpriv = &(padapter->recvpriv);
8254 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
8255 	struct sta_priv *pstapriv = &padapter->stapriv;
8256 	struct sta_info *psta;
8257 	struct sta_recv_dframe_info *psta_dframe_info;
8258 	int i;
8259 	_list	*plist, *phead;
8260 	char *BW;
8261 	u8 bc_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8262 	u8 null_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
8263 
8264 	if (precvpriv->store_law_data_flag) {
8265 
8266 		_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
8267 
8268 		for (i = 0; i < NUM_STA; i++) {
8269 			phead = &(pstapriv->sta_hash[i]);
8270 			plist = get_next(phead);
8271 
8272 			while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
8273 
8274 				psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
8275 				plist = get_next(plist);
8276 
8277 				if (psta) {
8278 					psta_dframe_info = &psta->sta_dframe_info;
8279 					if ((_rtw_memcmp(psta->hwaddr, bc_addr, 6)  !=   _TRUE)
8280 					    && (_rtw_memcmp(psta->hwaddr, null_addr, 6)  !=  _TRUE)
8281 					    && (_rtw_memcmp(psta->hwaddr, adapter_mac_addr(padapter), 6)  !=  _TRUE)) {
8282 
8283 
8284 						isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
8285 
8286 						switch (psta_dframe_info->sta_bw_mode) {
8287 
8288 						case CHANNEL_WIDTH_20:
8289 							BW = "20M";
8290 							break;
8291 
8292 						case CHANNEL_WIDTH_40:
8293 							BW = "40M";
8294 							break;
8295 
8296 						case CHANNEL_WIDTH_80:
8297 							BW = "80M";
8298 							break;
8299 
8300 						case CHANNEL_WIDTH_160:
8301 							BW = "160M";
8302 							break;
8303 
8304 						default:
8305 							BW = "";
8306 							break;
8307 						}
8308 
8309 						RTW_PRINT_SEL(sel, "==============================\n");
8310 						_RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
8311 						_RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", BW, psta_dframe_info->sta_sgi);
8312 						_RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
8313 
8314 						for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
8315 
8316 							if (!isCCKrate) {
8317 
8318 								_RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
8319 								_RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
8320 
8321 							} else
8322 
8323 								_RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
8324 						}
8325 					}
8326 				}
8327 			}
8328 		}
8329 		_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
8330 	}
8331 }
8332 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)8333 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
8334 {
8335 	u8 isCCKrate, rf_path , dframe_type;
8336 	u8 *ptr;
8337 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8338 #ifdef DBG_RX_DFRAME_RAW_DATA
8339 	struct sta_recv_dframe_info *psta_dframe_info;
8340 #endif
8341 	struct recv_priv *precvpriv = &(padapter->recvpriv);
8342 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
8343 	struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
8344 	struct sta_info *psta = prframe->u.hdr.psta;
8345 	PODM_PHY_INFO_T pPhyInfo  = (PODM_PHY_INFO_T)(&pattrib->phy_info);
8346 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
8347 	psample_pkt_rssi->data_rate = pattrib->data_rate;
8348 	ptr = prframe->u.hdr.rx_data;
8349 	dframe_type = GetFrameType(ptr);
8350 	/*RTW_INFO("=>%s\n", __FUNCTION__);*/
8351 
8352 
8353 	if (precvpriv->store_law_data_flag) {
8354 		isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
8355 
8356 		psample_pkt_rssi->pwdball = pPhyInfo->RxPWDBAll;
8357 		psample_pkt_rssi->pwr_all = pPhyInfo->RecvSignalPower;
8358 
8359 		for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
8360 			psample_pkt_rssi->mimo_signal_strength[rf_path] = pPhyInfo->RxMIMOSignalStrength[rf_path];
8361 			psample_pkt_rssi->mimo_signal_quality[rf_path] = pPhyInfo->RxMIMOSignalQuality[rf_path];
8362 			if (!isCCKrate) {
8363 				psample_pkt_rssi->ofdm_pwr[rf_path] = pPhyInfo->RxPwr[rf_path];
8364 				psample_pkt_rssi->ofdm_snr[rf_path] = pPhyInfo->RxSNR[rf_path];
8365 			}
8366 		}
8367 #ifdef DBG_RX_DFRAME_RAW_DATA
8368 		if (dframe_type == WIFI_DATA_TYPE  || dframe_type == WIFI_QOS_DATA_TYPE) {
8369 
8370 			/*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
8371 			if (psta) {
8372 				psta_dframe_info = &psta->sta_dframe_info;
8373 				/*RTW_INFO("=>%s psta->hwaddr="MAC_FMT" !\n", __FUNCTION__, MAC_ARG(psta->hwaddr));*/
8374 				if (_rtw_memcmp(psta->hwaddr, bc_addr, ETH_ALEN)  !=  _TRUE) {
8375 
8376 					psta_dframe_info->sta_data_rate = pattrib->data_rate;
8377 					psta_dframe_info->sta_sgi = pattrib->sgi;
8378 					psta_dframe_info->sta_bw_mode = pattrib->bw;
8379 					for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
8380 
8381 						psta_dframe_info->sta_mimo_signal_strength[rf_path] = (pPhyInfo->RxMIMOSignalStrength[rf_path]);/*Percentage to dbm*/
8382 
8383 						if (!isCCKrate) {
8384 							psta_dframe_info->sta_ofdm_snr[rf_path] = pPhyInfo->RxSNR[rf_path];
8385 							psta_dframe_info->sta_RxPwr[rf_path] = pPhyInfo->RxPwr[rf_path];
8386 						}
8387 					}
8388 				}
8389 			}
8390 		}
8391 #endif
8392 	}
8393 
8394 }
8395 
8396 
check_phy_efuse_tx_power_info_valid(PADAPTER padapter)8397 int check_phy_efuse_tx_power_info_valid(PADAPTER padapter)
8398 {
8399 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
8400 	u8 *pContent = pHalData->efuse_eeprom_data;
8401 	int index = 0;
8402 	u16 tx_index_offset = 0x0000;
8403 
8404 	switch (rtw_get_chip_type(padapter)) {
8405 	case RTL8723B:
8406 		tx_index_offset = EEPROM_TX_PWR_INX_8723B;
8407 		break;
8408 	case RTL8703B:
8409 		tx_index_offset = EEPROM_TX_PWR_INX_8703B;
8410 		break;
8411 	case RTL8723D:
8412 		tx_index_offset = EEPROM_TX_PWR_INX_8723D;
8413 		break;
8414 	case RTL8188E:
8415 		tx_index_offset = EEPROM_TX_PWR_INX_88E;
8416 		break;
8417 	case RTL8188F:
8418 		tx_index_offset = EEPROM_TX_PWR_INX_8188F;
8419 		break;
8420 	case RTL8192E:
8421 		tx_index_offset = EEPROM_TX_PWR_INX_8192E;
8422 		break;
8423 	case RTL8821:
8424 		tx_index_offset = EEPROM_TX_PWR_INX_8821;
8425 		break;
8426 	case RTL8812:
8427 		tx_index_offset = EEPROM_TX_PWR_INX_8812;
8428 		break;
8429 	case RTL8814A:
8430 		tx_index_offset = EEPROM_TX_PWR_INX_8814;
8431 		break;
8432 	case RTL8822B:
8433 		tx_index_offset = EEPROM_TX_PWR_INX_8822B;
8434 		break;
8435 	case RTL8821C:
8436 		tx_index_offset = EEPROM_TX_PWR_INX_8821C;
8437 		break;
8438 	default:
8439 		tx_index_offset = 0x0010;
8440 		break;
8441 	}
8442 
8443 	/* TODO: chacking length by ICs */
8444 	for (index = 0 ; index < 11 ; index++) {
8445 		if (pContent[tx_index_offset + index] == 0xFF)
8446 			return _FALSE;
8447 	}
8448 	return _TRUE;
8449 }
8450 
hal_efuse_macaddr_offset(_adapter * adapter)8451 int hal_efuse_macaddr_offset(_adapter *adapter)
8452 {
8453 	u8 interface_type = 0;
8454 	int addr_offset = -1;
8455 
8456 	interface_type = rtw_get_intf_type(adapter);
8457 
8458 	switch (rtw_get_chip_type(adapter)) {
8459 #ifdef CONFIG_RTL8723B
8460 	case RTL8723B:
8461 		if (interface_type == RTW_USB)
8462 			addr_offset = EEPROM_MAC_ADDR_8723BU;
8463 		else if (interface_type == RTW_SDIO)
8464 			addr_offset = EEPROM_MAC_ADDR_8723BS;
8465 		else if (interface_type == RTW_PCIE)
8466 			addr_offset = EEPROM_MAC_ADDR_8723BE;
8467 		break;
8468 #endif
8469 #ifdef CONFIG_RTL8703B
8470 	case RTL8703B:
8471 		if (interface_type == RTW_USB)
8472 			addr_offset = EEPROM_MAC_ADDR_8703BU;
8473 		else if (interface_type == RTW_SDIO)
8474 			addr_offset = EEPROM_MAC_ADDR_8703BS;
8475 		break;
8476 #endif
8477 #ifdef CONFIG_RTL8723D
8478 	case RTL8723D:
8479 		if (interface_type == RTW_USB)
8480 			addr_offset = EEPROM_MAC_ADDR_8723DU;
8481 		else if (interface_type == RTW_SDIO)
8482 			addr_offset = EEPROM_MAC_ADDR_8723DS;
8483 		else if (interface_type == RTW_PCIE)
8484 			addr_offset = EEPROM_MAC_ADDR_8723DE;
8485 		break;
8486 #endif
8487 
8488 #ifdef CONFIG_RTL8188E
8489 	case RTL8188E:
8490 		if (interface_type == RTW_USB)
8491 			addr_offset = EEPROM_MAC_ADDR_88EU;
8492 		else if (interface_type == RTW_SDIO)
8493 			addr_offset = EEPROM_MAC_ADDR_88ES;
8494 		else if (interface_type == RTW_PCIE)
8495 			addr_offset = EEPROM_MAC_ADDR_88EE;
8496 		break;
8497 #endif
8498 #ifdef CONFIG_RTL8188F
8499 	case RTL8188F:
8500 		if (interface_type == RTW_USB)
8501 			addr_offset = EEPROM_MAC_ADDR_8188FU;
8502 		else if (interface_type == RTW_SDIO)
8503 			addr_offset = EEPROM_MAC_ADDR_8188FS;
8504 		break;
8505 #endif
8506 #ifdef CONFIG_RTL8812A
8507 	case RTL8812:
8508 		if (interface_type == RTW_USB)
8509 			addr_offset = EEPROM_MAC_ADDR_8812AU;
8510 		else if (interface_type == RTW_PCIE)
8511 			addr_offset = EEPROM_MAC_ADDR_8812AE;
8512 		break;
8513 #endif
8514 #ifdef CONFIG_RTL8821A
8515 	case RTL8821:
8516 		if (interface_type == RTW_USB)
8517 			addr_offset = EEPROM_MAC_ADDR_8821AU;
8518 		else if (interface_type == RTW_SDIO)
8519 			addr_offset = EEPROM_MAC_ADDR_8821AS;
8520 		else if (interface_type == RTW_PCIE)
8521 			addr_offset = EEPROM_MAC_ADDR_8821AE;
8522 		break;
8523 #endif
8524 #ifdef CONFIG_RTL8192E
8525 	case RTL8192E:
8526 		if (interface_type == RTW_USB)
8527 			addr_offset = EEPROM_MAC_ADDR_8192EU;
8528 		else if (interface_type == RTW_SDIO)
8529 			addr_offset = EEPROM_MAC_ADDR_8192ES;
8530 		else if (interface_type == RTW_PCIE)
8531 			addr_offset = EEPROM_MAC_ADDR_8192EE;
8532 		break;
8533 #endif
8534 #ifdef CONFIG_RTL8814A
8535 	case RTL8814A:
8536 		if (interface_type == RTW_USB)
8537 			addr_offset = EEPROM_MAC_ADDR_8814AU;
8538 		else if (interface_type == RTW_PCIE)
8539 			addr_offset = EEPROM_MAC_ADDR_8814AE;
8540 		break;
8541 #endif
8542 
8543 #ifdef CONFIG_RTL8822B
8544 	case RTL8822B:
8545 		if (interface_type == RTW_USB)
8546 			addr_offset = EEPROM_MAC_ADDR_8822BU;
8547 		else if (interface_type == RTW_SDIO)
8548 			addr_offset = EEPROM_MAC_ADDR_8822BS;
8549 		else if (interface_type == RTW_PCIE)
8550 			addr_offset = EEPROM_MAC_ADDR_8822BE;
8551 		break;
8552 #endif /* CONFIG_RTL8822B */
8553 
8554 #ifdef CONFIG_RTL8821C
8555 	case RTL8821C:
8556 		if (interface_type == RTW_USB)
8557 			addr_offset = EEPROM_MAC_ADDR_8821CU;
8558 		else if (interface_type == RTW_SDIO)
8559 			addr_offset = EEPROM_MAC_ADDR_8821CS;
8560 		else if (interface_type == RTW_PCIE)
8561 			addr_offset = EEPROM_MAC_ADDR_8821CE;
8562 		break;
8563 #endif /* CONFIG_RTL8821C */
8564 	}
8565 
8566 	if (addr_offset == -1) {
8567 		RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
8568 			, __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
8569 	}
8570 
8571 	return addr_offset;
8572 }
8573 
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)8574 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
8575 {
8576 	int ret = _FAIL;
8577 	int addr_offset;
8578 
8579 	addr_offset = hal_efuse_macaddr_offset(padapter);
8580 	if (addr_offset == -1)
8581 		goto exit;
8582 
8583 	ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
8584 
8585 exit:
8586 	return ret;
8587 }
8588 
rtw_dump_cur_efuse(PADAPTER padapter)8589 void rtw_dump_cur_efuse(PADAPTER padapter)
8590 {
8591 	int i =0;
8592 	int mapsize =0;
8593 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
8594 
8595 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
8596 
8597 	if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
8598 		RTW_INFO("wrong map size %d\n", mapsize);
8599 		return;
8600 	}
8601 
8602 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
8603 		RTW_INFO("Use EFUSE FILE\n");
8604 	else
8605 		RTW_INFO("HW EFUSE\n");
8606 
8607 #ifdef CONFIG_RTW_DEBUG
8608 #ifdef PLATFORM_LINUX
8609 		RTW_INFO("eFuse Content:\n");
8610 		print_hex_dump(KERN_DEBUG, "eFuse ",
8611 				   DUMP_PREFIX_OFFSET, 16, 1,
8612 				   hal_data->efuse_eeprom_data, mapsize, false);
8613 #endif /* PLATFORM_LINUX */
8614 #endif /* CONFIG_RTW_DEBUG */
8615 }
8616 
8617 
8618 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)8619 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
8620 {
8621 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
8622 	u32 ret = _FALSE;
8623 	u32 maplen = 0;
8624 
8625 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
8626 
8627 	if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
8628 		RTW_ERR("eFuse length error :%d\n", maplen);
8629 		return _FALSE;
8630 	}
8631 
8632 	ret = rtw_efuse_file_read(padapter, EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
8633 	if (ret == _FALSE)
8634 		ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data);
8635 
8636 	hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
8637 
8638 	return ret;
8639 }
8640 
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)8641 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
8642 {
8643 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
8644 	u32 ret = _FAIL;
8645 
8646 	if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
8647 	    && rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
8648 	   ) {
8649 		hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
8650 		ret = _SUCCESS;
8651 	} else
8652 		hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
8653 
8654 	return ret;
8655 }
8656 #endif /* CONFIG_EFUSE_CONFIG_FILE */
8657 
hal_config_macaddr(_adapter * adapter,bool autoload_fail)8658 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
8659 {
8660 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
8661 	u8 addr[ETH_ALEN];
8662 	int addr_offset = hal_efuse_macaddr_offset(adapter);
8663 	u8 *hw_addr = NULL;
8664 	int ret = _SUCCESS;
8665 
8666 	if (autoload_fail)
8667 		goto bypass_hw_pg;
8668 
8669 	if (addr_offset != -1)
8670 		hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
8671 
8672 #ifdef CONFIG_EFUSE_CONFIG_FILE
8673 	/* if the hw_addr is written by efuse file, set to NULL */
8674 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
8675 		hw_addr = NULL;
8676 #endif
8677 
8678 	if (!hw_addr) {
8679 		/* try getting hw pg data */
8680 		if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
8681 			hw_addr = addr;
8682 	}
8683 
8684 	/* check hw pg data */
8685 	if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
8686 		_rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
8687 		goto exit;
8688 	}
8689 
8690 bypass_hw_pg:
8691 
8692 #ifdef CONFIG_EFUSE_CONFIG_FILE
8693 	/* check wifi mac file */
8694 	if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
8695 		_rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
8696 		goto exit;
8697 	}
8698 #endif
8699 
8700 	_rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
8701 	ret = _FAIL;
8702 
8703 exit:
8704 	return ret;
8705 }
8706 
8707 #ifdef CONFIG_RF_POWER_TRIM
8708 u32 Array_kfreemap[] = {
8709 	0x08, 0xe,
8710 	0x06, 0xc,
8711 	0x04, 0xa,
8712 	0x02, 0x8,
8713 	0x00, 0x6,
8714 	0x03, 0x4,
8715 	0x05, 0x2,
8716 	0x07, 0x0,
8717 	0x09, 0x0,
8718 	0x0c, 0x0,
8719 };
8720 
rtw_bb_rf_gain_offset(_adapter * padapter)8721 void rtw_bb_rf_gain_offset(_adapter *padapter)
8722 {
8723 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
8724 	struct registry_priv  *registry_par = &padapter->registrypriv;
8725 	struct kfree_data_t *kfree_data = &pHalData->kfree_data;
8726 	u8		value = pHalData->EEPROMRFGainOffset;
8727 	u8		tmp = 0x3e;
8728 	u32		res, i = 0;
8729 	u4Byte		ArrayLen	= sizeof(Array_kfreemap) / sizeof(u32);
8730 	pu4Byte		Array	= Array_kfreemap;
8731 	u4Byte		v1 = 0, v2 = 0, GainValue = 0, target = 0;
8732 
8733 	if (registry_par->RegPwrTrimEnable == 2) {
8734 		RTW_INFO("Registry kfree default force disable.\n");
8735 		return;
8736 	}
8737 
8738 #if defined(CONFIG_RTL8723B)
8739 	if (value & BIT4 || (registry_par->RegPwrTrimEnable == 1)) {
8740 		RTW_INFO("Offset RF Gain.\n");
8741 		RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
8742 
8743 		if (pHalData->EEPROMRFGainVal != 0xff) {
8744 
8745 			if (pHalData->ant_path == ODM_RF_PATH_A)
8746 				GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
8747 
8748 			else
8749 				GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
8750 			RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == ODM_RF_PATH_A) ? (ODM_RF_PATH_A) : (ODM_RF_PATH_B), GainValue);
8751 
8752 			for (i = 0; i < ArrayLen; i += 2) {
8753 				/* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
8754 				v1 = Array[i];
8755 				v2 = Array[i + 1];
8756 				if (v1 == GainValue) {
8757 					RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
8758 					target = v2;
8759 					break;
8760 				}
8761 			}
8762 			RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
8763 
8764 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
8765 			RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
8766 			PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
8767 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
8768 
8769 			RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
8770 
8771 		} else
8772 
8773 			RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x	!= 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
8774 	} else
8775 		RTW_INFO("Using the default RF gain.\n");
8776 
8777 #elif defined(CONFIG_RTL8188E)
8778 	if (value & BIT4 || (registry_par->RegPwrTrimEnable == 1)) {
8779 		RTW_INFO("8188ES Offset RF Gain.\n");
8780 		RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
8781 			 pHalData->EEPROMRFGainVal);
8782 
8783 		if (pHalData->EEPROMRFGainVal != 0xff) {
8784 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
8785 					 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
8786 
8787 			RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
8788 			res &= 0xfff87fff;
8789 
8790 			res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
8791 			RTW_INFO("Offset RF Gain. res=0x%x\n", res);
8792 
8793 			rtw_hal_write_rfreg(padapter, RF_PATH_A,
8794 					    REG_RF_BB_GAIN_OFFSET,
8795 					    RF_GAIN_OFFSET_MASK, res);
8796 		} else {
8797 			RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
8798 				 pHalData->EEPROMRFGainVal);
8799 		}
8800 	} else
8801 		RTW_INFO("Using the default RF gain.\n");
8802 #else
8803 	/* TODO: call this when channel switch */
8804 	if (kfree_data->flag & KFREE_FLAG_ON)
8805 		rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
8806 #endif
8807 
8808 }
8809 #endif /*CONFIG_RF_POWER_TRIM */
8810 
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)8811 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
8812 {
8813 #ifdef CONFIG_RF_POWER_TRIM
8814 	int i, j;
8815 
8816 	for (i = 0; i < BB_GAIN_NUM; i++)
8817 		for (j = 0; j < RF_PATH_MAX; j++)
8818 			if (data->bb_gain[i][j] != 0)
8819 				return 0;
8820 #endif
8821 	return 1;
8822 }
8823 
8824 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)8825 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
8826 {
8827 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
8828 	if (cur_wireless_mode < WIRELESS_11_24N
8829 	    && cur_wireless_mode > 0) { /* ABG mode */
8830 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
8831 		u32 remainder = 0;
8832 		u8 quotient = 0;
8833 
8834 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
8835 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
8836 
8837 		if (quotient > 5) {
8838 			pHalData->rxagg_usb_size = 0x6;
8839 			pHalData->rxagg_usb_timeout = 0x10;
8840 		} else {
8841 			if (remainder >= 2048) {
8842 				pHalData->rxagg_usb_size = quotient;
8843 				pHalData->rxagg_usb_timeout = 0x10;
8844 			} else {
8845 				pHalData->rxagg_usb_size = (quotient - 1);
8846 				pHalData->rxagg_usb_timeout = 0x10;
8847 			}
8848 		}
8849 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
8850 		if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
8851 			pHalData->rxagg_usb_size = 0x6;
8852 			pHalData->rxagg_usb_timeout = 0x10;
8853 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
8854 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
8855 		}
8856 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
8857 
8858 	} else if (cur_wireless_mode >= WIRELESS_11_24N
8859 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
8860 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
8861 		u32 remainder = 0;
8862 		u8 quotient = 0;
8863 
8864 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
8865 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
8866 
8867 		if (quotient > 5) {
8868 			pHalData->rxagg_usb_size = 0x5;
8869 			pHalData->rxagg_usb_timeout = 0x20;
8870 		} else {
8871 			if (remainder >= 2048) {
8872 				pHalData->rxagg_usb_size = quotient;
8873 				pHalData->rxagg_usb_timeout = 0x10;
8874 			} else {
8875 				pHalData->rxagg_usb_size = (quotient - 1);
8876 				pHalData->rxagg_usb_timeout = 0x10;
8877 			}
8878 		}
8879 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
8880 		if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
8881 			pHalData->rxagg_usb_size = 0x5;
8882 			pHalData->rxagg_usb_timeout = 0x20;
8883 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
8884 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
8885 		}
8886 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
8887 
8888 	} else {
8889 		/* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
8890 	}
8891 }
8892 
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)8893 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
8894 {
8895 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
8896 
8897 	if (cur_wireless_mode < WIRELESS_11_24N
8898 	    && cur_wireless_mode > 0) { /* ABG mode */
8899 		if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
8900 		    || 0x10 != pHalData->rxagg_usb_timeout) {
8901 			pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
8902 			pHalData->rxagg_usb_timeout = 0x10;
8903 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
8904 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
8905 		}
8906 	} else if (cur_wireless_mode >= WIRELESS_11_24N
8907 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
8908 		if (UsbDmaSize != pHalData->rxagg_usb_size
8909 		    || 0x20 != pHalData->rxagg_usb_timeout) {
8910 			pHalData->rxagg_usb_size = UsbDmaSize;
8911 			pHalData->rxagg_usb_timeout = 0x20;
8912 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
8913 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
8914 		}
8915 	} else {
8916 		/* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
8917 	}
8918 }
8919 
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)8920 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
8921 {
8922 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
8923 	rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
8924 	return;
8925 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
8926 
8927 	rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
8928 }
8929 #endif /* CONFIG_USB_RX_AGGREGATION */
8930 
8931 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)8932 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
8933 {
8934 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
8935 	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
8936 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
8937 	u8 cur_wireless_mode = WIRELESS_INVALID;
8938 
8939 #ifdef CONFIG_USB_RX_AGGREGATION
8940 	if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
8941 		/* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
8942 		if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
8943 			if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
8944 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
8945 			else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
8946 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
8947 			else
8948 				rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
8949 
8950 			/* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
8951 		}
8952 	} else if (IS_HARDWARE_TYPE_8812(padapter)) {
8953 #ifdef CONFIG_CONCURRENT_MODE
8954 		u8 i;
8955 		_adapter *iface;
8956 		u8 bassocaed = _FALSE;
8957 		struct mlme_ext_priv *mlmeext;
8958 
8959 		for (i = 0; i < pdvobjpriv->iface_nums; i++) {
8960 			iface = pdvobjpriv->padapters[i];
8961 			mlmeext = &iface->mlmeextpriv;
8962 			if (rtw_linked_check(iface) == _TRUE) {
8963 				if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
8964 					cur_wireless_mode = mlmeext->cur_wireless_mode;
8965 				bassocaed = _TRUE;
8966 			}
8967 		}
8968 		if (bassocaed)
8969 #endif
8970 			rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
8971 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
8972 	} else {
8973 		rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
8974 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
8975 	}
8976 #endif
8977 }
8978 
8979 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)8980 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
8981 {
8982 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8983 	u8 chk_rst = _SUCCESS;
8984 
8985 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8986 		return chk_rst;
8987 
8988 	/* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
8989 	/*	return chk_rst; */
8990 
8991 	if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
8992 	    && (pre_qsel != next_qsel)) {
8993 		/* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
8994 		/*	pre_qsel,next_qsel); */
8995 		chk_rst = _FAIL;
8996 	}
8997 	return chk_rst;
8998 }
8999 
9000 /*
9001  * Description:
9002  * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
9003  * contant.
9004  *
9005  * Input:
9006  * adapter: adapter pointer.
9007  * page_num: The max. page number that user want to dump.
9008  * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
9009  */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)9010 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
9011 {
9012 
9013 	int i;
9014 	u8 val = 0;
9015 	u8 base = 0;
9016 	u32 addr = 0;
9017 	u32 count = (page_size / 8);
9018 
9019 	if (page_num <= 0) {
9020 		RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
9021 		return;
9022 	}
9023 
9024 	if (page_size < 128 || page_size > 512) {
9025 		RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
9026 		return;
9027 	}
9028 
9029 	RTW_INFO("+%s+\n", __func__);
9030 	val = rtw_read8(padapter, 0x106);
9031 	rtw_write8(padapter, 0x106, 0x69);
9032 	RTW_INFO("0x106: 0x%02x\n", val);
9033 	base = rtw_read8(padapter, 0x209);
9034 	RTW_INFO("0x209: 0x%02x\n", base);
9035 
9036 	addr = ((base)*page_size) / 8;
9037 	for (i = 0 ; i < page_num * count ; i += 2) {
9038 		rtw_write32(padapter, 0x140, addr + i);
9039 		printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
9040 		rtw_write32(padapter, 0x140, addr + i + 1);
9041 		printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
9042 	}
9043 }
9044 
9045 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)9046 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
9047 {
9048 	u8 value = 0;
9049 	u8 direction = 0;
9050 	u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
9051 	u8 gpio_num_to_set = gpio_num;
9052 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9053 
9054 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
9055 		return value;
9056 
9057 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
9058 
9059 	RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
9060 	LeaveAllPowerSaveModeDirect(adapter);
9061 
9062 	if (gpio_num > 7) {
9063 		gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
9064 		gpio_num_to_set = gpio_num - 8;
9065 	}
9066 
9067 	/* Read GPIO Direction */
9068 	direction = (rtw_read8(adapter, gpio_ctrl_reg_to_set) & BIT(gpio_num_to_set)) >> gpio_num;
9069 
9070 	/* According the direction to read register value */
9071 	if (direction)
9072 		value =  (rtw_read8(adapter, gpio_ctrl_reg_to_set) & BIT(gpio_num_to_set)) >> gpio_num;
9073 	else
9074 		value =  (rtw_read8(adapter, gpio_ctrl_reg_to_set) & BIT(gpio_num_to_set)) >> gpio_num;
9075 
9076 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
9077 	RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
9078 
9079 	return value;
9080 }
9081 
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)9082 int  rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
9083 {
9084 	u8 direction = 0;
9085 	u8 res = -1;
9086 	u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
9087 	u8 gpio_num_to_set = gpio_num;
9088 
9089 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
9090 		return -1;
9091 
9092 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
9093 
9094 	LeaveAllPowerSaveModeDirect(adapter);
9095 
9096 	if (gpio_num > 7) {
9097 		gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
9098 		gpio_num_to_set = gpio_num - 8;
9099 	}
9100 
9101 	/* Read GPIO direction */
9102 	direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
9103 
9104 	/* If GPIO is output direction, setting value. */
9105 	if (direction) {
9106 		if (isHigh)
9107 			rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
9108 		else
9109 			rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
9110 
9111 		RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
9112 		res = 0;
9113 	} else {
9114 		RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
9115 		res = -1;
9116 	}
9117 
9118 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
9119 	return res;
9120 }
9121 
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)9122 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
9123 {
9124 	u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
9125 	u8 gpio_num_to_set = gpio_num;
9126 
9127 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
9128 		return -1;
9129 
9130 	RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
9131 
9132 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
9133 
9134 	LeaveAllPowerSaveModeDirect(adapter);
9135 
9136 	rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
9137 
9138 	if (gpio_num > 7) {
9139 		gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
9140 		gpio_num_to_set = gpio_num - 8;
9141 	}
9142 
9143 	if (isOutput)
9144 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
9145 	else
9146 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
9147 
9148 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
9149 
9150 	return 0;
9151 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))9152 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
9153 {
9154 	u8 value;
9155 	u8 direction;
9156 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
9157 
9158 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
9159 		if (gpio_num > 7 || gpio_num < 4) {
9160 			RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
9161 			return -1;
9162 		}
9163 	}
9164 
9165 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
9166 
9167 	LeaveAllPowerSaveModeDirect(adapter);
9168 
9169 	/* Read GPIO direction */
9170 	direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
9171 	if (direction) {
9172 		RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
9173 		return -1;
9174 	}
9175 
9176 	/* Config GPIO Mode */
9177 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
9178 
9179 	/* Register GPIO interrupt handler*/
9180 	adapter->gpiointpriv.callback[gpio_num] = callback;
9181 
9182 	/* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
9183 	value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
9184 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
9185 	rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
9186 
9187 	/* Enable GPIO interrupt */
9188 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
9189 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
9190 
9191 	rtw_hal_update_hisr_hsisr_ind(adapter, 1);
9192 
9193 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
9194 
9195 	return 0;
9196 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)9197 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
9198 {
9199 	u8 value;
9200 	u8 direction;
9201 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
9202 
9203 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
9204 		if (gpio_num > 7 || gpio_num < 4) {
9205 			RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
9206 			return -1;
9207 		}
9208 	}
9209 
9210 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
9211 
9212 	LeaveAllPowerSaveModeDirect(adapter);
9213 
9214 	/* Config GPIO Mode */
9215 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
9216 
9217 	/* Unregister GPIO interrupt handler*/
9218 	adapter->gpiointpriv.callback[gpio_num] = NULL;
9219 
9220 	/* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
9221 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
9222 	rtw_write8(adapter, REG_GPIO_INTM, 0x00);
9223 
9224 	/* Disable GPIO interrupt */
9225 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
9226 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
9227 
9228 	if (!adapter->gpiointpriv.interrupt_enable_mask)
9229 		rtw_hal_update_hisr_hsisr_ind(adapter, 0);
9230 
9231 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
9232 
9233 	return 0;
9234 }
9235 #endif
9236 
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)9237 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
9238 {
9239 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
9240 	u8 i;
9241 
9242 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
9243 		if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
9244 			if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
9245 			    && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
9246 				return i;
9247 		}
9248 	}
9249 
9250 	return -1;
9251 }
9252 
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)9253 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
9254 {
9255 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
9256 	s8 res;
9257 	u8 i;
9258 
9259 	/* If it's an existed record, overwrite it */
9260 	res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->CurrentChannel, pHalData->CurrentChannelBW);
9261 	if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
9262 		rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
9263 		return;
9264 	}
9265 
9266 	/* Search for the empty record to use */
9267 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
9268 		if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
9269 			rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
9270 			return;
9271 		}
9272 	}
9273 
9274 	/* Else, overwrite the oldest record */
9275 	for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
9276 		_rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
9277 
9278 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
9279 }
9280 
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)9281 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
9282 {
9283 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
9284 }
9285 
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)9286 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
9287 {
9288 	u32	mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
9289 	u32	mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
9290 	u32	mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
9291 	u32	DropPacket = 0;
9292 
9293 	if (!rx_counter) {
9294 		rtw_warn_on(1);
9295 		return;
9296 	}
9297 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
9298 		PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
9299 
9300 	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
9301 	mac_cck_ok	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	  */
9302 	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
9303 	mac_ofdm_ok	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
9304 	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
9305 	mac_ht_ok	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
9306 	mac_vht_ok	= 0;
9307 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
9308 		PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
9309 		PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x1);
9310 		mac_vht_ok	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
9311 		PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
9312 	}
9313 
9314 	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
9315 	mac_cck_err	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
9316 	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
9317 	mac_ofdm_err	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
9318 	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
9319 	mac_ht_err	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
9320 	mac_vht_err	= 0;
9321 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
9322 		PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
9323 		PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x1);
9324 		mac_vht_err	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
9325 		PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
9326 	}
9327 
9328 	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
9329 	mac_cck_fa	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
9330 	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
9331 	mac_ofdm_fa	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
9332 	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
9333 	mac_ht_fa	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
9334 
9335 	/* Mac_DropPacket */
9336 	rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
9337 	DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
9338 
9339 	rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
9340 	rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
9341 	rx_counter->rx_cck_fa = mac_cck_fa;
9342 	rx_counter->rx_ofdm_fa = mac_ofdm_fa;
9343 	rx_counter->rx_ht_fa = mac_ht_fa;
9344 	rx_counter->rx_pkt_drop = DropPacket;
9345 }
rtw_reset_mac_rx_counters(_adapter * padapter)9346 void rtw_reset_mac_rx_counters(_adapter *padapter)
9347 {
9348 
9349 	/* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
9350 	if (IS_HARDWARE_TYPE_8703B(padapter) ||
9351 	    IS_HARDWARE_TYPE_8723D(padapter) ||
9352 	    IS_HARDWARE_TYPE_8188F(padapter))
9353 		PHY_SetMacReg(padapter, REG_RCR, BIT19, 0x1);
9354 
9355 	/* reset mac counter */
9356 	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT27, 0x1);
9357 	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT27, 0x0);
9358 }
9359 
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)9360 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
9361 {
9362 	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;
9363 	if (!rx_counter) {
9364 		rtw_warn_on(1);
9365 		return;
9366 	}
9367 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
9368 		cckok	= PHY_QueryBBReg(padapter, 0xF04, 0x3FFF);	     /* [13:0] */
9369 		ofdmok	= PHY_QueryBBReg(padapter, 0xF14, 0x3FFF);	     /* [13:0] */
9370 		htok		= PHY_QueryBBReg(padapter, 0xF10, 0x3FFF);     /* [13:0] */
9371 		vht_ok	= PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF);     /* [13:0] */
9372 		cckcrc	= PHY_QueryBBReg(padapter, 0xF04, 0x3FFF0000); /* [29:16]	 */
9373 		ofdmcrc	= PHY_QueryBBReg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
9374 		htcrc	= PHY_QueryBBReg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
9375 		vht_err	= PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
9376 		CCK_FA	= PHY_QueryBBReg(padapter, 0xA5C, bMaskLWord);
9377 		OFDM_FA	= PHY_QueryBBReg(padapter, 0xF48, bMaskLWord);
9378 	} else {
9379 		cckok	= PHY_QueryBBReg(padapter, 0xF88, bMaskDWord);
9380 		ofdmok	= PHY_QueryBBReg(padapter, 0xF94, bMaskLWord);
9381 		htok		= PHY_QueryBBReg(padapter, 0xF90, bMaskLWord);
9382 		vht_ok	= 0;
9383 		cckcrc	= PHY_QueryBBReg(padapter, 0xF84, bMaskDWord);
9384 		ofdmcrc	= PHY_QueryBBReg(padapter, 0xF94, bMaskHWord);
9385 		htcrc	= PHY_QueryBBReg(padapter, 0xF90, bMaskHWord);
9386 		vht_err	= 0;
9387 		OFDM_FA = PHY_QueryBBReg(padapter, 0xCF0, bMaskLWord) + PHY_QueryBBReg(padapter, 0xCF2, bMaskLWord) +
9388 			PHY_QueryBBReg(padapter, 0xDA2, bMaskLWord) + PHY_QueryBBReg(padapter, 0xDA4, bMaskLWord) +
9389 			PHY_QueryBBReg(padapter, 0xDA6, bMaskLWord) + PHY_QueryBBReg(padapter, 0xDA8, bMaskLWord);
9390 
9391 		CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
9392 	}
9393 
9394 	rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
9395 	rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
9396 	rx_counter->rx_ofdm_fa = OFDM_FA;
9397 	rx_counter->rx_cck_fa = CCK_FA;
9398 
9399 }
9400 
rtw_reset_phy_trx_ok_counters(_adapter * padapter)9401 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
9402 {
9403 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
9404 		PHY_SetBBReg(padapter, 0xB58, BIT0, 0x1);
9405 		PHY_SetBBReg(padapter, 0xB58, BIT0, 0x0);
9406 	}
9407 }
rtw_reset_phy_rx_counters(_adapter * padapter)9408 void rtw_reset_phy_rx_counters(_adapter *padapter)
9409 {
9410 	/* reset phy counter */
9411 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
9412 		rtw_reset_phy_trx_ok_counters(padapter);
9413 
9414 		PHY_SetBBReg(padapter, 0x9A4, BIT17, 0x1);/* reset  OFDA FA counter */
9415 		PHY_SetBBReg(padapter, 0x9A4, BIT17, 0x0);
9416 
9417 		PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
9418 		PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x1);
9419 	} else {
9420 		PHY_SetBBReg(padapter, 0xF14, BIT16, 0x1);
9421 		rtw_msleep_os(10);
9422 		PHY_SetBBReg(padapter, 0xF14, BIT16, 0x0);
9423 
9424 		PHY_SetBBReg(padapter, 0xD00, BIT27, 0x1);/* reset  OFDA FA counter */
9425 		PHY_SetBBReg(padapter, 0xC0C, BIT31, 0x1);/* reset  OFDA FA counter */
9426 		PHY_SetBBReg(padapter, 0xD00, BIT27, 0x0);
9427 		PHY_SetBBReg(padapter, 0xC0C, BIT31, 0x0);
9428 
9429 		PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
9430 		PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x1);
9431 	}
9432 }
9433 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)9434 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
9435 {
9436 	struct recv_priv *precvpriv = &padapter->recvpriv;
9437 	if (!rx_counter) {
9438 		rtw_warn_on(1);
9439 		return;
9440 	}
9441 	rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
9442 	rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
9443 	rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
9444 }
rtw_reset_drv_rx_counters(_adapter * padapter)9445 void rtw_reset_drv_rx_counters(_adapter *padapter)
9446 {
9447 	struct recv_priv *precvpriv = &padapter->recvpriv;
9448 	padapter->drv_rx_cnt_ok = 0;
9449 	padapter->drv_rx_cnt_crcerror = 0;
9450 	padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
9451 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)9452 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
9453 {
9454 	u8 initialgain;
9455 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
9456 
9457 	if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
9458 		rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
9459 		RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
9460 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
9461 		/*disable dynamic functions, such as high power, DIG*/
9462 		rtw_phydm_ability_backup(padapter);
9463 		rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
9464 	} else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
9465 		/* turn on phy-dynamic functions */
9466 		rtw_phydm_ability_restore(padapter);
9467 		initialgain = 0xff; /* restore RX GAIN */
9468 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
9469 
9470 	}
9471 }
9472 
rtw_dump_rx_counters(_adapter * padapter)9473 void rtw_dump_rx_counters(_adapter *padapter)
9474 {
9475 	struct dbg_rx_counter rx_counter;
9476 
9477 	if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
9478 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
9479 		rtw_dump_drv_rx_counters(padapter, &rx_counter);
9480 		RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
9481 			rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
9482 		rtw_reset_drv_rx_counters(padapter);
9483 	}
9484 
9485 	if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
9486 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
9487 		rtw_dump_mac_rx_counters(padapter, &rx_counter);
9488 		RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
9489 			 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
9490 			rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
9491 			 rx_counter.rx_pkt_drop);
9492 		rtw_reset_mac_rx_counters(padapter);
9493 	}
9494 
9495 	if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
9496 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
9497 		rtw_dump_phy_rx_counters(padapter, &rx_counter);
9498 		/* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
9499 		/* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
9500 		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,
9501 			 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
9502 		rtw_reset_phy_rx_counters(padapter);
9503 	}
9504 }
9505 #endif
rtw_get_noise(_adapter * padapter)9506 void rtw_get_noise(_adapter *padapter)
9507 {
9508 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
9509 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
9510 	struct noise_info info;
9511 	if (rtw_linked_check(padapter)) {
9512 		info.bPauseDIG = _TRUE;
9513 		info.IGIValue = 0x1e;
9514 		info.max_time = 100;/* ms */
9515 		info.chan = pmlmeext->cur_channel ;/* rtw_get_oper_ch(padapter); */
9516 		rtw_ps_deny(padapter, PS_DENY_IOCTL);
9517 		LeaveAllPowerSaveModeDirect(padapter);
9518 
9519 		rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, _FALSE);
9520 		/* ODM_InbandNoise_Monitor(podmpriv,_TRUE,0x20,100); */
9521 		rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
9522 		rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &(info.chan), &(padapter->recvpriv.noise));
9523 #ifdef DBG_NOISE_MONITOR
9524 		RTW_INFO("chan:%d,noise_level:%d\n", info.chan, padapter->recvpriv.noise);
9525 #endif
9526 	}
9527 #endif
9528 
9529 }
rtw_get_current_tx_sgi(_adapter * padapter,u8 macid)9530 u8 rtw_get_current_tx_sgi(_adapter *padapter, u8 macid)
9531 {
9532 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
9533 	PDM_ODM_T		pDM_Odm = &pHalData->odmpriv;
9534 	pRA_T			pRA_Table = &pDM_Odm->DM_RA_Table;
9535 	u8 curr_tx_sgi = 0;
9536 
9537 #if defined(CONFIG_RTL8188E)
9538 	curr_tx_sgi = ODM_RA_GetDecisionRate_8188E(pDM_Odm, macid);
9539 #else
9540 	curr_tx_sgi = ((pRA_Table->link_tx_rate[macid]) & 0x80) >> 7;
9541 #endif
9542 
9543 	return curr_tx_sgi;
9544 
9545 }
rtw_get_current_tx_rate(_adapter * padapter,u8 macid)9546 u8 rtw_get_current_tx_rate(_adapter *padapter, u8 macid)
9547 {
9548 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
9549 	PDM_ODM_T		pDM_Odm = &pHalData->odmpriv;
9550 	pRA_T			pRA_Table = &pDM_Odm->DM_RA_Table;
9551 	u8 rate_id = 0;
9552 
9553 #if (RATE_ADAPTIVE_SUPPORT == 1)
9554 	rate_id = ODM_RA_GetDecisionRate_8188E(pDM_Odm, macid);
9555 #else
9556 	rate_id = (pRA_Table->link_tx_rate[macid]) & 0x7f;
9557 #endif
9558 
9559 	return rate_id;
9560 
9561 }
9562 
9563 #ifdef CONFIG_FW_C2H_DEBUG
9564 
9565 /*	C2H RX package original is 128.
9566 if enable CONFIG_FW_C2H_DEBUG, it should increase to 256.
9567  C2H FW debug message:
9568  without aggregate:
9569  {C2H_CmdID,Seq,SubID,Len,Content[0~n]}
9570  Content[0~n]={'a','b','c',...,'z','\n'}
9571  with aggregate:
9572  {C2H_CmdID,Seq,SubID,Len,Content[0~n]}
9573  Content[0~n]={'a','b','c',...,'z','\n',Extend C2H pkt 2...}
9574  Extend C2H pkt 2={C2H CmdID,Seq,SubID,Len,Content = {'a','b','c',...,'z','\n'}}
9575  Author: Isaac	*/
9576 
Debug_FwC2H(PADAPTER padapter,u8 * pdata,u8 len)9577 void Debug_FwC2H(PADAPTER padapter, u8 *pdata, u8 len)
9578 {
9579 	int i = 0;
9580 	int cnt = 0, total_length = 0;
9581 	u8 buf[128] = {0};
9582 	u8 more_data = _FALSE;
9583 	u8 *nextdata = NULL;
9584 	u8 test = 0;
9585 
9586 	u8 data_len;
9587 	u8 seq_no;
9588 
9589 	nextdata = pdata;
9590 	do {
9591 		data_len = *(nextdata + 1);
9592 		seq_no = *(nextdata + 2);
9593 
9594 		for (i = 0 ; i < data_len - 2 ; i++) {
9595 			cnt += sprintf((buf + cnt), "%c", nextdata[3 + i]);
9596 
9597 			if (nextdata[3 + i] == 0x0a && nextdata[4 + i] == 0xff)
9598 				more_data = _TRUE;
9599 			else if (nextdata[3 + i] == 0x0a && nextdata[4 + i] != 0xff)
9600 				more_data = _FALSE;
9601 		}
9602 
9603 		RTW_INFO("[RTKFW, SEQ=%d]: %s", seq_no, buf);
9604 		data_len += 3;
9605 		total_length += data_len;
9606 
9607 		if (more_data == _TRUE) {
9608 			_rtw_memset(buf, '\0', 128);
9609 			cnt = 0;
9610 			nextdata = (pdata + total_length);
9611 		}
9612 	} while (more_data == _TRUE);
9613 }
9614 #endif /*CONFIG_FW_C2H_DEBUG*/
update_IOT_info(_adapter * padapter)9615 void update_IOT_info(_adapter *padapter)
9616 {
9617 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
9618 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9619 
9620 	switch (pmlmeinfo->assoc_AP_vendor) {
9621 	case HT_IOT_PEER_MARVELL:
9622 		pmlmeinfo->turboMode_cts2self = 1;
9623 		pmlmeinfo->turboMode_rtsen = 0;
9624 		break;
9625 
9626 	case HT_IOT_PEER_RALINK:
9627 		pmlmeinfo->turboMode_cts2self = 0;
9628 		pmlmeinfo->turboMode_rtsen = 1;
9629 		/* disable high power			 */
9630 		rtw_phydm_func_clr(padapter, ODM_BB_DYNAMIC_TXPWR);
9631 		break;
9632 	case HT_IOT_PEER_REALTEK:
9633 		/* rtw_write16(padapter, 0x4cc, 0xffff); */
9634 		/* rtw_write16(padapter, 0x546, 0x01c0); */
9635 		/* disable high power			 */
9636 		rtw_phydm_func_clr(padapter, ODM_BB_DYNAMIC_TXPWR);
9637 		break;
9638 	default:
9639 		pmlmeinfo->turboMode_cts2self = 0;
9640 		pmlmeinfo->turboMode_rtsen = 1;
9641 		break;
9642 	}
9643 
9644 }
9645 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
rtw_acs_start(_adapter * padapter,bool bStart)9646 void rtw_acs_start(_adapter *padapter, bool bStart)
9647 {
9648 	if (_TRUE == bStart) {
9649 		ACS_OP acs_op = ACS_INIT;
9650 
9651 		rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
9652 		rtw_set_acs_channel(padapter, 0);
9653 		SET_ACS_STATE(padapter, ACS_ENABLE);
9654 	} else {
9655 		SET_ACS_STATE(padapter, ACS_DISABLE);
9656 #ifdef DBG_AUTO_CHNL_SEL_NHM
9657 		if (1) {
9658 			u8 best_24g_ch = 0;
9659 			u8 best_5g_ch = 0;
9660 
9661 			rtw_hal_get_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &(best_24g_ch), &(best_5g_ch));
9662 			RTW_INFO("[ACS-"ADPT_FMT"] Best 2.4G CH:%u\n", ADPT_ARG(padapter), best_24g_ch);
9663 			RTW_INFO("[ACS-"ADPT_FMT"] Best 5G CH:%u\n", ADPT_ARG(padapter), best_5g_ch);
9664 		}
9665 #endif
9666 	}
9667 }
9668 #endif
9669 
9670 /* TODO: merge with phydm, see odm_SetCrystalCap() */
hal_set_crystal_cap(_adapter * adapter,u8 crystal_cap)9671 void hal_set_crystal_cap(_adapter *adapter, u8 crystal_cap)
9672 {
9673 	crystal_cap = crystal_cap & 0x3F;
9674 
9675 	switch (rtw_get_chip_type(adapter)) {
9676 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F)
9677 	case RTL8188E:
9678 	case RTL8188F:
9679 		/* write 0x24[16:11] = 0x24[22:17] = CrystalCap */
9680 		PHY_SetBBReg(adapter, REG_AFE_XTAL_CTRL, 0x007FF800, (crystal_cap | (crystal_cap << 6)));
9681 		break;
9682 #endif
9683 #if defined(CONFIG_RTL8812A)
9684 	case RTL8812:
9685 		/* write 0x2C[30:25] = 0x2C[24:19] = CrystalCap */
9686 		PHY_SetBBReg(adapter, REG_MAC_PHY_CTRL, 0x7FF80000, (crystal_cap | (crystal_cap << 6)));
9687 		break;
9688 #endif
9689 #if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || \
9690 		defined(CONFIG_RTL8723D) || defined(CONFIG_RTL8821A) || \
9691 		defined(CONFIG_RTL8192E)
9692 	case RTL8723B:
9693 	case RTL8703B:
9694 	case RTL8723D:
9695 	case RTL8821:
9696 	case RTL8192E:
9697 		/* write 0x2C[23:18] = 0x2C[17:12] = CrystalCap */
9698 		PHY_SetBBReg(adapter, REG_MAC_PHY_CTRL, 0x00FFF000, (crystal_cap | (crystal_cap << 6)));
9699 		break;
9700 #endif
9701 #if defined(CONFIG_RTL8814A)
9702 	case RTL8814A:
9703 		/* write 0x2C[26:21] = 0x2C[20:15] = CrystalCap*/
9704 		PHY_SetBBReg(adapter, REG_MAC_PHY_CTRL, 0x07FF8000, (crystal_cap | (crystal_cap << 6)));
9705 		break;
9706 #endif
9707 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)
9708 
9709 	case RTL8822B:
9710 	case RTL8821C:
9711 		/* write 0x28[6:1] = 0x24[30:25] = CrystalCap */
9712 		crystal_cap = crystal_cap & 0x3F;
9713 		PHY_SetBBReg(adapter, REG_AFE_XTAL_CTRL, 0x7E000000, crystal_cap);
9714 		PHY_SetBBReg(adapter, REG_AFE_PLL_CTRL, 0x7E, crystal_cap);
9715 		break;
9716 #endif
9717 	default:
9718 		rtw_warn_on(1);
9719 	}
9720 }
9721 
hal_spec_init(_adapter * adapter)9722 int hal_spec_init(_adapter *adapter)
9723 {
9724 	u8 interface_type = 0;
9725 	int ret = _SUCCESS;
9726 
9727 	interface_type = rtw_get_intf_type(adapter);
9728 
9729 	switch (rtw_get_chip_type(adapter)) {
9730 #ifdef CONFIG_RTL8723B
9731 	case RTL8723B:
9732 		init_hal_spec_8723b(adapter);
9733 		break;
9734 #endif
9735 #ifdef CONFIG_RTL8703B
9736 	case RTL8703B:
9737 		init_hal_spec_8703b(adapter);
9738 		break;
9739 #endif
9740 #ifdef CONFIG_RTL8723D
9741 	case RTL8723D:
9742 		init_hal_spec_8723d(adapter);
9743 		break;
9744 #endif
9745 #ifdef CONFIG_RTL8188E
9746 	case RTL8188E:
9747 		init_hal_spec_8188e(adapter);
9748 		break;
9749 #endif
9750 #ifdef CONFIG_RTL8188F
9751 	case RTL8188F:
9752 		init_hal_spec_8188f(adapter);
9753 		break;
9754 #endif
9755 #ifdef CONFIG_RTL8812A
9756 	case RTL8812:
9757 		init_hal_spec_8812a(adapter);
9758 		break;
9759 #endif
9760 #ifdef CONFIG_RTL8821A
9761 	case RTL8821:
9762 		init_hal_spec_8821a(adapter);
9763 		break;
9764 #endif
9765 #ifdef CONFIG_RTL8192E
9766 	case RTL8192E:
9767 		init_hal_spec_8192e(adapter);
9768 		break;
9769 #endif
9770 #ifdef CONFIG_RTL8814A
9771 	case RTL8814A:
9772 		init_hal_spec_8814a(adapter);
9773 		break;
9774 #endif
9775 #ifdef CONFIG_RTL8822B
9776 	case RTL8822B:
9777 		rtl8822b_init_hal_spec(adapter);
9778 		break;
9779 #endif
9780 #ifdef CONFIG_RTL8821C
9781 	case RTL8821C:
9782 		init_hal_spec_rtl8821c(adapter);
9783 		break;
9784 #endif
9785 	default:
9786 		RTW_ERR("%s: unknown chip_type:%u\n"
9787 			, __func__, rtw_get_chip_type(adapter));
9788 		ret = _FAIL;
9789 		break;
9790 	}
9791 
9792 	return ret;
9793 }
9794 
9795 static const char *const _band_cap_str[] = {
9796 	/* BIT0 */"2G",
9797 	/* BIT1 */"5G",
9798 };
9799 
9800 static const char *const _bw_cap_str[] = {
9801 	/* BIT0 */"5M",
9802 	/* BIT1 */"10M",
9803 	/* BIT2 */"20M",
9804 	/* BIT3 */"40M",
9805 	/* BIT4 */"80M",
9806 	/* BIT5 */"160M",
9807 	/* BIT6 */"80_80M",
9808 };
9809 
9810 static const char *const _proto_cap_str[] = {
9811 	/* BIT0 */"b",
9812 	/* BIT1 */"g",
9813 	/* BIT2 */"n",
9814 	/* BIT3 */"ac",
9815 };
9816 
9817 static const char *const _wl_func_str[] = {
9818 	/* BIT0 */"P2P",
9819 	/* BIT1 */"MIRACAST",
9820 	/* BIT2 */"TDLS",
9821 	/* BIT3 */"FTM",
9822 };
9823 
dump_hal_spec(void * sel,_adapter * adapter)9824 void dump_hal_spec(void *sel, _adapter *adapter)
9825 {
9826 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
9827 	int i;
9828 
9829 	RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
9830 	RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
9831 	RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
9832 	RTW_PRINT_SEL(sel, "nss_num:%u\n", hal_spec->nss_num);
9833 
9834 	RTW_PRINT_SEL(sel, "band_cap:");
9835 	for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
9836 		if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
9837 			_RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
9838 	}
9839 	_RTW_PRINT_SEL(sel, "\n");
9840 
9841 	RTW_PRINT_SEL(sel, "bw_cap:");
9842 	for (i = 0; i < BW_CAP_BIT_NUM; i++) {
9843 		if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
9844 			_RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
9845 	}
9846 	_RTW_PRINT_SEL(sel, "\n");
9847 
9848 	RTW_PRINT_SEL(sel, "proto_cap:");
9849 	for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
9850 		if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
9851 			_RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
9852 	}
9853 	_RTW_PRINT_SEL(sel, "\n");
9854 
9855 	RTW_PRINT_SEL(sel, "wl_func:");
9856 	for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
9857 		if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
9858 			_RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
9859 	}
9860 	_RTW_PRINT_SEL(sel, "\n");
9861 }
9862 
hal_chk_band_cap(_adapter * adapter,u8 cap)9863 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
9864 {
9865 	return GET_HAL_SPEC(adapter)->band_cap & cap;
9866 }
9867 
hal_chk_bw_cap(_adapter * adapter,u8 cap)9868 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
9869 {
9870 	return GET_HAL_SPEC(adapter)->bw_cap & cap;
9871 }
9872 
hal_chk_proto_cap(_adapter * adapter,u8 cap)9873 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
9874 {
9875 	return GET_HAL_SPEC(adapter)->proto_cap & cap;
9876 }
9877 
hal_chk_wl_func(_adapter * adapter,u8 func)9878 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
9879 {
9880 	return GET_HAL_SPEC(adapter)->wl_func & func;
9881 }
9882 
hal_is_band_support(_adapter * adapter,u8 band)9883 inline bool hal_is_band_support(_adapter *adapter, u8 band)
9884 {
9885 	return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
9886 }
9887 
hal_is_bw_support(_adapter * adapter,u8 bw)9888 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
9889 {
9890 	return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
9891 }
9892 
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)9893 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
9894 {
9895 	u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
9896 
9897 	if (mode == WIRELESS_11B)
9898 		if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
9899 			return 1;
9900 
9901 	if (mode == WIRELESS_11G)
9902 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
9903 			return 1;
9904 
9905 	if (mode == WIRELESS_11A)
9906 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
9907 			return 1;
9908 
9909 	if (mode == WIRELESS_11_24N)
9910 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
9911 			return 1;
9912 
9913 	if (mode == WIRELESS_11_5N)
9914 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
9915 			return 1;
9916 
9917 	if (mode == WIRELESS_11AC)
9918 		if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
9919 			return 1;
9920 
9921 	return 0;
9922 }
9923 
9924 /*
9925 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
9926 * @adapter:
9927 * @in_bw: starting bw, value of CHANNEL_WIDTH
9928 *
9929 * Returns: value of CHANNEL_WIDTH
9930 */
hal_largest_bw(_adapter * adapter,u8 in_bw)9931 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
9932 {
9933 	for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
9934 		if (hal_is_bw_support(adapter, in_bw))
9935 			break;
9936 	}
9937 
9938 	if (!hal_is_bw_support(adapter, in_bw))
9939 		rtw_warn_on(1);
9940 
9941 	return in_bw;
9942 }
9943 
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)9944 void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
9945 {
9946 	if (hw_port == HW_PORT0) {
9947 		/*disable related TSF function*/
9948 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
9949 
9950 		rtw_write32(padapter, REG_TSFTR, tsf);
9951 		rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
9952 
9953 		/*enable related TSF function*/
9954 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
9955 	} else if (hw_port == HW_PORT1) {
9956 		/*disable related TSF function*/
9957 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
9958 
9959 		rtw_write32(padapter, REG_TSFTR1, tsf);
9960 		rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
9961 
9962 		/*enable related TSF function*/
9963 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
9964 	} else
9965 		RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
9966 }
9967 
ResumeTxBeacon(_adapter * padapter)9968 void ResumeTxBeacon(_adapter *padapter)
9969 {
9970 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9971 
9972 
9973 	/* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
9974 	/* which should be read from register to a global variable. */
9975 
9976 	RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
9977 
9978 	pHalData->RegFwHwTxQCtrl |= BIT(6);
9979 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl);
9980 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0xff);
9981 	pHalData->RegReg542 |= BIT(0);
9982 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
9983 }
9984 
StopTxBeacon(_adapter * padapter)9985 void StopTxBeacon(_adapter *padapter)
9986 {
9987 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9988 
9989 
9990 	/* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
9991 	/* which should be read from register to a global variable. */
9992 
9993 	RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
9994 
9995 	pHalData->RegFwHwTxQCtrl &= ~BIT(6);
9996 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl);
9997 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0x64);
9998 	pHalData->RegReg542 &= ~BIT(0);
9999 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
10000 
10001 	/*CheckFwRsvdPageContent(padapter);*/  /* 2010.06.23. Added by tynli. */
10002 }
10003 
10004 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)10005 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
10006 {
10007 	RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
10008 
10009 	rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) & (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)));
10010 
10011 	/* disable Port0 TSF update*/
10012 	rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | DIS_TSF_UDT);
10013 
10014 	/* set net_type */
10015 	Set_MSR(Adapter, mode);
10016 
10017 	if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
10018 		if (!rtw_mi_check_status(Adapter, MI_AP_MODE))
10019 			StopTxBeacon(Adapter);
10020 
10021 		rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM);/*disable atim wnd*/
10022 	} else if (mode == _HW_STATE_ADHOC_) {
10023 		ResumeTxBeacon(Adapter);
10024 		rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
10025 
10026 	} else if (mode == _HW_STATE_AP_) {
10027 		ResumeTxBeacon(Adapter);
10028 
10029 		rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
10030 
10031 		/*enable to rx data frame*/
10032 		rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
10033 
10034 		/*Beacon Control related register for first time*/
10035 		rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */
10036 
10037 		/*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
10038 		rtw_write8(Adapter, REG_ATIMWND, 0x0a); /* 10ms */
10039 		rtw_write16(Adapter, REG_BCNTCFG, 0x00);
10040 		rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04);
10041 		rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
10042 
10043 		/*reset TSF*/
10044 		rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
10045 
10046 		/*enable BCN0 Function for if1*/
10047 		/*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
10048 		rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
10049 
10050 		if (IS_HARDWARE_TYPE_8821(Adapter) || IS_HARDWARE_TYPE_8192E(Adapter))/* select BCN on port 0 for DualBeacon*/
10051 			rtw_write8(Adapter, REG_CCK_CHECK, rtw_read8(Adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
10052 
10053 	}
10054 
10055 }
10056 #endif
10057 
10058 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)10059 u8	rtw_hal_antdiv_before_linked(_adapter *padapter)
10060 {
10061 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10062 	u8 cur_ant, change_ant;
10063 
10064 	if (!pHalData->AntDivCfg)
10065 		return _FALSE;
10066 
10067 	if (pHalData->sw_antdiv_bl_state == 0) {
10068 		pHalData->sw_antdiv_bl_state = 1;
10069 
10070 		rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
10071 		change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
10072 
10073 		return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
10074 	}
10075 
10076 	pHalData->sw_antdiv_bl_state = 0;
10077 	return _FALSE;
10078 }
10079 
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)10080 void	rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
10081 {
10082 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10083 
10084 	if (pHalData->AntDivCfg) {
10085 		/*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
10086 		/*select optimum_antenna for before linked =>For antenna diversity*/
10087 		if (dst->Rssi >=  src->Rssi) {/*keep org parameter*/
10088 			src->Rssi = dst->Rssi;
10089 			src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
10090 		}
10091 	}
10092 }
10093 #endif
10094 
10095 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap(void * sel,_adapter * adapter)10096 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
10097 {
10098 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
10099 	struct phy_spec_t *phy_spec = &pHalData->phy_spec;
10100 
10101 	RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
10102 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
10103 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
10104 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index	[15:8]*/
10105 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index	[7:0]*/
10106 
10107 	RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
10108 	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]*/
10109 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx : %s\n", ((phy_spec->stbc_cap >> 16) & 0xFF) ? "Supported" : "N/A"); /*VHT STBC Rx [23:16]*/
10110 	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]*/
10111 	/*HT STBC Rx [7:0]
10112 	0 = not support
10113 	1 = support for 1 spatial stream
10114 	2 = support for 1 or 2 spatial streams
10115 	3 = support for 1 or 2 or 3 spatial streams*/
10116 	if (phy_spec->stbc_cap & 0xFF)
10117 		RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n", (phy_spec->stbc_cap & 0xFF));
10118 	else
10119 		RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : N/A\n");
10120 
10121 	RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
10122 	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]*/
10123 	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]*/
10124 	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]*/
10125 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Rx : %s\n", (phy_spec->ldpc_cap & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Rx [7:0]*/
10126 
10127 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
10128 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
10129 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
10130 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
10131 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
10132 
10133 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
10134 	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]*/
10135 	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]*/
10136 	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]*/
10137 	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]*/
10138 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF)  ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
10139 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
10140 }
10141 #endif
10142