xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8723bs/hal/hal_com.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2017 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define _HAL_COM_C_
16 
17 #include <drv_types.h>
18 #include "hal_com_h2c.h"
19 
20 #include "hal_data.h"
21 
22 #ifdef RTW_HALMAC
23 #include "../../hal/hal_halmac.h"
24 #endif
25 
rtw_dump_fw_info(void * sel,_adapter * adapter)26 void rtw_dump_fw_info(void *sel, _adapter *adapter)
27 {
28 	HAL_DATA_TYPE	*hal_data = NULL;
29 
30 	if (!adapter)
31 		return;
32 
33 	hal_data = GET_HAL_DATA(adapter);
34 	if (hal_data->bFWReady)
35 		RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);
36 	else
37 		RTW_PRINT_SEL(sel, "FW not ready\n");
38 }
39 
40 /* #define CONFIG_GTK_OL_DBG */
41 
42 /*#define DBG_SEC_CAM_MOVE*/
43 #ifdef DBG_SEC_CAM_MOVE
rtw_hal_move_sta_gk_to_dk(_adapter * adapter)44 void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
45 {
46 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
47 	int cam_id, index = 0;
48 	u8 *addr = NULL;
49 
50 	if (!MLME_IS_STA(adapter))
51 		return;
52 
53 	addr = get_bssid(pmlmepriv);
54 
55 	if (addr == NULL) {
56 		RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
57 		return;
58 	}
59 
60 	rtw_clean_dk_section(adapter);
61 
62 	do {
63 		cam_id = rtw_camid_search(adapter, addr, index, 1);
64 
65 		if (cam_id == -1)
66 			RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
67 		else
68 			rtw_sec_cam_swap(adapter, cam_id, index);
69 
70 		index++;
71 	} while (index < 4);
72 
73 }
74 
rtw_hal_read_sta_dk_key(_adapter * adapter,u8 key_id)75 void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
76 {
77 	struct security_priv *psecuritypriv = &adapter->securitypriv;
78 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
79 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
80 	_irqL irqL;
81 	u8 get_key[16];
82 
83 	_rtw_memset(get_key, 0, sizeof(get_key));
84 
85 	if (key_id > 4) {
86 		RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
87 		rtw_warn_on(1);
88 		return;
89 	}
90 	rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
91 
92 	/*update key into related sw variable*/
93 	_enter_critical_bh(&cam_ctl->lock, &irqL);
94 	if (_rtw_camid_is_gk(adapter, key_id)) {
95 		RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
96 		RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
97 	}
98 	_exit_critical_bh(&cam_ctl->lock, &irqL);
99 
100 }
101 #endif
102 
103 
104 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
105 	char	rtw_phy_para_file_path[PATH_LENGTH_MAX];
106 #endif
107 
dump_chip_info(HAL_VERSION ChipVersion)108 void dump_chip_info(HAL_VERSION	ChipVersion)
109 {
110 	int cnt = 0;
111 	u8 buf[128] = {0};
112 
113 	if (IS_8188E(ChipVersion))
114 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
115 	else if (IS_8188F(ChipVersion))
116 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
117 	else if (IS_8812_SERIES(ChipVersion))
118 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
119 	else if (IS_8192E(ChipVersion))
120 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
121 	else if (IS_8821_SERIES(ChipVersion))
122 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
123 	else if (IS_8723B_SERIES(ChipVersion))
124 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
125 	else if (IS_8703B_SERIES(ChipVersion))
126 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
127 	else if (IS_8723D_SERIES(ChipVersion))
128 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
129 	else if (IS_8814A_SERIES(ChipVersion))
130 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
131 	else if (IS_8822B_SERIES(ChipVersion))
132 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
133 	else if (IS_8821C_SERIES(ChipVersion))
134 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
135 	else
136 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
137 
138 	cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(ChipVersion) ? "Normal_Chip" : "Test_Chip");
139 	if (IS_CHIP_VENDOR_TSMC(ChipVersion))
140 		cnt += sprintf((buf + cnt), "%s_", "TSMC");
141 	else if (IS_CHIP_VENDOR_UMC(ChipVersion))
142 		cnt += sprintf((buf + cnt), "%s_", "UMC");
143 	else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
144 		cnt += sprintf((buf + cnt), "%s_", "SMIC");
145 
146 	if (IS_A_CUT(ChipVersion))
147 		cnt += sprintf((buf + cnt), "A_CUT_");
148 	else if (IS_B_CUT(ChipVersion))
149 		cnt += sprintf((buf + cnt), "B_CUT_");
150 	else if (IS_C_CUT(ChipVersion))
151 		cnt += sprintf((buf + cnt), "C_CUT_");
152 	else if (IS_D_CUT(ChipVersion))
153 		cnt += sprintf((buf + cnt), "D_CUT_");
154 	else if (IS_E_CUT(ChipVersion))
155 		cnt += sprintf((buf + cnt), "E_CUT_");
156 	else if (IS_F_CUT(ChipVersion))
157 		cnt += sprintf((buf + cnt), "F_CUT_");
158 	else if (IS_I_CUT(ChipVersion))
159 		cnt += sprintf((buf + cnt), "I_CUT_");
160 	else if (IS_J_CUT(ChipVersion))
161 		cnt += sprintf((buf + cnt), "J_CUT_");
162 	else if (IS_K_CUT(ChipVersion))
163 		cnt += sprintf((buf + cnt), "K_CUT_");
164 	else
165 		cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion);
166 
167 	if (IS_1T1R(ChipVersion))
168 		cnt += sprintf((buf + cnt), "1T1R_");
169 	else if (IS_1T2R(ChipVersion))
170 		cnt += sprintf((buf + cnt), "1T2R_");
171 	else if (IS_2T2R(ChipVersion))
172 		cnt += sprintf((buf + cnt), "2T2R_");
173 	else if (IS_3T3R(ChipVersion))
174 		cnt += sprintf((buf + cnt), "3T3R_");
175 	else if (IS_3T4R(ChipVersion))
176 		cnt += sprintf((buf + cnt), "3T4R_");
177 	else if (IS_4T4R(ChipVersion))
178 		cnt += sprintf((buf + cnt), "4T4R_");
179 	else
180 		cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
181 
182 	cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
183 
184 	RTW_INFO("%s", buf);
185 }
rtw_hal_config_rftype(PADAPTER padapter)186 void rtw_hal_config_rftype(PADAPTER  padapter)
187 {
188 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
189 
190 	if (IS_1T1R(pHalData->version_id)) {
191 		pHalData->rf_type = RF_1T1R;
192 		pHalData->NumTotalRFPath = 1;
193 	} else if (IS_2T2R(pHalData->version_id)) {
194 		pHalData->rf_type = RF_2T2R;
195 		pHalData->NumTotalRFPath = 2;
196 	} else if (IS_1T2R(pHalData->version_id)) {
197 		pHalData->rf_type = RF_1T2R;
198 		pHalData->NumTotalRFPath = 2;
199 	} else if (IS_3T3R(pHalData->version_id)) {
200 		pHalData->rf_type = RF_3T3R;
201 		pHalData->NumTotalRFPath = 3;
202 	} else if (IS_4T4R(pHalData->version_id)) {
203 		pHalData->rf_type = RF_4T4R;
204 		pHalData->NumTotalRFPath = 4;
205 	} else {
206 		pHalData->rf_type = RF_1T1R;
207 		pHalData->NumTotalRFPath = 1;
208 	}
209 
210 	RTW_INFO("%s RF_Type is %d TotalTxPath is %d\n", __FUNCTION__, pHalData->rf_type, pHalData->NumTotalRFPath);
211 }
212 
213 #define	EEPROM_CHANNEL_PLAN_BY_HW_MASK	0x80
214 
215 /*
216  * Description:
217  *	Use hardware(efuse), driver parameter(registry) and default channel plan
218  *	to decide which one should be used.
219  *
220  * Parameters:
221  *	padapter			pointer of adapter
222  *	hw_alpha2		country code from HW (efuse/eeprom/mapfile)
223  *	hw_chplan		channel plan from HW (efuse/eeprom/mapfile)
224  *						BIT[7] software configure mode; 0:Enable, 1:disable
225  *						BIT[6:0] Channel Plan
226  *	sw_alpha2		country code from HW (registry/module param)
227  *	sw_chplan		channel plan from SW (registry/module param)
228  *	def_chplan		channel plan used when HW/SW both invalid
229  *	AutoLoadFail		efuse autoload fail or not
230  *
231  */
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)232 void hal_com_config_channel_plan(
233 	IN	PADAPTER padapter,
234 	IN	char *hw_alpha2,
235 	IN	u8 hw_chplan,
236 	IN	char *sw_alpha2,
237 	IN	u8 sw_chplan,
238 	IN	u8 def_chplan,
239 	IN	BOOLEAN AutoLoadFail
240 )
241 {
242 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
243 	PHAL_DATA_TYPE	pHalData;
244 	u8 force_hw_chplan = _FALSE;
245 	int chplan = -1;
246 	const struct country_chplan *country_ent = NULL, *ent;
247 
248 	pHalData = GET_HAL_DATA(padapter);
249 
250 	/* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
251 	if (hw_chplan == 0xFF)
252 		goto chk_hw_country_code;
253 
254 	if (AutoLoadFail == _TRUE)
255 		goto chk_sw_config;
256 
257 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
258 	if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
259 		force_hw_chplan = _TRUE;
260 #endif
261 
262 	hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
263 
264 chk_hw_country_code:
265 	if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
266 		ent = rtw_get_chplan_from_country(hw_alpha2);
267 		if (ent) {
268 			/* get chplan from hw country code, by pass hw chplan setting */
269 			country_ent = ent;
270 			chplan = ent->chplan;
271 			goto chk_sw_config;
272 		} else
273 			RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
274 	}
275 
276 	if (rtw_is_channel_plan_valid(hw_chplan))
277 		chplan = hw_chplan;
278 	else if (force_hw_chplan == _TRUE) {
279 		RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
280 		/* hw infomaton invalid, refer to sw information */
281 		force_hw_chplan = _FALSE;
282 	}
283 
284 chk_sw_config:
285 	if (force_hw_chplan == _TRUE)
286 		goto done;
287 
288 	if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
289 		ent = rtw_get_chplan_from_country(sw_alpha2);
290 		if (ent) {
291 			/* get chplan from sw country code, by pass sw chplan setting */
292 			country_ent = ent;
293 			chplan = ent->chplan;
294 			goto done;
295 		} else
296 			RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
297 	}
298 
299 	if (rtw_is_channel_plan_valid(sw_chplan)) {
300 		/* cancel hw_alpha2 because chplan is specified by sw_chplan*/
301 		country_ent = NULL;
302 		chplan = sw_chplan;
303 	} else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
304 		RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
305 
306 done:
307 	if (chplan == -1) {
308 		RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
309 		chplan = def_chplan;
310 	} else if (country_ent) {
311 		RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
312 			, country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
313 	} else
314 		RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
315 
316 	rfctl->country_ent = country_ent;
317 	rfctl->ChannelPlan = chplan;
318 	pHalData->bDisableSWChannelPlan = force_hw_chplan;
319 }
320 
321 BOOLEAN
HAL_IsLegalChannel(IN PADAPTER Adapter,IN u32 Channel)322 HAL_IsLegalChannel(
323 	IN	PADAPTER	Adapter,
324 	IN	u32			Channel
325 )
326 {
327 	BOOLEAN bLegalChannel = _TRUE;
328 
329 	if (Channel > 14) {
330 		if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
331 			bLegalChannel = _FALSE;
332 			RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
333 		}
334 	} else if ((Channel <= 14) && (Channel >= 1)) {
335 		if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
336 			bLegalChannel = _FALSE;
337 			RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
338 		}
339 	} else {
340 		bLegalChannel = _FALSE;
341 		RTW_INFO("Channel is Invalid !!!\n");
342 	}
343 
344 	return bLegalChannel;
345 }
346 
MRateToHwRate(u8 rate)347 u8	MRateToHwRate(u8 rate)
348 {
349 	u8	ret = DESC_RATE1M;
350 
351 	switch (rate) {
352 	case MGN_1M:
353 		ret = DESC_RATE1M;
354 		break;
355 	case MGN_2M:
356 		ret = DESC_RATE2M;
357 		break;
358 	case MGN_5_5M:
359 		ret = DESC_RATE5_5M;
360 		break;
361 	case MGN_11M:
362 		ret = DESC_RATE11M;
363 		break;
364 	case MGN_6M:
365 		ret = DESC_RATE6M;
366 		break;
367 	case MGN_9M:
368 		ret = DESC_RATE9M;
369 		break;
370 	case MGN_12M:
371 		ret = DESC_RATE12M;
372 		break;
373 	case MGN_18M:
374 		ret = DESC_RATE18M;
375 		break;
376 	case MGN_24M:
377 		ret = DESC_RATE24M;
378 		break;
379 	case MGN_36M:
380 		ret = DESC_RATE36M;
381 		break;
382 	case MGN_48M:
383 		ret = DESC_RATE48M;
384 		break;
385 	case MGN_54M:
386 		ret = DESC_RATE54M;
387 		break;
388 
389 	case MGN_MCS0:
390 		ret = DESC_RATEMCS0;
391 		break;
392 	case MGN_MCS1:
393 		ret = DESC_RATEMCS1;
394 		break;
395 	case MGN_MCS2:
396 		ret = DESC_RATEMCS2;
397 		break;
398 	case MGN_MCS3:
399 		ret = DESC_RATEMCS3;
400 		break;
401 	case MGN_MCS4:
402 		ret = DESC_RATEMCS4;
403 		break;
404 	case MGN_MCS5:
405 		ret = DESC_RATEMCS5;
406 		break;
407 	case MGN_MCS6:
408 		ret = DESC_RATEMCS6;
409 		break;
410 	case MGN_MCS7:
411 		ret = DESC_RATEMCS7;
412 		break;
413 	case MGN_MCS8:
414 		ret = DESC_RATEMCS8;
415 		break;
416 	case MGN_MCS9:
417 		ret = DESC_RATEMCS9;
418 		break;
419 	case MGN_MCS10:
420 		ret = DESC_RATEMCS10;
421 		break;
422 	case MGN_MCS11:
423 		ret = DESC_RATEMCS11;
424 		break;
425 	case MGN_MCS12:
426 		ret = DESC_RATEMCS12;
427 		break;
428 	case MGN_MCS13:
429 		ret = DESC_RATEMCS13;
430 		break;
431 	case MGN_MCS14:
432 		ret = DESC_RATEMCS14;
433 		break;
434 	case MGN_MCS15:
435 		ret = DESC_RATEMCS15;
436 		break;
437 	case MGN_MCS16:
438 		ret = DESC_RATEMCS16;
439 		break;
440 	case MGN_MCS17:
441 		ret = DESC_RATEMCS17;
442 		break;
443 	case MGN_MCS18:
444 		ret = DESC_RATEMCS18;
445 		break;
446 	case MGN_MCS19:
447 		ret = DESC_RATEMCS19;
448 		break;
449 	case MGN_MCS20:
450 		ret = DESC_RATEMCS20;
451 		break;
452 	case MGN_MCS21:
453 		ret = DESC_RATEMCS21;
454 		break;
455 	case MGN_MCS22:
456 		ret = DESC_RATEMCS22;
457 		break;
458 	case MGN_MCS23:
459 		ret = DESC_RATEMCS23;
460 		break;
461 	case MGN_MCS24:
462 		ret = DESC_RATEMCS24;
463 		break;
464 	case MGN_MCS25:
465 		ret = DESC_RATEMCS25;
466 		break;
467 	case MGN_MCS26:
468 		ret = DESC_RATEMCS26;
469 		break;
470 	case MGN_MCS27:
471 		ret = DESC_RATEMCS27;
472 		break;
473 	case MGN_MCS28:
474 		ret = DESC_RATEMCS28;
475 		break;
476 	case MGN_MCS29:
477 		ret = DESC_RATEMCS29;
478 		break;
479 	case MGN_MCS30:
480 		ret = DESC_RATEMCS30;
481 		break;
482 	case MGN_MCS31:
483 		ret = DESC_RATEMCS31;
484 		break;
485 
486 	case MGN_VHT1SS_MCS0:
487 		ret = DESC_RATEVHTSS1MCS0;
488 		break;
489 	case MGN_VHT1SS_MCS1:
490 		ret = DESC_RATEVHTSS1MCS1;
491 		break;
492 	case MGN_VHT1SS_MCS2:
493 		ret = DESC_RATEVHTSS1MCS2;
494 		break;
495 	case MGN_VHT1SS_MCS3:
496 		ret = DESC_RATEVHTSS1MCS3;
497 		break;
498 	case MGN_VHT1SS_MCS4:
499 		ret = DESC_RATEVHTSS1MCS4;
500 		break;
501 	case MGN_VHT1SS_MCS5:
502 		ret = DESC_RATEVHTSS1MCS5;
503 		break;
504 	case MGN_VHT1SS_MCS6:
505 		ret = DESC_RATEVHTSS1MCS6;
506 		break;
507 	case MGN_VHT1SS_MCS7:
508 		ret = DESC_RATEVHTSS1MCS7;
509 		break;
510 	case MGN_VHT1SS_MCS8:
511 		ret = DESC_RATEVHTSS1MCS8;
512 		break;
513 	case MGN_VHT1SS_MCS9:
514 		ret = DESC_RATEVHTSS1MCS9;
515 		break;
516 	case MGN_VHT2SS_MCS0:
517 		ret = DESC_RATEVHTSS2MCS0;
518 		break;
519 	case MGN_VHT2SS_MCS1:
520 		ret = DESC_RATEVHTSS2MCS1;
521 		break;
522 	case MGN_VHT2SS_MCS2:
523 		ret = DESC_RATEVHTSS2MCS2;
524 		break;
525 	case MGN_VHT2SS_MCS3:
526 		ret = DESC_RATEVHTSS2MCS3;
527 		break;
528 	case MGN_VHT2SS_MCS4:
529 		ret = DESC_RATEVHTSS2MCS4;
530 		break;
531 	case MGN_VHT2SS_MCS5:
532 		ret = DESC_RATEVHTSS2MCS5;
533 		break;
534 	case MGN_VHT2SS_MCS6:
535 		ret = DESC_RATEVHTSS2MCS6;
536 		break;
537 	case MGN_VHT2SS_MCS7:
538 		ret = DESC_RATEVHTSS2MCS7;
539 		break;
540 	case MGN_VHT2SS_MCS8:
541 		ret = DESC_RATEVHTSS2MCS8;
542 		break;
543 	case MGN_VHT2SS_MCS9:
544 		ret = DESC_RATEVHTSS2MCS9;
545 		break;
546 	case MGN_VHT3SS_MCS0:
547 		ret = DESC_RATEVHTSS3MCS0;
548 		break;
549 	case MGN_VHT3SS_MCS1:
550 		ret = DESC_RATEVHTSS3MCS1;
551 		break;
552 	case MGN_VHT3SS_MCS2:
553 		ret = DESC_RATEVHTSS3MCS2;
554 		break;
555 	case MGN_VHT3SS_MCS3:
556 		ret = DESC_RATEVHTSS3MCS3;
557 		break;
558 	case MGN_VHT3SS_MCS4:
559 		ret = DESC_RATEVHTSS3MCS4;
560 		break;
561 	case MGN_VHT3SS_MCS5:
562 		ret = DESC_RATEVHTSS3MCS5;
563 		break;
564 	case MGN_VHT3SS_MCS6:
565 		ret = DESC_RATEVHTSS3MCS6;
566 		break;
567 	case MGN_VHT3SS_MCS7:
568 		ret = DESC_RATEVHTSS3MCS7;
569 		break;
570 	case MGN_VHT3SS_MCS8:
571 		ret = DESC_RATEVHTSS3MCS8;
572 		break;
573 	case MGN_VHT3SS_MCS9:
574 		ret = DESC_RATEVHTSS3MCS9;
575 		break;
576 	case MGN_VHT4SS_MCS0:
577 		ret = DESC_RATEVHTSS4MCS0;
578 		break;
579 	case MGN_VHT4SS_MCS1:
580 		ret = DESC_RATEVHTSS4MCS1;
581 		break;
582 	case MGN_VHT4SS_MCS2:
583 		ret = DESC_RATEVHTSS4MCS2;
584 		break;
585 	case MGN_VHT4SS_MCS3:
586 		ret = DESC_RATEVHTSS4MCS3;
587 		break;
588 	case MGN_VHT4SS_MCS4:
589 		ret = DESC_RATEVHTSS4MCS4;
590 		break;
591 	case MGN_VHT4SS_MCS5:
592 		ret = DESC_RATEVHTSS4MCS5;
593 		break;
594 	case MGN_VHT4SS_MCS6:
595 		ret = DESC_RATEVHTSS4MCS6;
596 		break;
597 	case MGN_VHT4SS_MCS7:
598 		ret = DESC_RATEVHTSS4MCS7;
599 		break;
600 	case MGN_VHT4SS_MCS8:
601 		ret = DESC_RATEVHTSS4MCS8;
602 		break;
603 	case MGN_VHT4SS_MCS9:
604 		ret = DESC_RATEVHTSS4MCS9;
605 		break;
606 	default:
607 		break;
608 	}
609 
610 	return ret;
611 }
612 
hw_rate_to_m_rate(u8 rate)613 u8	hw_rate_to_m_rate(u8 rate)
614 {
615 	u8	ret_rate = MGN_1M;
616 
617 	switch (rate) {
618 
619 	case DESC_RATE1M:
620 		ret_rate = MGN_1M;
621 		break;
622 	case DESC_RATE2M:
623 		ret_rate = MGN_2M;
624 		break;
625 	case DESC_RATE5_5M:
626 		ret_rate = MGN_5_5M;
627 		break;
628 	case DESC_RATE11M:
629 		ret_rate = MGN_11M;
630 		break;
631 	case DESC_RATE6M:
632 		ret_rate = MGN_6M;
633 		break;
634 	case DESC_RATE9M:
635 		ret_rate = MGN_9M;
636 		break;
637 	case DESC_RATE12M:
638 		ret_rate = MGN_12M;
639 		break;
640 	case DESC_RATE18M:
641 		ret_rate = MGN_18M;
642 		break;
643 	case DESC_RATE24M:
644 		ret_rate = MGN_24M;
645 		break;
646 	case DESC_RATE36M:
647 		ret_rate = MGN_36M;
648 		break;
649 	case DESC_RATE48M:
650 		ret_rate = MGN_48M;
651 		break;
652 	case DESC_RATE54M:
653 		ret_rate = MGN_54M;
654 		break;
655 	case DESC_RATEMCS0:
656 		ret_rate = MGN_MCS0;
657 		break;
658 	case DESC_RATEMCS1:
659 		ret_rate = MGN_MCS1;
660 		break;
661 	case DESC_RATEMCS2:
662 		ret_rate = MGN_MCS2;
663 		break;
664 	case DESC_RATEMCS3:
665 		ret_rate = MGN_MCS3;
666 		break;
667 	case DESC_RATEMCS4:
668 		ret_rate = MGN_MCS4;
669 		break;
670 	case DESC_RATEMCS5:
671 		ret_rate = MGN_MCS5;
672 		break;
673 	case DESC_RATEMCS6:
674 		ret_rate = MGN_MCS6;
675 		break;
676 	case DESC_RATEMCS7:
677 		ret_rate = MGN_MCS7;
678 		break;
679 	case DESC_RATEMCS8:
680 		ret_rate = MGN_MCS8;
681 		break;
682 	case DESC_RATEMCS9:
683 		ret_rate = MGN_MCS9;
684 		break;
685 	case DESC_RATEMCS10:
686 		ret_rate = MGN_MCS10;
687 		break;
688 	case DESC_RATEMCS11:
689 		ret_rate = MGN_MCS11;
690 		break;
691 	case DESC_RATEMCS12:
692 		ret_rate = MGN_MCS12;
693 		break;
694 	case DESC_RATEMCS13:
695 		ret_rate = MGN_MCS13;
696 		break;
697 	case DESC_RATEMCS14:
698 		ret_rate = MGN_MCS14;
699 		break;
700 	case DESC_RATEMCS15:
701 		ret_rate = MGN_MCS15;
702 		break;
703 	case DESC_RATEMCS16:
704 		ret_rate = MGN_MCS16;
705 		break;
706 	case DESC_RATEMCS17:
707 		ret_rate = MGN_MCS17;
708 		break;
709 	case DESC_RATEMCS18:
710 		ret_rate = MGN_MCS18;
711 		break;
712 	case DESC_RATEMCS19:
713 		ret_rate = MGN_MCS19;
714 		break;
715 	case DESC_RATEMCS20:
716 		ret_rate = MGN_MCS20;
717 		break;
718 	case DESC_RATEMCS21:
719 		ret_rate = MGN_MCS21;
720 		break;
721 	case DESC_RATEMCS22:
722 		ret_rate = MGN_MCS22;
723 		break;
724 	case DESC_RATEMCS23:
725 		ret_rate = MGN_MCS23;
726 		break;
727 	case DESC_RATEMCS24:
728 		ret_rate = MGN_MCS24;
729 		break;
730 	case DESC_RATEMCS25:
731 		ret_rate = MGN_MCS25;
732 		break;
733 	case DESC_RATEMCS26:
734 		ret_rate = MGN_MCS26;
735 		break;
736 	case DESC_RATEMCS27:
737 		ret_rate = MGN_MCS27;
738 		break;
739 	case DESC_RATEMCS28:
740 		ret_rate = MGN_MCS28;
741 		break;
742 	case DESC_RATEMCS29:
743 		ret_rate = MGN_MCS29;
744 		break;
745 	case DESC_RATEMCS30:
746 		ret_rate = MGN_MCS30;
747 		break;
748 	case DESC_RATEMCS31:
749 		ret_rate = MGN_MCS31;
750 		break;
751 	case DESC_RATEVHTSS1MCS0:
752 		ret_rate = MGN_VHT1SS_MCS0;
753 		break;
754 	case DESC_RATEVHTSS1MCS1:
755 		ret_rate = MGN_VHT1SS_MCS1;
756 		break;
757 	case DESC_RATEVHTSS1MCS2:
758 		ret_rate = MGN_VHT1SS_MCS2;
759 		break;
760 	case DESC_RATEVHTSS1MCS3:
761 		ret_rate = MGN_VHT1SS_MCS3;
762 		break;
763 	case DESC_RATEVHTSS1MCS4:
764 		ret_rate = MGN_VHT1SS_MCS4;
765 		break;
766 	case DESC_RATEVHTSS1MCS5:
767 		ret_rate = MGN_VHT1SS_MCS5;
768 		break;
769 	case DESC_RATEVHTSS1MCS6:
770 		ret_rate = MGN_VHT1SS_MCS6;
771 		break;
772 	case DESC_RATEVHTSS1MCS7:
773 		ret_rate = MGN_VHT1SS_MCS7;
774 		break;
775 	case DESC_RATEVHTSS1MCS8:
776 		ret_rate = MGN_VHT1SS_MCS8;
777 		break;
778 	case DESC_RATEVHTSS1MCS9:
779 		ret_rate = MGN_VHT1SS_MCS9;
780 		break;
781 	case DESC_RATEVHTSS2MCS0:
782 		ret_rate = MGN_VHT2SS_MCS0;
783 		break;
784 	case DESC_RATEVHTSS2MCS1:
785 		ret_rate = MGN_VHT2SS_MCS1;
786 		break;
787 	case DESC_RATEVHTSS2MCS2:
788 		ret_rate = MGN_VHT2SS_MCS2;
789 		break;
790 	case DESC_RATEVHTSS2MCS3:
791 		ret_rate = MGN_VHT2SS_MCS3;
792 		break;
793 	case DESC_RATEVHTSS2MCS4:
794 		ret_rate = MGN_VHT2SS_MCS4;
795 		break;
796 	case DESC_RATEVHTSS2MCS5:
797 		ret_rate = MGN_VHT2SS_MCS5;
798 		break;
799 	case DESC_RATEVHTSS2MCS6:
800 		ret_rate = MGN_VHT2SS_MCS6;
801 		break;
802 	case DESC_RATEVHTSS2MCS7:
803 		ret_rate = MGN_VHT2SS_MCS7;
804 		break;
805 	case DESC_RATEVHTSS2MCS8:
806 		ret_rate = MGN_VHT2SS_MCS8;
807 		break;
808 	case DESC_RATEVHTSS2MCS9:
809 		ret_rate = MGN_VHT2SS_MCS9;
810 		break;
811 	case DESC_RATEVHTSS3MCS0:
812 		ret_rate = MGN_VHT3SS_MCS0;
813 		break;
814 	case DESC_RATEVHTSS3MCS1:
815 		ret_rate = MGN_VHT3SS_MCS1;
816 		break;
817 	case DESC_RATEVHTSS3MCS2:
818 		ret_rate = MGN_VHT3SS_MCS2;
819 		break;
820 	case DESC_RATEVHTSS3MCS3:
821 		ret_rate = MGN_VHT3SS_MCS3;
822 		break;
823 	case DESC_RATEVHTSS3MCS4:
824 		ret_rate = MGN_VHT3SS_MCS4;
825 		break;
826 	case DESC_RATEVHTSS3MCS5:
827 		ret_rate = MGN_VHT3SS_MCS5;
828 		break;
829 	case DESC_RATEVHTSS3MCS6:
830 		ret_rate = MGN_VHT3SS_MCS6;
831 		break;
832 	case DESC_RATEVHTSS3MCS7:
833 		ret_rate = MGN_VHT3SS_MCS7;
834 		break;
835 	case DESC_RATEVHTSS3MCS8:
836 		ret_rate = MGN_VHT3SS_MCS8;
837 		break;
838 	case DESC_RATEVHTSS3MCS9:
839 		ret_rate = MGN_VHT3SS_MCS9;
840 		break;
841 	case DESC_RATEVHTSS4MCS0:
842 		ret_rate = MGN_VHT4SS_MCS0;
843 		break;
844 	case DESC_RATEVHTSS4MCS1:
845 		ret_rate = MGN_VHT4SS_MCS1;
846 		break;
847 	case DESC_RATEVHTSS4MCS2:
848 		ret_rate = MGN_VHT4SS_MCS2;
849 		break;
850 	case DESC_RATEVHTSS4MCS3:
851 		ret_rate = MGN_VHT4SS_MCS3;
852 		break;
853 	case DESC_RATEVHTSS4MCS4:
854 		ret_rate = MGN_VHT4SS_MCS4;
855 		break;
856 	case DESC_RATEVHTSS4MCS5:
857 		ret_rate = MGN_VHT4SS_MCS5;
858 		break;
859 	case DESC_RATEVHTSS4MCS6:
860 		ret_rate = MGN_VHT4SS_MCS6;
861 		break;
862 	case DESC_RATEVHTSS4MCS7:
863 		ret_rate = MGN_VHT4SS_MCS7;
864 		break;
865 	case DESC_RATEVHTSS4MCS8:
866 		ret_rate = MGN_VHT4SS_MCS8;
867 		break;
868 	case DESC_RATEVHTSS4MCS9:
869 		ret_rate = MGN_VHT4SS_MCS9;
870 		break;
871 
872 	default:
873 		RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate);
874 		break;
875 	}
876 
877 	return ret_rate;
878 }
879 
HalSetBrateCfg(IN PADAPTER Adapter,IN u8 * mBratesOS,OUT u16 * pBrateCfg)880 void	HalSetBrateCfg(
881 	IN PADAPTER		Adapter,
882 	IN u8			*mBratesOS,
883 	OUT u16			*pBrateCfg)
884 {
885 	u8	i, is_brate, brate;
886 
887 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
888 		is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
889 		brate = mBratesOS[i] & 0x7f;
890 
891 		if (is_brate) {
892 			switch (brate) {
893 			case IEEE80211_CCK_RATE_1MB:
894 				*pBrateCfg |= RATE_1M;
895 				break;
896 			case IEEE80211_CCK_RATE_2MB:
897 				*pBrateCfg |= RATE_2M;
898 				break;
899 			case IEEE80211_CCK_RATE_5MB:
900 				*pBrateCfg |= RATE_5_5M;
901 				break;
902 			case IEEE80211_CCK_RATE_11MB:
903 				*pBrateCfg |= RATE_11M;
904 				break;
905 			case IEEE80211_OFDM_RATE_6MB:
906 				*pBrateCfg |= RATE_6M;
907 				break;
908 			case IEEE80211_OFDM_RATE_9MB:
909 				*pBrateCfg |= RATE_9M;
910 				break;
911 			case IEEE80211_OFDM_RATE_12MB:
912 				*pBrateCfg |= RATE_12M;
913 				break;
914 			case IEEE80211_OFDM_RATE_18MB:
915 				*pBrateCfg |= RATE_18M;
916 				break;
917 			case IEEE80211_OFDM_RATE_24MB:
918 				*pBrateCfg |= RATE_24M;
919 				break;
920 			case IEEE80211_OFDM_RATE_36MB:
921 				*pBrateCfg |= RATE_36M;
922 				break;
923 			case IEEE80211_OFDM_RATE_48MB:
924 				*pBrateCfg |= RATE_48M;
925 				break;
926 			case IEEE80211_OFDM_RATE_54MB:
927 				*pBrateCfg |= RATE_54M;
928 				break;
929 			}
930 		}
931 	}
932 }
933 
934 static VOID
_OneOutPipeMapping(IN PADAPTER pAdapter)935 _OneOutPipeMapping(
936 	IN	PADAPTER	pAdapter
937 )
938 {
939 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
940 
941 	pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
942 	pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
943 	pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
944 	pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
945 
946 	pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
947 	pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
948 	pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
949 	pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
950 }
951 
952 static VOID
_TwoOutPipeMapping(IN PADAPTER pAdapter,IN BOOLEAN bWIFICfg)953 _TwoOutPipeMapping(
954 	IN	PADAPTER	pAdapter,
955 	IN	BOOLEAN		bWIFICfg
956 )
957 {
958 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
959 
960 	if (bWIFICfg) { /* WMM */
961 
962 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
963 		/* {  0, 	1, 	0, 	1, 	0, 	0, 	0, 	0, 		0	}; */
964 		/* 0:ep_0 num, 1:ep_1 num */
965 
966 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
967 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
968 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
969 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
970 
971 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
972 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
973 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
974 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
975 
976 	} else { /* typical setting */
977 
978 
979 		/* BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA */
980 		/* {  1, 	1, 	0, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
981 		/* 0:ep_0 num, 1:ep_1 num */
982 
983 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
984 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
985 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
986 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
987 
988 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
989 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
990 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
991 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
992 
993 	}
994 
995 }
996 
_ThreeOutPipeMapping(IN PADAPTER pAdapter,IN BOOLEAN bWIFICfg)997 static VOID _ThreeOutPipeMapping(
998 	IN	PADAPTER	pAdapter,
999 	IN	BOOLEAN		bWIFICfg
1000 )
1001 {
1002 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
1003 
1004 	if (bWIFICfg) { /* for WMM */
1005 
1006 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1007 		/* {  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	}; */
1008 		/* 0:H, 1:N, 2:L */
1009 
1010 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1011 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1012 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1013 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1014 
1015 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1016 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1017 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1018 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1019 
1020 	} else { /* typical setting */
1021 
1022 
1023 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1024 		/* {  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
1025 		/* 0:H, 1:N, 2:L */
1026 
1027 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1028 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1029 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1030 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1031 
1032 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1033 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1034 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1035 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
1036 	}
1037 
1038 }
_FourOutPipeMapping(IN PADAPTER pAdapter,IN BOOLEAN bWIFICfg)1039 static VOID _FourOutPipeMapping(
1040 	IN	PADAPTER	pAdapter,
1041 	IN	BOOLEAN		bWIFICfg
1042 )
1043 {
1044 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
1045 
1046 	if (bWIFICfg) { /* for WMM */
1047 
1048 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1049 		/* {  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	}; */
1050 		/* 0:H, 1:N, 2:L ,3:E */
1051 
1052 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1053 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1054 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1055 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1056 
1057 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1058 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1059 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1060 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1061 
1062 	} else { /* typical setting */
1063 
1064 
1065 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1066 		/* {  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
1067 		/* 0:H, 1:N, 2:L */
1068 
1069 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1070 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1071 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1072 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1073 
1074 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1075 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1076 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1077 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
1078 	}
1079 
1080 }
1081 BOOLEAN
Hal_MappingOutPipe(IN PADAPTER pAdapter,IN u8 NumOutPipe)1082 Hal_MappingOutPipe(
1083 	IN	PADAPTER	pAdapter,
1084 	IN	u8		NumOutPipe
1085 )
1086 {
1087 	struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1088 
1089 	BOOLEAN	 bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1090 
1091 	BOOLEAN result = _TRUE;
1092 
1093 	switch (NumOutPipe) {
1094 	case 2:
1095 		_TwoOutPipeMapping(pAdapter, bWIFICfg);
1096 		break;
1097 	case 3:
1098 	case 4:
1099 		_ThreeOutPipeMapping(pAdapter, bWIFICfg);
1100 		break;
1101 	case 1:
1102 		_OneOutPipeMapping(pAdapter);
1103 		break;
1104 	default:
1105 		result = _FALSE;
1106 		break;
1107 	}
1108 
1109 	return result;
1110 
1111 }
1112 
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1113 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1114 {
1115 	if (padapter->hal_func.reqtxrpt)
1116 		padapter->hal_func.reqtxrpt(padapter, macid);
1117 }
1118 
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1119 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1120 {
1121 	int i;
1122 	_adapter *iface;
1123 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1124 	u8 mac_addr[ETH_ALEN];
1125 
1126 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1127 	rtw_mbid_cam_dump(sel, __func__, adapter);
1128 #else
1129 	for (i = 0; i < dvobj->iface_nums; i++) {
1130 		iface = dvobj->padapters[i];
1131 		if (iface) {
1132 			rtw_hal_get_hwreg(iface, HW_VAR_MAC_ADDR, mac_addr);
1133 			RTW_PRINT_SEL(sel, ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",
1134 				ADPT_ARG(iface), iface->hw_port, MAC_ARG(mac_addr));
1135 		}
1136 	}
1137 #endif
1138 }
1139 
1140 #ifdef RTW_HALMAC
rtw_hal_hw_port_enable(_adapter * adapter)1141 void rtw_hal_hw_port_enable(_adapter *adapter)
1142 {
1143 #if 1
1144 	u8 port_enable = _TRUE;
1145 
1146 	rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1147 #else
1148 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1149 	struct rtw_halmac_bcn_ctrl bcn_ctrl;
1150 
1151 	_rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
1152 	bcn_ctrl.enable_bcn = 1;
1153 
1154 	/*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1155 				struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
1156 	if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
1157 		RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
1158 		rtw_warn_on(1);
1159 	}
1160 #endif
1161 }
rtw_hal_hw_port_disable(_adapter * adapter)1162 void rtw_hal_hw_port_disable(_adapter *adapter)
1163 {
1164 	u8 port_enable = _FALSE;
1165 
1166 	rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1167 }
1168 
rtw_restore_hw_port_cfg(_adapter * adapter)1169 void rtw_restore_hw_port_cfg(_adapter *adapter)
1170 {
1171 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1172 
1173 #else
1174 	int i;
1175 	_adapter *iface;
1176 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1177 
1178 	for (i = 0; i < dvobj->iface_nums; i++) {
1179 		iface = dvobj->padapters[i];
1180 		if (iface)
1181 			rtw_hal_hw_port_enable(iface);
1182 	}
1183 #endif
1184 }
1185 #endif
1186 
rtw_restore_mac_addr(_adapter * adapter)1187 void rtw_restore_mac_addr(_adapter *adapter)
1188 {
1189 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1190 	_adapter *iface;
1191 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1192 
1193 	rtw_mbid_cam_restore(adapter);
1194 #else
1195 	int i;
1196 	_adapter *iface;
1197 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1198 
1199 	for (i = 0; i < dvobj->iface_nums; i++) {
1200 		iface = dvobj->padapters[i];
1201 		if (iface)
1202 			rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
1203 	}
1204 #endif
1205 	if (1)
1206 		rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1207 }
1208 
rtw_init_hal_com_default_value(PADAPTER Adapter)1209 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1210 {
1211 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
1212 	struct registry_priv *regsty = adapter_to_regsty(Adapter);
1213 
1214 	pHalData->AntDetection = 1;
1215 	pHalData->antenna_test = _FALSE;
1216 	pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
1217 }
1218 
1219 #ifdef CONFIG_FW_C2H_REG
c2h_evt_clear(_adapter * adapter)1220 void c2h_evt_clear(_adapter *adapter)
1221 {
1222 	rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1223 }
1224 
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1225 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1226 {
1227 	s32 ret = _FAIL;
1228 	int i;
1229 	u8 trigger;
1230 
1231 	if (buf == NULL)
1232 		goto exit;
1233 
1234 	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1235 
1236 	if (trigger == C2H_EVT_HOST_CLOSE) {
1237 		goto exit; /* Not ready */
1238 	} else if (trigger != C2H_EVT_FW_CLOSE) {
1239 		goto clear_evt; /* Not a valid value */
1240 	}
1241 
1242 	_rtw_memset(buf, 0, C2H_REG_LEN);
1243 
1244 	/* Read ID, LEN, SEQ */
1245 	SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1246 	SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1247 	SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1248 
1249 	if (0) {
1250 		RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1251 			, C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1252 	}
1253 
1254 	/* Read the content */
1255 	for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1256 		*(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1257 
1258 	RTW_DBG_DUMP("payload:\n", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1259 
1260 	ret = _SUCCESS;
1261 
1262 clear_evt:
1263 	/*
1264 	* Clear event to notify FW we have read the command.
1265 	* If this field isn't clear, the FW won't update the next command message.
1266 	*/
1267 	c2h_evt_clear(adapter);
1268 
1269 exit:
1270 	return ret;
1271 }
1272 #endif /* CONFIG_FW_C2H_REG */
1273 
1274 #ifdef CONFIG_FW_C2H_PKT
1275 #ifndef DBG_C2H_PKT_PRE_HDL
1276 #define DBG_C2H_PKT_PRE_HDL 0
1277 #endif
1278 #ifndef DBG_C2H_PKT_HDL
1279 #define DBG_C2H_PKT_HDL 0
1280 #endif
rtw_hal_c2h_pkt_pre_hdl(_adapter * adapter,u8 * buf,u16 len)1281 void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1282 {
1283 #ifdef RTW_HALMAC
1284 	/* TODO: extract hal_mac IC's code here*/
1285 #else
1286 	u8 parse_fail = 0;
1287 	u8 hdl_here = 0;
1288 	s32 ret = _FAIL;
1289 	u8 id, seq, plen;
1290 	u8 *payload;
1291 
1292 	if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1293 		parse_fail = 1;
1294 		goto exit;
1295 	}
1296 
1297 	hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1298 	if (hdl_here)
1299 		ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1300 	else
1301 		ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1302 
1303 exit:
1304 	if (parse_fail)
1305 		RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1306 	else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1307 		RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1308 			, hdl_here ? "handle" : "enqueue"
1309 			, ret == _SUCCESS ? "ok" : "fail"
1310 		);
1311 		if (DBG_C2H_PKT_PRE_HDL >= 2)
1312 			RTW_PRINT_DUMP("dump: ", buf, len);
1313 	}
1314 #endif
1315 }
1316 
rtw_hal_c2h_pkt_hdl(_adapter * adapter,u8 * buf,u16 len)1317 void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1318 {
1319 #ifdef RTW_HALMAC
1320 	adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1321 #else
1322 	u8 parse_fail = 0;
1323 	u8 bypass = 0;
1324 	s32 ret = _FAIL;
1325 	u8 id, seq, plen;
1326 	u8 *payload;
1327 
1328 	if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1329 		parse_fail = 1;
1330 		goto exit;
1331 	}
1332 
1333 #ifdef CONFIG_WOWLAN
1334 	if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1335 		bypass = 1;
1336 		ret = _SUCCESS;
1337 		goto exit;
1338 	}
1339 #endif
1340 
1341 	ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1342 
1343 exit:
1344 	if (parse_fail)
1345 		RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1346 	else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1347 		RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1348 			, !bypass ? "handle" : "bypass"
1349 			, ret == _SUCCESS ? "ok" : "fail"
1350 		);
1351 		if (DBG_C2H_PKT_HDL >= 2)
1352 			RTW_PRINT_DUMP("dump: ", buf, len);
1353 	}
1354 #endif
1355 }
1356 #endif /* CONFIG_FW_C2H_PKT */
1357 
c2h_iqk_offload(_adapter * adapter,u8 * data,u8 len)1358 void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1359 {
1360 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1361 	struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1362 
1363 	RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1364 	if (0)
1365 		RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1366 
1367 	rtw_sctx_done(&iqk_sctx);
1368 }
1369 
c2h_iqk_offload_wait(_adapter * adapter,u32 timeout_ms)1370 int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1371 {
1372 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1373 	struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1374 
1375 	iqk_sctx->submit_time = rtw_get_current_time();
1376 	iqk_sctx->timeout_ms = timeout_ms;
1377 	iqk_sctx->status = RTW_SCTX_SUBMITTED;
1378 
1379 	return rtw_sctx_wait(iqk_sctx, __func__);
1380 }
1381 
1382 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1383 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1384 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1385 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data)			LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1386 #define	GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1387 #define	GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1388 #define	GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1389 #define	GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1390 #define	GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1391 #define	GET_C2H_MAC_HIDDEN_RPT_BW(_data)				LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1392 #define	GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1393 #define	GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1394 #define	GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1395 
1396 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1397 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1398 #endif
1399 
1400 #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1401 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1402 {
1403 	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
1404 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1405 	int ret = _FAIL;
1406 
1407 	u32 uuid;
1408 	u8 uuid_x;
1409 	u8 uuid_y;
1410 	u8 uuid_z;
1411 	u16 uuid_crc;
1412 
1413 	u8 hci_type;
1414 	u8 package_type;
1415 	u8 tr_switch;
1416 	u8 wl_func;
1417 	u8 hw_stype;
1418 	u8 bw;
1419 	u8 ant_num;
1420 	u8 protocol;
1421 	u8 nic;
1422 
1423 	int i;
1424 
1425 	if (len < MAC_HIDDEN_RPT_LEN) {
1426 		RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1427 		goto exit;
1428 	}
1429 
1430 	uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1431 	uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1432 	uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1433 	uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1434 
1435 	hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1436 	package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1437 
1438 	tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1439 
1440 	wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1441 	hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1442 
1443 	bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1444 	ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1445 
1446 	protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1447 	nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1448 
1449 	if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1450 		for (i = 0; i < len; i++)
1451 			RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1452 
1453 		RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1454 		RTW_PRINT("hci_type:0x%x\n", hci_type);
1455 		RTW_PRINT("package_type:0x%x\n", package_type);
1456 		RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1457 		RTW_PRINT("wl_func:0x%x\n", wl_func);
1458 		RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1459 		RTW_PRINT("bw:0x%x\n", bw);
1460 		RTW_PRINT("ant_num:0x%x\n", ant_num);
1461 		RTW_PRINT("protocol:0x%x\n", protocol);
1462 		RTW_PRINT("nic:0x%x\n", nic);
1463 	}
1464 
1465 	/*
1466 	* NOTICE:
1467 	* for now, the following is common info/format
1468 	* if there is any hal difference need to export
1469 	* some IC dependent code will need to be implement
1470 	*/
1471 	hal_data->PackageType = package_type;
1472 	hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1473 	hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1474 	hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ant_num);
1475 	hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ant_num);
1476 	hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1477 	hal_spec->hci_type = hci_type;
1478 
1479 	/* TODO: tr_switch */
1480 
1481 	ret = _SUCCESS;
1482 
1483 exit:
1484 	return ret;
1485 }
1486 
c2h_mac_hidden_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1487 int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1488 {
1489 	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
1490 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1491 	int ret = _FAIL;
1492 
1493 	int i;
1494 
1495 	if (len < MAC_HIDDEN_RPT_2_LEN) {
1496 		RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1497 		goto exit;
1498 	}
1499 
1500 	if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1501 		for (i = 0; i < len; i++)
1502 			RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1503 	}
1504 
1505 	#ifdef CONFIG_RTL8188F
1506 	if (IS_8188F(hal_data->version_id)) {
1507 		#define GET_C2H_MAC_HIDDEN_RPT_IRV(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
1508 		u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
1509 
1510 		if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1511 			RTW_PRINT("irv:0x%x\n", irv);
1512 
1513 		if(irv != 0xf)
1514 			hal_data->version_id.CUTVersion = irv;
1515 	}
1516 	#endif
1517 
1518 	ret = _SUCCESS;
1519 
1520 exit:
1521 	return ret;
1522 }
1523 
hal_read_mac_hidden_rpt(_adapter * adapter)1524 int hal_read_mac_hidden_rpt(_adapter *adapter)
1525 {
1526 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(adapter);
1527 	int ret = _FAIL;
1528 	int ret_fwdl;
1529 	u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1530 	systime start = rtw_get_current_time();
1531 	u32 cnt = 0;
1532 	u32 timeout_ms = 800;
1533 	u32 min_cnt = 10;
1534 	u8 id = C2H_DEFEATURE_RSVD;
1535 	int i;
1536 
1537 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1538 	u8 hci_type = rtw_get_intf_type(adapter);
1539 
1540 	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1541 		&& !rtw_is_hw_init_completed(adapter))
1542 		rtw_hal_power_on(adapter);
1543 #endif
1544 
1545 	/* inform FW mac hidden rpt from reg is needed */
1546 	rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1547 
1548 	/* download FW */
1549 	pHalData->not_xmitframe_fw_dl = 1;
1550 	ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1551 	pHalData->not_xmitframe_fw_dl = 0;
1552 	if (ret_fwdl != _SUCCESS)
1553 		goto mac_hidden_rpt_hdl;
1554 
1555 	/* polling for data ready */
1556 	start = rtw_get_current_time();
1557 	do {
1558 		cnt++;
1559 		id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1560 		if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1561 			break;
1562 		rtw_msleep_os(10);
1563 	} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1564 
1565 	if (id == C2H_MAC_HIDDEN_RPT) {
1566 		/* read data */
1567 		for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1568 			mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1569 	}
1570 
1571 	/* inform FW mac hidden rpt has read */
1572 	rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1573 
1574 mac_hidden_rpt_hdl:
1575 	c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1576 	c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1577 
1578 	if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1579 		ret = _SUCCESS;
1580 
1581 exit:
1582 
1583 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1584 	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1585 		&& !rtw_is_hw_init_completed(adapter))
1586 		rtw_hal_power_off(adapter);
1587 #endif
1588 
1589 	RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1590 		, (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1591 
1592 	return ret;
1593 }
1594 #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1595 
c2h_defeature_dbg_hdl(_adapter * adapter,u8 * data,u8 len)1596 int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1597 {
1598 	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
1599 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1600 	int ret = _FAIL;
1601 
1602 	int i;
1603 
1604 	if (len < DEFEATURE_DBG_LEN) {
1605 		RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1606 		goto exit;
1607 	}
1608 
1609 	for (i = 0; i < len; i++)
1610 		RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1611 
1612 	ret = _SUCCESS;
1613 
1614 exit:
1615 	return ret;
1616 }
1617 
1618 #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1619 #define DBG_CUSTOMER_STR_RPT_HANDLE 0
1620 #endif
1621 
1622 #ifdef CONFIG_RTW_CUSTOMER_STR
rtw_hal_h2c_customer_str_req(_adapter * adapter)1623 s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1624 {
1625 	u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1626 
1627 	SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1628 	return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1629 }
1630 
1631 #define	C2H_CUSTOMER_STR_RPT_BYTE0(_data)		((u8 *)(_data))
1632 #define	C2H_CUSTOMER_STR_RPT_2_BYTE8(_data)		((u8 *)(_data))
1633 
c2h_customer_str_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1634 int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1635 {
1636 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1637 	int ret = _FAIL;
1638 	int i;
1639 
1640 	if (len < CUSTOMER_STR_RPT_LEN) {
1641 		RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1642 		goto exit;
1643 	}
1644 
1645 	if (DBG_CUSTOMER_STR_RPT_HANDLE)
1646 		RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1647 
1648 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1649 
1650 	if (dvobj->customer_str_sctx != NULL) {
1651 		if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1652 			RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1653 		_rtw_memcpy(dvobj->customer_str,  C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1654 		dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1655 	} else
1656 		RTW_WARN("%s sctx not set\n", __func__);
1657 
1658 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1659 
1660 	ret = _SUCCESS;
1661 
1662 exit:
1663 	return ret;
1664 }
1665 
c2h_customer_str_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1666 int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1667 {
1668 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1669 	int ret = _FAIL;
1670 	int i;
1671 
1672 	if (len < CUSTOMER_STR_RPT_2_LEN) {
1673 		RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1674 		goto exit;
1675 	}
1676 
1677 	if (DBG_CUSTOMER_STR_RPT_HANDLE)
1678 		RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1679 
1680 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1681 
1682 	if (dvobj->customer_str_sctx != NULL) {
1683 		if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1684 			RTW_WARN("%s rpt not ready\n", __func__);
1685 		_rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN,  C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1686 		rtw_sctx_done(&dvobj->customer_str_sctx);
1687 	} else
1688 		RTW_WARN("%s sctx not set\n", __func__);
1689 
1690 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1691 
1692 	ret = _SUCCESS;
1693 
1694 exit:
1695 	return ret;
1696 }
1697 
1698 /* read customer str */
rtw_hal_customer_str_read(_adapter * adapter,u8 * cs)1699 s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1700 {
1701 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1702 	struct submit_ctx sctx;
1703 	s32 ret = _SUCCESS;
1704 
1705 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1706 	if (dvobj->customer_str_sctx != NULL)
1707 		ret = _FAIL;
1708 	else {
1709 		rtw_sctx_init(&sctx, 2 * 1000);
1710 		dvobj->customer_str_sctx = &sctx;
1711 	}
1712 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1713 
1714 	if (ret == _FAIL) {
1715 		RTW_WARN("%s another handle ongoing\n", __func__);
1716 		goto exit;
1717 	}
1718 
1719 	ret = rtw_customer_str_req_cmd(adapter);
1720 	if (ret != _SUCCESS) {
1721 		RTW_WARN("%s read cmd fail\n", __func__);
1722 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1723 		dvobj->customer_str_sctx = NULL;
1724 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1725 		goto exit;
1726 	}
1727 
1728 	/* wait till rpt done or timeout */
1729 	rtw_sctx_wait(&sctx, __func__);
1730 
1731 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1732 	dvobj->customer_str_sctx = NULL;
1733 	if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1734 		_rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1735 	else
1736 		ret = _FAIL;
1737 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1738 
1739 exit:
1740 	return ret;
1741 }
1742 
rtw_hal_h2c_customer_str_write(_adapter * adapter,const u8 * cs)1743 s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1744 {
1745 	u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1746 	u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1747 	u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1748 	s32 ret;
1749 
1750 	SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1751 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1752 
1753 	SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1754 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1755 
1756 	SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1757 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1758 
1759 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1760 	if (ret != _SUCCESS) {
1761 		RTW_WARN("%s w1 fail\n", __func__);
1762 		goto exit;
1763 	}
1764 
1765 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1766 	if (ret != _SUCCESS) {
1767 		RTW_WARN("%s w2 fail\n", __func__);
1768 		goto exit;
1769 	}
1770 
1771 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1772 	if (ret != _SUCCESS) {
1773 		RTW_WARN("%s w3 fail\n", __func__);
1774 		goto exit;
1775 	}
1776 
1777 exit:
1778 	return ret;
1779 }
1780 
1781 /* write customer str and check if value reported is the same as requested */
rtw_hal_customer_str_write(_adapter * adapter,const u8 * cs)1782 s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1783 {
1784 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1785 	struct submit_ctx sctx;
1786 	s32 ret = _SUCCESS;
1787 
1788 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1789 	if (dvobj->customer_str_sctx != NULL)
1790 		ret = _FAIL;
1791 	else {
1792 		rtw_sctx_init(&sctx, 2 * 1000);
1793 		dvobj->customer_str_sctx = &sctx;
1794 	}
1795 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1796 
1797 	if (ret == _FAIL) {
1798 		RTW_WARN("%s another handle ongoing\n", __func__);
1799 		goto exit;
1800 	}
1801 
1802 	ret = rtw_customer_str_write_cmd(adapter, cs);
1803 	if (ret != _SUCCESS) {
1804 		RTW_WARN("%s write cmd fail\n", __func__);
1805 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1806 		dvobj->customer_str_sctx = NULL;
1807 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1808 		goto exit;
1809 	}
1810 
1811 	ret = rtw_customer_str_req_cmd(adapter);
1812 	if (ret != _SUCCESS) {
1813 		RTW_WARN("%s read cmd fail\n", __func__);
1814 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1815 		dvobj->customer_str_sctx = NULL;
1816 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1817 		goto exit;
1818 	}
1819 
1820 	/* wait till rpt done or timeout */
1821 	rtw_sctx_wait(&sctx, __func__);
1822 
1823 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1824 	dvobj->customer_str_sctx = NULL;
1825 	if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
1826 		if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
1827 			RTW_WARN("%s read back check fail\n", __func__);
1828 			RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
1829 			RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1830 			ret = _FAIL;
1831 		}
1832 	} else
1833 		ret = _FAIL;
1834 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1835 
1836 exit:
1837 	return ret;
1838 }
1839 #endif /* CONFIG_RTW_CUSTOMER_STR */
1840 
rtw_hal_update_sta_wset(_adapter * adapter,struct sta_info * psta)1841 void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
1842 {
1843 	u8 w_set = 0;
1844 
1845 	if (psta->wireless_mode & WIRELESS_11B)
1846 		w_set |= WIRELESS_CCK;
1847 
1848 	if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
1849 		w_set |= WIRELESS_OFDM;
1850 
1851 	if (psta->wireless_mode & WIRELESS_11_24N)
1852 		w_set |= WIRELESS_HT;
1853 
1854 	if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))
1855 		w_set |= WIRELESS_VHT;
1856 
1857 	psta->cmn.support_wireless_set = w_set;
1858 }
1859 
rtw_hal_update_sta_mimo_type(_adapter * adapter,struct sta_info * psta)1860 void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
1861 {
1862 	s8 tx_nss, rx_nss;
1863 
1864 	tx_nss = rtw_get_sta_tx_nss(adapter, psta);
1865 	rx_nss =  rtw_get_sta_rx_nss(adapter, psta);
1866 	if ((tx_nss == 1) && (rx_nss == 1))
1867 		psta->cmn.mimo_type = RF_1T1R;
1868 	else if ((tx_nss == 1) && (rx_nss == 2))
1869 		psta->cmn.mimo_type = RF_1T2R;
1870 	else if ((tx_nss == 2) && (rx_nss == 2))
1871 		psta->cmn.mimo_type = RF_2T2R;
1872 	else if ((tx_nss == 2) && (rx_nss == 3))
1873 		psta->cmn.mimo_type = RF_2T3R;
1874 	else if ((tx_nss == 2) && (rx_nss == 4))
1875 		psta->cmn.mimo_type = RF_2T4R;
1876 	else if ((tx_nss == 3) && (rx_nss == 3))
1877 		psta->cmn.mimo_type = RF_3T3R;
1878 	else if ((tx_nss == 3) && (rx_nss == 4))
1879 		psta->cmn.mimo_type = RF_3T4R;
1880 	else if ((tx_nss == 4) && (rx_nss == 4))
1881 		psta->cmn.mimo_type = RF_4T4R;
1882 	else
1883 		rtw_warn_on(1);
1884 
1885 	RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
1886 			psta->cmn.mac_id, tx_nss, rx_nss);
1887 }
1888 
rtw_hal_update_sta_smps_cap(_adapter * adapter,struct sta_info * psta)1889 void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
1890 {
1891 	/*Spatial Multiplexing Power Save*/
1892 #if 0
1893 	if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
1894 		#ifdef CONFIG_80211N_HT
1895 		if (psta->htpriv.ht_option) {
1896 			if (psta->htpriv.smps_cap == 0)
1897 				psta->cmn.sm_ps = SM_PS_STATIC;
1898 			else if (psta->htpriv.smps_cap == 1)
1899 				psta->cmn.sm_ps = SM_PS_DYNAMIC;
1900 			else
1901 				psta->cmn.sm_ps = SM_PS_DISABLE;
1902 		}
1903 		#endif /* CONFIG_80211N_HT */
1904 	} else
1905 #endif
1906 		psta->cmn.sm_ps = SM_PS_DISABLE;
1907 
1908 	RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
1909 			psta->cmn.mac_id, psta->cmn.sm_ps);
1910 }
1911 
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)1912 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
1913 {
1914 
1915 	u8 raid;
1916 	if (IS_NEW_GENERATION_IC(adapter)) {
1917 
1918 		raid = (network_type & WIRELESS_11B)	? RATEID_IDX_B
1919 		       : RATEID_IDX_G;
1920 	} else {
1921 		raid = (network_type & WIRELESS_11B)	? RATR_INX_WIRELESS_B
1922 		       : RATR_INX_WIRELESS_G;
1923 	}
1924 	return raid;
1925 }
1926 
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)1927 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
1928 {
1929 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
1930 	u8 i, rf_type, tx_nss;
1931 	u64 tx_ra_bitmap = 0;
1932 
1933 	if (psta == NULL)
1934 		return;
1935 
1936 	/* b/g mode ra_bitmap  */
1937 	for (i = 0; i < sizeof(psta->bssrateset); i++) {
1938 		if (psta->bssrateset[i])
1939 			tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
1940 	}
1941 
1942 #ifdef CONFIG_80211N_HT
1943 	rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1944 	tx_nss = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->tx_nss_num);
1945 #ifdef CONFIG_80211AC_VHT
1946 	if (psta->vhtpriv.vht_option) {
1947 		/* AC mode ra_bitmap */
1948 		tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
1949 	} else
1950 #endif /* CONFIG_80211AC_VHT */
1951 	if (psta->htpriv.ht_option) {
1952 		/* n mode ra_bitmap */
1953 
1954 		/* Handling SMPS mode for AP MODE only*/
1955 		if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
1956 			/*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
1957 			if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
1958 				/*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
1959 				tx_nss = rtw_min(tx_nss, 1);
1960 			}
1961 		}
1962 
1963 		tx_ra_bitmap |= (rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss) << 12);
1964 	}
1965 #endif /* CONFIG_80211N_HT */
1966 	psta->cmn.ra_info.ramask = tx_ra_bitmap;
1967 	psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
1968 }
1969 
rtw_hal_update_sta_ra_info(PADAPTER padapter,struct sta_info * psta)1970 void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
1971 {
1972 	rtw_hal_update_sta_mimo_type(padapter, psta);
1973 	rtw_hal_update_sta_smps_cap(padapter, psta);
1974 	rtw_hal_update_sta_rate_mask(padapter, psta);
1975 }
1976 
1977 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
1978 	#define SEC_CAM_ACCESS_TIMEOUT_MS 200
1979 #endif
1980 
1981 #ifndef DBG_SEC_CAM_ACCESS
1982 	#define DBG_SEC_CAM_ACCESS 0
1983 #endif
1984 
rtw_sec_read_cam(_adapter * adapter,u8 addr)1985 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
1986 {
1987 	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
1988 	u32 rdata;
1989 	u32 cnt = 0;
1990 	systime start = 0, end = 0;
1991 	u8 timeout = 0;
1992 	u8 sr = 0;
1993 
1994 	_enter_critical_mutex(mutex, NULL);
1995 
1996 	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
1997 
1998 	start = rtw_get_current_time();
1999 	while (1) {
2000 		if (rtw_is_surprise_removed(adapter)) {
2001 			sr = 1;
2002 			break;
2003 		}
2004 
2005 		cnt++;
2006 		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2007 			break;
2008 
2009 		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2010 			timeout = 1;
2011 			break;
2012 		}
2013 	}
2014 	end = rtw_get_current_time();
2015 
2016 	rdata = rtw_read32(adapter, REG_CAMREAD);
2017 
2018 	_exit_critical_mutex(mutex, NULL);
2019 
2020 	if (DBG_SEC_CAM_ACCESS || timeout) {
2021 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
2022 			, FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2023 	}
2024 
2025 	return rdata;
2026 }
2027 
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)2028 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
2029 {
2030 	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2031 	u32 cnt = 0;
2032 	systime start = 0, end = 0;
2033 	u8 timeout = 0;
2034 	u8 sr = 0;
2035 
2036 	_enter_critical_mutex(mutex, NULL);
2037 
2038 	rtw_write32(adapter, REG_CAMWRITE, wdata);
2039 	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
2040 
2041 	start = rtw_get_current_time();
2042 	while (1) {
2043 		if (rtw_is_surprise_removed(adapter)) {
2044 			sr = 1;
2045 			break;
2046 		}
2047 
2048 		cnt++;
2049 		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2050 			break;
2051 
2052 		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2053 			timeout = 1;
2054 			break;
2055 		}
2056 	}
2057 	end = rtw_get_current_time();
2058 
2059 	_exit_critical_mutex(mutex, NULL);
2060 
2061 	if (DBG_SEC_CAM_ACCESS || timeout) {
2062 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
2063 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2064 	}
2065 }
2066 
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)2067 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
2068 {
2069 	unsigned int val, addr;
2070 	u8 i;
2071 	u32 rdata;
2072 	u8 begin = 0;
2073 	u8 end = 5; /* TODO: consider other key length accordingly */
2074 
2075 	if (!ctrl && !mac && !key) {
2076 		rtw_warn_on(1);
2077 		goto exit;
2078 	}
2079 
2080 	/* TODO: check id range */
2081 
2082 	if (!ctrl && !mac)
2083 		begin = 2; /* read from key */
2084 
2085 	if (!key && !mac)
2086 		end = 0; /* read to ctrl */
2087 	else if (!key)
2088 		end = 2; /* read to mac */
2089 
2090 	for (i = begin; i <= end; i++) {
2091 		rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
2092 
2093 		switch (i) {
2094 		case 0:
2095 			if (ctrl)
2096 				_rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
2097 			if (mac)
2098 				_rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
2099 			break;
2100 		case 1:
2101 			if (mac)
2102 				_rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
2103 			break;
2104 		default:
2105 			if (key)
2106 				_rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2107 			break;
2108 		}
2109 	}
2110 
2111 exit:
2112 	return;
2113 }
2114 
2115 
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)2116 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2117 {
2118 	unsigned int i;
2119 	int j;
2120 	u8 addr;
2121 	u32 wdata;
2122 
2123 	/* TODO: consider other key length accordingly */
2124 #if 0
2125 	switch ((ctrl & 0x1c) >> 2) {
2126 	case _WEP40_:
2127 	case _TKIP_:
2128 	case _AES_:
2129 	case _WEP104_:
2130 
2131 	}
2132 #else
2133 	j = 7;
2134 #endif
2135 
2136 	for (; j >= 0; j--) {
2137 		switch (j) {
2138 		case 0:
2139 			wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2140 			break;
2141 		case 1:
2142 			wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2143 			break;
2144 		case 6:
2145 		case 7:
2146 			wdata = 0;
2147 			break;
2148 		default:
2149 			i = (j - 2) << 2;
2150 			wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2151 			break;
2152 		}
2153 
2154 		addr = (id << 3) + j;
2155 
2156 		rtw_sec_write_cam(adapter, addr, wdata);
2157 	}
2158 }
2159 
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)2160 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2161 {
2162 	u8 addr;
2163 
2164 	addr = (id << 3);
2165 	rtw_sec_write_cam(adapter, addr, 0);
2166 }
2167 
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)2168 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2169 {
2170 	bool res;
2171 	u16 ctrl;
2172 
2173 	rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2174 
2175 	res = (ctrl & BIT6) ? _TRUE : _FALSE;
2176 	return res;
2177 }
2178 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)2179 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2180 {
2181 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2182 
2183 	_rtw_spinlock_init(&mbid_cam_ctl->lock);
2184 	mbid_cam_ctl->bitmap = 0;
2185 	ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2186 	_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2187 }
2188 
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)2189 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2190 {
2191 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2192 
2193 	_rtw_spinlock_free(&mbid_cam_ctl->lock);
2194 }
2195 
rtw_mbid_cam_reset(_adapter * adapter)2196 void rtw_mbid_cam_reset(_adapter *adapter)
2197 {
2198 	_irqL irqL;
2199 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2200 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2201 
2202 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2203 	mbid_cam_ctl->bitmap = 0;
2204 	_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2205 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2206 
2207 	ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2208 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2209 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2210 {
2211 	u8 i;
2212 	u8 cam_id = INVALID_CAM_ID;
2213 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2214 
2215 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2216 		if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2217 			cam_id = i;
2218 			break;
2219 		}
2220 	}
2221 
2222 	RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2223 	return cam_id;
2224 }
2225 
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2226 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2227 {
2228 	_irqL irqL;
2229 
2230 	u8 cam_id = INVALID_CAM_ID;
2231 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2232 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2233 
2234 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2235 	cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2236 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2237 
2238 	return cam_id;
2239 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2240 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2241 {
2242 	u8 i;
2243 	u8 cam_id = INVALID_CAM_ID;
2244 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2245 
2246 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2247 		if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2248 			cam_id = i;
2249 			break;
2250 		}
2251 	}
2252 	if (cam_id != INVALID_CAM_ID)
2253 		RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2254 			__func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2255 
2256 	return cam_id;
2257 }
2258 
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2259 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2260 {
2261 	_irqL irqL;
2262 	u8 cam_id = INVALID_CAM_ID;
2263 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2264 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2265 
2266 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2267 	cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2268 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2269 
2270 	return cam_id;
2271 }
rtw_get_max_mbid_cam_id(_adapter * adapter)2272 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2273 {
2274 	_irqL irqL;
2275 	s8 i;
2276 	u8 cam_id = INVALID_CAM_ID;
2277 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2278 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2279 
2280 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2281 	for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2282 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2283 			cam_id = i;
2284 			break;
2285 		}
2286 	}
2287 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2288 	/*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2289 	return cam_id;
2290 }
2291 
rtw_get_mbid_cam_entry_num(_adapter * adapter)2292 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2293 {
2294 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2295 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2296 
2297 	return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2298 }
2299 
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)2300 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2301 {
2302 	if (adapter && pmbid_cam && mac_addr) {
2303 		_rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2304 		pmbid_cam->iface_id = adapter->iface_id;
2305 	}
2306 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)2307 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2308 {
2309 	if (pmbid_cam) {
2310 		_rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2311 		pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2312 	}
2313 }
2314 
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)2315 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2316 {
2317 	_irqL irqL;
2318 	u8 cam_id = INVALID_CAM_ID, i;
2319 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2320 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2321 	u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2322 
2323 	if (entry_num >= TOTAL_MBID_CAM_NUM) {
2324 		RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2325 		rtw_warn_on(1);
2326 	}
2327 
2328 	if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2329 		goto exit;
2330 
2331 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2332 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2333 		if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2334 			mbid_cam_ctl->bitmap |= BIT(i);
2335 			cam_id = i;
2336 			break;
2337 		}
2338 	}
2339 	if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2340 		mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2341 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2342 
2343 	if (cam_id != INVALID_CAM_ID) {
2344 		ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2345 		RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2346 #ifdef DBG_MBID_CAM_DUMP
2347 		rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2348 #endif
2349 	} else
2350 		RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2351 exit:
2352 	return cam_id;
2353 }
2354 
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)2355 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2356 {
2357 	_irqL irqL;
2358 	u8 entry_id = INVALID_CAM_ID;
2359 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2360 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2361 
2362 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2363 	entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2364 	if (entry_id != INVALID_CAM_ID)
2365 		mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2366 
2367 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2368 
2369 	return entry_id;
2370 }
2371 
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)2372 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2373 {
2374 	_irqL irqL;
2375 	u8 ret = _FALSE;
2376 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2377 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2378 
2379 	if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2380 		RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2381 		rtw_warn_on(1);
2382 	}
2383 	if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2384 		goto exit;
2385 
2386 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2387 	if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2388 		if (mac_addr) {
2389 			mbid_cam_ctl->bitmap |= BIT(camid);
2390 			mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2391 			ret = _TRUE;
2392 		}
2393 	}
2394 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2395 
2396 	if (ret == _TRUE) {
2397 		ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2398 		RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2399 #ifdef DBG_MBID_CAM_DUMP
2400 		rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2401 #endif
2402 	} else
2403 		RTW_INFO("%s  [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2404 
2405 exit:
2406 	return ret;
2407 }
2408 
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)2409 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2410 {
2411 	_irqL irqL;
2412 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2413 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2414 
2415 	if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2416 		RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2417 		rtw_warn_on(1);
2418 	}
2419 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2420 	mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2421 	mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2422 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2423 	ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2424 	RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2425 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)2426 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2427 {
2428 	_irqL irqL;
2429 	u8 i;
2430 	_adapter *iface;
2431 	u8 iface_id;
2432 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2433 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2434 	u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2435 	u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2436 
2437 	RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2438 
2439 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2440 	RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2441 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2442 		RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2443 
2444 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2445 			iface_id = dvobj->mbid_cam_cache[i].iface_id;
2446 			RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2447 			RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2448 
2449 			iface = dvobj->padapters[iface_id];
2450 			if (iface) {
2451 				if (MLME_IS_STA(iface))
2452 					RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2453 				else if (MLME_IS_AP(iface))
2454 					RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2455 				else if (MLME_IS_MESH(iface))
2456 					RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
2457 				else
2458 					RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2459 			}
2460 
2461 		} else
2462 			RTW_PRINT_SEL(sel, "N/A\n");
2463 	}
2464 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2465 	return 0;
2466 }
2467 
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2468 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2469 {
2470 	u8 poll = 1;
2471 	u8 cam_ready = _FALSE;
2472 	u32 cam_data1 = 0;
2473 	u16 cam_data2 = 0;
2474 
2475 	if (RTW_CANNOT_RUN(padapter))
2476 		return;
2477 
2478 	rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2479 
2480 	do {
2481 		if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2482 			cam_ready = _TRUE;
2483 			break;
2484 		}
2485 		poll++;
2486 	} while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2487 
2488 	if (cam_ready) {
2489 		cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2490 		mac[0] = cam_data1 & 0xFF;
2491 		mac[1] = (cam_data1 >> 8) & 0xFF;
2492 		mac[2] = (cam_data1 >> 16) & 0xFF;
2493 		mac[3] = (cam_data1 >> 24) & 0xFF;
2494 
2495 		cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
2496 		mac[4] = cam_data2 & 0xFF;
2497 		mac[5] = (cam_data2 >> 8) & 0xFF;
2498 	}
2499 
2500 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)2501 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
2502 {
2503 	/*_irqL irqL;*/
2504 	u8 i;
2505 	u8 mac_addr[ETH_ALEN];
2506 
2507 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2508 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2509 
2510 	RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
2511 
2512 	/*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2513 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2514 		RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2515 		_rtw_memset(mac_addr, 0, ETH_ALEN);
2516 		read_mbssid_cam(adapter, i, mac_addr);
2517 		RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
2518 	}
2519 	/*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2520 	return 0;
2521 }
2522 
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2523 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2524 {
2525 	u32	cam_val[2] = {0};
2526 
2527 	cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
2528 	cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT)  | (mac[5] << 8) | mac[4];
2529 
2530 	rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
2531 }
2532 
clear_mbssid_cam(_adapter * padapter,u8 cam_addr)2533 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
2534 {
2535 	rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
2536 }
enable_mbssid_cam(_adapter * adapter)2537 static void enable_mbssid_cam(_adapter *adapter)
2538 {
2539 	u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2540 	/*enable MBSSID*/
2541 	rtw_hal_rcr_add(adapter, RCR_ENMBID);
2542 	if (max_cam_id != INVALID_CAM_ID) {
2543 		rtw_write8(adapter, REG_MBID_NUM,
2544 			((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | (max_cam_id & 0x07)));
2545 	}
2546 }
rtw_mbid_cam_restore(_adapter * adapter)2547 void rtw_mbid_cam_restore(_adapter *adapter)
2548 {
2549 	u8 i;
2550 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2551 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2552 
2553 #ifdef DBG_MBID_CAM_DUMP
2554 	rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2555 #endif
2556 
2557 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2558 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2559 			write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
2560 			RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2561 		}
2562 	}
2563 	enable_mbssid_cam(adapter);
2564 }
2565 #endif /*CONFIG_MBSSID_CAM*/
2566 
2567 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)2568 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
2569 {
2570 
2571 #if 0 /*TODO - modify for more flexible*/
2572 	u8 idx = 0;
2573 
2574 	if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
2575 	    (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
2576 		for (idx = 0; idx < 6; idx++)
2577 			rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
2578 	}  else {
2579 		/*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
2580 		u8 entry_id;
2581 
2582 		if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
2583 		    (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
2584 			entry_id = 0;
2585 			if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
2586 				RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
2587 				write_mbssid_cam(adapter, entry_id, val);
2588 			}
2589 		} else {
2590 			entry_id = rtw_mbid_camid_alloc(adapter, val);
2591 			if (entry_id != INVALID_CAM_ID)
2592 				write_mbssid_cam(adapter, entry_id, val);
2593 		}
2594 	}
2595 #else
2596 	{
2597 		/*
2598 			MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
2599 		*/
2600 		u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
2601 
2602 
2603 		if (entry_id != INVALID_CAM_ID) {
2604 			write_mbssid_cam(adapter, entry_id, mac_addr);
2605 			enable_mbssid_cam(adapter);
2606 		}
2607 	}
2608 #endif
2609 }
2610 
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)2611 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
2612 {
2613 	u8 idx = 0;
2614 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2615 	u8 entry_id;
2616 
2617 	if (!mac_addr) {
2618 		rtw_warn_on(1);
2619 		return;
2620 	}
2621 
2622 
2623 	entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
2624 
2625 	if (entry_id != INVALID_CAM_ID)
2626 		write_mbssid_cam(adapter, entry_id, mac_addr);
2627 }
2628 
2629 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)2630 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
2631 {
2632 	if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
2633 		return adapter_to_dvobj(adapter)->inter_bcn_space;
2634 	else
2635 		return bcn_interval;
2636 }
2637 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
2638 
2639 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
2640 
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * val)2641 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *val)
2642 {
2643 	u8 idx = 0;
2644 	u32 reg_macid = 0;
2645 
2646 	if (val == NULL)
2647 		return;
2648 
2649 	RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
2650 		 ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(val));
2651 
2652 #ifdef RTW_HALMAC
2653 	rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), adapter->hw_port, val);
2654 #else /* !RTW_HALMAC */
2655 	switch (adapter->hw_port) {
2656 	case HW_PORT0:
2657 	default:
2658 		reg_macid = REG_MACID;
2659 		break;
2660 	case HW_PORT1:
2661 		reg_macid = REG_MACID1;
2662 		break;
2663 #if defined(CONFIG_RTL8814A)
2664 	case HW_PORT2:
2665 		reg_macid = REG_MACID2;
2666 		break;
2667 	case HW_PORT3:
2668 		reg_macid = REG_MACID3;
2669 		break;
2670 	case HW_PORT4:
2671 		reg_macid = REG_MACID4;
2672 		break;
2673 #endif/*defined(CONFIG_RTL8814A)*/
2674 	}
2675 
2676 	for (idx = 0; idx < 6; idx++)
2677 		rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx), val[idx]);
2678 #endif /* !RTW_HALMAC */
2679 }
2680 
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)2681 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
2682 {
2683 	u8 idx = 0;
2684 	u32 reg_macid = 0;
2685 
2686 	if (mac_addr == NULL)
2687 		return;
2688 
2689 	_rtw_memset(mac_addr, 0, ETH_ALEN);
2690 #ifdef RTW_HALMAC
2691 	rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), adapter->hw_port, mac_addr);
2692 #else /* !RTW_HALMAC */
2693 	switch (adapter->hw_port) {
2694 	case HW_PORT0:
2695 	default:
2696 		reg_macid = REG_MACID;
2697 		break;
2698 	case HW_PORT1:
2699 		reg_macid = REG_MACID1;
2700 		break;
2701 #if defined(CONFIG_RTL8814A)
2702 	case HW_PORT2:
2703 		reg_macid = REG_MACID2;
2704 		break;
2705 	case HW_PORT3:
2706 		reg_macid = REG_MACID3;
2707 		break;
2708 	case HW_PORT4:
2709 		reg_macid = REG_MACID4;
2710 		break;
2711 #endif /*defined(CONFIG_RTL8814A)*/
2712 	}
2713 
2714 	for (idx = 0; idx < 6; idx++)
2715 		mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx));
2716 #endif /* !RTW_HALMAC */
2717 
2718 	RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
2719 		 ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(mac_addr));
2720 }
2721 
rtw_hal_set_bssid(_adapter * adapter,u8 * val)2722 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
2723 {
2724 #ifdef RTW_HALMAC
2725 	rtw_halmac_set_bssid(adapter_to_dvobj(adapter), adapter->hw_port, val);
2726 #else /* !RTW_HALMAC */
2727 	u8	idx = 0;
2728 	u32 reg_bssid = 0;
2729 
2730 	switch (adapter->hw_port) {
2731 	case HW_PORT0:
2732 	default:
2733 		reg_bssid = REG_BSSID;
2734 		break;
2735 	case HW_PORT1:
2736 		reg_bssid = REG_BSSID1;
2737 		break;
2738 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)
2739 	case HW_PORT2:
2740 		reg_bssid = REG_BSSID2;
2741 		break;
2742 	case HW_PORT3:
2743 		reg_bssid = REG_BSSID3;
2744 		break;
2745 	case HW_PORT4:
2746 		reg_bssid = REG_BSSID4;
2747 		break;
2748 #endif/*defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)*/
2749 	}
2750 
2751 	for (idx = 0 ; idx < 6; idx++)
2752 		rtw_write8(adapter, (reg_bssid + idx), val[idx]);
2753 #endif /* !RTW_HALMAC */
2754 
2755 	RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n", __func__, ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(val));
2756 }
2757 
hw_var_rcr_config(_adapter * adapter,u32 rcr)2758 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
2759 {
2760 	int err;
2761 
2762 	err = rtw_write32(adapter, REG_RCR, rcr);
2763 	if (err == _SUCCESS)
2764 		GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
2765 	return err;
2766 }
2767 
hw_var_rcr_get(_adapter * adapter,u32 * rcr)2768 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
2769 {
2770 	u32 v32;
2771 
2772 	v32 = rtw_read32(adapter, REG_RCR);
2773 	if (rcr)
2774 		*rcr = v32;
2775 	GET_HAL_DATA(adapter)->ReceiveConfig = v32;
2776 	return _SUCCESS;
2777 }
2778 
2779 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)2780 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
2781 {
2782 	PHAL_DATA_TYPE hal;
2783 	u32 rcr;
2784 
2785 	hal = GET_HAL_DATA(adapter);
2786 
2787 	rcr = hal->ReceiveConfig;
2788 	if ((rcr & check_bit) == check_bit)
2789 		return 1;
2790 
2791 	return 0;
2792 }
2793 
rtw_hal_rcr_add(_adapter * adapter,u32 add)2794 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
2795 {
2796 	PHAL_DATA_TYPE hal;
2797 	u32 rcr;
2798 	u8 ret = _SUCCESS;
2799 
2800 	hal = GET_HAL_DATA(adapter);
2801 
2802 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
2803 	rcr |= add;
2804 	if (rcr != hal->ReceiveConfig)
2805 		ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
2806 
2807 	return ret;
2808 }
2809 
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)2810 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
2811 {
2812 	PHAL_DATA_TYPE hal;
2813 	u32 rcr;
2814 	u8 ret = _SUCCESS;
2815 
2816 	hal = GET_HAL_DATA(adapter);
2817 
2818 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
2819 	rcr &= ~clear;
2820 	if (rcr != hal->ReceiveConfig)
2821 		ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
2822 
2823 	return ret;
2824 }
2825 
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)2826 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
2827 {
2828 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2829 	u32 rcr, rcr_new;
2830 	struct mi_state mstate, mstate_s;
2831 
2832 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
2833 	rcr_new = rcr;
2834 
2835 #ifdef CONFIG_MI_WITH_MBSSID_CAM
2836 	rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
2837 #else
2838 	rtw_mi_status_no_self(adapter, &mstate);
2839 	rtw_mi_status_no_others(adapter, &mstate_s);
2840 
2841 	/* only adjust parameters interested */
2842 	switch (self_action) {
2843 	case MLME_SCAN_ENTER:
2844 		mstate_s.scan_num = 1;
2845 		mstate_s.scan_enter_num = 1;
2846 		break;
2847 	case MLME_SCAN_DONE:
2848 		mstate_s.scan_enter_num = 0;
2849 		break;
2850 #ifdef CONFIG_TDLS
2851 	case MLME_TDLS_LINKED:
2852 		mstate_s.ld_tdls_num = 1;
2853 		break;
2854 	case MLME_TDLS_NOLINK:
2855 		mstate_s.ld_tdls_num = 0;
2856 		break;
2857 #endif
2858 #ifdef CONFIG_AP_MODE
2859 	case MLME_AP_STARTED:
2860 		mstate_s.ap_num = 1;
2861 		break;
2862 	case MLME_AP_STOPPED:
2863 		mstate_s.ap_num = 0;
2864 		mstate_s.ld_ap_num = 0;
2865 		break;
2866 #endif
2867 #ifdef CONFIG_RTW_MESH
2868 	case MLME_MESH_STARTED:
2869 		mstate_s.mesh_num = 1;
2870 		break;
2871 	case MLME_MESH_STOPPED:
2872 		mstate_s.mesh_num = 0;
2873 		mstate_s.ld_mesh_num = 0;
2874 		break;
2875 #endif
2876 	case MLME_ACTION_NONE:
2877 	case MLME_STA_CONNECTING:
2878 	case MLME_ADHOC_STARTED:
2879 		/* caller without effect of decision */
2880 		break;
2881 	default:
2882 		rtw_warn_on(1);
2883 	};
2884 
2885 	rtw_mi_status_merge(&mstate, &mstate_s);
2886 
2887 	if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
2888 		#ifdef CONFIG_FIND_BEST_CHANNEL
2889 		|| MSTATE_SCAN_ENTER_NUM(&mstate)
2890 		#endif
2891 		|| hal_data->in_cta_test
2892 	)
2893 		rcr_new &= ~RCR_CBSSID_DATA;
2894 	else
2895 		rcr_new |= RCR_CBSSID_DATA;
2896 
2897 	if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
2898 		|| MSTATE_MESH_NUM(&mstate)
2899 		|| MSTATE_SCAN_ENTER_NUM(&mstate)
2900 		|| hal_data->in_cta_test
2901 	)
2902 		rcr_new &= ~RCR_CBSSID_BCN;
2903 	else
2904 		rcr_new |= RCR_CBSSID_BCN;
2905 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
2906 
2907 	if (rcr != rcr_new)
2908 		rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
2909 }
2910 
hw_var_set_rcr_am(_adapter * adapter,u8 enable)2911 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
2912 {
2913 	u32 rcr = RCR_AM;
2914 
2915 	if (enable)
2916 		rtw_hal_rcr_add(adapter, rcr);
2917 	else
2918 		rtw_hal_rcr_clear(adapter, rcr);
2919 }
2920 
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2921 static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2922 {
2923 #ifdef RTW_HALMAC
2924 	rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
2925 				adapter->hw_port, net_type);
2926 #else /* !RTW_HALMAC */
2927 	switch (adapter->hw_port) {
2928 	case HW_PORT0:
2929 		/*REG_CR - BIT[17:16]-Network Type for port 1*/
2930 		*net_type = rtw_read8(adapter, MSR) & 0x03;
2931 		break;
2932 	case HW_PORT1:
2933 		/*REG_CR - BIT[19:18]-Network Type for port 1*/
2934 		*net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2935 		break;
2936 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)
2937 	case HW_PORT2:
2938 		/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2939 		*net_type = rtw_read8(adapter, MSR1) & 0x03;
2940 		break;
2941 	case HW_PORT3:
2942 		/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2943 		*net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2944 		break;
2945 	case HW_PORT4:
2946 		/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2947 		*net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2948 		break;
2949 #endif /*#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)*/
2950 	default:
2951 		RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2952 			 ADPT_ARG(adapter), adapter->hw_port);
2953 		rtw_warn_on(1);
2954 		break;
2955 	}
2956 #endif /* !RTW_HALMAC */
2957 }
2958 
2959 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
rtw_hal_net_type_decision(_adapter * adapter,u8 net_type)2960 static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
2961 {
2962 	if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
2963 		if (net_type != _HW_STATE_NOLINK_)
2964 			return _HW_STATE_AP_;
2965 	}
2966 	return net_type;
2967 }
2968 #endif
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2969 static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2970 {
2971 #ifdef RTW_HALMAC
2972 	#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2973 	net_type = rtw_hal_net_type_decision(adapter, net_type);
2974 	#endif
2975 	rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
2976 				adapter->hw_port, net_type);
2977 #else /* !RTW_HALMAC */
2978 	u8 val8 = 0;
2979 
2980 	switch (adapter->hw_port) {
2981 	case HW_PORT0:
2982 		#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2983 		net_type = rtw_hal_net_type_decision(adapter, net_type);
2984 		#endif
2985 		/*REG_CR - BIT[17:16]-Network Type for port 0*/
2986 		val8 = rtw_read8(adapter, MSR) & 0x0C;
2987 		val8 |= net_type;
2988 		rtw_write8(adapter, MSR, val8);
2989 		break;
2990 	case HW_PORT1:
2991 		/*REG_CR - BIT[19:18]-Network Type for port 1*/
2992 		val8 = rtw_read8(adapter, MSR) & 0x03;
2993 		val8 |= net_type << 2;
2994 		rtw_write8(adapter, MSR, val8);
2995 		break;
2996 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)
2997 	case HW_PORT2:
2998 		/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2999 		val8 = rtw_read8(adapter, MSR1) & 0xFC;
3000 		val8 |= net_type;
3001 		rtw_write8(adapter, MSR1, val8);
3002 		break;
3003 	case HW_PORT3:
3004 		/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
3005 		val8 = rtw_read8(adapter, MSR1) & 0xF3;
3006 		val8 |= net_type << 2;
3007 		rtw_write8(adapter, MSR1, val8);
3008 		break;
3009 	case HW_PORT4:
3010 		/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
3011 		val8 = rtw_read8(adapter, MSR1) & 0xCF;
3012 		val8 |= net_type << 4;
3013 		rtw_write8(adapter, MSR1, val8);
3014 		break;
3015 #endif /* CONFIG_RTL8814A | CONFIG_RTL8822B */
3016 	default:
3017 		RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
3018 			 ADPT_ARG(adapter), adapter->hw_port);
3019 		rtw_warn_on(1);
3020 		break;
3021 	}
3022 #endif /* !RTW_HALMAC */
3023 }
3024 
hw_var_set_bcn_interval(struct _ADAPTER * a,u16 interval)3025 static void hw_var_set_bcn_interval(struct _ADAPTER *a, u16 interval)
3026 {
3027 #ifdef RTW_HALMAC
3028 	rtw_halmac_set_bcn_interval(adapter_to_dvobj(a), a->hw_port, interval);
3029 #else /* !RTW_HALMAC */
3030 	RTW_ERR(FUNC_ADPT_FMT ": Not implemented yet!!\n", FUNC_ADPT_ARG(a));
3031 	rtw_warn_on(1);
3032 #endif /* !RTW_HALMAC */
3033 }
3034 
hw_var_port_switch(_adapter * adapter)3035 void hw_var_port_switch(_adapter *adapter)
3036 {
3037 #ifdef CONFIG_CONCURRENT_MODE
3038 #ifdef CONFIG_RUNTIME_PORT_SWITCH
3039 	/*
3040 	0x102: MSR
3041 	0x550: REG_BCN_CTRL
3042 	0x551: REG_BCN_CTRL_1
3043 	0x55A: REG_ATIMWND
3044 	0x560: REG_TSFTR
3045 	0x568: REG_TSFTR1
3046 	0x570: REG_ATIMWND_1
3047 	0x610: REG_MACID
3048 	0x618: REG_BSSID
3049 	0x700: REG_MACID1
3050 	0x708: REG_BSSID1
3051 	*/
3052 
3053 	int i;
3054 	u8 msr;
3055 	u8 bcn_ctrl;
3056 	u8 bcn_ctrl_1;
3057 	u8 atimwnd[2];
3058 	u8 atimwnd_1[2];
3059 	u8 tsftr[8];
3060 	u8 tsftr_1[8];
3061 	u8 macid[6];
3062 	u8 bssid[6];
3063 	u8 macid_1[6];
3064 	u8 bssid_1[6];
3065 
3066 	u8 hw_port;
3067 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3068 	_adapter *iface = NULL;
3069 
3070 	msr = rtw_read8(adapter, MSR);
3071 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
3072 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
3073 
3074 	for (i = 0; i < 2; i++)
3075 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
3076 	for (i = 0; i < 2; i++)
3077 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
3078 
3079 	for (i = 0; i < 8; i++)
3080 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
3081 	for (i = 0; i < 8; i++)
3082 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
3083 
3084 	for (i = 0; i < 6; i++)
3085 		macid[i] = rtw_read8(adapter, REG_MACID + i);
3086 
3087 	for (i = 0; i < 6; i++)
3088 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
3089 
3090 	for (i = 0; i < 6; i++)
3091 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
3092 
3093 	for (i = 0; i < 6; i++)
3094 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
3095 
3096 #ifdef DBG_RUNTIME_PORT_SWITCH
3097 	RTW_INFO(FUNC_ADPT_FMT" before switch\n"
3098 		 "msr:0x%02x\n"
3099 		 "bcn_ctrl:0x%02x\n"
3100 		 "bcn_ctrl_1:0x%02x\n"
3101 		 "atimwnd:0x%04x\n"
3102 		 "atimwnd_1:0x%04x\n"
3103 		 "tsftr:%llu\n"
3104 		 "tsftr1:%llu\n"
3105 		 "macid:"MAC_FMT"\n"
3106 		 "bssid:"MAC_FMT"\n"
3107 		 "macid_1:"MAC_FMT"\n"
3108 		 "bssid_1:"MAC_FMT"\n"
3109 		 , FUNC_ADPT_ARG(adapter)
3110 		 , msr
3111 		 , bcn_ctrl
3112 		 , bcn_ctrl_1
3113 		 , *((u16 *)atimwnd)
3114 		 , *((u16 *)atimwnd_1)
3115 		 , *((u64 *)tsftr)
3116 		 , *((u64 *)tsftr_1)
3117 		 , MAC_ARG(macid)
3118 		 , MAC_ARG(bssid)
3119 		 , MAC_ARG(macid_1)
3120 		 , MAC_ARG(bssid_1)
3121 		);
3122 #endif /* DBG_RUNTIME_PORT_SWITCH */
3123 
3124 	/* disable bcn function, disable update TSF */
3125 	rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
3126 	rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
3127 
3128 	/* switch msr */
3129 	msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
3130 	rtw_write8(adapter, MSR, msr);
3131 
3132 	/* write port0 */
3133 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
3134 	for (i = 0; i < 2; i++)
3135 		rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
3136 	for (i = 0; i < 8; i++)
3137 		rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
3138 	for (i = 0; i < 6; i++)
3139 		rtw_write8(adapter, REG_MACID + i, macid_1[i]);
3140 	for (i = 0; i < 6; i++)
3141 		rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
3142 
3143 	/* write port1 */
3144 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
3145 	for (i = 0; i < 2; i++)
3146 		rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
3147 	for (i = 0; i < 8; i++)
3148 		rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
3149 	for (i = 0; i < 6; i++)
3150 		rtw_write8(adapter, REG_MACID1 + i, macid[i]);
3151 	for (i = 0; i < 6; i++)
3152 		rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
3153 
3154 	/* write bcn ctl */
3155 #ifdef CONFIG_BT_COEXIST
3156 	/* always enable port0 beacon function for PSTDMA */
3157 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
3158 	    || IS_HARDWARE_TYPE_8723D(adapter))
3159 		bcn_ctrl_1 |= EN_BCN_FUNCTION;
3160 	/* always disable port1 beacon function for PSTDMA */
3161 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
3162 		bcn_ctrl &= ~EN_BCN_FUNCTION;
3163 #endif
3164 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
3165 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
3166 
3167 	if (adapter->iface_id == IFACE_ID0)
3168 		iface = dvobj->padapters[IFACE_ID1];
3169 	else if (adapter->iface_id == IFACE_ID1)
3170 		iface = dvobj->padapters[IFACE_ID0];
3171 
3172 
3173 	if (adapter->hw_port == HW_PORT0) {
3174 		adapter->hw_port = HW_PORT1;
3175 		iface->hw_port = HW_PORT0;
3176 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
3177 			  ADPT_ARG(iface), ADPT_ARG(adapter));
3178 	} else {
3179 		adapter->hw_port = HW_PORT0;
3180 		iface->hw_port = HW_PORT1;
3181 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
3182 			  ADPT_ARG(adapter), ADPT_ARG(iface));
3183 	}
3184 
3185 #ifdef DBG_RUNTIME_PORT_SWITCH
3186 	msr = rtw_read8(adapter, MSR);
3187 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
3188 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
3189 
3190 	for (i = 0; i < 2; i++)
3191 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
3192 	for (i = 0; i < 2; i++)
3193 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
3194 
3195 	for (i = 0; i < 8; i++)
3196 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
3197 	for (i = 0; i < 8; i++)
3198 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
3199 
3200 	for (i = 0; i < 6; i++)
3201 		macid[i] = rtw_read8(adapter, REG_MACID + i);
3202 
3203 	for (i = 0; i < 6; i++)
3204 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
3205 
3206 	for (i = 0; i < 6; i++)
3207 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
3208 
3209 	for (i = 0; i < 6; i++)
3210 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
3211 
3212 	RTW_INFO(FUNC_ADPT_FMT" after switch\n"
3213 		 "msr:0x%02x\n"
3214 		 "bcn_ctrl:0x%02x\n"
3215 		 "bcn_ctrl_1:0x%02x\n"
3216 		 "atimwnd:%u\n"
3217 		 "atimwnd_1:%u\n"
3218 		 "tsftr:%llu\n"
3219 		 "tsftr1:%llu\n"
3220 		 "macid:"MAC_FMT"\n"
3221 		 "bssid:"MAC_FMT"\n"
3222 		 "macid_1:"MAC_FMT"\n"
3223 		 "bssid_1:"MAC_FMT"\n"
3224 		 , FUNC_ADPT_ARG(adapter)
3225 		 , msr
3226 		 , bcn_ctrl
3227 		 , bcn_ctrl_1
3228 		 , *((u16 *)atimwnd)
3229 		 , *((u16 *)atimwnd_1)
3230 		 , *((u64 *)tsftr)
3231 		 , *((u64 *)tsftr_1)
3232 		 , MAC_ARG(macid)
3233 		 , MAC_ARG(bssid)
3234 		 , MAC_ARG(macid_1)
3235 		 , MAC_ARG(bssid_1)
3236 		);
3237 #endif /* DBG_RUNTIME_PORT_SWITCH */
3238 
3239 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
3240 #endif /* CONFIG_CONCURRENT_MODE */
3241 }
3242 
3243 const char *const _h2c_msr_role_str[] = {
3244 	"RSVD",
3245 	"STA",
3246 	"AP",
3247 	"GC",
3248 	"GO",
3249 	"TDLS",
3250 	"ADHOC",
3251 	"MESH",
3252 	"INVALID",
3253 };
3254 
3255 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)3256 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
3257 {
3258 	s32 ret = _SUCCESS;
3259 	u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
3260 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3261 
3262 	SET_H2CCMD_DFTPID_PORT_ID(parm, adapter->hw_port);
3263 	SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
3264 
3265 	RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
3266 	RTW_INFO("%s port_id :%d, mad_id:%d\n", __func__, adapter->hw_port, mac_id);
3267 
3268 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
3269 	dvobj->default_port_id = adapter->hw_port;
3270 
3271 	return ret;
3272 }
rtw_set_default_port_id(_adapter * adapter)3273 s32 rtw_set_default_port_id(_adapter *adapter)
3274 {
3275 	s32 ret = _SUCCESS;
3276 	struct sta_info		*psta;
3277 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3278 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3279 
3280 	if (adapter->hw_port == dvobj->default_port_id)
3281 		return ret;
3282 
3283 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
3284 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
3285 		if (psta)
3286 			ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
3287 	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
3288 
3289 	} else {
3290 	}
3291 
3292 	return ret;
3293 }
rtw_set_ps_rsvd_page(_adapter * adapter)3294 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
3295 {
3296 	s32 ret = _SUCCESS;
3297 	u16 media_status_rpt = RT_MEDIA_CONNECT;
3298 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3299 
3300 	if (adapter->hw_port == dvobj->default_port_id)
3301 		return ret;
3302 
3303 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
3304 			  (u8 *)&media_status_rpt);
3305 
3306 	return ret;
3307 }
3308 
3309 #endif
3310 
3311 #ifdef CONFIG_P2P_PS
3312 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)3313 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
3314 {
3315 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
3316 	struct wifidirect_info *pwdinfo = &adapter->wdinfo;
3317 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
3318 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3319 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
3320 	struct sta_priv		*pstapriv = &adapter->stapriv;
3321 	struct sta_info		*psta;
3322 	HAL_P2P_PS_PARA p2p_ps_para;
3323 	int status = -1;
3324 	u8 i;
3325 
3326 	_rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
3327 	_rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
3328 
3329 	(&p2p_ps_para)->p2p_port_id = adapter->hw_port;
3330 	(&p2p_ps_para)->p2p_group = 0;
3331 	psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
3332 	if (psta) {
3333 		(&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
3334 	} else {
3335 		if (p2p_ps_state != P2P_PS_DISABLE) {
3336 			RTW_ERR("%s , psta was NULL\n", __func__);
3337 			return;
3338 		}
3339 	}
3340 
3341 
3342 	switch (p2p_ps_state) {
3343 	case P2P_PS_DISABLE:
3344 		RTW_INFO("P2P_PS_DISABLE\n");
3345 		_rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
3346 		break;
3347 
3348 	case P2P_PS_ENABLE:
3349 		RTW_INFO("P2P_PS_ENABLE\n");
3350 		/* update CTWindow value. */
3351 		if (pwdinfo->ctwindow > 0) {
3352 			(&p2p_ps_para)->ctwindow_en = 1;
3353 			(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
3354 			/*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
3355 		}
3356 
3357 
3358 		if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
3359 			(&p2p_ps_para)->offload_en = 1;
3360 			if (pwdinfo->role == P2P_ROLE_GO) {
3361 				(&p2p_ps_para)->role = 1;
3362 				(&p2p_ps_para)->all_sta_sleep = 0;
3363 			} else
3364 				(&p2p_ps_para)->role = 0;
3365 
3366 			(&p2p_ps_para)->discovery = 0;
3367 		}
3368 		/* hw only support 2 set of NoA */
3369 		for (i = 0; i < pwdinfo->noa_num; i++) {
3370 			/* To control the register setting for which NOA */
3371 			(&p2p_ps_para)->noa_sel = i;
3372 			(&p2p_ps_para)->noa_en = 1;
3373 			/* config P2P NoA Descriptor Register */
3374 			/* config NOA duration */
3375 			(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
3376 			/* config NOA interval */
3377 			(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
3378 			/* config NOA start time */
3379 			(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
3380 			/* config NOA count */
3381 			(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
3382 			/*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
3383 				(&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
3384 				(&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
3385 			status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
3386 			if (status == -1)
3387 				RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
3388 		}
3389 
3390 		break;
3391 
3392 	case P2P_PS_SCAN:
3393 		/*This feature FW not ready 20161116 YiWei*/
3394 		return;
3395 		RTW_INFO("P2P_PS_SCAN\n");
3396 		(&p2p_ps_para)->discovery = 1;
3397 		/*
3398 		(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
3399 		(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
3400 		(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
3401 		(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
3402 		(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
3403 		*/
3404 		break;
3405 
3406 	case P2P_PS_SCAN_DONE:
3407 		/*This feature FW not ready 20161116 YiWei*/
3408 		return;
3409 		RTW_INFO("P2P_PS_SCAN_DONE\n");
3410 		(&p2p_ps_para)->discovery = 0;
3411 		/*
3412 		pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
3413 		(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
3414 		(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
3415 		(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
3416 		(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
3417 		(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
3418 		*/
3419 		break;
3420 
3421 	default:
3422 		break;
3423 	}
3424 
3425 	if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
3426 		status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
3427 		if (status == -1)
3428 			RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
3429 	}
3430 	_rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
3431 
3432 }
3433 #endif /* RTW_HALMAC */
3434 #endif /* CONFIG_P2P */
3435 
3436 /*
3437 * rtw_hal_set_FwMediaStatusRpt_cmd -
3438 *
3439 * @adapter:
3440 * @opmode:  0:disconnect, 1:connect
3441 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
3442 * @miracast_sink: 0:source. 1:sink
3443 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
3444 * @macid:
3445 * @macid_ind:  0:update Media Status to macid.  1:update Media Status from macid to macid_end
3446 * @macid_end:
3447 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)3448 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)
3449 {
3450 	struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
3451 	u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
3452 	int i;
3453 	s32 ret;
3454 
3455 	SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
3456 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
3457 	SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
3458 	SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
3459 	SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
3460 	SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
3461 	SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
3462 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
3463 	SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, adapter->hw_port);
3464 #endif
3465 	RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
3466 
3467 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
3468 	if (ret != _SUCCESS)
3469 		goto exit;
3470 
3471 #if defined(CONFIG_RTL8188E)
3472 	if (rtw_get_chip_type(adapter) == RTL8188E) {
3473 		HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3474 
3475 		/* 8188E FW doesn't set macid no link, driver does it by self */
3476 		if (opmode)
3477 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
3478 		else
3479 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
3480 
3481 		/* for 8188E RA */
3482 #if (RATE_ADAPTIVE_SUPPORT == 1)
3483 		if (hal_data->fw_ractrl == _FALSE) {
3484 			u8 max_macid;
3485 
3486 			max_macid = rtw_search_max_mac_id(adapter);
3487 			rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
3488 		}
3489 #endif
3490 	}
3491 #endif
3492 
3493 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
3494 	/* TODO: this should move to IOT issue area */
3495 	if (rtw_get_chip_type(adapter) == RTL8812
3496 		|| rtw_get_chip_type(adapter) == RTL8821
3497 	) {
3498 		if (MLME_IS_STA(adapter))
3499 			Hal_PatchwithJaguar_8812(adapter, opmode);
3500 	}
3501 #endif
3502 
3503 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
3504 	if (macid_ind == 0)
3505 		macid_end = macid;
3506 
3507 	for (i = macid; macid <= macid_end; macid++) {
3508 		rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
3509 		if (!opmode) {
3510 			rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
3511 			rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
3512 			rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
3513 			rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
3514 		}
3515 	}
3516 	if (!opmode)
3517 		rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
3518 
3519 exit:
3520 	return ret;
3521 }
3522 
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)3523 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
3524 {
3525 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
3526 }
3527 
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)3528 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
3529 {
3530 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
3531 }
3532 
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)3533 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
3534 {
3535 	struct	hal_ops *pHalFunc = &padapter->hal_func;
3536 	u8	u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
3537 	u8	ret = 0;
3538 
3539 	RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
3540 		 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
3541 		 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
3542 		 rsvdpageloc->LocBTQosNull);
3543 
3544 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
3545 	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
3546 	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
3547 	SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
3548 	SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
3549 
3550 	ret = rtw_hal_fill_h2c_cmd(padapter,
3551 				   H2C_RSVD_PAGE,
3552 				   H2C_RSVDPAGE_LOC_LEN,
3553 				   u1H2CRsvdPageParm);
3554 
3555 }
3556 
3557 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)3558 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
3559 {
3560 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3561 
3562 	if (IS_8723D_SERIES(pHalData->version_id) || IS_8822B_SERIES(pHalData->version_id))
3563 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
3564 	/*
3565 	* Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
3566 	* It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
3567 	* and implement HAL function.
3568 	* TODO: GPIO_8 multi function?
3569 	*/
3570 
3571 	if ((index == 13 || index == 14)
3572 		#if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
3573 		/* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
3574 		&& (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
3575 		#endif
3576 	)
3577 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
3578 }
3579 
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)3580 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
3581 {
3582 	if (index <= 7) {
3583 		/* config GPIO mode */
3584 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
3585 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
3586 
3587 		/* config GPIO Sel */
3588 		/* 0: input */
3589 		/* 1: output */
3590 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
3591 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
3592 
3593 		/* set output value */
3594 		if (outputval) {
3595 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
3596 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
3597 		} else {
3598 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
3599 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
3600 		}
3601 	} else if (index <= 15) {
3602 		/* 88C Series: */
3603 		/* index: 11~8 transform to 3~0 */
3604 		/* 8723 Series: */
3605 		/* index: 12~8 transform to 4~0 */
3606 
3607 		index -= 8;
3608 
3609 		/* config GPIO mode */
3610 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
3611 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
3612 
3613 		/* config GPIO Sel */
3614 		/* 0: input */
3615 		/* 1: output */
3616 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
3617 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
3618 
3619 		/* set output value */
3620 		if (outputval) {
3621 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
3622 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
3623 		} else {
3624 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
3625 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
3626 		}
3627 	} else {
3628 		RTW_INFO("%s: invalid GPIO%d=%d\n",
3629 			 __FUNCTION__, index, outputval);
3630 	}
3631 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)3632 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
3633 {
3634 	if (index <= 7) {
3635 		/* config GPIO mode */
3636 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
3637 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
3638 
3639 		/* config GPIO Sel */
3640 		/* 0: input */
3641 		/* 1: output */
3642 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
3643 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
3644 
3645 	} else if (index <= 15) {
3646 		/* 88C Series: */
3647 		/* index: 11~8 transform to 3~0 */
3648 		/* 8723 Series: */
3649 		/* index: 12~8 transform to 4~0 */
3650 
3651 		index -= 8;
3652 
3653 		/* config GPIO mode */
3654 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
3655 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
3656 
3657 		/* config GPIO Sel */
3658 		/* 0: input */
3659 		/* 1: output */
3660 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
3661 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
3662 	} else
3663 		RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
3664 
3665 }
3666 
3667 #endif
3668 
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)3669 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
3670 {
3671 	struct	hal_ops *pHalFunc = &padapter->hal_func;
3672 	struct	pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
3673 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
3674 	u8	res = 0, count = 0, ret = 0;
3675 #ifdef CONFIG_WOWLAN
3676 	u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
3677 
3678 	RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
3679 		 __func__, rsvdpageloc->LocRemoteCtrlInfo,
3680 		 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
3681 		 rsvdpageloc->LocNDPInfo);
3682 	RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
3683 		 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
3684 		 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
3685 
3686 	if (check_fwstate(pmlmepriv, _FW_LINKED)) {
3687 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
3688 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
3689 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
3690 							rsvdpageloc->LocNbrAdv);
3691 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
3692 						      rsvdpageloc->LocNDPInfo);
3693 #ifdef CONFIG_GTK_OL
3694 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
3695 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
3696 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
3697 #endif /* CONFIG_GTK_OL */
3698 		ret = rtw_hal_fill_h2c_cmd(padapter,
3699 					   H2C_AOAC_RSVD_PAGE,
3700 					   H2C_AOAC_RSVDPAGE_LOC_LEN,
3701 					   u1H2CAoacRsvdPageParm);
3702 
3703 		RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
3704 		_rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
3705 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
3706 					 rsvdpageloc->LocAOACReport);
3707 		ret = rtw_hal_fill_h2c_cmd(padapter,
3708 				   H2C_AOAC_RSVDPAGE3,
3709 				   H2C_AOAC_RSVDPAGE_LOC_LEN,
3710 				   u1H2CAoacRsvdPageParm);
3711 		pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
3712 	}
3713 #ifdef CONFIG_PNO_SUPPORT
3714 	else {
3715 
3716 		if (!pwrpriv->wowlan_in_resume) {
3717 			RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
3718 			_rtw_memset(&u1H2CAoacRsvdPageParm, 0,
3719 				    sizeof(u1H2CAoacRsvdPageParm));
3720 			SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
3721 						      rsvdpageloc->LocPNOInfo);
3722 			ret = rtw_hal_fill_h2c_cmd(padapter,
3723 						   H2C_AOAC_RSVDPAGE3,
3724 						   H2C_AOAC_RSVDPAGE_LOC_LEN,
3725 						   u1H2CAoacRsvdPageParm);
3726 		}
3727 	}
3728 #endif /* CONFIG_PNO_SUPPORT */
3729 #endif /* CONFIG_WOWLAN */
3730 }
3731 
3732 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)3733 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
3734 	u32 page_num, u8 *buffer, u32 buffer_size)
3735 {
3736 	u32 addr = 0, size = 0, count = 0;
3737 	u32 page_size = 0, data_low = 0, data_high = 0;
3738 	u16 txbndy = 0, offset = 0;
3739 	u8 i = 0;
3740 	bool rst = _FALSE;
3741 
3742 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
3743 
3744 	addr = page_offset * page_size;
3745 	size = page_num * page_size;
3746 
3747 	if (buffer_size < size) {
3748 		RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
3749 			__func__, buffer_size, size);
3750 		return rst;
3751 	}
3752 #ifdef RTW_HALMAC
3753 	if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
3754 		rst = _FALSE;
3755 	else
3756 		rst = _TRUE;
3757 #else
3758 	txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
3759 
3760 	offset = (txbndy + page_offset) * page_size / 8;
3761 	count = (buffer_size / 8) + 1;
3762 
3763 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
3764 
3765 	for (i = 0 ; i < count ; i++) {
3766 		rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
3767 		data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
3768 		data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
3769 		_rtw_memcpy(buffer + (i * 8),
3770 			&data_low, sizeof(data_low));
3771 		_rtw_memcpy(buffer + ((i * 8) + 4),
3772 			&data_high, sizeof(data_high));
3773 	}
3774 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
3775 	rst = _TRUE;
3776 #endif /*RTW_HALMAC*/
3777 
3778 #ifdef DBG_GET_RSVD_PAGE
3779 	RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
3780 		 __func__, page_offset, page_num, addr, size);
3781 	RTW_INFO_DUMP("\n", buffer, size);
3782 	RTW_INFO(" ==================================================\n");
3783 #endif
3784 	return rst;
3785 }
3786 
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)3787 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
3788 {
3789 	u32 page_size = 0;
3790 	u8 *buffer = NULL;
3791 	u32 buf_size = 0;
3792 
3793 	if (page_num == 0)
3794 		return;
3795 
3796 	RTW_PRINT_SEL(sel, "======= RSVG PAGE DUMP =======\n");
3797 	RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
3798 
3799 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
3800 	if (page_size) {
3801 		buf_size = page_size * page_num;
3802 		buffer = rtw_zvmalloc(buf_size);
3803 
3804 		if (buffer) {
3805 			rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
3806 			_RTW_DUMP_SEL(sel, buffer, buf_size);
3807 			rtw_vmfree(buffer, buf_size);
3808 		} else
3809 			RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
3810 	} else
3811 			RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
3812 
3813 	RTW_PRINT_SEL(sel, "==========================\n");
3814 }
3815 
3816 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)3817 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
3818 {
3819 	u8 *buffer = NULL;
3820 	u8 buff_size = 0;
3821 	static const char * const fifo_sel_str[] = {
3822 		"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
3823 	};
3824 
3825 	if (fifo_sel > 5) {
3826 		RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
3827 		return;
3828 	}
3829 
3830 	RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
3831 	RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
3832 
3833 	if (fifo_size) {
3834 		buff_size = RND4(fifo_size);
3835 		buffer = rtw_zvmalloc(buff_size);
3836 		if (buffer == NULL)
3837 			buff_size = 0;
3838 	}
3839 
3840 	rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
3841 
3842 	if (buffer) {
3843 		_RTW_DUMP_SEL(sel, buffer, fifo_size);
3844 		rtw_vmfree(buffer, buff_size);
3845 	}
3846 
3847 	RTW_PRINT_SEL(sel, "==========================\n");
3848 }
3849 #endif
3850 
3851 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)3852 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
3853 {
3854 	RTW_INFO("%s: Set 0x690=0x00\n", __func__);
3855 	rtw_write8(adapter, REG_WOW_CTRL,
3856 		   (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
3857 	RTW_PRINT("%s: Release RXDMA\n", __func__);
3858 	rtw_write32(adapter, REG_RXPKT_NUM,
3859 		    (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
3860 }
3861 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)3862 static void rtw_hal_disable_tx_report(_adapter *adapter)
3863 {
3864 	rtw_write8(adapter, REG_TX_RPT_CTRL,
3865 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
3866 	RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
3867 }
3868 
rtw_hal_enable_tx_report(_adapter * adapter)3869 static void rtw_hal_enable_tx_report(_adapter *adapter)
3870 {
3871 	rtw_write8(adapter, REG_TX_RPT_CTRL,
3872 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
3873 	RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
3874 }
3875 #endif
rtw_hal_release_rx_dma(_adapter * adapter)3876 static void rtw_hal_release_rx_dma(_adapter *adapter)
3877 {
3878 	u32 val32 = 0;
3879 
3880 	val32 = rtw_read32(adapter, REG_RXPKT_NUM);
3881 
3882 	rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
3883 
3884 	RTW_INFO("%s, [0x%04x]: 0x%08x\n",
3885 		 __func__, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
3886 }
3887 
rtw_hal_pause_rx_dma(_adapter * adapter)3888 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
3889 {
3890 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
3891 	u8 ret = 0;
3892 	s8 trycnt = 100;
3893 	u32 tmp = 0;
3894 	int res = 0;
3895 	/* RX DMA stop */
3896 	RTW_PRINT("Pause DMA\n");
3897 	rtw_write32(adapter, REG_RXPKT_NUM,
3898 		    (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
3899 	do {
3900 		if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
3901 #ifdef CONFIG_USB_HCI
3902 			/* stop interface before leave */
3903 			if (_TRUE == hal->usb_intf_start) {
3904 				rtw_intf_stop(adapter);
3905 				RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
3906 				RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
3907 			}
3908 #endif /* CONFIG_USB_HCI */
3909 
3910 			RTW_PRINT("RX_DMA_IDLE is true\n");
3911 			ret = _SUCCESS;
3912 			break;
3913 		}
3914 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3915 		else {
3916 			res = RecvOnePkt(adapter);
3917 			RTW_PRINT("RecvOnePkt Result: %d\n", res);
3918 		}
3919 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
3920 
3921 #ifdef CONFIG_USB_HCI
3922 		else {
3923 			/* to avoid interface start repeatedly  */
3924 			if (_FALSE == hal->usb_intf_start)
3925 				rtw_intf_start(adapter);
3926 		}
3927 #endif /* CONFIG_USB_HCI */
3928 	} while (trycnt--);
3929 
3930 	if (trycnt < 0) {
3931 		tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
3932 
3933 		RTW_PRINT("Stop RX DMA failed......\n");
3934 		RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
3935 			  __func__, ((tmp & 0xFF00) >> 8));
3936 
3937 		if (tmp & BIT(3))
3938 			RTW_PRINT("%s, RX DMA has req\n",
3939 				  __func__);
3940 		else
3941 			RTW_PRINT("%s, RX DMA no req\n",
3942 				  __func__);
3943 		ret = _FAIL;
3944 	}
3945 
3946 	return ret;
3947 }
3948 
3949 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3950 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)3951 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
3952 {
3953 	u8 ret = 0;
3954 	int res = 0;
3955 	u32 tmp = 0;
3956 #ifdef CONFIG_GPIO_WAKEUP
3957 	return _SUCCESS;
3958 #else
3959 	RTW_PRINT("%s\n", __func__);
3960 
3961 	res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
3962 	if (!res)
3963 		RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
3964 	else
3965 		RTW_INFO("sdio_local_read fail\n");
3966 
3967 	tmp = SDIO_HIMR_CPWM2_MSK;
3968 
3969 	res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
3970 
3971 	if (!res) {
3972 		res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
3973 		RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
3974 		ret = _SUCCESS;
3975 	} else {
3976 		RTW_INFO("sdio_local_write fail\n");
3977 		ret = _FAIL;
3978 	}
3979 	return ret;
3980 #endif /* CONFIG_CPIO_WAKEUP */
3981 }
3982 #endif
3983 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
3984 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
3985 
3986 #ifdef CONFIG_WOWLAN
3987 /*
3988  * rtw_hal_check_wow_ctrl
3989  * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
3990  *									If 0x1C7 == 0 (for 3081), WOW enable successful.
3991  *		     _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
3992  *									If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
3993  */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)3994 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
3995 {
3996 	u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
3997 	u8 mstatus = 0;
3998 	u8 reason = 0xFF;
3999 	u8 trycnt = 25;
4000 	u8 res = _FALSE;
4001 
4002 	if (IS_HARDWARE_TYPE_JAGUAR2(adapter)) {
4003 		if (chk_type) {
4004 			reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
4005 			RTW_INFO("%s reason:0x%02x\n", __func__, reason);
4006 
4007 			while (reason && trycnt > 1) {
4008 				reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
4009 				RTW_PRINT("Loop index: %d :0x%02x\n",
4010 					  trycnt, reason);
4011 				trycnt--;
4012 				rtw_msleep_os(20);
4013 			}
4014 			if (!reason)
4015 				res = _TRUE;
4016 			else
4017 				res = _FALSE;
4018 		} else {
4019 			/* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
4020 			fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
4021 			rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
4022 			RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
4023 
4024 			while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
4025 				rtw_msleep_os(20);
4026 				fe1_imr = rtw_read32(adapter, REG_FE1IMR);
4027 				rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
4028 				RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
4029 					  trycnt, fe1_imr, rxpkt_num);
4030 				trycnt--;
4031 			}
4032 
4033 			if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
4034 				res = _FALSE;
4035 			else
4036 				res = _TRUE;
4037 		}
4038 	} else {
4039 		mstatus = rtw_read8(adapter, REG_WOW_CTRL);
4040 		RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
4041 
4042 
4043 		if (chk_type) {
4044 			while (!(mstatus & BIT1) && trycnt > 1) {
4045 				mstatus = rtw_read8(adapter, REG_WOW_CTRL);
4046 				RTW_PRINT("Loop index: %d :0x%02x\n",
4047 					  trycnt, mstatus);
4048 				trycnt--;
4049 				rtw_msleep_os(20);
4050 			}
4051 			if (mstatus & BIT1)
4052 				res = _TRUE;
4053 			else
4054 				res = _FALSE;
4055 		} else {
4056 			while (mstatus & BIT1 && trycnt > 1) {
4057 				mstatus = rtw_read8(adapter, REG_WOW_CTRL);
4058 				RTW_PRINT("Loop index: %d :0x%02x\n",
4059 					  trycnt, mstatus);
4060 				trycnt--;
4061 				rtw_msleep_os(20);
4062 			}
4063 
4064 			if (mstatus & BIT1)
4065 				res = _FALSE;
4066 			else
4067 				res = _TRUE;
4068 		}
4069 	}
4070 
4071 	RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
4072 		  __func__, chk_type, res, (25 - trycnt));
4073 	return res;
4074 }
4075 
4076 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)4077 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
4078 {
4079 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
4080 	u8 res = 0, count = 0;
4081 	u8 ret = _FALSE;
4082 
4083 	if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
4084 		res = rtw_read8(adapter, REG_PNO_STATUS);
4085 		while (!(res & BIT(7)) && count < 25) {
4086 			RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
4087 				 count, res);
4088 			res = rtw_read8(adapter, REG_PNO_STATUS);
4089 			count++;
4090 			rtw_msleep_os(2);
4091 		}
4092 		if (res & BIT(7))
4093 			ret = _TRUE;
4094 		else
4095 			ret = _FALSE;
4096 		RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
4097 	}
4098 	return ret;
4099 }
4100 #endif
4101 
rtw_hal_backup_rate(_adapter * adapter)4102 static void rtw_hal_backup_rate(_adapter *adapter)
4103 {
4104 	RTW_INFO("%s\n", __func__);
4105 	/* backup data rate to register 0x8b for wowlan FW */
4106 	rtw_write8(adapter, 0x8d, 1);
4107 	rtw_write8(adapter, 0x8c, 0);
4108 	rtw_write8(adapter, 0x8f, 0x40);
4109 	rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
4110 }
4111 
4112 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)4113 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
4114 {
4115 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4116 	int cam_id, index = 0;
4117 	u8 *addr = NULL;
4118 
4119 	if (!MLME_IS_STA(adapter))
4120 		return;
4121 
4122 	addr = get_bssid(pmlmepriv);
4123 
4124 	if (addr == NULL) {
4125 		RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
4126 		return;
4127 	}
4128 
4129 	rtw_clean_dk_section(adapter);
4130 
4131 	do {
4132 		cam_id = rtw_camid_search(adapter, addr, index, 1);
4133 
4134 		if (cam_id == -1)
4135 			RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
4136 		else
4137 			rtw_sec_cam_swap(adapter, cam_id, index);
4138 
4139 		index++;
4140 	} while (index < 4);
4141 
4142 	rtw_write8(adapter, REG_SECCFG, 0xcc);
4143 }
4144 
rtw_hal_update_gtk_offload_info(_adapter * adapter)4145 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
4146 {
4147 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4148 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
4149 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4150 	struct security_priv *psecuritypriv = &adapter->securitypriv;
4151 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4152 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
4153 	_irqL irqL;
4154 	u8 get_key[16];
4155 	u8 gtk_id = 0, offset = 0, i = 0, sz = 0;
4156 	u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
4157 
4158 	if (!MLME_IS_STA(adapter))
4159 		return;
4160 
4161 	_rtw_memset(get_key, 0, sizeof(get_key));
4162 	_rtw_memcpy(&replay_count,
4163 		paoac_rpt->replay_counter_eapol_key, 8);
4164 
4165 	/*read gtk key index*/
4166 	gtk_id = paoac_rpt->key_index;
4167 
4168 	if (gtk_id == 5 || gtk_id == 0) {
4169 		RTW_INFO("%s no rekey event happened.\n", __func__);
4170 	} else if (gtk_id > 0 && gtk_id < 4) {
4171 		RTW_INFO("%s update security key.\n", __func__);
4172 		/*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
4173 		rtw_sec_read_cam_ent(adapter, gtk_id,
4174 				     NULL, NULL, get_key);
4175 		rtw_clean_hw_dk_cam(adapter);
4176 
4177 		if (_rtw_camid_is_gk(adapter, gtk_id)) {
4178 			_enter_critical_bh(&cam_ctl->lock, &irqL);
4179 			_rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
4180 				    get_key, 16);
4181 			_exit_critical_bh(&cam_ctl->lock, &irqL);
4182 		} else {
4183 			struct setkey_parm parm_gtk;
4184 
4185 			parm_gtk.algorithm = paoac_rpt->security_type;
4186 			parm_gtk.keyid = gtk_id;
4187 			_rtw_memcpy(parm_gtk.key, get_key, 16);
4188 			setkey_hdl(adapter, (u8 *)&parm_gtk);
4189 		}
4190 
4191 		/*update key into related sw variable and sec-cam cache*/
4192 		psecuritypriv->dot118021XGrpKeyid = gtk_id;
4193 		_rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
4194 				get_key, 16);
4195 		/* update SW TKIP TX/RX MIC value */
4196 		if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
4197 			offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
4198 			_rtw_memcpy(
4199 				&psecuritypriv->dot118021XGrptxmickey[gtk_id],
4200 				&(paoac_rpt->group_key[offset]),
4201 				RTW_TKIP_MIC_LEN);
4202 
4203 			offset = RTW_KEK_LEN;
4204 			_rtw_memcpy(
4205 				&psecuritypriv->dot118021XGrprxmickey[gtk_id],
4206 				&(paoac_rpt->group_key[offset]),
4207 				RTW_TKIP_MIC_LEN);
4208 		}
4209 		RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
4210 			KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
4211 	}
4212 
4213 	/* Update broadcast RX IV */
4214 	if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
4215 		sz = sizeof(psecuritypriv->iv_seq[0]);
4216 		for (i = 0 ; i < 4 ; i++) {
4217 			_rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
4218 			tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
4219 			pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
4220 			_rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
4221 		}
4222 	}
4223 
4224 	rtw_clean_dk_section(adapter);
4225 
4226 	rtw_write8(adapter, REG_SECCFG, 0x0c);
4227 
4228 	#ifdef CONFIG_GTK_OL_DBG
4229 	/* if (gtk_keyindex != 5) */
4230 	dump_sec_cam(RTW_DBGDUMP, adapter);
4231 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
4232 	#endif
4233 }
4234 #endif /*CONFIG_GTK_OL*/
4235 
rtw_dump_aoac_rpt(_adapter * adapter)4236 static void rtw_dump_aoac_rpt(_adapter *adapter)
4237 {
4238 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4239 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
4240 	int i = 0;
4241 
4242 	RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
4243 	RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
4244 		paoac_rpt->replay_counter_eapol_key, 8);
4245 	RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
4246 	RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
4247 	RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
4248 	RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
4249 		 paoac_rpt->wow_pattern_idx);
4250 	RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
4251 	RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
4252 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
4253 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
4254 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
4255 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
4256 }
4257 
rtw_hal_get_aoac_rpt(_adapter * adapter)4258 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
4259 {
4260 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4261 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
4262 	u32 page_offset = 0, page_number = 0;
4263 	u32 page_size = 0, buf_size = 0;
4264 	u8 *buffer = NULL;
4265 	u8 i = 0, tmp = 0;
4266 	int ret = -1;
4267 
4268 	/* read aoac report from rsvd page */
4269 	page_offset = pwrctl->wowlan_aoac_rpt_loc;
4270 	page_number = 1;
4271 
4272 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
4273 	buf_size = page_size * page_number;
4274 
4275 	buffer = rtw_zvmalloc(buf_size);
4276 
4277 	if (buffer == NULL) {
4278 		RTW_ERR("%s buffer allocate failed size(%d)\n",
4279 			__func__, buf_size);
4280 		return;
4281 	}
4282 
4283 	RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
4284 
4285 	ret = rtw_hal_get_rsvd_page(adapter, page_offset,
4286 		page_number, buffer, buf_size);
4287 
4288 	if (ret == _FALSE) {
4289 		RTW_ERR("%s get aoac report failed\n", __func__);
4290 		rtw_warn_on(1);
4291 		goto _exit;
4292 	}
4293 
4294 	_rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
4295 	_rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
4296 
4297 	for (i = 0 ; i < 4 ; i++) {
4298 		tmp = paoac_rpt->replay_counter_eapol_key[i];
4299 		paoac_rpt->replay_counter_eapol_key[i] =
4300 			paoac_rpt->replay_counter_eapol_key[7 - i];
4301 		paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
4302 	}
4303 
4304 	rtw_dump_aoac_rpt(adapter);
4305 
4306 _exit:
4307 	if (buffer)
4308 		rtw_vmfree(buffer, buf_size);
4309 }
4310 
rtw_hal_update_tx_iv(_adapter * adapter)4311 static void rtw_hal_update_tx_iv(_adapter *adapter)
4312 {
4313 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4314 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
4315 	struct sta_info	*psta;
4316 	struct mlme_ext_priv	*pmlmeext = &(adapter->mlmeextpriv);
4317 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4318 	struct security_priv	*psecpriv = &adapter->securitypriv;
4319 
4320 	u16 val16 = 0;
4321 	u32 val32 = 0;
4322 	u64 txiv = 0;
4323 	u8 *pval = NULL;
4324 
4325 	psta = rtw_get_stainfo(&adapter->stapriv,
4326 			       get_my_bssid(&pmlmeinfo->network));
4327 
4328 	/* Update TX iv data. */
4329 	pval = (u8 *)&paoac_rpt->iv;
4330 
4331 	if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
4332 		val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
4333 			((u16)(paoac_rpt->iv[0]) << 8);
4334 		val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
4335 			((u32)(paoac_rpt->iv[5]) << 8) +
4336 			((u32)(paoac_rpt->iv[6]) << 16) +
4337 			((u32)(paoac_rpt->iv[7]) << 24);
4338 	} else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
4339 		val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
4340 			((u16)(paoac_rpt->iv[1]) << 8);
4341 		val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
4342 			((u32)(paoac_rpt->iv[5]) << 8) +
4343 			((u32)(paoac_rpt->iv[6]) << 16) +
4344 			((u32)(paoac_rpt->iv[7]) << 24);
4345 	}
4346 
4347 	if (psta) {
4348 		txiv = val16 + ((u64)val32 << 16);
4349 		if (txiv != 0)
4350 			psta->dot11txpn.val = txiv;
4351 	}
4352 }
4353 
rtw_hal_update_sw_security_info(_adapter * adapter)4354 static void rtw_hal_update_sw_security_info(_adapter *adapter)
4355 {
4356 	struct security_priv *psecpriv = &adapter->securitypriv;
4357 	u8 sz = sizeof (psecpriv->iv_seq);
4358 
4359 	rtw_hal_update_tx_iv(adapter);
4360 #ifdef CONFIG_GTK_OL
4361 	if (psecpriv->binstallKCK_KEK == _TRUE &&
4362 	    psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
4363 		rtw_hal_update_gtk_offload_info(adapter);
4364 #else
4365 	_rtw_memset(psecpriv->iv_seq, 0, sz);
4366 #endif
4367 }
4368 
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)4369 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
4370 {
4371 	struct hal_ops *pHalFunc = &adapter->hal_func;
4372 
4373 	u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
4374 	u8 adopt = 1, check_period = 5;
4375 	u8 ret = _FAIL;
4376 
4377 	SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
4378 	SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
4379 	SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
4380 	SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
4381 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4382 	SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, adapter->hw_port);
4383 	RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, adapter->hw_port);
4384 #else
4385 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
4386 #endif
4387 	ret = rtw_hal_fill_h2c_cmd(adapter,
4388 				   H2C_KEEP_ALIVE,
4389 				   H2C_KEEP_ALIVE_CTRL_LEN,
4390 				   u1H2CKeepAliveParm);
4391 
4392 	return ret;
4393 }
4394 
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)4395 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
4396 {
4397 	struct hal_ops *pHalFunc = &adapter->hal_func;
4398 	u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
4399 	u8 adopt = 1, check_period = 30, trypkt_num = 5;
4400 	u8 ret = _FAIL;
4401 
4402 	SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
4403 	SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
4404 	SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
4405 	SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
4406 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4407 	SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, adapter->hw_port);
4408 	RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, adapter->hw_port);
4409 #else
4410 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
4411 #endif
4412 
4413 	ret = rtw_hal_fill_h2c_cmd(adapter,
4414 				   H2C_DISCON_DECISION,
4415 				   H2C_DISCON_DECISION_LEN,
4416 				   u1H2CDisconDecisionParm);
4417 	return ret;
4418 }
4419 
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)4420 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
4421 {
4422 	struct registry_priv  *registry_par = &adapter->registrypriv;
4423 	struct security_priv *psecpriv = &adapter->securitypriv;
4424 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
4425 	struct hal_ops *pHalFunc = &adapter->hal_func;
4426 
4427 	u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
4428 	u8 discont_wake = 0, gpionum = 0, gpio_dur = 0;
4429 	u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
4430 	u8 sdio_wakeup_enable = 1;
4431 	u8 gpio_high_active = 0;
4432 	u8 magic_pkt = 0;
4433 	u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
4434 	u8 ret = _FAIL;
4435 
4436 #ifdef CONFIG_GPIO_WAKEUP
4437 	gpio_high_active = ppwrpriv->is_high_active;
4438 	gpionum = WAKEUP_GPIO_IDX;
4439 	sdio_wakeup_enable = 0;
4440 #endif /* CONFIG_GPIO_WAKEUP */
4441 
4442 	if (!ppwrpriv->wowlan_pno_enable &&
4443 	    registry_par->wakeup_event & BIT(0))
4444 		magic_pkt = enable;
4445 
4446 	if ((registry_par->wakeup_event & BIT(1)) &&
4447 	    (psecpriv->dot11PrivacyAlgrthm == _WEP40_ ||
4448 	     psecpriv->dot11PrivacyAlgrthm == _WEP104_))
4449 			hw_unicast = 1;
4450 
4451 	if (registry_par->wakeup_event & BIT(2))
4452 		discont_wake = enable;
4453 
4454 	RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
4455 		 enable, change_unit);
4456 
4457 	/* time = (gpio_dur/2) * gpio_unit, default:256 ms */
4458 	if (enable && change_unit) {
4459 		gpio_dur = 0x40;
4460 		gpio_unit = 1;
4461 		gpio_pulse_en = 1;
4462 	}
4463 
4464 #ifdef CONFIG_PLATFORM_ARM_RK3188
4465 	if (enable) {
4466 		gpio_pulse_en = 1;
4467 		gpio_pulse_cnt = 0x04;
4468 	}
4469 #endif
4470 
4471 	SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
4472 	SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
4473 	SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
4474 	SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
4475 	SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
4476 	SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
4477 
4478 #ifdef CONFIG_GTK_OL
4479 	if (psecpriv->binstallKCK_KEK == _TRUE &&
4480 	    psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
4481 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
4482 	else
4483 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
4484 #else
4485 	SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
4486 #endif
4487 	SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
4488 	SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
4489 	SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
4490 
4491 	SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
4492 	SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
4493 
4494 	SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
4495 	SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
4496 
4497 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
4498 	if (enable)
4499 		SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
4500 #endif
4501 	ret = rtw_hal_fill_h2c_cmd(adapter,
4502 				   H2C_WOWLAN,
4503 				   H2C_WOWLAN_LEN,
4504 				   u1H2CWoWlanCtrlParm);
4505 	return ret;
4506 }
4507 
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)4508 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
4509 {
4510 	struct hal_ops *pHalFunc = &adapter->hal_func;
4511 	struct security_priv *psecuritypriv = &(adapter->securitypriv);
4512 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
4513 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
4514 	u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
4515 	u8 ret = _FAIL, count = 0;
4516 
4517 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
4518 
4519 	if (!ppwrpriv->wowlan_pno_enable) {
4520 		SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
4521 			u1H2CRemoteWakeCtrlParm, enable);
4522 		SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
4523 			u1H2CRemoteWakeCtrlParm, 1);
4524 #ifdef CONFIG_GTK_OL
4525 		if (psecuritypriv->binstallKCK_KEK == _TRUE &&
4526 		    psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
4527 			SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
4528 				u1H2CRemoteWakeCtrlParm, 1);
4529 		} else {
4530 			RTW_INFO("no kck kek\n");
4531 			SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
4532 				u1H2CRemoteWakeCtrlParm, 0);
4533 		}
4534 #endif /* CONFIG_GTK_OL */
4535 
4536 #ifdef CONFIG_IPV6
4537 		if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
4538 			RTW_INFO("enable NS offload\n");
4539 			SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
4540 				u1H2CRemoteWakeCtrlParm, enable);
4541 		}
4542 
4543 		/*
4544 		 * filter NetBios name service pkt to avoid being waked-up
4545 		 * by this kind of unicast pkt this exceptional modification
4546 		 * is used for match competitor's behavior
4547 		 */
4548 
4549 		SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
4550 			u1H2CRemoteWakeCtrlParm, enable);
4551 #endif /*CONFIG_IPV6*/
4552 
4553 		if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
4554 			(psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
4555 			(psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
4556 			SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
4557 				u1H2CRemoteWakeCtrlParm, 0);
4558 		} else {
4559 			SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
4560 				u1H2CRemoteWakeCtrlParm, 1);
4561 		}
4562 
4563 		if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_ &&
4564 		    psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
4565 			SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
4566 					u1H2CRemoteWakeCtrlParm, enable);
4567 
4568 			if (IS_HARDWARE_TYPE_8188E(adapter) ||
4569 			    IS_HARDWARE_TYPE_8812(adapter)) {
4570 				SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
4571 					u1H2CRemoteWakeCtrlParm, 0);
4572 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
4573 					u1H2CRemoteWakeCtrlParm, 1);
4574 			}
4575 		}
4576 
4577 		SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
4578 			u1H2CRemoteWakeCtrlParm, 1);
4579 	}
4580 #ifdef CONFIG_PNO_SUPPORT
4581 	else {
4582 		SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
4583 			u1H2CRemoteWakeCtrlParm, enable);
4584 		SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
4585 			u1H2CRemoteWakeCtrlParm, enable);
4586 	}
4587 #endif
4588 
4589 #ifdef CONFIG_P2P_WOWLAN
4590 	if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
4591 		RTW_INFO("P2P OFFLOAD ENABLE\n");
4592 		SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
4593 	} else {
4594 		RTW_INFO("P2P OFFLOAD DISABLE\n");
4595 		SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
4596 	}
4597 #endif /* CONFIG_P2P_WOWLAN */
4598 
4599 
4600 	ret = rtw_hal_fill_h2c_cmd(adapter,
4601 				   H2C_REMOTE_WAKE_CTRL,
4602 				   H2C_REMOTE_WAKE_CTRL_LEN,
4603 				   u1H2CRemoteWakeCtrlParm);
4604 	return ret;
4605 }
4606 
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)4607 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
4608 {
4609 	struct hal_ops *pHalFunc = &adapter->hal_func;
4610 	u8 ret = _FAIL;
4611 	u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
4612 
4613 	RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
4614 		 __func__, group_alg, pairwise_alg);
4615 	SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
4616 			pairwise_alg);
4617 	SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
4618 			group_alg);
4619 
4620 	ret = rtw_hal_fill_h2c_cmd(adapter,
4621 				   H2C_AOAC_GLOBAL_INFO,
4622 				   H2C_AOAC_GLOBAL_INFO_LEN,
4623 				   u1H2CAOACGlobalInfoParm);
4624 
4625 	return ret;
4626 }
4627 
4628 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)4629 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
4630 		PRSVDPAGE_LOC rsvdpageloc, u8 enable)
4631 {
4632 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
4633 	struct hal_ops *pHalFunc = &adapter->hal_func;
4634 
4635 	u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
4636 	u8 res = 0, count = 0, ret = _FAIL;
4637 
4638 	RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
4639 		 __func__, rsvdpageloc->LocProbePacket,
4640 		 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
4641 
4642 	SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
4643 	SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
4644 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
4645 					       rsvdpageloc->LocScanInfo);
4646 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
4647 			rsvdpageloc->LocProbePacket);
4648 	/*
4649 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
4650 				rsvdpageloc->LocSSIDInfo);
4651 	*/
4652 	ret = rtw_hal_fill_h2c_cmd(adapter,
4653 				   H2C_D0_SCAN_OFFLOAD_INFO,
4654 				   H2C_SCAN_OFFLOAD_CTRL_LEN,
4655 				   u1H2CScanOffloadInfoParm);
4656 	return ret;
4657 }
4658 #endif /* CONFIG_PNO_SUPPORT */
4659 
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)4660 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
4661 {
4662 	struct security_priv *psecpriv = &padapter->securitypriv;
4663 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
4664 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
4665 	struct registry_priv *pregistry = &padapter->registrypriv;
4666 	struct sta_info *psta = NULL;
4667 	u16 media_status_rpt;
4668 	u8	pkt_type = 0;
4669 	u8 ret = _SUCCESS;
4670 
4671 	RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
4672 
4673 	rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
4674 
4675 	if (enable) {
4676 		rtw_hal_set_global_info_cmd(padapter,
4677 					    psecpriv->dot118021XGrpPrivacy,
4678 					    psecpriv->dot11PrivacyAlgrthm);
4679 
4680 		if (!(ppwrpriv->wowlan_pno_enable)) {
4681 			if (pregistry->wakeup_event & BIT(2))
4682 				rtw_hal_set_disconnect_decision_cmd(padapter,
4683 								    enable);
4684 #ifdef CONFIG_ARP_KEEP_ALIVE
4685 			if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
4686 			    (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
4687 				pkt_type = 0;
4688 			else
4689 				pkt_type = 1;
4690 #else
4691 			pkt_type = 0;
4692 #endif /* CONFIG_ARP_KEEP_ALIVE */
4693 			rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
4694 		}
4695 		rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
4696 #ifdef CONFIG_PNO_SUPPORT
4697 		rtw_hal_check_pno_enabled(padapter);
4698 #endif /* CONFIG_PNO_SUPPORT */
4699 	} else {
4700 #if 0
4701 		{
4702 			u32 PageSize = 0;
4703 			rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
4704 			dump_TX_FIFO(padapter, 4, PageSize);
4705 		}
4706 #endif
4707 
4708 		rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
4709 	}
4710 	RTW_PRINT("-%s()-\n", __func__);
4711 }
4712 #endif /* CONFIG_WOWLAN */
4713 
4714 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)4715 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
4716 {
4717 	struct security_priv *psecpriv = &adapter->securitypriv;
4718 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
4719 	struct hal_ops *pHalFunc = &adapter->hal_func;
4720 
4721 	u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
4722 	u8 gpionum = 0, gpio_dur = 0;
4723 	u8 gpio_pulse = enable;
4724 	u8 sdio_wakeup_enable = 1;
4725 	u8 gpio_high_active = 0;
4726 	u8 ret = _FAIL;
4727 
4728 #ifdef CONFIG_GPIO_WAKEUP
4729 	gpio_high_active = ppwrpriv->is_high_active;
4730 	gpionum = WAKEUP_GPIO_IDX;
4731 	sdio_wakeup_enable = 0;
4732 #endif /*CONFIG_GPIO_WAKEUP*/
4733 
4734 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
4735 
4736 	SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
4737 					  gpionum);
4738 	SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
4739 					 gpio_pulse);
4740 	SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
4741 						gpio_high_active);
4742 	SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
4743 				       enable);
4744 	SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
4745 					     gpio_dur);
4746 
4747 	ret = rtw_hal_fill_h2c_cmd(adapter,
4748 				   H2C_AP_WOW_GPIO_CTRL,
4749 				   H2C_AP_WOW_GPIO_CTRL_LEN,
4750 				   u1H2CAPWoWlanCtrlParm);
4751 
4752 	return ret;
4753 }
4754 
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)4755 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
4756 {
4757 	struct hal_ops *pHalFunc = &adapter->hal_func;
4758 	u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
4759 	u8 ret = _FAIL;
4760 
4761 	RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
4762 
4763 	SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
4764 
4765 	ret = rtw_hal_fill_h2c_cmd(adapter,
4766 				   H2C_AP_OFFLOAD,
4767 				   H2C_AP_OFFLOAD_LEN,
4768 				   u1H2CAPOffloadCtrlParm);
4769 
4770 	return ret;
4771 }
4772 
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)4773 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
4774 {
4775 	struct hal_ops *pHalFunc = &adapter->hal_func;
4776 	u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
4777 	u8 ret = _FAIL;
4778 
4779 	RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
4780 
4781 	SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
4782 #ifndef CONFIG_USB_HCI
4783 	SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
4784 #endif /*CONFIG_USB_HCI*/
4785 	SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
4786 
4787 	if (enable)
4788 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
4789 	else
4790 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
4791 
4792 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
4793 				   H2C_AP_PS_LEN, ap_ps_parm);
4794 
4795 	return ret;
4796 }
4797 
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4798 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
4799 		PRSVDPAGE_LOC rsvdpageloc)
4800 {
4801 	struct hal_ops *pHalFunc = &padapter->hal_func;
4802 	u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
4803 	u8 ret = _FAIL, header = 0;
4804 
4805 	if (pHalFunc->fill_h2c_cmd == NULL) {
4806 		RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
4807 		return;
4808 	}
4809 
4810 	header = rtw_read8(padapter, REG_BCNQ_BDNY);
4811 
4812 	RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
4813 		 rsvdpageloc->LocApOffloadBCN,
4814 		 rsvdpageloc->LocProbeRsp,
4815 		 header);
4816 
4817 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
4818 				      rsvdpageloc->LocApOffloadBCN + header);
4819 
4820 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
4821 				   H2C_BCN_RSVDPAGE_LEN, rsvdparm);
4822 
4823 	if (ret == _FAIL)
4824 		RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
4825 
4826 	rtw_msleep_os(10);
4827 
4828 	_rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
4829 
4830 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
4831 			rsvdpageloc->LocProbeRsp + header);
4832 
4833 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
4834 				   H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
4835 
4836 	if (ret == _FAIL)
4837 		RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
4838 
4839 	rtw_msleep_os(10);
4840 }
4841 
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)4842 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
4843 {
4844 	rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
4845 	rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
4846 	rtw_hal_set_ap_ps_cmd(padapter, enable);
4847 }
4848 
rtw_hal_ap_wow_enable(_adapter * padapter)4849 static void rtw_hal_ap_wow_enable(_adapter *padapter)
4850 {
4851 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4852 	struct security_priv *psecuritypriv = &padapter->securitypriv;
4853 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4854 	struct hal_ops *pHalFunc = &padapter->hal_func;
4855 	struct sta_info *psta = NULL;
4856 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4857 #ifdef DBG_CHECK_FW_PS_STATE
4858 	struct dvobj_priv *psdpriv = padapter->dvobj;
4859 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
4860 #endif /*DBG_CHECK_FW_PS_STATE*/
4861 	int res;
4862 	u16 media_status_rpt;
4863 
4864 	RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
4865 #ifdef DBG_CHECK_FW_PS_STATE
4866 	if (rtw_fw_ps_state(padapter) == _FAIL) {
4867 		pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
4868 		RTW_PRINT("wowlan enable no leave 32k\n");
4869 	}
4870 #endif /*DBG_CHECK_FW_PS_STATE*/
4871 
4872 	/* 1. Download WOWLAN FW*/
4873 	rtw_hal_fw_dl(padapter, _TRUE);
4874 
4875 	media_status_rpt = RT_MEDIA_CONNECT;
4876 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
4877 			  (u8 *)&media_status_rpt);
4878 
4879 	issue_beacon(padapter, 0);
4880 
4881 	rtw_msleep_os(2);
4882 	#if defined(CONFIG_RTL8188E)
4883 	if (IS_HARDWARE_TYPE_8188E(padapter))
4884 		rtw_hal_disable_tx_report(padapter);
4885 	#endif
4886 	/* RX DMA stop */
4887 	res = rtw_hal_pause_rx_dma(padapter);
4888 	if (res == _FAIL)
4889 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
4890 
4891 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
4892 	/* Enable CPWM2 only. */
4893 	res = rtw_hal_enable_cpwm2(padapter);
4894 	if (res == _FAIL)
4895 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
4896 #endif
4897 
4898 #ifdef CONFIG_GPIO_WAKEUP
4899 	rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE);
4900 #endif
4901 	/* 5. Set Enable WOWLAN H2C command. */
4902 	RTW_PRINT("Set Enable AP WOWLan cmd\n");
4903 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
4904 
4905 	rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
4906 #ifdef CONFIG_USB_HCI
4907 	rtw_mi_intf_stop(padapter);
4908 #endif
4909 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
4910 	/* Invoid SE0 reset signal during suspending*/
4911 	rtw_write8(padapter, REG_RSV_CTRL, 0x20);
4912 	if (IS_8188F(pHalData->version_id) == FALSE)
4913 		rtw_write8(padapter, REG_RSV_CTRL, 0x60);
4914 #endif
4915 }
4916 
rtw_hal_ap_wow_disable(_adapter * padapter)4917 static void rtw_hal_ap_wow_disable(_adapter *padapter)
4918 {
4919 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4920 	struct hal_ops *pHalFunc = &padapter->hal_func;
4921 #ifdef DBG_CHECK_FW_PS_STATE
4922 	struct dvobj_priv *psdpriv = padapter->dvobj;
4923 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
4924 #endif /*DBG_CHECK_FW_PS_STATE*/
4925 	u16 media_status_rpt;
4926 	u8 val8;
4927 
4928 	RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
4929 	/* 1. Read wakeup reason*/
4930 	pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
4931 
4932 	RTW_PRINT("wakeup_reason: 0x%02x\n",
4933 		  pwrctl->wowlan_wake_reason);
4934 
4935 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
4936 
4937 	rtw_msleep_os(2);
4938 #ifdef DBG_CHECK_FW_PS_STATE
4939 	if (rtw_fw_ps_state(padapter) == _FAIL) {
4940 		pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
4941 		RTW_PRINT("wowlan enable no leave 32k\n");
4942 	}
4943 #endif /*DBG_CHECK_FW_PS_STATE*/
4944 
4945 	#if defined(CONFIG_RTL8188E)
4946 	if (IS_HARDWARE_TYPE_8188E(padapter))
4947 		rtw_hal_enable_tx_report(padapter);
4948 	#endif
4949 
4950 	rtw_hal_force_enable_rxdma(padapter);
4951 
4952 	rtw_hal_fw_dl(padapter, _FALSE);
4953 
4954 #ifdef CONFIG_GPIO_WAKEUP
4955 	#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
4956 	if (pwrctl->is_high_active == 0)
4957 		rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX);
4958 	else
4959 		rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, 0);
4960 	#else
4961 	val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
4962 	RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
4963 	rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8);
4964 
4965 	rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _FALSE);
4966 	#endif/*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
4967 #endif
4968 	media_status_rpt = RT_MEDIA_CONNECT;
4969 
4970 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
4971 			  (u8 *)&media_status_rpt);
4972 
4973 	issue_beacon(padapter, 0);
4974 }
4975 #endif /*CONFIG_AP_WOWLAN*/
4976 
4977 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)4978 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
4979 {
4980 	u8 *ssid_ie;
4981 	sint ssid_len_ori;
4982 	int len_diff = 0;
4983 
4984 	ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
4985 
4986 	/* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
4987 
4988 	if (ssid_ie && ssid_len_ori > 0) {
4989 		switch (hidden_ssid_mode) {
4990 		case 1: {
4991 			u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
4992 			u32 remain_len = 0;
4993 
4994 			remain_len = ies_len - (next_ie - ies);
4995 
4996 			ssid_ie[1] = 0;
4997 			_rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
4998 			len_diff -= ssid_len_ori;
4999 
5000 			break;
5001 		}
5002 		case 2:
5003 			_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
5004 			break;
5005 		default:
5006 			break;
5007 		}
5008 	}
5009 
5010 	return len_diff;
5011 }
5012 
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)5013 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
5014 {
5015 	/* struct xmit_frame	*pmgntframe; */
5016 	/* struct pkt_attrib	*pattrib; */
5017 	/* unsigned char	*pframe; */
5018 	struct rtw_ieee80211_hdr *pwlanhdr;
5019 	unsigned short *fctrl;
5020 	unsigned int	rate_len;
5021 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
5022 	u32	pktlen;
5023 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5024 	/*	_irqL irqL;
5025 	 *	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5026 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5027 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5028 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5029 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5030 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
5031 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5032 #ifdef CONFIG_P2P
5033 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5034 #endif /* CONFIG_P2P */
5035 
5036 	/* for debug */
5037 	u8 *dbgbuf = pframe;
5038 	u8 dbgbufLen = 0, index = 0;
5039 
5040 	RTW_INFO("%s\n", __FUNCTION__);
5041 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5042 	/*	_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
5043 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5044 
5045 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5046 
5047 
5048 	fctrl = &(pwlanhdr->frame_ctl);
5049 	*(fctrl) = 0;
5050 
5051 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
5052 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5053 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
5054 
5055 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
5056 	/* pmlmeext->mgnt_seq++; */
5057 	set_frame_sub_type(pframe, WIFI_BEACON);
5058 
5059 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5060 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5061 
5062 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
5063 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
5064 #ifdef CONFIG_P2P
5065 		/* for P2P : Primary Device Type & Device Name */
5066 		u32 wpsielen = 0, insert_len = 0;
5067 		u8 *wpsie = NULL;
5068 		wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
5069 
5070 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
5071 			uint wps_offset, remainder_ielen;
5072 			u8 *premainder_ie, *pframe_wscie;
5073 
5074 			wps_offset = (uint)(wpsie - cur_network->IEs);
5075 
5076 			premainder_ie = wpsie + wpsielen;
5077 
5078 			remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
5079 
5080 #ifdef CONFIG_IOCTL_CFG80211
5081 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
5082 				if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
5083 					_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
5084 					pframe += wps_offset;
5085 					pktlen += wps_offset;
5086 
5087 					_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
5088 					pframe += pmlmepriv->wps_beacon_ie_len;
5089 					pktlen += pmlmepriv->wps_beacon_ie_len;
5090 
5091 					/* copy remainder_ie to pframe */
5092 					_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
5093 					pframe += remainder_ielen;
5094 					pktlen += remainder_ielen;
5095 				} else {
5096 					_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
5097 					pframe += cur_network->IELength;
5098 					pktlen += cur_network->IELength;
5099 				}
5100 			} else
5101 #endif /* CONFIG_IOCTL_CFG80211 */
5102 			{
5103 				pframe_wscie = pframe + wps_offset;
5104 				_rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
5105 				pframe += (wps_offset + wpsielen);
5106 				pktlen += (wps_offset + wpsielen);
5107 
5108 				/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
5109 				/*	Primary Device Type */
5110 				/*	Type: */
5111 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
5112 				insert_len += 2;
5113 
5114 				/*	Length: */
5115 				*(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
5116 				insert_len += 2;
5117 
5118 				/*	Value: */
5119 				/*	Category ID */
5120 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5121 				insert_len += 2;
5122 
5123 				/*	OUI */
5124 				*(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
5125 				insert_len += 4;
5126 
5127 				/*	Sub Category ID */
5128 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5129 				insert_len += 2;
5130 
5131 
5132 				/*	Device Name */
5133 				/*	Type: */
5134 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5135 				insert_len += 2;
5136 
5137 				/*	Length: */
5138 				*(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
5139 				insert_len += 2;
5140 
5141 				/*	Value: */
5142 				_rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
5143 				insert_len += pwdinfo->device_name_len;
5144 
5145 
5146 				/* update wsc ie length */
5147 				*(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
5148 
5149 				/* pframe move to end */
5150 				pframe += insert_len;
5151 				pktlen += insert_len;
5152 
5153 				/* copy remainder_ie to pframe */
5154 				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
5155 				pframe += remainder_ielen;
5156 				pktlen += remainder_ielen;
5157 			}
5158 		} else
5159 #endif /* CONFIG_P2P */
5160 		{
5161 			int len_diff;
5162 			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
5163 			len_diff = update_hidden_ssid(
5164 					   pframe + _BEACON_IE_OFFSET_
5165 				   , cur_network->IELength - _BEACON_IE_OFFSET_
5166 					   , pmlmeinfo->hidden_ssid_mode
5167 				   );
5168 			pframe += (cur_network->IELength + len_diff);
5169 			pktlen += (cur_network->IELength + len_diff);
5170 		}
5171 #if 0
5172 		{
5173 			u8 *wps_ie;
5174 			uint wps_ielen;
5175 			u8 sr = 0;
5176 			wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
5177 				pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
5178 			if (wps_ie && wps_ielen > 0)
5179 				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
5180 			if (sr != 0)
5181 				set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
5182 			else
5183 				_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
5184 		}
5185 #endif
5186 #ifdef CONFIG_P2P
5187 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5188 			u32 len;
5189 #ifdef CONFIG_IOCTL_CFG80211
5190 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
5191 				len = pmlmepriv->p2p_beacon_ie_len;
5192 				if (pmlmepriv->p2p_beacon_ie && len > 0)
5193 					_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
5194 			} else
5195 #endif /* CONFIG_IOCTL_CFG80211 */
5196 			{
5197 				len = build_beacon_p2p_ie(pwdinfo, pframe);
5198 			}
5199 
5200 			pframe += len;
5201 			pktlen += len;
5202 
5203 			#ifdef CONFIG_WFD
5204 			len = rtw_append_beacon_wfd_ie(padapter, pframe);
5205 			pframe += len;
5206 			pktlen += len;
5207 			#endif
5208 
5209 		}
5210 #endif /* CONFIG_P2P */
5211 
5212 		goto _issue_bcn;
5213 
5214 	}
5215 
5216 	/* below for ad-hoc mode */
5217 
5218 	/* timestamp will be inserted by hardware */
5219 	pframe += 8;
5220 	pktlen += 8;
5221 
5222 	/* beacon interval: 2 bytes */
5223 
5224 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
5225 
5226 	pframe += 2;
5227 	pktlen += 2;
5228 
5229 	/* capability info: 2 bytes */
5230 
5231 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
5232 
5233 	pframe += 2;
5234 	pktlen += 2;
5235 
5236 	/* SSID */
5237 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
5238 
5239 	/* supported rates... */
5240 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
5241 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
5242 
5243 	/* DS parameter set */
5244 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
5245 
5246 	/* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
5247 	{
5248 		u8 erpinfo = 0;
5249 		u32 ATIMWindow;
5250 		/* IBSS Parameter Set... */
5251 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
5252 		ATIMWindow = 0;
5253 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
5254 
5255 		/* ERP IE */
5256 		pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
5257 	}
5258 
5259 
5260 	/* EXTERNDED SUPPORTED RATE */
5261 	if (rate_len > 8)
5262 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
5263 
5264 
5265 	/* todo:HT for adhoc */
5266 
5267 _issue_bcn:
5268 
5269 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5270 	/*	pmlmepriv->update_bcn = _FALSE;
5271 	 *
5272 	 *	_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
5273 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5274 
5275 	*pLength = pktlen;
5276 #if 0
5277 	/* printf dbg msg */
5278 	dbgbufLen = pktlen;
5279 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
5280 
5281 	for (index = 0; index < dbgbufLen; index++)
5282 		printk("%x ", *(dbgbuf + index));
5283 
5284 	printk("\n");
5285 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
5286 
5287 #endif
5288 }
5289 
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)5290 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
5291 {
5292 	/* struct xmit_frame			*pmgntframe; */
5293 	/* struct pkt_attrib			*pattrib; */
5294 	/* unsigned char					*pframe; */
5295 	struct rtw_ieee80211_hdr	*pwlanhdr;
5296 	unsigned short				*fctrl;
5297 	unsigned char					*mac;
5298 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
5299 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5300 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5301 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5302 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
5303 	u16					beacon_interval = 100;
5304 	u16					capInfo = 0;
5305 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5306 	u8					wpsie[255] = { 0x00 };
5307 	u32					wpsielen = 0, p2pielen = 0;
5308 	u32					pktlen;
5309 #ifdef CONFIG_WFD
5310 	u32					wfdielen = 0;
5311 #endif
5312 #ifdef CONFIG_INTEL_WIDI
5313 	u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
5314 #endif /* CONFIG_INTEL_WIDI */
5315 
5316 	/* for debug */
5317 	u8 *dbgbuf = pframe;
5318 	u8 dbgbufLen = 0, index = 0;
5319 
5320 	RTW_INFO("%s\n", __FUNCTION__);
5321 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5322 
5323 	mac = adapter_mac_addr(padapter);
5324 
5325 	fctrl = &(pwlanhdr->frame_ctl);
5326 	*(fctrl) = 0;
5327 
5328 	/* DA filled by FW */
5329 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
5330 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5331 
5332 	/*	Use the device address for BSSID field.	 */
5333 	_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
5334 
5335 	SetSeqNum(pwlanhdr, 0);
5336 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
5337 
5338 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5339 	pframe += pktlen;
5340 
5341 
5342 	/* timestamp will be inserted by hardware */
5343 	pframe += 8;
5344 	pktlen += 8;
5345 
5346 	/* beacon interval: 2 bytes */
5347 	_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
5348 	pframe += 2;
5349 	pktlen += 2;
5350 
5351 	/*	capability info: 2 bytes */
5352 	/*	ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
5353 	capInfo |= cap_ShortPremble;
5354 	capInfo |= cap_ShortSlot;
5355 
5356 	_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
5357 	pframe += 2;
5358 	pktlen += 2;
5359 
5360 
5361 	/* SSID */
5362 	pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
5363 
5364 	/* supported rates... */
5365 	/*	Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
5366 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
5367 
5368 	/* DS parameter set */
5369 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
5370 
5371 #ifdef CONFIG_IOCTL_CFG80211
5372 	if (pwdinfo->driver_interface == DRIVER_CFG80211) {
5373 		if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
5374 			/* WPS IE */
5375 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
5376 			pktlen += pmlmepriv->wps_probe_resp_ie_len;
5377 			pframe += pmlmepriv->wps_probe_resp_ie_len;
5378 
5379 			/* P2P IE */
5380 			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
5381 			pktlen += pmlmepriv->p2p_probe_resp_ie_len;
5382 			pframe += pmlmepriv->p2p_probe_resp_ie_len;
5383 		}
5384 	} else
5385 #endif /* CONFIG_IOCTL_CFG80211		 */
5386 	{
5387 
5388 		/*	Todo: WPS IE */
5389 		/*	Noted by Albert 20100907 */
5390 		/*	According to the WPS specification, all the WPS attribute is presented by Big Endian. */
5391 
5392 		wpsielen = 0;
5393 		/*	WPS OUI */
5394 		*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
5395 		wpsielen += 4;
5396 
5397 		/*	WPS version */
5398 		/*	Type: */
5399 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5400 		wpsielen += 2;
5401 
5402 		/*	Length: */
5403 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5404 		wpsielen += 2;
5405 
5406 		/*	Value: */
5407 		wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
5408 
5409 #ifdef CONFIG_INTEL_WIDI
5410 		/*	Commented by Kurt */
5411 		/*	Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext. */
5412 		if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
5413 		    || pmlmepriv->num_p2p_sdt != 0) {
5414 			/* Sec dev type */
5415 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SEC_DEV_TYPE_LIST);
5416 			wpsielen += 2;
5417 
5418 			/*	Length: */
5419 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
5420 			wpsielen += 2;
5421 
5422 			/*	Value: */
5423 			/*	Category ID */
5424 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_DISPLAYS);
5425 			wpsielen += 2;
5426 
5427 			/*	OUI */
5428 			*(u32 *)(wpsie + wpsielen) = cpu_to_be32(INTEL_DEV_TYPE_OUI);
5429 			wpsielen += 4;
5430 
5431 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_WIDI_CONSUMER_SINK);
5432 			wpsielen += 2;
5433 
5434 			if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE) {
5435 				/*	Vendor Extension */
5436 				_rtw_memcpy(wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN);
5437 				wpsielen += L2SDTA_SERVICE_VE_LEN;
5438 			}
5439 		}
5440 #endif /* CONFIG_INTEL_WIDI */
5441 
5442 		/*	WiFi Simple Config State */
5443 		/*	Type: */
5444 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
5445 		wpsielen += 2;
5446 
5447 		/*	Length: */
5448 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5449 		wpsielen += 2;
5450 
5451 		/*	Value: */
5452 		wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;	/*	Not Configured. */
5453 
5454 		/*	Response Type */
5455 		/*	Type: */
5456 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
5457 		wpsielen += 2;
5458 
5459 		/*	Length: */
5460 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5461 		wpsielen += 2;
5462 
5463 		/*	Value: */
5464 		wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
5465 
5466 		/*	UUID-E */
5467 		/*	Type: */
5468 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
5469 		wpsielen += 2;
5470 
5471 		/*	Length: */
5472 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
5473 		wpsielen += 2;
5474 
5475 		/*	Value: */
5476 		if (pwdinfo->external_uuid == 0) {
5477 			_rtw_memset(wpsie + wpsielen, 0x0, 16);
5478 			_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5479 		} else
5480 			_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
5481 		wpsielen += 0x10;
5482 
5483 		/*	Manufacturer */
5484 		/*	Type: */
5485 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
5486 		wpsielen += 2;
5487 
5488 		/*	Length: */
5489 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
5490 		wpsielen += 2;
5491 
5492 		/*	Value: */
5493 		_rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
5494 		wpsielen += 7;
5495 
5496 		/*	Model Name */
5497 		/*	Type: */
5498 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
5499 		wpsielen += 2;
5500 
5501 		/*	Length: */
5502 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
5503 		wpsielen += 2;
5504 
5505 		/*	Value: */
5506 		_rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
5507 		wpsielen += 6;
5508 
5509 		/*	Model Number */
5510 		/*	Type: */
5511 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
5512 		wpsielen += 2;
5513 
5514 		/*	Length: */
5515 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5516 		wpsielen += 2;
5517 
5518 		/*	Value: */
5519 		wpsie[wpsielen++] = 0x31;		/*	character 1 */
5520 
5521 		/*	Serial Number */
5522 		/*	Type: */
5523 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
5524 		wpsielen += 2;
5525 
5526 		/*	Length: */
5527 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
5528 		wpsielen += 2;
5529 
5530 		/*	Value: */
5531 		_rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
5532 		wpsielen += ETH_ALEN;
5533 
5534 		/*	Primary Device Type */
5535 		/*	Type: */
5536 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
5537 		wpsielen += 2;
5538 
5539 		/*	Length: */
5540 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
5541 		wpsielen += 2;
5542 
5543 		/*	Value: */
5544 		/*	Category ID */
5545 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5546 		wpsielen += 2;
5547 
5548 		/*	OUI */
5549 		*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
5550 		wpsielen += 4;
5551 
5552 		/*	Sub Category ID */
5553 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5554 		wpsielen += 2;
5555 
5556 		/*	Device Name */
5557 		/*	Type: */
5558 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5559 		wpsielen += 2;
5560 
5561 		/*	Length: */
5562 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
5563 		wpsielen += 2;
5564 
5565 		/*	Value: */
5566 		_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
5567 		wpsielen += pwdinfo->device_name_len;
5568 
5569 		/*	Config Method */
5570 		/*	Type: */
5571 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
5572 		wpsielen += 2;
5573 
5574 		/*	Length: */
5575 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
5576 		wpsielen += 2;
5577 
5578 		/*	Value: */
5579 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
5580 		wpsielen += 2;
5581 
5582 
5583 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
5584 
5585 
5586 		p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
5587 		pframe += p2pielen;
5588 		pktlen += p2pielen;
5589 	}
5590 
5591 #ifdef CONFIG_WFD
5592 	wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
5593 	pframe += wfdielen;
5594 	pktlen += wfdielen;
5595 #endif
5596 
5597 	*pLength = pktlen;
5598 
5599 #if 0
5600 	/* printf dbg msg */
5601 	dbgbufLen = pktlen;
5602 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
5603 
5604 	for (index = 0; index < dbgbufLen; index++)
5605 		printk("%x ", *(dbgbuf + index));
5606 
5607 	printk("\n");
5608 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
5609 #endif
5610 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)5611 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
5612 {
5613 	struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
5614 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5615 	u8			action = P2P_PUB_ACTION_ACTION;
5616 	u32			p2poui = cpu_to_be32(P2POUI);
5617 	u8			oui_subtype = P2P_GO_NEGO_RESP;
5618 	u8			wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
5619 	u8			p2pielen = 0, i;
5620 	uint			wpsielen = 0;
5621 	u16			wps_devicepassword_id = 0x0000;
5622 	uint			wps_devicepassword_id_len = 0;
5623 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
5624 	u16			len_channellist_attr = 0;
5625 	u32			pktlen;
5626 	u8			dialogToken = 0;
5627 
5628 	/* struct xmit_frame			*pmgntframe; */
5629 	/* struct pkt_attrib			*pattrib; */
5630 	/* unsigned char					*pframe; */
5631 	struct rtw_ieee80211_hdr	*pwlanhdr;
5632 	unsigned short				*fctrl;
5633 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
5634 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5635 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5636 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5637 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
5638 
5639 #ifdef CONFIG_WFD
5640 	u32					wfdielen = 0;
5641 #endif
5642 
5643 	/* for debug */
5644 	u8 *dbgbuf = pframe;
5645 	u8 dbgbufLen = 0, index = 0;
5646 
5647 	RTW_INFO("%s\n", __FUNCTION__);
5648 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5649 
5650 	fctrl = &(pwlanhdr->frame_ctl);
5651 	*(fctrl) = 0;
5652 
5653 	/* RA, filled by FW */
5654 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
5655 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5656 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
5657 
5658 	SetSeqNum(pwlanhdr, 0);
5659 	set_frame_sub_type(pframe, WIFI_ACTION);
5660 
5661 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5662 	pframe += pktlen;
5663 
5664 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
5665 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
5666 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
5667 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
5668 
5669 	/* dialog token, filled by FW */
5670 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
5671 
5672 	_rtw_memset(wpsie, 0x00, 255);
5673 	wpsielen = 0;
5674 
5675 	/*	WPS Section */
5676 	wpsielen = 0;
5677 	/*	WPS OUI */
5678 	*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
5679 	wpsielen += 4;
5680 
5681 	/*	WPS version */
5682 	/*	Type: */
5683 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5684 	wpsielen += 2;
5685 
5686 	/*	Length: */
5687 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5688 	wpsielen += 2;
5689 
5690 	/*	Value: */
5691 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
5692 
5693 	/*	Device Password ID */
5694 	/*	Type: */
5695 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
5696 	wpsielen += 2;
5697 
5698 	/*	Length: */
5699 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
5700 	wpsielen += 2;
5701 
5702 	/*	Value: */
5703 	if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
5704 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
5705 	else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
5706 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
5707 	else
5708 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
5709 	wpsielen += 2;
5710 
5711 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
5712 
5713 
5714 	/*	P2P IE Section. */
5715 
5716 	/*	P2P OUI */
5717 	p2pielen = 0;
5718 	p2pie[p2pielen++] = 0x50;
5719 	p2pie[p2pielen++] = 0x6F;
5720 	p2pie[p2pielen++] = 0x9A;
5721 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
5722 
5723 	/*	Commented by Albert 20100908 */
5724 	/*	According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
5725 	/*	1. Status */
5726 	/*	2. P2P Capability */
5727 	/*	3. Group Owner Intent */
5728 	/*	4. Configuration Timeout */
5729 	/*	5. Operating Channel */
5730 	/*	6. Intended P2P Interface Address */
5731 	/*	7. Channel List */
5732 	/*	8. Device Info */
5733 	/*	9. Group ID	( Only GO ) */
5734 
5735 
5736 	/*	ToDo: */
5737 
5738 	/*	P2P Status */
5739 	/*	Type: */
5740 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
5741 
5742 	/*	Length: */
5743 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5744 	p2pielen += 2;
5745 
5746 	/*	Value, filled by FW */
5747 	p2pie[p2pielen++] = 1;
5748 
5749 	/*	P2P Capability */
5750 	/*	Type: */
5751 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
5752 
5753 	/*	Length: */
5754 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5755 	p2pielen += 2;
5756 
5757 	/*	Value: */
5758 	/*	Device Capability Bitmap, 1 byte */
5759 
5760 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
5761 		/*	Commented by Albert 2011/03/08 */
5762 		/*	According to the P2P specification */
5763 		/*	if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
5764 		p2pie[p2pielen++] = 0;
5765 	} else {
5766 		/*	Be group owner or meet the error case */
5767 		p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
5768 	}
5769 
5770 	/*	Group Capability Bitmap, 1 byte */
5771 	if (pwdinfo->persistent_supported)
5772 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
5773 	else
5774 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
5775 
5776 	/*	Group Owner Intent */
5777 	/*	Type: */
5778 	p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
5779 
5780 	/*	Length: */
5781 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5782 	p2pielen += 2;
5783 
5784 	/*	Value: */
5785 	if (pwdinfo->peer_intent & 0x01) {
5786 		/*	Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
5787 		p2pie[p2pielen++] = (pwdinfo->intent << 1);
5788 	} else {
5789 		/*	Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
5790 		p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
5791 	}
5792 
5793 
5794 	/*	Configuration Timeout */
5795 	/*	Type: */
5796 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5797 
5798 	/*	Length: */
5799 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5800 	p2pielen += 2;
5801 
5802 	/*	Value: */
5803 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
5804 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
5805 
5806 	/*	Operating Channel */
5807 	/*	Type: */
5808 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5809 
5810 	/*	Length: */
5811 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5812 	p2pielen += 2;
5813 
5814 	/*	Value: */
5815 	/*	Country String */
5816 	p2pie[p2pielen++] = 'X';
5817 	p2pie[p2pielen++] = 'X';
5818 
5819 	/*	The third byte should be set to 0x04. */
5820 	/*	Described in the "Operating Channel Attribute" section. */
5821 	p2pie[p2pielen++] = 0x04;
5822 
5823 	/*	Operating Class */
5824 	if (pwdinfo->operating_channel <= 14) {
5825 		/*	Operating Class */
5826 		p2pie[p2pielen++] = 0x51;
5827 	} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
5828 		/*	Operating Class */
5829 		p2pie[p2pielen++] = 0x73;
5830 	} else {
5831 		/*	Operating Class */
5832 		p2pie[p2pielen++] = 0x7c;
5833 	}
5834 
5835 	/*	Channel Number */
5836 	p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
5837 
5838 	/*	Intended P2P Interface Address	 */
5839 	/*	Type: */
5840 	p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
5841 
5842 	/*	Length: */
5843 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5844 	p2pielen += 2;
5845 
5846 	/*	Value: */
5847 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5848 	p2pielen += ETH_ALEN;
5849 
5850 	/*	Channel List */
5851 	/*	Type: */
5852 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5853 
5854 	/* Country String(3) */
5855 	/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5856 	/* + number of channels in all classes */
5857 	len_channellist_attr = 3
5858 		       + (1 + 1) * (u16)ch_list->reg_classes
5859 		       + get_reg_classes_full_count(ch_list);
5860 
5861 #ifdef CONFIG_CONCURRENT_MODE
5862 	if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED))
5863 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5864 	else
5865 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5866 
5867 #else
5868 
5869 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5870 
5871 #endif
5872 	p2pielen += 2;
5873 
5874 	/*	Value: */
5875 	/*	Country String */
5876 	p2pie[p2pielen++] = 'X';
5877 	p2pie[p2pielen++] = 'X';
5878 
5879 	/*	The third byte should be set to 0x04. */
5880 	/*	Described in the "Operating Channel Attribute" section. */
5881 	p2pie[p2pielen++] = 0x04;
5882 
5883 	/*	Channel Entry List */
5884 
5885 #ifdef CONFIG_CONCURRENT_MODE
5886 	if (rtw_mi_check_status(padapter, MI_LINKED)) {
5887 		u8 union_ch = rtw_mi_get_union_chan(padapter);
5888 
5889 		/*	Operating Class */
5890 		if (union_ch > 14) {
5891 			if (union_ch >= 149)
5892 				p2pie[p2pielen++] = 0x7c;
5893 			else
5894 				p2pie[p2pielen++] = 0x73;
5895 		} else
5896 			p2pie[p2pielen++] = 0x51;
5897 
5898 
5899 		/*	Number of Channels */
5900 		/*	Just support 1 channel and this channel is AP's channel */
5901 		p2pie[p2pielen++] = 1;
5902 
5903 		/*	Channel List */
5904 		p2pie[p2pielen++] = union_ch;
5905 	} else
5906 #endif /* CONFIG_CONCURRENT_MODE */
5907 	{
5908 		int i, j;
5909 		for (j = 0; j < ch_list->reg_classes; j++) {
5910 			/*	Operating Class */
5911 			p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
5912 
5913 			/*	Number of Channels */
5914 			p2pie[p2pielen++] = ch_list->reg_class[j].channels;
5915 
5916 			/*	Channel List */
5917 			for (i = 0; i < ch_list->reg_class[j].channels; i++)
5918 				p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
5919 		}
5920 	}
5921 
5922 	/*	Device Info */
5923 	/*	Type: */
5924 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
5925 
5926 	/*	Length: */
5927 	/*	21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
5928 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
5929 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
5930 	p2pielen += 2;
5931 
5932 	/*	Value: */
5933 	/*	P2P Device Address */
5934 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5935 	p2pielen += ETH_ALEN;
5936 
5937 	/*	Config Method */
5938 	/*	This field should be big endian. Noted by P2P specification. */
5939 
5940 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
5941 
5942 	p2pielen += 2;
5943 
5944 	/*	Primary Device Type */
5945 	/*	Category ID */
5946 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5947 	p2pielen += 2;
5948 
5949 	/*	OUI */
5950 	*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
5951 	p2pielen += 4;
5952 
5953 	/*	Sub Category ID */
5954 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5955 	p2pielen += 2;
5956 
5957 	/*	Number of Secondary Device Types */
5958 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
5959 
5960 	/*	Device Name */
5961 	/*	Type: */
5962 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5963 	p2pielen += 2;
5964 
5965 	/*	Length: */
5966 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
5967 	p2pielen += 2;
5968 
5969 	/*	Value: */
5970 	_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
5971 	p2pielen += pwdinfo->device_name_len;
5972 
5973 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5974 		/*	Group ID Attribute */
5975 		/*	Type: */
5976 		p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
5977 
5978 		/*	Length: */
5979 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
5980 		p2pielen += 2;
5981 
5982 		/*	Value: */
5983 		/*	p2P Device Address */
5984 		_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
5985 		p2pielen += ETH_ALEN;
5986 
5987 		/*	SSID */
5988 		_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
5989 		p2pielen += pwdinfo->nego_ssidlen;
5990 
5991 	}
5992 
5993 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
5994 
5995 #ifdef CONFIG_WFD
5996 	wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
5997 	pframe += wfdielen;
5998 	pktlen += wfdielen;
5999 #endif
6000 
6001 	*pLength = pktlen;
6002 #if 0
6003 	/* printf dbg msg */
6004 	dbgbufLen = pktlen;
6005 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
6006 
6007 	for (index = 0; index < dbgbufLen; index++)
6008 		printk("%x ", *(dbgbuf + index));
6009 
6010 	printk("\n");
6011 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
6012 #endif
6013 }
6014 
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6015 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6016 {
6017 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
6018 	u8			action = P2P_PUB_ACTION_ACTION;
6019 	u32			p2poui = cpu_to_be32(P2POUI);
6020 	u8			oui_subtype = P2P_INVIT_RESP;
6021 	u8			p2pie[255] = { 0x00 };
6022 	u8			p2pielen = 0, i;
6023 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
6024 	u16			len_channellist_attr = 0;
6025 	u32			pktlen;
6026 	u8			dialogToken = 0;
6027 #ifdef CONFIG_WFD
6028 	u32					wfdielen = 0;
6029 #endif
6030 
6031 	/* struct xmit_frame			*pmgntframe; */
6032 	/* struct pkt_attrib			*pattrib; */
6033 	/* unsigned char					*pframe; */
6034 	struct rtw_ieee80211_hdr	*pwlanhdr;
6035 	unsigned short				*fctrl;
6036 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
6037 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6038 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6039 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6040 
6041 	/* for debug */
6042 	u8 *dbgbuf = pframe;
6043 	u8 dbgbufLen = 0, index = 0;
6044 
6045 
6046 	RTW_INFO("%s\n", __FUNCTION__);
6047 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6048 
6049 	fctrl = &(pwlanhdr->frame_ctl);
6050 	*(fctrl) = 0;
6051 
6052 	/* RA fill by FW */
6053 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6054 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6055 
6056 	/* BSSID fill by FW */
6057 	_rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
6058 
6059 	SetSeqNum(pwlanhdr, 0);
6060 	set_frame_sub_type(pframe, WIFI_ACTION);
6061 
6062 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6063 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6064 
6065 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
6066 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
6067 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
6068 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
6069 
6070 	/* dialog token, filled by FW */
6071 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
6072 
6073 	/*	P2P IE Section. */
6074 
6075 	/*	P2P OUI */
6076 	p2pielen = 0;
6077 	p2pie[p2pielen++] = 0x50;
6078 	p2pie[p2pielen++] = 0x6F;
6079 	p2pie[p2pielen++] = 0x9A;
6080 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
6081 
6082 	/*	Commented by Albert 20101005 */
6083 	/*	According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
6084 	/*	1. Status */
6085 	/*	2. Configuration Timeout */
6086 	/*	3. Operating Channel	( Only GO ) */
6087 	/*	4. P2P Group BSSID	( Only GO ) */
6088 	/*	5. Channel List */
6089 
6090 	/*	P2P Status */
6091 	/*	Type: */
6092 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
6093 
6094 	/*	Length: */
6095 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
6096 	p2pielen += 2;
6097 
6098 	/*	Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
6099 	p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6100 
6101 	/*	Configuration Timeout */
6102 	/*	Type: */
6103 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
6104 
6105 	/*	Length: */
6106 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
6107 	p2pielen += 2;
6108 
6109 	/*	Value: */
6110 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
6111 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
6112 
6113 	/* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
6114 #if 0
6115 	if (status_code == P2P_STATUS_SUCCESS) {
6116 		struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
6117 
6118 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6119 			/*	The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
6120 			/*	In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
6121 			/*	First one is operating channel attribute. */
6122 			/*	Second one is P2P Group BSSID attribute. */
6123 
6124 			/*	Operating Channel */
6125 			/*	Type: */
6126 			p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
6127 
6128 			/*	Length: */
6129 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
6130 			p2pielen += 2;
6131 
6132 			/*	Value: */
6133 			/*	Country String */
6134 			p2pie[p2pielen++] = 'X';
6135 			p2pie[p2pielen++] = 'X';
6136 
6137 			/*	The third byte should be set to 0x04. */
6138 			/*	Described in the "Operating Channel Attribute" section. */
6139 			p2pie[p2pielen++] = 0x04;
6140 
6141 			/*	Operating Class */
6142 			p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
6143 
6144 			/*	Channel Number */
6145 			p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
6146 
6147 
6148 			/*	P2P Group BSSID */
6149 			/*	Type: */
6150 			p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
6151 
6152 			/*	Length: */
6153 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
6154 			p2pielen += 2;
6155 
6156 			/*	Value: */
6157 			/*	P2P Device Address for GO */
6158 			_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
6159 			p2pielen += ETH_ALEN;
6160 
6161 		}
6162 
6163 		/*	Channel List */
6164 		/*	Type: */
6165 		p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
6166 
6167 		/*	Length: */
6168 		/* Country String(3) */
6169 		/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
6170 		/* + number of channels in all classes */
6171 		len_channellist_attr = 3
6172 			+ (1 + 1) * (u16)ch_list->reg_classes
6173 			+ get_reg_classes_full_count(ch_list);
6174 
6175 #ifdef CONFIG_CONCURRENT_MODE
6176 		if (rtw_mi_check_status(padapter, MI_LINKED))
6177 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
6178 		else
6179 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
6180 
6181 #else
6182 
6183 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
6184 
6185 #endif
6186 		p2pielen += 2;
6187 
6188 		/*	Value: */
6189 		/*	Country String */
6190 		p2pie[p2pielen++] = 'X';
6191 		p2pie[p2pielen++] = 'X';
6192 
6193 		/*	The third byte should be set to 0x04. */
6194 		/*	Described in the "Operating Channel Attribute" section. */
6195 		p2pie[p2pielen++] = 0x04;
6196 
6197 		/*	Channel Entry List */
6198 #ifdef CONFIG_CONCURRENT_MODE
6199 		if (rtw_mi_check_status(padapter, MI_LINKED)) {
6200 			u8 union_ch = rtw_mi_get_union_chan(padapter);
6201 
6202 			/*	Operating Class */
6203 			if (union_ch > 14) {
6204 				if (union_ch >= 149)
6205 					p2pie[p2pielen++] = 0x7c;
6206 				else
6207 					p2pie[p2pielen++] = 0x73;
6208 
6209 			} else
6210 				p2pie[p2pielen++] = 0x51;
6211 
6212 
6213 			/*	Number of Channels */
6214 			/*	Just support 1 channel and this channel is AP's channel */
6215 			p2pie[p2pielen++] = 1;
6216 
6217 			/*	Channel List */
6218 			p2pie[p2pielen++] = union_ch;
6219 		} else
6220 #endif /* CONFIG_CONCURRENT_MODE */
6221 		{
6222 			int i, j;
6223 			for (j = 0; j < ch_list->reg_classes; j++) {
6224 				/*	Operating Class */
6225 				p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
6226 
6227 				/*	Number of Channels */
6228 				p2pie[p2pielen++] = ch_list->reg_class[j].channels;
6229 
6230 				/*	Channel List */
6231 				for (i = 0; i < ch_list->reg_class[j].channels; i++)
6232 					p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
6233 			}
6234 		}
6235 	}
6236 #endif
6237 
6238 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
6239 
6240 #ifdef CONFIG_WFD
6241 	wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
6242 	pframe += wfdielen;
6243 	pktlen += wfdielen;
6244 #endif
6245 
6246 	*pLength = pktlen;
6247 
6248 #if 0
6249 	/* printf dbg msg */
6250 	dbgbufLen = pktlen;
6251 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
6252 
6253 	for (index = 0; index < dbgbufLen; index++)
6254 		printk("%x ", *(dbgbuf + index));
6255 
6256 	printk("\n");
6257 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
6258 #endif
6259 }
6260 
6261 
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6262 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6263 {
6264 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
6265 	u8			action = P2P_PUB_ACTION_ACTION;
6266 	u8			dialogToken = 0;
6267 	u32			p2poui = cpu_to_be32(P2POUI);
6268 	u8			oui_subtype = P2P_PROVISION_DISC_RESP;
6269 	u8			wpsie[100] = { 0x00 };
6270 	u8			wpsielen = 0;
6271 	u32			pktlen;
6272 #ifdef CONFIG_WFD
6273 	u32					wfdielen = 0;
6274 #endif
6275 
6276 	/* struct xmit_frame			*pmgntframe; */
6277 	/* struct pkt_attrib			*pattrib; */
6278 	/* unsigned char					*pframe; */
6279 	struct rtw_ieee80211_hdr	*pwlanhdr;
6280 	unsigned short				*fctrl;
6281 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
6282 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6283 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6284 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6285 
6286 	/* for debug */
6287 	u8 *dbgbuf = pframe;
6288 	u8 dbgbufLen = 0, index = 0;
6289 
6290 	RTW_INFO("%s\n", __FUNCTION__);
6291 
6292 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6293 
6294 	fctrl = &(pwlanhdr->frame_ctl);
6295 	*(fctrl) = 0;
6296 
6297 	/* RA filled by FW */
6298 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6299 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6300 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
6301 
6302 	SetSeqNum(pwlanhdr, 0);
6303 	set_frame_sub_type(pframe, WIFI_ACTION);
6304 
6305 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6306 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6307 
6308 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
6309 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
6310 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
6311 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
6312 	/* dialog token, filled by FW */
6313 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
6314 
6315 	wpsielen = 0;
6316 	/*	WPS OUI */
6317 	/* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
6318 	RTW_PUT_BE32(wpsie, WPSOUI);
6319 	wpsielen += 4;
6320 
6321 #if 0
6322 	/*	WPS version */
6323 	/*	Type: */
6324 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6325 	wpsielen += 2;
6326 
6327 	/*	Length: */
6328 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6329 	wpsielen += 2;
6330 
6331 	/*	Value: */
6332 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
6333 #endif
6334 
6335 	/*	Config Method */
6336 	/*	Type: */
6337 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
6338 	RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
6339 	wpsielen += 2;
6340 
6341 	/*	Length: */
6342 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
6343 	RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
6344 	wpsielen += 2;
6345 
6346 	/*	Value: filled by FW, default value is PBC */
6347 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
6348 	RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
6349 	wpsielen += 2;
6350 
6351 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
6352 
6353 #ifdef CONFIG_WFD
6354 	wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
6355 	pframe += wfdielen;
6356 	pktlen += wfdielen;
6357 #endif
6358 
6359 	*pLength = pktlen;
6360 
6361 	/* printf dbg msg */
6362 #if 0
6363 	dbgbufLen = pktlen;
6364 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT  ProvisionDis Rsp\n");
6365 
6366 	for (index = 0; index < dbgbufLen; index++)
6367 		printk("%x ", *(dbgbuf + index));
6368 
6369 	printk("\n");
6370 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
6371 #endif
6372 }
6373 
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)6374 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
6375 {
6376 	u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
6377 	struct hal_ops *pHalFunc = &adapter->hal_func;
6378 	u8 ret = _FAIL;
6379 
6380 	RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
6381 		 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
6382 		 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
6383 		 rsvdpageloc->LocPDRsp);
6384 
6385 	SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
6386 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
6387 	SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
6388 	SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
6389 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
6390 
6391 	/* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
6392 	ret = rtw_hal_fill_h2c_cmd(adapter,
6393 				   H2C_P2P_OFFLOAD_RSVD_PAGE,
6394 				   H2C_P2PRSVDPAGE_LOC_LEN,
6395 				   u1H2CP2PRsvdPageParm);
6396 
6397 	return ret;
6398 }
6399 
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)6400 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
6401 {
6402 
6403 	u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
6404 	struct wifidirect_info	*pwdinfo = &(adapter->wdinfo);
6405 	struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
6406 	struct hal_ops *pHalFunc = &adapter->hal_func;
6407 	u8 ret = _FAIL;
6408 
6409 	_rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
6410 	RTW_INFO("%s\n", __func__);
6411 	switch (pwdinfo->role) {
6412 	case P2P_ROLE_DEVICE:
6413 		RTW_INFO("P2P_ROLE_DEVICE\n");
6414 		p2p_wowlan_offload->role = 0;
6415 		break;
6416 	case P2P_ROLE_CLIENT:
6417 		RTW_INFO("P2P_ROLE_CLIENT\n");
6418 		p2p_wowlan_offload->role = 1;
6419 		break;
6420 	case P2P_ROLE_GO:
6421 		RTW_INFO("P2P_ROLE_GO\n");
6422 		p2p_wowlan_offload->role = 2;
6423 		break;
6424 	default:
6425 		RTW_INFO("P2P_ROLE_DISABLE\n");
6426 		break;
6427 	}
6428 	p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
6429 	p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
6430 	offload_cmd = (u8 *)p2p_wowlan_offload;
6431 	RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
6432 
6433 	ret = rtw_hal_fill_h2c_cmd(adapter,
6434 				   H2C_P2P_OFFLOAD,
6435 				   H2C_P2P_OFFLOAD_LEN,
6436 				   offload_cmd);
6437 	return ret;
6438 
6439 	/* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
6440 }
6441 #endif /* CONFIG_P2P_WOWLAN */
6442 
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)6443 static void rtw_hal_construct_beacon(_adapter *padapter,
6444 				     u8 *pframe, u32 *pLength)
6445 {
6446 	struct rtw_ieee80211_hdr	*pwlanhdr;
6447 	u16					*fctrl;
6448 	u32					rate_len, pktlen;
6449 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6450 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6451 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
6452 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6453 
6454 
6455 	/* RTW_INFO("%s\n", __FUNCTION__); */
6456 
6457 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6458 
6459 	fctrl = &(pwlanhdr->frame_ctl);
6460 	*(fctrl) = 0;
6461 
6462 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6463 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6464 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6465 
6466 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6467 	/* pmlmeext->mgnt_seq++; */
6468 	set_frame_sub_type(pframe, WIFI_BEACON);
6469 
6470 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6471 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6472 
6473 	/* timestamp will be inserted by hardware */
6474 	pframe += 8;
6475 	pktlen += 8;
6476 
6477 	/* beacon interval: 2 bytes */
6478 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6479 
6480 	pframe += 2;
6481 	pktlen += 2;
6482 
6483 	/* capability info: 2 bytes */
6484 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6485 
6486 	pframe += 2;
6487 	pktlen += 2;
6488 
6489 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6490 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6491 		pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
6492 		_rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
6493 
6494 		goto _ConstructBeacon;
6495 	}
6496 
6497 	/* below for ad-hoc mode */
6498 
6499 	/* SSID */
6500 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6501 
6502 	/* supported rates... */
6503 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6504 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6505 
6506 	/* DS parameter set */
6507 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6508 
6509 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
6510 		u32 ATIMWindow;
6511 		/* IBSS Parameter Set... */
6512 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
6513 		ATIMWindow = 0;
6514 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6515 	}
6516 
6517 
6518 	/* todo: ERP IE */
6519 
6520 
6521 	/* EXTERNDED SUPPORTED RATE */
6522 	if (rate_len > 8)
6523 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6524 
6525 
6526 	/* todo:HT for adhoc */
6527 
6528 _ConstructBeacon:
6529 
6530 	if ((pktlen + TXDESC_SIZE) > 512) {
6531 		RTW_INFO("beacon frame too large\n");
6532 		return;
6533 	}
6534 
6535 	*pLength = pktlen;
6536 
6537 	/* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
6538 
6539 }
6540 
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)6541 static void rtw_hal_construct_PSPoll(_adapter *padapter,
6542 				     u8 *pframe, u32 *pLength)
6543 {
6544 	struct rtw_ieee80211_hdr	*pwlanhdr;
6545 	u16					*fctrl;
6546 	u32					pktlen;
6547 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6548 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6549 
6550 	/* RTW_INFO("%s\n", __FUNCTION__); */
6551 
6552 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6553 
6554 	/* Frame control. */
6555 	fctrl = &(pwlanhdr->frame_ctl);
6556 	*(fctrl) = 0;
6557 	SetPwrMgt(fctrl);
6558 	set_frame_sub_type(pframe, WIFI_PSPOLL);
6559 
6560 	/* AID. */
6561 	set_duration(pframe, (pmlmeinfo->aid | 0xc000));
6562 
6563 	/* BSSID. */
6564 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6565 
6566 	/* TA. */
6567 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6568 
6569 	*pLength = 16;
6570 }
6571 
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * StaAddr,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)6572 void rtw_hal_construct_NullFunctionData(
6573 	PADAPTER padapter,
6574 	u8		*pframe,
6575 	u32		*pLength,
6576 	u8		*StaAddr,
6577 	u8		bQoS,
6578 	u8		AC,
6579 	u8		bEosp,
6580 	u8		bForcePowerSave)
6581 {
6582 	struct rtw_ieee80211_hdr	*pwlanhdr;
6583 	u16						*fctrl;
6584 	u32						pktlen;
6585 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
6586 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
6587 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6588 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6589 
6590 
6591 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
6592 
6593 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6594 
6595 	fctrl = &pwlanhdr->frame_ctl;
6596 	*(fctrl) = 0;
6597 	if (bForcePowerSave)
6598 		SetPwrMgt(fctrl);
6599 
6600 	switch (cur_network->network.InfrastructureMode) {
6601 	case Ndis802_11Infrastructure:
6602 		SetToDs(fctrl);
6603 		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6604 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6605 		_rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
6606 		break;
6607 	case Ndis802_11APMode:
6608 		SetFrDs(fctrl);
6609 		_rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
6610 		_rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6611 		_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
6612 		break;
6613 	case Ndis802_11IBSS:
6614 	default:
6615 		_rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
6616 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6617 		_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6618 		break;
6619 	}
6620 
6621 	SetSeqNum(pwlanhdr, 0);
6622 
6623 	if (bQoS == _TRUE) {
6624 		struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
6625 
6626 		set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
6627 
6628 		pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
6629 		SetPriority(&pwlanqoshdr->qc, AC);
6630 		SetEOSP(&pwlanqoshdr->qc, bEosp);
6631 
6632 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
6633 	} else {
6634 		set_frame_sub_type(pframe, WIFI_DATA_NULL);
6635 
6636 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6637 	}
6638 
6639 	*pLength = pktlen;
6640 }
6641 
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,u8 * StaAddr,BOOLEAN bHideSSID)6642 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
6643 				u8 *StaAddr, BOOLEAN bHideSSID)
6644 {
6645 	struct rtw_ieee80211_hdr	*pwlanhdr;
6646 	u16					*fctrl;
6647 	u8					*mac, *bssid;
6648 	u32					pktlen;
6649 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6650 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6651 	WLAN_BSSID_EX  *cur_network = &(pmlmeinfo->network);
6652 
6653 	/*RTW_INFO("%s\n", __FUNCTION__);*/
6654 
6655 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6656 
6657 	mac = adapter_mac_addr(padapter);
6658 	bssid = cur_network->MacAddress;
6659 
6660 	fctrl = &(pwlanhdr->frame_ctl);
6661 	*(fctrl) = 0;
6662 	_rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
6663 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6664 	_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
6665 
6666 	SetSeqNum(pwlanhdr, 0);
6667 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
6668 
6669 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6670 	pframe += pktlen;
6671 
6672 	if (cur_network->IELength > MAX_IE_SZ)
6673 		return;
6674 
6675 	_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6676 	pframe += cur_network->IELength;
6677 	pktlen += cur_network->IELength;
6678 
6679 	*pLength = pktlen;
6680 }
6681 
6682 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)6683 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
6684 				    u8 *pframe, u32 offset)
6685 {
6686 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6687 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6688 	struct rtw_ieee80211_hdr	*pwlanhdr;
6689 	struct mic_data	micdata;
6690 	struct sta_info	*psta = NULL;
6691 	int res = 0;
6692 
6693 	u8	*payload = (u8 *)(pframe + offset);
6694 
6695 	u8	mic[8];
6696 	u8	priority[4] = {0x0};
6697 	u8	null_key[16] = {0x0};
6698 
6699 	RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
6700 
6701 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6702 
6703 	psta = rtw_get_stainfo(&padapter->stapriv,
6704 			get_my_bssid(&(pmlmeinfo->network)));
6705 	if (psta != NULL) {
6706 		res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
6707 				  null_key, 16);
6708 		if (res == _TRUE)
6709 			RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
6710 		rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
6711 	}
6712 
6713 	rtw_secmicappend(&micdata, pwlanhdr->addr3, 6);  /* DA */
6714 
6715 	rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
6716 
6717 	priority[0] = 0;
6718 
6719 	rtw_secmicappend(&micdata, &priority[0], 4);
6720 
6721 	rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
6722 
6723 	rtw_secgetmic(&micdata, &(mic[0]));
6724 
6725 	payload += 36;
6726 
6727 	_rtw_memcpy(payload, &(mic[0]), 8);
6728 }
6729 /*
6730  * Description:
6731  *	Construct the ARP response packet to support ARP offload.
6732  *   */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)6733 static void rtw_hal_construct_ARPRsp(
6734 	PADAPTER padapter,
6735 	u8			*pframe,
6736 	u32			*pLength,
6737 	u8			*pIPAddress
6738 )
6739 {
6740 	struct rtw_ieee80211_hdr	*pwlanhdr;
6741 	u16	*fctrl;
6742 	u32	pktlen;
6743 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
6744 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
6745 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6746 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6747 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
6748 	static u8	ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
6749 	u8	*pARPRspPkt = pframe;
6750 	/* for TKIP Cal MIC */
6751 	u8	*payload = pframe;
6752 	u8	EncryptionHeadOverhead = 0, arp_offset = 0;
6753 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
6754 
6755 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6756 
6757 	fctrl = &pwlanhdr->frame_ctl;
6758 	*(fctrl) = 0;
6759 
6760 	/* ------------------------------------------------------------------------- */
6761 	/* MAC Header. */
6762 	/* ------------------------------------------------------------------------- */
6763 	SetFrameType(fctrl, WIFI_DATA);
6764 	/* set_frame_sub_type(fctrl, 0); */
6765 	SetToDs(fctrl);
6766 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6767 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6768 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6769 
6770 	SetSeqNum(pwlanhdr, 0);
6771 	set_duration(pwlanhdr, 0);
6772 	/* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
6773 	/* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
6774 	/* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
6775 	/* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
6776 	/* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
6777 	/* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
6778 
6779 	/* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
6780 	/* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
6781 #ifdef CONFIG_WAPI_SUPPORT
6782 	*pLength = sMacHdrLng;
6783 #else
6784 	*pLength = 24;
6785 #endif
6786 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
6787 	case _WEP40_:
6788 	case _WEP104_:
6789 		EncryptionHeadOverhead = 4;
6790 		break;
6791 	case _TKIP_:
6792 		EncryptionHeadOverhead = 8;
6793 		break;
6794 	case _AES_:
6795 		EncryptionHeadOverhead = 8;
6796 		break;
6797 #ifdef CONFIG_WAPI_SUPPORT
6798 	case _SMS4_:
6799 		EncryptionHeadOverhead = 18;
6800 		break;
6801 #endif
6802 	default:
6803 		EncryptionHeadOverhead = 0;
6804 	}
6805 
6806 	if (EncryptionHeadOverhead > 0) {
6807 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
6808 		*pLength += EncryptionHeadOverhead;
6809 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
6810 		SetPrivacy(fctrl);
6811 	}
6812 
6813 	/* ------------------------------------------------------------------------- */
6814 	/* Frame Body. */
6815 	/* ------------------------------------------------------------------------- */
6816 	arp_offset = *pLength;
6817 	pARPRspPkt = (u8 *)(pframe + arp_offset);
6818 	payload = pARPRspPkt; /* Get Payload pointer */
6819 	/* LLC header */
6820 	_rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
6821 	*pLength += 8;
6822 
6823 	/* ARP element */
6824 	pARPRspPkt += 8;
6825 	SET_ARP_PKT_HW(pARPRspPkt, 0x0100);
6826 	SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008);	/* IP protocol */
6827 	SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);
6828 	SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);
6829 	SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200);	/* ARP response */
6830 	SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
6831 	SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
6832 #ifdef CONFIG_ARP_KEEP_ALIVE
6833 	if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
6834 		SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
6835 		SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
6836 	} else
6837 #endif
6838 	{
6839 		SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt,
6840 				    get_my_bssid(&(pmlmeinfo->network)));
6841 		SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt,
6842 					   pIPAddress);
6843 		RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
6844 			 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
6845 		RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
6846 			 IP_ARG(pIPAddress));
6847 	}
6848 
6849 	*pLength += 28;
6850 
6851 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
6852 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
6853 		    IS_HARDWARE_TYPE_8812(padapter)) {
6854 			rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
6855 		}
6856 		*pLength += 8;
6857 	}
6858 }
6859 
6860 #ifdef CONFIG_IPV6
6861 /*
6862  * Description: Neighbor Discovery Offload.
6863  */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)6864 static void rtw_hal_construct_na_message(_adapter *padapter,
6865 				     u8 *pframe, u32 *pLength)
6866 {
6867 	struct rtw_ieee80211_hdr *pwlanhdr = NULL;
6868 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
6869 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
6870 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
6871 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
6872 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
6873 
6874 	u32 pktlen = 0;
6875 	u16 *fctrl = NULL;
6876 
6877 	u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
6878 	u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
6879 	u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
6880 	u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
6881 	u8 val8 = 0;
6882 
6883 	u8 *p_na_msg = pframe;
6884 	/* for TKIP Cal MIC */
6885 	u8 *payload = pframe;
6886 	u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
6887 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
6888 
6889 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6890 
6891 	fctrl = &pwlanhdr->frame_ctl;
6892 	*(fctrl) = 0;
6893 
6894 	/* ------------------------------------------------------------------------- */
6895 	/* MAC Header. */
6896 	/* ------------------------------------------------------------------------- */
6897 	SetFrameType(fctrl, WIFI_DATA);
6898 	SetToDs(fctrl);
6899 	_rtw_memcpy(pwlanhdr->addr1,
6900 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6901 	_rtw_memcpy(pwlanhdr->addr2,
6902 		    adapter_mac_addr(padapter), ETH_ALEN);
6903 	_rtw_memcpy(pwlanhdr->addr3,
6904 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6905 
6906 	SetSeqNum(pwlanhdr, 0);
6907 	set_duration(pwlanhdr, 0);
6908 
6909 #ifdef CONFIG_WAPI_SUPPORT
6910 	*pLength = sMacHdrLng;
6911 #else
6912 	*pLength = 24;
6913 #endif
6914 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
6915 	case _WEP40_:
6916 	case _WEP104_:
6917 		EncryptionHeadOverhead = 4;
6918 		break;
6919 	case _TKIP_:
6920 		EncryptionHeadOverhead = 8;
6921 		break;
6922 	case _AES_:
6923 		EncryptionHeadOverhead = 8;
6924 		break;
6925 #ifdef CONFIG_WAPI_SUPPORT
6926 	case _SMS4_:
6927 		EncryptionHeadOverhead = 18;
6928 		break;
6929 #endif
6930 	default:
6931 		EncryptionHeadOverhead = 0;
6932 	}
6933 
6934 	if (EncryptionHeadOverhead > 0) {
6935 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
6936 		*pLength += EncryptionHeadOverhead;
6937 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
6938 		SetPrivacy(fctrl);
6939 	}
6940 
6941 	/* ------------------------------------------------------------------------- */
6942 	/* Frame Body. */
6943 	/* ------------------------------------------------------------------------- */
6944 	na_msg_offset = *pLength;
6945 	p_na_msg = (u8 *)(pframe + na_msg_offset);
6946 	payload = p_na_msg; /* Get Payload pointer */
6947 
6948 	/* LLC header */
6949 	val8 = sizeof(ns_hdr);
6950 	_rtw_memcpy(p_na_msg, ns_hdr, val8);
6951 	*pLength += val8;
6952 	p_na_msg += val8;
6953 
6954 	/* IPv6 Header */
6955 	/* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
6956 	val8 = sizeof(ipv6_info);
6957 	_rtw_memcpy(p_na_msg, ipv6_info, val8);
6958 	*pLength += val8;
6959 	p_na_msg += val8;
6960 
6961 	/* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
6962 	val8 = sizeof(ipv6_contx);
6963 	_rtw_memcpy(p_na_msg, ipv6_contx, val8);
6964 	*pLength += val8;
6965 	p_na_msg += val8;
6966 
6967 	/* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
6968 	_rtw_memset(&(p_na_msg[*pLength]), 0, 32);
6969 	*pLength += 32;
6970 	p_na_msg += 32;
6971 
6972 	/* ICMPv6 */
6973 	/* 1. Type : 0x88 (NA)
6974 	 * 2. Code : 0x00
6975 	 * 3. ChechSum : 0x00 0x00 (RSvd)
6976 	 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
6977 	 */
6978 	val8 = sizeof(icmpv6_hdr);
6979 	_rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
6980 	*pLength += val8;
6981 	p_na_msg += val8;
6982 
6983 	/* TA: 16 bytes*/
6984 	_rtw_memset(&(p_na_msg[*pLength]), 0, 16);
6985 	*pLength += 16;
6986 	p_na_msg += 16;
6987 
6988 	/* ICMPv6 Target Link Layer Address */
6989 	p_na_msg[0] = 0x02; /* type */
6990 	p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
6991 	*pLength += 2;
6992 	p_na_msg += 2;
6993 
6994 	_rtw_memset(&(p_na_msg[*pLength]), 0, 6);
6995 	*pLength += 6;
6996 	p_na_msg += 6;
6997 
6998 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
6999 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
7000 		    IS_HARDWARE_TYPE_8812(padapter)) {
7001 			rtw_hal_append_tkip_mic(padapter, pframe,
7002 						na_msg_offset);
7003 		}
7004 		*pLength += 8;
7005 	}
7006 }
7007 /*
7008  * Description: Neighbor Discovery Protocol Information.
7009  */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)7010 static void rtw_hal_construct_ndp_info(_adapter *padapter,
7011 				     u8 *pframe, u32 *pLength)
7012 {
7013 	struct mlme_ext_priv *pmlmeext = NULL;
7014 	struct mlme_ext_info *pmlmeinfo = NULL;
7015 	struct rtw_ndp_info ndp_info;
7016 	u8	*pndp_info = pframe;
7017 	u8	len = sizeof(struct rtw_ndp_info);
7018 
7019 	RTW_INFO("%s: len: %d\n", __func__, len);
7020 
7021 	pmlmeext =  &padapter->mlmeextpriv;
7022 	pmlmeinfo = &pmlmeext->mlmext_info;
7023 
7024 	_rtw_memset(pframe, 0, len);
7025 	_rtw_memset(&ndp_info, 0, len);
7026 
7027 	ndp_info.enable = 1;
7028 	ndp_info.check_remote_ip = 0;
7029 	ndp_info.num_of_target_ip = 1;
7030 
7031 	_rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
7032 		    ETH_ALEN);
7033 	_rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
7034 		    RTW_IPv6_ADDR_LEN);
7035 
7036 	_rtw_memcpy(pndp_info, &ndp_info, len);
7037 }
7038 #endif /* CONFIG_IPV6 */
7039 
7040 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)7041 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
7042 				       u32 *pLength, pno_ssid_t *ssid)
7043 {
7044 	struct rtw_ieee80211_hdr	*pwlanhdr;
7045 	u16				*fctrl;
7046 	u32				pktlen;
7047 	unsigned char			*mac;
7048 	unsigned char			bssrate[NumRates];
7049 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
7050 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7051 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7052 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7053 	int	bssrate_len = 0;
7054 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7055 
7056 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7057 	mac = adapter_mac_addr(padapter);
7058 
7059 	fctrl = &(pwlanhdr->frame_ctl);
7060 	*(fctrl) = 0;
7061 
7062 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7063 	_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
7064 
7065 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
7066 
7067 	SetSeqNum(pwlanhdr, 0);
7068 	set_frame_sub_type(pframe, WIFI_PROBEREQ);
7069 
7070 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7071 	pframe += pktlen;
7072 
7073 	if (ssid == NULL)
7074 		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
7075 	else {
7076 		/* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
7077 		pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
7078 	}
7079 
7080 	get_rate_set(padapter, bssrate, &bssrate_len);
7081 
7082 	if (bssrate_len > 8) {
7083 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
7084 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
7085 	} else
7086 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
7087 
7088 	*pLength = pktlen;
7089 }
7090 
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)7091 static void rtw_hal_construct_PNO_info(_adapter *padapter,
7092 				       u8 *pframe, u32 *pLength)
7093 {
7094 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
7095 	int i;
7096 
7097 	u8	*pPnoInfoPkt = pframe;
7098 	pPnoInfoPkt = (u8 *)(pframe + *pLength);
7099 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
7100 
7101 	pPnoInfoPkt += 1;
7102 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
7103 
7104 	pPnoInfoPkt += 3;
7105 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
7106 
7107 	pPnoInfoPkt += 4;
7108 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
7109 
7110 	pPnoInfoPkt += 4;
7111 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
7112 
7113 	pPnoInfoPkt += 4;
7114 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
7115 
7116 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
7117 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
7118 
7119 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
7120 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
7121 
7122 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
7123 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
7124 
7125 	pPnoInfoPkt += MAX_HIDDEN_AP;
7126 
7127 	/*
7128 	SSID is located at 128th Byte in NLO info Page
7129 	*/
7130 
7131 	*pLength += 128;
7132 	pPnoInfoPkt = pframe + 128;
7133 
7134 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
7135 		_rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
7136 			    pwrctl->pnlo_info->ssid_length[i]);
7137 		*pLength += WLAN_SSID_MAXLEN;
7138 		pPnoInfoPkt += WLAN_SSID_MAXLEN;
7139 	}
7140 }
7141 
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)7142 static void rtw_hal_construct_ssid_list(_adapter *padapter,
7143 					u8 *pframe, u32 *pLength)
7144 {
7145 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
7146 	u8 *pSSIDListPkt = pframe;
7147 	int i;
7148 
7149 	pSSIDListPkt = (u8 *)(pframe + *pLength);
7150 
7151 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
7152 		_rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
7153 			    pwrctl->pnlo_info->ssid_length[i]);
7154 
7155 		*pLength += WLAN_SSID_MAXLEN;
7156 		pSSIDListPkt += WLAN_SSID_MAXLEN;
7157 	}
7158 }
7159 
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)7160 static void rtw_hal_construct_scan_info(_adapter *padapter,
7161 					u8 *pframe, u32 *pLength)
7162 {
7163 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
7164 	u8 *pScanInfoPkt = pframe;
7165 	int i;
7166 
7167 	pScanInfoPkt = (u8 *)(pframe + *pLength);
7168 
7169 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
7170 
7171 	*pLength += 1;
7172 	pScanInfoPkt += 1;
7173 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
7174 
7175 
7176 	*pLength += 1;
7177 	pScanInfoPkt += 1;
7178 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
7179 
7180 
7181 	*pLength += 1;
7182 	pScanInfoPkt += 1;
7183 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
7184 
7185 	*pLength += 1;
7186 	pScanInfoPkt += 1;
7187 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
7188 
7189 	*pLength += 1;
7190 	pScanInfoPkt += 1;
7191 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
7192 
7193 	*pLength += 1;
7194 	pScanInfoPkt += 1;
7195 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
7196 
7197 	*pLength += 1;
7198 	pScanInfoPkt += 1;
7199 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
7200 
7201 	*pLength += 1;
7202 	pScanInfoPkt += 1;
7203 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
7204 
7205 	*pLength += 8;
7206 	pScanInfoPkt += 8;
7207 
7208 	for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
7209 		_rtw_memcpy(pScanInfoPkt,
7210 			    &pwrctl->pscan_info->ssid_channel_info[i], 4);
7211 		*pLength += 4;
7212 		pScanInfoPkt += 4;
7213 	}
7214 }
7215 #endif /* CONFIG_PNO_SUPPORT */
7216 
7217 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)7218 static void rtw_hal_construct_GTKRsp(
7219 	PADAPTER	padapter,
7220 	u8		*pframe,
7221 	u32		*pLength
7222 )
7223 {
7224 	struct rtw_ieee80211_hdr	*pwlanhdr;
7225 	u16	*fctrl;
7226 	u32	pktlen;
7227 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
7228 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
7229 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7230 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7231 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
7232 	static u8	LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
7233 	static u8	GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
7234 	u8	*pGTKRspPkt = pframe;
7235 	u8	EncryptionHeadOverhead = 0;
7236 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
7237 
7238 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7239 
7240 	fctrl = &pwlanhdr->frame_ctl;
7241 	*(fctrl) = 0;
7242 
7243 	/* ------------------------------------------------------------------------- */
7244 	/* MAC Header. */
7245 	/* ------------------------------------------------------------------------- */
7246 	SetFrameType(fctrl, WIFI_DATA);
7247 	/* set_frame_sub_type(fctrl, 0); */
7248 	SetToDs(fctrl);
7249 
7250 	_rtw_memcpy(pwlanhdr->addr1,
7251 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7252 
7253 	_rtw_memcpy(pwlanhdr->addr2,
7254 		    adapter_mac_addr(padapter), ETH_ALEN);
7255 
7256 	_rtw_memcpy(pwlanhdr->addr3,
7257 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7258 
7259 	SetSeqNum(pwlanhdr, 0);
7260 	set_duration(pwlanhdr, 0);
7261 
7262 #ifdef CONFIG_WAPI_SUPPORT
7263 	*pLength = sMacHdrLng;
7264 #else
7265 	*pLength = 24;
7266 #endif /* CONFIG_WAPI_SUPPORT */
7267 
7268 	/* ------------------------------------------------------------------------- */
7269 	/* Security Header: leave space for it if necessary. */
7270 	/* ------------------------------------------------------------------------- */
7271 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
7272 	case _WEP40_:
7273 	case _WEP104_:
7274 		EncryptionHeadOverhead = 4;
7275 		break;
7276 	case _TKIP_:
7277 		EncryptionHeadOverhead = 8;
7278 		break;
7279 	case _AES_:
7280 		EncryptionHeadOverhead = 8;
7281 		break;
7282 #ifdef CONFIG_WAPI_SUPPORT
7283 	case _SMS4_:
7284 		EncryptionHeadOverhead = 18;
7285 		break;
7286 #endif /* CONFIG_WAPI_SUPPORT */
7287 	default:
7288 		EncryptionHeadOverhead = 0;
7289 	}
7290 
7291 	if (EncryptionHeadOverhead > 0) {
7292 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
7293 		*pLength += EncryptionHeadOverhead;
7294 		/* SET_80211_HDR_WEP(pGTKRspPkt, 1);  */ /* Suggested by CCW. */
7295 		/* GTK's privacy bit is done by FW */
7296 		/* SetPrivacy(fctrl); */
7297 	}
7298 	/* ------------------------------------------------------------------------- */
7299 	/* Frame Body. */
7300 	/* ------------------------------------------------------------------------- */
7301 	pGTKRspPkt = (u8 *)(pframe + *pLength);
7302 	/* LLC header */
7303 	_rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
7304 	*pLength += 8;
7305 
7306 	/* GTK element */
7307 	pGTKRspPkt += 8;
7308 
7309 	/* GTK frame body after LLC, part 1 */
7310 	/* TKIP key_length = 32, AES key_length = 16 */
7311 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
7312 		GTKbody_a[8] = 0x20;
7313 
7314 	/* GTK frame body after LLC, part 1 */
7315 	_rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
7316 	*pLength += 11;
7317 	pGTKRspPkt += 11;
7318 	/* GTK frame body after LLC, part 2 */
7319 	_rtw_memset(&(pframe[*pLength]), 0, 88);
7320 	*pLength += 88;
7321 	pGTKRspPkt += 88;
7322 
7323 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
7324 		*pLength += 8;
7325 }
7326 #endif /* CONFIG_GTK_OL */
7327 
7328 #define PN_2_CCMPH(ch,key_id)	((ch) & 0x000000000000ffff) \
7329 				| (((ch) & 0x0000ffffffff0000) << 16) \
7330 				| (((key_id) << 30)) \
7331 				| BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)7332 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
7333 						  u8 *pframe, u32 *pLength)
7334 {
7335 	struct mlme_priv   *pmlmepriv = &adapter->mlmepriv;
7336 	struct sta_priv *pstapriv = &adapter->stapriv;
7337 	struct security_priv *psecuritypriv = &adapter->securitypriv;
7338 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
7339 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
7340 	struct sta_info *psta;
7341 	struct stainfo_rxcache *prxcache;
7342 	u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
7343 	size_t sz = 0, total = 0;
7344 	u64 ccmp_hdr = 0, tmp_key = 0;
7345 
7346 	psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
7347 
7348 	if (psta == NULL) {
7349 		rtw_warn_on(1);
7350 		return;
7351 	}
7352 
7353 	prxcache = &psta->sta_recvpriv.rxcache;
7354 	sz = sizeof(cur_dot11rxiv);
7355 
7356 	/* 3 SEC IV * 1 page */
7357 	rtw_get_sec_iv(adapter, cur_dot11rxiv,
7358 		       get_my_bssid(&pmlmeinfo->network));
7359 
7360 	_rtw_memcpy(pframe, cur_dot11rxiv, sz);
7361 	*pLength += sz;
7362 	pframe += sz;
7363 
7364 	_rtw_memset(&cur_dot11rxiv, 0, sz);
7365 
7366 	if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
7367 		id = psecuritypriv->dot118021XGrpKeyid;
7368 		tid_id = prxcache->last_tid;
7369 		REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
7370 		REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
7371 		REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
7372 		REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
7373 		_rtw_memcpy(pframe, cur_dot11rxiv, sz);
7374 		*pLength += sz;
7375 		pframe += sz;
7376 
7377 		_rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
7378 		*pLength += sz;
7379 		pframe += sz;
7380 
7381 		total = sizeof(psecuritypriv->iv_seq);
7382 		total /= sizeof(psecuritypriv->iv_seq[0]);
7383 
7384 		for (i = 0 ; i < total ; i ++) {
7385 			ccmp_hdr =
7386 				le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
7387 			_rtw_memset(&cur_dot11rxiv, 0, sz);
7388 			if (ccmp_hdr != 0) {
7389 				tmp_key = i;
7390 				ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
7391 				*(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
7392 				_rtw_memcpy(pframe, cur_dot11rxiv, sz);
7393 			}
7394 			*pLength += sz;
7395 			pframe += sz;
7396 		}
7397 	}
7398 }
7399 
7400 /*#define DBG_RSVD_PAGE_CFG*/
7401 #ifdef DBG_RSVD_PAGE_CFG
7402 #define RSVD_PAGE_CFG(ops, v1, v2, v3)	\
7403 	RTW_INFO("=== [RSVD][%s]-NeedPage:%d, TotalPageNum:%d TotalPacketLen:%d ===\n",	\
7404 		ops, v1, v2, v3)
7405 #endif
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)7406 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
7407 		  u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
7408 				  RSVDPAGE_LOC *rsvd_page_loc)
7409 {
7410 	struct security_priv *psecuritypriv = &adapter->securitypriv;
7411 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
7412 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
7413 	struct mlme_ext_priv	*pmlmeext;
7414 	struct mlme_ext_info	*pmlmeinfo;
7415 	u32	ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
7416 	u32     SSIDLegnth = 0, ProbeReqLength = 0, ns_len = 0, rc_len = 0;
7417 	u8 CurtPktPageNum = 0;
7418 
7419 #ifdef CONFIG_GTK_OL
7420 	struct sta_priv *pstapriv = &adapter->stapriv;
7421 	struct sta_info *psta;
7422 	struct security_priv *psecpriv = &adapter->securitypriv;
7423 	u8 kek[RTW_KEK_LEN];
7424 	u8 kck[RTW_KCK_LEN];
7425 #endif /* CONFIG_GTK_OL */
7426 #ifdef CONFIG_PNO_SUPPORT
7427 	int pno_index;
7428 	u8 ssid_num;
7429 #endif /* CONFIG_PNO_SUPPORT */
7430 
7431 	pmlmeext = &adapter->mlmeextpriv;
7432 	pmlmeinfo = &pmlmeext->mlmext_info;
7433 
7434 	if (pwrctl->wowlan_pno_enable == _FALSE) {
7435 		/* ARP RSP * 1 page */
7436 
7437 		rsvd_page_loc->LocArpRsp = *page_num;
7438 
7439 		RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
7440 
7441 		rtw_hal_construct_ARPRsp(adapter, &pframe[index],
7442 					 &ARPLength, pmlmeinfo->ip_addr);
7443 
7444 		rtw_hal_fill_fake_txdesc(adapter,
7445 					 &pframe[index - tx_desc],
7446 					 ARPLength, _FALSE, _FALSE, _TRUE);
7447 
7448 		CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
7449 
7450 		*page_num += CurtPktPageNum;
7451 
7452 		index += (CurtPktPageNum * page_size);
7453 #ifdef CONFIG_IPV6
7454 		/* 2 NS offload and NDP Info*/
7455 		if (pwrctl->wowlan_ns_offload_en == _TRUE) {
7456 			rsvd_page_loc->LocNbrAdv = *page_num;
7457 			RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
7458 			rtw_hal_construct_na_message(adapter,
7459 						     &pframe[index], &ns_len);
7460 			rtw_hal_fill_fake_txdesc(adapter,
7461 						 &pframe[index - tx_desc],
7462 						 ns_len, _FALSE,
7463 						 _FALSE, _TRUE);
7464 			CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
7465 						      page_size);
7466 			*page_num += CurtPktPageNum;
7467 			index += (CurtPktPageNum * page_size);
7468 
7469 			rsvd_page_loc->LocNDPInfo = *page_num;
7470 			RTW_INFO("LocNDPInfo: %d\n",
7471 				 rsvd_page_loc->LocNDPInfo);
7472 
7473 			rtw_hal_construct_ndp_info(adapter,
7474 						   &pframe[index - tx_desc],
7475 						   &ns_len);
7476 			CurtPktPageNum =
7477 				(u8)PageNum(tx_desc + ns_len, page_size);
7478 			*page_num += CurtPktPageNum;
7479 			index += (CurtPktPageNum * page_size);
7480 		}
7481 #endif /*CONFIG_IPV6*/
7482 		/* 3 Remote Control Info. * 1 page */
7483 		rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
7484 		RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
7485 		rtw_hal_construct_remote_control_info(adapter,
7486 						      &pframe[index - tx_desc],
7487 						      &rc_len);
7488 		CurtPktPageNum = (u8)PageNum(rc_len, page_size);
7489 		*page_num += CurtPktPageNum;
7490 		*total_pkt_len = index + rc_len;
7491 		#ifdef DBG_RSVD_PAGE_CFG
7492 		RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
7493 		#endif
7494 #ifdef CONFIG_GTK_OL
7495 		index += (CurtPktPageNum * page_size);
7496 
7497 		/* if the ap staion info. exists, get the kek, kck from staion info. */
7498 		psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
7499 		if (psta == NULL) {
7500 			_rtw_memset(kek, 0, RTW_KEK_LEN);
7501 			_rtw_memset(kck, 0, RTW_KCK_LEN);
7502 			RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
7503 				 __func__);
7504 		} else {
7505 			_rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
7506 			_rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
7507 		}
7508 
7509 		/* 3 KEK, KCK */
7510 		rsvd_page_loc->LocGTKInfo = *page_num;
7511 		RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
7512 
7513 		if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
7514 			struct security_priv *psecpriv = NULL;
7515 
7516 			psecpriv = &adapter->securitypriv;
7517 			_rtw_memcpy(pframe + index - tx_desc,
7518 				    &psecpriv->dot11PrivacyAlgrthm, 1);
7519 			_rtw_memcpy(pframe + index - tx_desc + 1,
7520 				    &psecpriv->dot118021XGrpPrivacy, 1);
7521 			_rtw_memcpy(pframe + index - tx_desc + 2,
7522 				    kck, RTW_KCK_LEN);
7523 			_rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
7524 				    kek, RTW_KEK_LEN);
7525 			CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
7526 		} else {
7527 
7528 			_rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
7529 			_rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
7530 				    kek, RTW_KEK_LEN);
7531 			GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
7532 
7533 			if (psta != NULL &&
7534 				psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
7535 				_rtw_memcpy(pframe + index - tx_desc + 56,
7536 					&psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
7537 				GTKLength += RTW_TKIP_MIC_LEN;
7538 			}
7539 			CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
7540 		}
7541 #if 0
7542 		{
7543 			int i;
7544 			printk("\ntoFW KCK: ");
7545 			for (i = 0; i < 16; i++)
7546 				printk(" %02x ", kck[i]);
7547 			printk("\ntoFW KEK: ");
7548 			for (i = 0; i < 16; i++)
7549 				printk(" %02x ", kek[i]);
7550 			printk("\n");
7551 		}
7552 
7553 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
7554 			 __FUNCTION__, &pframe[index - tx_desc],
7555 			 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
7556 #endif
7557 
7558 		*page_num += CurtPktPageNum;
7559 
7560 		index += (CurtPktPageNum * page_size);
7561 
7562 		/* 3 GTK Response */
7563 		rsvd_page_loc->LocGTKRsp = *page_num;
7564 		RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
7565 		rtw_hal_construct_GTKRsp(adapter, &pframe[index], &GTKLength);
7566 
7567 		rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
7568 					 GTKLength, _FALSE, _FALSE, _TRUE);
7569 #if 0
7570 		{
7571 			int gj;
7572 			printk("123GTK pkt=>\n");
7573 			for (gj = 0; gj < GTKLength + tx_desc; gj++) {
7574 				printk(" %02x ", pframe[index - tx_desc + gj]);
7575 				if ((gj + 1) % 16 == 0)
7576 					printk("\n");
7577 			}
7578 			printk(" <=end\n");
7579 		}
7580 
7581 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
7582 			 __FUNCTION__, &pframe[index - tx_desc],
7583 			 (tx_desc + GTKLength));
7584 #endif
7585 
7586 		CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
7587 
7588 		*page_num += CurtPktPageNum;
7589 
7590 		index += (CurtPktPageNum * page_size);
7591 
7592 		/* below page is empty for GTK extension memory */
7593 		/* 3(11) GTK EXT MEM */
7594 		rsvd_page_loc->LocGTKEXTMEM = *page_num;
7595 		RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
7596 		CurtPktPageNum = 2;
7597 
7598 		if (page_size >= 256)
7599 			CurtPktPageNum = 1;
7600 
7601 		*page_num += CurtPktPageNum;
7602 		/* extension memory for FW */
7603 		*total_pkt_len = index + (page_size * CurtPktPageNum);
7604 #endif /* CONFIG_GTK_OL */
7605 
7606 		index += (CurtPktPageNum * page_size);
7607 
7608 		/*Reserve 1 page for AOAC report*/
7609 		rsvd_page_loc->LocAOACReport = *page_num;
7610 		RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
7611 		*page_num += 1;
7612 		*total_pkt_len = index + (page_size * 1);
7613 	} else {
7614 #ifdef CONFIG_PNO_SUPPORT
7615 		if (pwrctl->wowlan_in_resume == _FALSE &&
7616 		    pwrctl->pno_inited == _TRUE) {
7617 
7618 			/* Broadcast Probe Request */
7619 			rsvd_page_loc->LocProbePacket = *page_num;
7620 
7621 			RTW_INFO("loc_probe_req: %d\n",
7622 				 rsvd_page_loc->LocProbePacket);
7623 
7624 			rtw_hal_construct_ProbeReq(
7625 				adapter,
7626 				&pframe[index],
7627 				&ProbeReqLength,
7628 				NULL);
7629 
7630 			rtw_hal_fill_fake_txdesc(adapter,
7631 						 &pframe[index - tx_desc],
7632 				 ProbeReqLength, _FALSE, _FALSE, _FALSE);
7633 
7634 			CurtPktPageNum =
7635 				(u8)PageNum(tx_desc + ProbeReqLength, page_size);
7636 
7637 			*page_num += CurtPktPageNum;
7638 
7639 			index += (CurtPktPageNum * page_size);
7640 
7641 			/* Hidden SSID Probe Request */
7642 			ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
7643 
7644 			for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
7645 				pwrctl->pnlo_info->loc_probe_req[pno_index] =
7646 					*page_num;
7647 
7648 				rtw_hal_construct_ProbeReq(
7649 					adapter,
7650 					&pframe[index],
7651 					&ProbeReqLength,
7652 					&pwrctl->pno_ssid_list->node[pno_index]);
7653 
7654 				rtw_hal_fill_fake_txdesc(adapter,
7655 						 &pframe[index - tx_desc],
7656 					ProbeReqLength, _FALSE, _FALSE, _FALSE);
7657 
7658 				CurtPktPageNum =
7659 					(u8)PageNum(tx_desc + ProbeReqLength, page_size);
7660 
7661 				*page_num += CurtPktPageNum;
7662 
7663 				index += (CurtPktPageNum * page_size);
7664 			}
7665 
7666 			/* PNO INFO Page */
7667 			rsvd_page_loc->LocPNOInfo = *page_num;
7668 			RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
7669 			rtw_hal_construct_PNO_info(adapter,
7670 						   &pframe[index - tx_desc],
7671 						   &PNOLength);
7672 
7673 			CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
7674 			*page_num += CurtPktPageNum;
7675 			index += (CurtPktPageNum * page_size);
7676 
7677 			/* Scan Info Page */
7678 			rsvd_page_loc->LocScanInfo = *page_num;
7679 			RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
7680 			rtw_hal_construct_scan_info(adapter,
7681 						    &pframe[index - tx_desc],
7682 						    &ScanInfoLength);
7683 
7684 			CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
7685 			*page_num += CurtPktPageNum;
7686 			*total_pkt_len = index + ScanInfoLength;
7687 			index += (CurtPktPageNum * page_size);
7688 		}
7689 #endif /* CONFIG_PNO_SUPPORT */
7690 	}
7691 }
7692 
rtw_hal_gate_bb(_adapter * adapter,bool stop)7693 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
7694 {
7695 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
7696 	u8 i = 0, val8 = 0, empty = _FAIL;
7697 	u16 val16 = 0;
7698 
7699 	if (stop) {
7700 		/* checking TX queue status */
7701 		for (i = 0 ; i < 5 ; i++) {
7702 			rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
7703 			if (empty) {
7704 				break;
7705 			} else {
7706 				RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
7707 					 __func__, i);
7708 				rtw_mdelay_os(10);
7709 			}
7710 		}
7711 
7712 		if (val8 == 5)
7713 			RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
7714 
7715 		/* Pause TX*/
7716 		pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
7717 		rtw_write8(adapter, REG_TXPAUSE, 0xff);
7718 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
7719 		val8 &= ~BIT(0);
7720 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
7721 		RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
7722 			 __func__,
7723 			 rtw_read8(adapter, REG_SYS_FUNC_EN),
7724 			 pwrpriv->wowlan_txpause_status);
7725 	} else {
7726 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
7727 		val8 |= BIT(0);
7728 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
7729 		RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
7730 			 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
7731 			 pwrpriv->wowlan_txpause_status);
7732 		/* release TX*/
7733 		rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
7734 	}
7735 }
7736 
rtw_hal_reset_mac_rx(_adapter * adapter)7737 static void rtw_hal_reset_mac_rx(_adapter *adapter)
7738 {
7739 	u8 val8 = 0;
7740 	/* Set REG_CR bit1, bit3, bit7 to 0*/
7741 	val8 = rtw_read8(adapter, REG_CR);
7742 	val8 &= 0x75;
7743 	rtw_write8(adapter, REG_CR, val8);
7744 	val8 = rtw_read8(adapter, REG_CR);
7745 	/* Set REG_CR bit1, bit3, bit7 to 1*/
7746 	val8 |= 0x8a;
7747 	rtw_write8(adapter, REG_CR, val8);
7748 	RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
7749 }
7750 
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)7751 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
7752 {
7753 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
7754 	 u8 *pattern;
7755 	 u8 len = 0;
7756 	 u8 *mask;
7757 
7758 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
7759 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
7760 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7761 	u8 multicast_addr1[2] = {0x33, 0x33};
7762 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
7763 	u8 mask_len = 0;
7764 	u8 mac_addr[ETH_ALEN] = {0};
7765 	u16 count = 0;
7766 	int i, j;
7767 
7768 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
7769 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
7770 			 __func__, MAX_WKFM_CAM_NUM);
7771 		return _FAIL;
7772 	}
7773 
7774 	pattern = pwrctl->patterns[idx].content;
7775 	len = pwrctl->patterns[idx].len;
7776 	mask = pwrctl->patterns[idx].mask;
7777 
7778 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
7779 	_rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
7780 
7781 	mask_len = DIV_ROUND_UP(len, 8);
7782 
7783 	/* 1. setup A1 table */
7784 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
7785 		pwow_pattern->type = PATTERN_BROADCAST;
7786 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
7787 		pwow_pattern->type = PATTERN_MULTICAST;
7788 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
7789 		pwow_pattern->type = PATTERN_MULTICAST;
7790 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
7791 		pwow_pattern->type = PATTERN_UNICAST;
7792 	else
7793 		pwow_pattern->type = PATTERN_INVALID;
7794 
7795 	/* translate mask from os to mask for hw */
7796 
7797 	/******************************************************************************
7798 	 * pattern from OS uses 'ethenet frame', like this:
7799 
7800 		|    6   |    6   |   2  |     20    |  Variable  |  4  |
7801 		|--------+--------+------+-----------+------------+-----|
7802 		|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
7803 		|   DA   |   SA   | Type |
7804 
7805 	 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
7806 
7807 		|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
7808 		|-------------------+--------+------+-----------+------------+-----|
7809 		| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
7810 				    | Others | Tpye |
7811 
7812 	 * Therefore, we need translate mask_from_OS to mask_to_hw.
7813 	 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
7814 	 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
7815 	 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
7816 	 ******************************************************************************/
7817 	/* Shift 6 bits */
7818 	for (i = 0; i < mask_len - 1; i++) {
7819 		mask_hw[i] = mask[i] >> 6;
7820 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
7821 	}
7822 
7823 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
7824 	/* Set bit 0-5 to zero */
7825 	mask_hw[0] &= 0xC0;
7826 
7827 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
7828 		pwow_pattern->mask[i] = mask_hw[i * 4];
7829 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
7830 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
7831 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
7832 	}
7833 
7834 	/* To get the wake up pattern from the mask.
7835 	 * We do not count first 12 bits which means
7836 	 * DA[6] and SA[6] in the pattern to match HW design. */
7837 	count = 0;
7838 	for (i = 12; i < len; i++) {
7839 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
7840 			content[count] = pattern[i];
7841 			count++;
7842 		}
7843 	}
7844 
7845 	pwow_pattern->crc = rtw_calc_crc(content, count);
7846 
7847 	if (pwow_pattern->crc != 0) {
7848 		if (pwow_pattern->type == PATTERN_INVALID)
7849 			pwow_pattern->type = PATTERN_VALID;
7850 	}
7851 
7852 	return _SUCCESS;
7853 }
7854 
7855 #ifndef CONFIG_WOW_PATTERN_HW_CAM
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)7856 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
7857 {
7858 	u8 val8 = 0;
7859 	u16 rxff_bndy = 0;
7860 	u32 rx_dma_buff_sz = 0;
7861 
7862 	val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
7863 	if (val8 != 0)
7864 		RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
7865 			 __func__, (REG_FIFOPAGE + 3));
7866 
7867 	rtw_hal_reset_mac_rx(adapter);
7868 
7869 	if (wow_mode) {
7870 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
7871 				    (u8 *)&rx_dma_buff_sz);
7872 		rxff_bndy = rx_dma_buff_sz - 1;
7873 
7874 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
7875 		RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
7876 			 REG_TRXFF_BNDY + 2,
7877 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
7878 	} else {
7879 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
7880 				    (u8 *)&rx_dma_buff_sz);
7881 		rxff_bndy = rx_dma_buff_sz - 1;
7882 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
7883 		RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
7884 			 REG_TRXFF_BNDY + 2,
7885 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
7886 	}
7887 }
7888 
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)7889 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
7890 {
7891 	u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
7892 	u16 offset, rx_buf_ptr = 0;
7893 	u16 cam_start_offset = 0;
7894 	u16 ctrl_l = 0, ctrl_h = 0;
7895 	u8 count = 0, tmp = 0;
7896 	int i = 0;
7897 	bool res = _TRUE;
7898 
7899 	if (idx > MAX_WKFM_CAM_NUM) {
7900 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
7901 			 __func__);
7902 		return _FALSE;
7903 	}
7904 
7905 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
7906 			    (u8 *)&rx_dma_buff_sz);
7907 
7908 	if (rx_dma_buff_sz == 0) {
7909 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
7910 		return _FALSE;
7911 	}
7912 
7913 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
7914 
7915 	if (page_sz == 0) {
7916 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
7917 		return _FALSE;
7918 	}
7919 
7920 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
7921 	cam_start_offset = offset * page_sz;
7922 
7923 	ctrl_l = 0x0;
7924 	ctrl_h = 0x0;
7925 
7926 	/* Enable RX packet buffer access */
7927 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
7928 
7929 	/* Read the WKFM CAM */
7930 	for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
7931 		/*
7932 		 * Set Rx packet buffer offset.
7933 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
7934 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
7935 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
7936 		 * * Index: The index of the wake up frame mask
7937 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
7938 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
7939 		 */
7940 		rx_buf_ptr =
7941 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
7942 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
7943 
7944 		rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
7945 		data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
7946 		data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
7947 
7948 		RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
7949 
7950 		count = 0;
7951 
7952 		do {
7953 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
7954 			rtw_udelay_os(2);
7955 			count++;
7956 		} while (!tmp && count < 100);
7957 
7958 		if (count >= 100) {
7959 			RTW_INFO("%s count:%d\n", __func__, count);
7960 			res = _FALSE;
7961 		}
7962 	}
7963 
7964 	/* Disable RX packet buffer access */
7965 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
7966 		   DISABLE_TRXPKT_BUF_ACCESS);
7967 	return res;
7968 }
7969 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)7970 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
7971 			     struct  rtl_wow_pattern *context)
7972 {
7973 	u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
7974 	u16 offset, rx_buf_ptr = 0;
7975 	u16 cam_start_offset = 0;
7976 	u16 ctrl_l = 0, ctrl_h = 0;
7977 	u8 count = 0, tmp = 0;
7978 	int res = 0, i = 0;
7979 
7980 	if (idx > MAX_WKFM_CAM_NUM) {
7981 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
7982 			 __func__);
7983 		return _FALSE;
7984 	}
7985 
7986 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
7987 			    (u8 *)&rx_dma_buff_sz);
7988 
7989 	if (rx_dma_buff_sz == 0) {
7990 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
7991 		return _FALSE;
7992 	}
7993 
7994 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
7995 
7996 	if (page_sz == 0) {
7997 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
7998 		return _FALSE;
7999 	}
8000 
8001 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
8002 
8003 	cam_start_offset = offset * page_sz;
8004 
8005 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
8006 		ctrl_l = 0x0001;
8007 		ctrl_h = 0x0001;
8008 	} else {
8009 		ctrl_l = 0x0f01;
8010 		ctrl_h = 0xf001;
8011 	}
8012 
8013 	/* Enable RX packet buffer access */
8014 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
8015 
8016 	/* Write the WKFM CAM */
8017 	for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
8018 		/*
8019 		 * Set Rx packet buffer offset.
8020 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
8021 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
8022 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
8023 		 * * Index: The index of the wake up frame mask
8024 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
8025 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
8026 		 */
8027 		rx_buf_ptr =
8028 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
8029 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
8030 
8031 		if (i == 0) {
8032 			if (context->type == PATTERN_VALID)
8033 				data = BIT(31);
8034 			else if (context->type == PATTERN_BROADCAST)
8035 				data = BIT(31) | BIT(26);
8036 			else if (context->type == PATTERN_MULTICAST)
8037 				data = BIT(31) | BIT(25);
8038 			else if (context->type == PATTERN_UNICAST)
8039 				data = BIT(31) | BIT(24);
8040 
8041 			if (context->crc != 0)
8042 				data |= context->crc;
8043 
8044 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
8045 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
8046 		} else if (i == 1) {
8047 			data = 0;
8048 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
8049 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
8050 		} else if (i == 2 || i == 4) {
8051 			data = context->mask[i - 2];
8052 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
8053 			/* write to RX packet buffer*/
8054 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
8055 		} else if (i == 3 || i == 5) {
8056 			data = context->mask[i - 2];
8057 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
8058 			/* write to RX packet buffer*/
8059 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
8060 		}
8061 
8062 		count = 0;
8063 		do {
8064 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
8065 			rtw_udelay_os(2);
8066 			count++;
8067 		} while (tmp && count < 100);
8068 
8069 		if (count >= 100)
8070 			res = _FALSE;
8071 		else
8072 			res = _TRUE;
8073 	}
8074 
8075 	/* Disable RX packet buffer access */
8076 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
8077 		   DISABLE_TRXPKT_BUF_ACCESS);
8078 
8079 	return res;
8080 }
rtw_clean_pattern(_adapter * adapter)8081 void rtw_clean_pattern(_adapter *adapter)
8082 {
8083 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8084 	struct rtl_wow_pattern zero_pattern;
8085 	int i = 0;
8086 
8087 	_rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
8088 
8089 	zero_pattern.type = PATTERN_INVALID;
8090 
8091 	for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
8092 		rtw_write_to_frame_mask(adapter, i, &zero_pattern);
8093 
8094 	rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
8095 }
rtw_hal_set_pattern(_adapter * adapter,u8 * pattern,u8 len,u8 * mask,u8 idx)8096 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
8097 			       u8 len, u8 *mask, u8 idx)
8098 {
8099 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8100 	struct mlme_ext_priv *pmlmeext = NULL;
8101 	struct mlme_ext_info *pmlmeinfo = NULL;
8102 	struct rtl_wow_pattern wow_pattern;
8103 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
8104 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
8105 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8106 	u8 multicast_addr1[2] = {0x33, 0x33};
8107 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
8108 	u8 res = _FALSE, index = 0, mask_len = 0;
8109 	u8 mac_addr[ETH_ALEN] = {0};
8110 	u16 count = 0;
8111 	int i, j;
8112 
8113 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
8114 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
8115 			 __func__, MAX_WKFM_CAM_NUM);
8116 		return _FALSE;
8117 	}
8118 
8119 	pmlmeext = &adapter->mlmeextpriv;
8120 	pmlmeinfo = &pmlmeext->mlmext_info;
8121 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
8122 	_rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
8123 
8124 	mask_len = DIV_ROUND_UP(len, 8);
8125 
8126 	/* 1. setup A1 table */
8127 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
8128 		wow_pattern.type = PATTERN_BROADCAST;
8129 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
8130 		wow_pattern.type = PATTERN_MULTICAST;
8131 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
8132 		wow_pattern.type = PATTERN_MULTICAST;
8133 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
8134 		wow_pattern.type = PATTERN_UNICAST;
8135 	else
8136 		wow_pattern.type = PATTERN_INVALID;
8137 
8138 	/* translate mask from os to mask for hw */
8139 
8140 /******************************************************************************
8141  * pattern from OS uses 'ethenet frame', like this:
8142 
8143 	|    6   |    6   |   2  |     20    |  Variable  |  4  |
8144 	|--------+--------+------+-----------+------------+-----|
8145 	|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
8146 	|   DA   |   SA   | Type |
8147 
8148  * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
8149 
8150 	|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
8151 	|-------------------+--------+------+-----------+------------+-----|
8152 	| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
8153 			    | Others | Tpye |
8154 
8155  * Therefore, we need translate mask_from_OS to mask_to_hw.
8156  * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
8157  * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
8158  * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
8159  ******************************************************************************/
8160 	/* Shift 6 bits */
8161 	for (i = 0; i < mask_len - 1; i++) {
8162 		mask_hw[i] = mask[i] >> 6;
8163 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
8164 	}
8165 
8166 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
8167 	/* Set bit 0-5 to zero */
8168 	mask_hw[0] &= 0xC0;
8169 
8170 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
8171 		wow_pattern.mask[i] = mask_hw[i * 4];
8172 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
8173 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
8174 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
8175 	}
8176 
8177 	/* To get the wake up pattern from the mask.
8178 	 * We do not count first 12 bits which means
8179 	 * DA[6] and SA[6] in the pattern to match HW design. */
8180 	count = 0;
8181 	for (i = 12; i < len; i++) {
8182 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
8183 			content[count] = pattern[i];
8184 			count++;
8185 		}
8186 	}
8187 
8188 	wow_pattern.crc = rtw_calc_crc(content, count);
8189 
8190 	if (wow_pattern.crc != 0) {
8191 		if (wow_pattern.type == PATTERN_INVALID)
8192 			wow_pattern.type = PATTERN_VALID;
8193 	}
8194 
8195 	index = idx;
8196 
8197 	if (!pwrctl->bInSuspend)
8198 		index += 2;
8199 
8200 	/* write pattern */
8201 	res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
8202 
8203 	if (res == _FALSE)
8204 		RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
8205 			 __func__, idx);
8206 
8207 	return res;
8208 }
rtw_fill_pattern(_adapter * adapter)8209 void rtw_fill_pattern(_adapter *adapter)
8210 {
8211 	int i = 0, total = 0, index;
8212 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8213 	struct rtl_wow_pattern wow_pattern;
8214 
8215 	total = pwrpriv->wowlan_pattern_idx;
8216 
8217 	if (total > MAX_WKFM_CAM_NUM)
8218 		total = MAX_WKFM_CAM_NUM;
8219 
8220 	for (i = 0 ; i < total ; i++) {
8221 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
8222 
8223 			index = i;
8224 			if (!pwrpriv->bInSuspend)
8225 				index += 2;
8226 
8227 			if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
8228 				RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
8229 		}
8230 
8231 	}
8232 	rtw_write8(adapter, REG_WKFMCAM_NUM, total);
8233 
8234 }
8235 
8236 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
8237 
8238 #define WOW_CAM_ACCESS_TIMEOUT_MS	200
8239 #define WOW_VALID_BIT	BIT31
8240 #define WOW_BC_BIT		BIT26
8241 #define WOW_MC_BIT		BIT25
8242 #define WOW_UC_BIT		BIT24
8243 
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)8244 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
8245 {
8246 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8247 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
8248 
8249 	u32 rdata = 0;
8250 	u32 cnt = 0;
8251 	systime start = 0;
8252 	u8 timeout = 0;
8253 	u8 rst = _FALSE;
8254 
8255 	_enter_critical_mutex(mutex, NULL);
8256 
8257 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
8258 
8259 	start = rtw_get_current_time();
8260 	while (1) {
8261 		if (rtw_is_surprise_removed(adapter))
8262 			break;
8263 
8264 		cnt++;
8265 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
8266 			rst = _SUCCESS;
8267 			break;
8268 		}
8269 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
8270 			timeout = 1;
8271 			break;
8272 		}
8273 	}
8274 
8275 	rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
8276 
8277 	_exit_critical_mutex(mutex, NULL);
8278 
8279 	/*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
8280 
8281 	if (timeout)
8282 		RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
8283 
8284 	return rdata;
8285 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)8286 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
8287 {
8288 	int i;
8289 	u32 rdata;
8290 
8291 	_rtw_memset(context, 0, sizeof(struct  rtl_wow_pattern));
8292 
8293 	for (i = 4; i >= 0; i--) {
8294 		rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
8295 
8296 		switch (i) {
8297 		case 4:
8298 			if (rdata & WOW_BC_BIT)
8299 				context->type = PATTERN_BROADCAST;
8300 			else if (rdata & WOW_MC_BIT)
8301 				context->type = PATTERN_MULTICAST;
8302 			else if (rdata & WOW_UC_BIT)
8303 				context->type = PATTERN_UNICAST;
8304 			else
8305 				context->type = PATTERN_INVALID;
8306 
8307 			context->crc = rdata & 0xFFFF;
8308 			break;
8309 		default:
8310 			_rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
8311 			break;
8312 		}
8313 	}
8314 }
8315 
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)8316 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
8317 {
8318 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8319 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
8320 	u32 cnt = 0;
8321 	systime start = 0, end = 0;
8322 	u8 timeout = 0;
8323 
8324 	/*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
8325 	_enter_critical_mutex(mutex, NULL);
8326 
8327 	rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
8328 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
8329 
8330 	start = rtw_get_current_time();
8331 	while (1) {
8332 		if (rtw_is_surprise_removed(adapter))
8333 			break;
8334 
8335 		cnt++;
8336 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
8337 			break;
8338 
8339 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
8340 			timeout = 1;
8341 			break;
8342 		}
8343 	}
8344 	end = rtw_get_current_time();
8345 
8346 	_exit_critical_mutex(mutex, NULL);
8347 
8348 	if (timeout) {
8349 		RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
8350 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
8351 	}
8352 }
8353 
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)8354 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
8355 {
8356 	int j;
8357 	u8 addr;
8358 	u32 wdata = 0;
8359 
8360 	for (j = 4; j >= 0; j--) {
8361 		switch (j) {
8362 		case 4:
8363 			wdata = context->crc;
8364 
8365 			if (PATTERN_BROADCAST == context->type)
8366 				wdata |= WOW_BC_BIT;
8367 			if (PATTERN_MULTICAST == context->type)
8368 				wdata |= WOW_MC_BIT;
8369 			if (PATTERN_UNICAST == context->type)
8370 				wdata |= WOW_UC_BIT;
8371 			if (PATTERN_INVALID != context->type)
8372 				wdata |= WOW_VALID_BIT;
8373 			break;
8374 		default:
8375 			wdata = context->mask[j];
8376 			break;
8377 		}
8378 
8379 		addr = (id << 3) + j;
8380 
8381 		_rtw_wow_pattern_write_cam(adapter, addr, wdata);
8382 	}
8383 }
8384 
_rtw_wow_pattern_clean_cam(_adapter * adapter)8385 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
8386 {
8387 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8388 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
8389 	u32 cnt = 0;
8390 	systime start = 0;
8391 	u8 timeout = 0;
8392 	u8 rst = _FAIL;
8393 
8394 	_enter_critical_mutex(mutex, NULL);
8395 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
8396 
8397 	start = rtw_get_current_time();
8398 	while (1) {
8399 		if (rtw_is_surprise_removed(adapter))
8400 			break;
8401 
8402 		cnt++;
8403 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
8404 			rst = _SUCCESS;
8405 			break;
8406 		}
8407 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
8408 			timeout = 1;
8409 			break;
8410 		}
8411 	}
8412 	_exit_critical_mutex(mutex, NULL);
8413 
8414 	if (timeout)
8415 		RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
8416 
8417 	return rst;
8418 }
8419 
rtw_clean_pattern(_adapter * adapter)8420 void rtw_clean_pattern(_adapter *adapter)
8421 {
8422 	if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
8423 		RTW_ERR("rtw_clean_pattern failed\n");
8424 }
8425 
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)8426 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
8427 {
8428 	int j;
8429 
8430 	RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
8431 	RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
8432 	RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
8433 	for (j = 0; j < 4; j++)
8434 		RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
8435 }
8436 
rtw_fill_pattern(_adapter * adapter)8437 void rtw_fill_pattern(_adapter *adapter)
8438 {
8439 	int i = 0, total = 0;
8440 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8441 	struct rtl_wow_pattern wow_pattern;
8442 
8443 	total = pwrpriv->wowlan_pattern_idx;
8444 
8445 	if (total > MAX_WKFM_CAM_NUM)
8446 		total = MAX_WKFM_CAM_NUM;
8447 
8448 	for (i = 0 ; i < total ; i++) {
8449 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
8450 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
8451 			rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
8452 		}
8453 	}
8454 }
8455 
8456 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)8457 void rtw_wow_pattern_cam_dump(_adapter *adapter)
8458 {
8459 
8460 #ifndef CONFIG_WOW_PATTERN_HW_CAM
8461 	int i;
8462 
8463 	for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
8464 		RTW_INFO("=======[%d]=======\n", i);
8465 		rtw_read_from_frame_mask(adapter, i);
8466 	}
8467 #else
8468 	struct  rtl_wow_pattern context;
8469 	int i;
8470 
8471 	for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
8472 		rtw_wow_pattern_read_cam_ent(adapter, i, &context);
8473 		rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
8474 	}
8475 
8476 #endif
8477 }
8478 
8479 
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)8480 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
8481 {
8482 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8483 
8484 	switch (mode) {
8485 	case 0:
8486 		rtw_clean_pattern(adapter);
8487 		RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
8488 		break;
8489 	case 1:
8490 		rtw_set_default_pattern(adapter);
8491 		rtw_fill_pattern(adapter);
8492 		RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
8493 		break;
8494 	case 2:
8495 		rtw_clean_pattern(adapter);
8496 		rtw_wow_pattern_sw_reset(adapter);
8497 		RTW_INFO("%s: clean patterns\n", __func__);
8498 		break;
8499 	default:
8500 		RTW_INFO("%s: unknown mode\n", __func__);
8501 		break;
8502 	}
8503 }
8504 
rtw_hal_wow_enable(_adapter * adapter)8505 static void rtw_hal_wow_enable(_adapter *adapter)
8506 {
8507 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8508 	struct security_priv *psecuritypriv = &adapter->securitypriv;
8509 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8510 	struct hal_ops *pHalFunc = &adapter->hal_func;
8511 	struct sta_info *psta = NULL;
8512 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
8513 	int res;
8514 	u16 media_status_rpt;
8515 
8516 
8517 	RTW_PRINT("%s, WOWLAN_ENABLE\n", __func__);
8518 	rtw_hal_gate_bb(adapter, _TRUE);
8519 #ifdef CONFIG_GTK_OL
8520 	if (psecuritypriv->binstallKCK_KEK == _TRUE)
8521 		rtw_hal_fw_sync_cam_id(adapter);
8522 #endif
8523 	if (IS_HARDWARE_TYPE_8723B(adapter))
8524 		rtw_hal_backup_rate(adapter);
8525 
8526 	rtw_hal_fw_dl(adapter, _TRUE);
8527 	media_status_rpt = RT_MEDIA_CONNECT;
8528 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
8529 			  (u8 *)&media_status_rpt);
8530 
8531 	/* RX DMA stop */
8532 	#if defined(CONFIG_RTL8188E)
8533 	if (IS_HARDWARE_TYPE_8188E(adapter))
8534 		rtw_hal_disable_tx_report(adapter);
8535 	#endif
8536 
8537 	res = rtw_hal_pause_rx_dma(adapter);
8538 	if (res == _FAIL)
8539 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
8540 
8541 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
8542 	/* Reconfig RX_FF Boundary */
8543 	rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
8544 	#endif
8545 
8546 	/* redownload wow pattern */
8547 	rtw_hal_dl_pattern(adapter, 1);
8548 
8549 	if (!pwrctl->wowlan_pno_enable) {
8550 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
8551 
8552 		if (psta != NULL) {
8553 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
8554 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
8555 			#endif
8556 
8557 			rtw_sta_media_status_rpt(adapter, psta, 1);
8558 		}
8559 	}
8560 
8561 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
8562 	/* Enable CPWM2 only. */
8563 	res = rtw_hal_enable_cpwm2(adapter);
8564 	if (res == _FAIL)
8565 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
8566 #endif
8567 #ifdef CONFIG_GPIO_WAKEUP
8568 	rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _TRUE);
8569 #endif
8570 	/* Set WOWLAN H2C command. */
8571 	RTW_PRINT("Set WOWLan cmd\n");
8572 	rtw_hal_set_fw_wow_related_cmd(adapter, 1);
8573 
8574 	res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
8575 
8576 	if (res == _FALSE)
8577 		RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
8578 
8579 	pwrctl->wowlan_wake_reason =
8580 		rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
8581 
8582 	RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
8583 		  pwrctl->wowlan_wake_reason);
8584 #ifdef CONFIG_GTK_OL_DBG
8585 	dump_sec_cam(RTW_DBGDUMP, adapter);
8586 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
8587 #endif
8588 #ifdef CONFIG_USB_HCI
8589 	/* free adapter's resource */
8590 	rtw_mi_intf_stop(adapter);
8591 
8592 #endif
8593 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
8594 	/* Invoid SE0 reset signal during suspending*/
8595 	rtw_write8(adapter, REG_RSV_CTRL, 0x20);
8596 	if (IS_8188F(pHalData->version_id) == FALSE)
8597 		rtw_write8(adapter, REG_RSV_CTRL, 0x60);
8598 #endif
8599 
8600 	rtw_hal_gate_bb(adapter, _FALSE);
8601 }
8602 
8603 #define DBG_WAKEUP_REASON
8604 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)8605 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
8606 {
8607 	RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
8608 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)8609 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
8610 {
8611 	if (RX_PAIRWISEKEY == reason)
8612 		_dbg_wake_up_reason_string(adapter, "Rx pairwise key");
8613 	else if (RX_GTK == reason)
8614 		_dbg_wake_up_reason_string(adapter, "Rx GTK");
8615 	else if (RX_FOURWAY_HANDSHAKE == reason)
8616 		_dbg_wake_up_reason_string(adapter, "Rx four way handshake");
8617 	else if (RX_DISASSOC == reason)
8618 		_dbg_wake_up_reason_string(adapter, "Rx disassoc");
8619 	else if (RX_DEAUTH == reason)
8620 		_dbg_wake_up_reason_string(adapter, "Rx deauth");
8621 	else if (RX_ARP_REQUEST == reason)
8622 		_dbg_wake_up_reason_string(adapter, "Rx ARP request");
8623 	else if (FW_DECISION_DISCONNECT == reason)
8624 		_dbg_wake_up_reason_string(adapter, "FW detect disconnect");
8625 	else if (RX_MAGIC_PKT == reason)
8626 		_dbg_wake_up_reason_string(adapter, "Rx magic packet");
8627 	else if (RX_UNICAST_PKT == reason)
8628 		_dbg_wake_up_reason_string(adapter, "Rx unicast packet");
8629 	else if (RX_PATTERN_PKT == reason)
8630 		_dbg_wake_up_reason_string(adapter, "Rx pattern packet");
8631 	else if (RTD3_SSID_MATCH == reason)
8632 		_dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
8633 	else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
8634 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
8635 	else if (RX_REALWOW_V2_ACK_LOST == reason)
8636 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
8637 	else if (ENABLE_FAIL_DMA_IDLE == reason)
8638 		_dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
8639 	else if (ENABLE_FAIL_DMA_PAUSE == reason)
8640 		_dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
8641 	else if (AP_OFFLOAD_WAKEUP == reason)
8642 		_dbg_wake_up_reason_string(adapter, "AP offload wakeup");
8643 	else if (CLK_32K_UNLOCK == reason)
8644 		_dbg_wake_up_reason_string(adapter, "clk 32k unlock");
8645 	else if (RTIME_FAIL_DMA_IDLE == reason)
8646 		_dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
8647 	else if (CLK_32K_LOCK == reason)
8648 		_dbg_wake_up_reason_string(adapter, "clk 32k lock");
8649 	else
8650 		_dbg_wake_up_reason_string(adapter, "unknown reasoen");
8651 }
8652 #endif
8653 
rtw_hal_wow_disable(_adapter * adapter)8654 static void rtw_hal_wow_disable(_adapter *adapter)
8655 {
8656 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8657 	struct security_priv *psecuritypriv = &adapter->securitypriv;
8658 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8659 	struct hal_ops *pHalFunc = &adapter->hal_func;
8660 	struct sta_info *psta = NULL;
8661 	int res;
8662 	u16 media_status_rpt;
8663 	u8 val8;
8664 
8665 	RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
8666 
8667 	if (!pwrctl->wowlan_pno_enable) {
8668 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
8669 		if (psta != NULL)
8670 			rtw_sta_media_status_rpt(adapter, psta, 0);
8671 		else
8672 			RTW_INFO("%s: psta is null\n", __func__);
8673 	}
8674 
8675 	if (0) {
8676 		RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
8677 		RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
8678 		RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
8679 		RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
8680 	}
8681 
8682 	pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
8683 
8684 	RTW_PRINT("wakeup_reason: 0x%02x\n",
8685 		  pwrctl->wowlan_wake_reason);
8686 	#ifdef DBG_WAKEUP_REASON
8687 	_dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
8688 	#endif
8689 
8690 	rtw_hal_set_fw_wow_related_cmd(adapter, 0);
8691 
8692 	res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
8693 
8694 	if (res == _FALSE) {
8695 		RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
8696 		rtw_hal_force_enable_rxdma(adapter);
8697 	}
8698 
8699 	rtw_hal_gate_bb(adapter, _TRUE);
8700 
8701 	res = rtw_hal_pause_rx_dma(adapter);
8702 	if (res == _FAIL)
8703 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
8704 
8705 	/* clean HW pattern match */
8706 	rtw_hal_dl_pattern(adapter, 0);
8707 
8708 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
8709 	/* config RXFF boundary to original */
8710 	rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
8711 	#endif
8712 	rtw_hal_release_rx_dma(adapter);
8713 
8714 	#if defined(CONFIG_RTL8188E)
8715 	if (IS_HARDWARE_TYPE_8188E(adapter))
8716 		rtw_hal_enable_tx_report(adapter);
8717 	#endif
8718 
8719 	if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) ||
8720 		(pwrctl->wowlan_wake_reason != RX_DEAUTH) ||
8721 		(pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
8722 		rtw_hal_get_aoac_rpt(adapter);
8723 		rtw_hal_update_sw_security_info(adapter);
8724 	}
8725 
8726 	rtw_hal_fw_dl(adapter, _FALSE);
8727 
8728 #ifdef CONFIG_GPIO_WAKEUP
8729 
8730 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
8731 	if (pwrctl->is_high_active == 0)
8732 		rtw_hal_set_input_gpio(adapter, WAKEUP_GPIO_IDX);
8733 	else
8734 		rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, 0);
8735 #else
8736 	val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
8737 	RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
8738 
8739 	rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, val8);
8740 	rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _FALSE);
8741 #endif
8742 
8743 #endif
8744 	if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
8745 	    (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
8746 	    (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
8747 	    (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
8748 
8749 		media_status_rpt = RT_MEDIA_CONNECT;
8750 		rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
8751 				  (u8 *)&media_status_rpt);
8752 
8753 		if (psta != NULL) {
8754 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
8755 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
8756 			#endif
8757 			rtw_sta_media_status_rpt(adapter, psta, 1);
8758 		}
8759 	}
8760 	rtw_hal_gate_bb(adapter, _FALSE);
8761 }
8762 #endif /*CONFIG_WOWLAN*/
8763 
8764 #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)8765 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
8766 	      u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
8767 				      RSVDPAGE_LOC *rsvd_page_loc)
8768 {
8769 	u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
8770 	u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
8771 	u8 CurtPktPageNum = 0;
8772 
8773 	/* P2P Beacon */
8774 	rsvd_page_loc->LocP2PBeacon = *page_num;
8775 	rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
8776 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
8777 				 P2PBCNLength, _FALSE, _FALSE, _FALSE);
8778 
8779 #if 0
8780 	RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
8781 		__FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
8782 #endif
8783 
8784 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
8785 
8786 	*page_num += CurtPktPageNum;
8787 
8788 	index += (CurtPktPageNum * page_size);
8789 
8790 	/* P2P Probe rsp */
8791 	rsvd_page_loc->LocP2PProbeRsp = *page_num;
8792 	rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
8793 				      &P2PProbeRspLength);
8794 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
8795 				 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
8796 
8797 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",  */
8798 	/*	__FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
8799 
8800 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
8801 
8802 	*page_num += CurtPktPageNum;
8803 
8804 	index += (CurtPktPageNum * page_size);
8805 
8806 	/* P2P nego rsp */
8807 	rsvd_page_loc->LocNegoRsp = *page_num;
8808 	rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
8809 				     &P2PNegoRspLength);
8810 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
8811 				 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
8812 
8813 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
8814 	/*	__FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
8815 
8816 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
8817 
8818 	*page_num += CurtPktPageNum;
8819 
8820 	index += (CurtPktPageNum * page_size);
8821 
8822 	/* P2P invite rsp */
8823 	rsvd_page_loc->LocInviteRsp = *page_num;
8824 	rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
8825 				       &P2PInviteRspLength);
8826 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
8827 				 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
8828 
8829 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
8830 	/* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
8831 
8832 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
8833 
8834 	*page_num += CurtPktPageNum;
8835 
8836 	index += (CurtPktPageNum * page_size);
8837 
8838 	/* P2P provision discovery rsp */
8839 	rsvd_page_loc->LocPDRsp = *page_num;
8840 	rtw_hal_construct_P2PProvisionDisRsp(adapter,
8841 					     &pframe[index], &P2PPDRspLength);
8842 
8843 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
8844 				 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
8845 
8846 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
8847 	/*	__FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
8848 
8849 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
8850 
8851 	*page_num += CurtPktPageNum;
8852 
8853 	*total_pkt_len = index + P2PPDRspLength;
8854 
8855 	index += (CurtPktPageNum * page_size);
8856 
8857 
8858 }
8859 #endif /* CONFIG_P2P_WOWLAN */
8860 
8861 #ifdef CONFIG_LPS_PG
8862 #include "hal_halmac.h"
8863 
8864 #define DBG_LPSPG_SEC_DUMP
8865 #define LPS_PG_INFO_RSVD_LEN	16
8866 #define LPS_PG_INFO_RSVD_PAGE_NUM	1
8867 
8868 #define DBG_LPSPG_INFO_DUMP
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)8869 static void rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
8870 {
8871 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8872 	struct sta_info	*psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
8873 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
8874 	PHAL_DATA_TYPE phal_data = GET_HAL_DATA(adapter);
8875 	u8 lps_pg_info[LPS_PG_INFO_RSVD_LEN] = {0};
8876 #ifdef CONFIG_MBSSID_CAM
8877 	u8 cam_id = INVALID_CAM_ID;
8878 #endif
8879 	u8 *psec_cam_id = lps_pg_info + 8;
8880 	u8 sec_cam_num = 0;
8881 	u8 drv_rsvdpage_num = 0;
8882 
8883 	if (!psta) {
8884 		RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
8885 		rtw_warn_on(1);
8886 		return;
8887 	}
8888 
8889 	/*Byte 0 - used macid*/
8890 	LPSPG_RSVD_PAGE_SET_MACID(lps_pg_info, psta->cmn.mac_id);
8891 	RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
8892 
8893 #ifdef CONFIG_MBSSID_CAM
8894 	/*Byte 1 - used BSSID CAM entry*/
8895 	cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
8896 	if (cam_id != INVALID_CAM_ID)
8897 		LPSPG_RSVD_PAGE_SET_MBSSCAMID(lps_pg_info, cam_id);
8898 	RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
8899 #endif
8900 
8901 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
8902 	/*Btye 2 - Max used Pattern Match CAM entry*/
8903 	if (pwrpriv->wowlan_mode == _TRUE &&
8904 	    check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _TRUE) {
8905 		LPSPG_RSVD_PAGE_SET_PMC_NUM(lps_pg_info, pwrpriv->wowlan_pattern_idx);
8906 		RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
8907 	}
8908 #endif
8909 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
8910 	/*Btye 3 - Max MU rate table Group ID*/
8911 	LPSPG_RSVD_PAGE_SET_MU_RAID_GID(lps_pg_info, _value);
8912 	RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", _value);
8913 #endif
8914 
8915 	/*Btye 8 ~15 - used Security CAM entry */
8916 	sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
8917 
8918 	/*Btye 4 - used Security CAM entry number*/
8919 	if (sec_cam_num < 8)
8920 		LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(lps_pg_info, sec_cam_num);
8921 	RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
8922 
8923 	/*Btye 5 - Txbuf used page number for fw offload*/
8924 	if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
8925 		drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
8926 	else
8927 		drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
8928 	LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(lps_pg_info, drv_rsvdpage_num);
8929 	RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
8930 
8931 #ifdef DBG_LPSPG_SEC_DUMP
8932 	{
8933 		int i;
8934 
8935 		for (i = 0; i < sec_cam_num; i++)
8936 			RTW_INFO("%d = sec_cam_id:%d\n", i, psec_cam_id[i]);
8937 	}
8938 #endif
8939 
8940 #ifdef DBG_LPSPG_INFO_DUMP
8941 	RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
8942 	RTW_INFO("  %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
8943 		*(lps_pg_info), *(lps_pg_info + 1), *(lps_pg_info + 2), *(lps_pg_info + 3),
8944 		*(lps_pg_info + 4), *(lps_pg_info + 5), *(lps_pg_info + 6), *(lps_pg_info + 7));
8945 	RTW_INFO("  %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
8946 		*(lps_pg_info + 8), *(lps_pg_info + 9), *(lps_pg_info + 10), *(lps_pg_info + 11),
8947 		*(lps_pg_info + 12), *(lps_pg_info + 13), *(lps_pg_info + 14), *(lps_pg_info + 15));
8948 	RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
8949 #endif
8950 
8951 	rtw_halmac_download_rsvd_page(dvobj, pwrpriv->lpspg_rsvd_page_locate, lps_pg_info, LPS_PG_INFO_RSVD_LEN);
8952 
8953 #ifdef DBG_LPSPG_INFO_DUMP
8954 	RTW_INFO("Get LPS-PG INFO from rsvd page_offset:%d\n", pwrpriv->lpspg_rsvd_page_locate);
8955 	rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, pwrpriv->lpspg_rsvd_page_locate, 1);
8956 #endif
8957 }
8958 
8959 
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)8960 static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
8961 {
8962 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8963 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8964 
8965 	u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
8966 	u8 ret = _FAIL;
8967 
8968 	RTW_INFO("%s: loc_lpspg_info:%d\n", __func__, pwrpriv->lpspg_rsvd_page_locate);
8969 
8970 	if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
8971 		SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1);	/*SecurityCAM_En*/
8972 #ifdef CONFIG_MBSSID_CAM
8973 	SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1);		/*BSSIDCAM_En*/
8974 #endif
8975 
8976 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
8977 	if (pwrpriv->wowlan_mode == _TRUE &&
8978 	    check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
8979 
8980 		SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1);	/*PatternMatchCAM_En*/
8981 	}
8982 #endif
8983 
8984 #ifdef CONFIG_MACID_SEARCH
8985 	SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1);	/*MACIDSearch_En*/
8986 #endif
8987 
8988 #ifdef CONFIG_TX_SC
8989 	SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1);	/*TXSC_En*/
8990 #endif
8991 
8992 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
8993 	SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1);	/*MURateTable_En*/
8994 #endif
8995 
8996 	SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_rsvd_page_locate);
8997 
8998 #ifdef DBG_LPSPG_INFO_DUMP
8999 	RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
9000 	RTW_INFO("  H2C_CMD: 0x%02x, H2C_LEN: %d\n", H2C_LPS_PG_INFO, H2C_LPS_PG_INFO_LEN);
9001 	RTW_INFO("  %02X:%02X\n", *(lpspg_info), *(lpspg_info + 1));
9002 	RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
9003 #endif
9004 
9005 	ret = rtw_hal_fill_h2c_cmd(adapter,
9006 				   H2C_LPS_PG_INFO,
9007 				   H2C_LPS_PG_INFO_LEN,
9008 				   lpspg_info);
9009 	return ret;
9010 }
rtw_hal_set_lps_pg_info(_adapter * adapter)9011 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
9012 {
9013 	u8 ret = _FAIL;
9014 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9015 
9016 	if (pwrpriv->lpspg_rsvd_page_locate == 0) {
9017 		RTW_ERR("%s [ERROR] lpspg_rsvd_page_locate = 0\n", __func__);
9018 		rtw_warn_on(1);
9019 		return ret;
9020 	}
9021 
9022 	rtw_hal_set_lps_pg_info_rsvd_page(adapter);
9023 	ret = rtw_hal_set_lps_pg_info_cmd(adapter);
9024 	if (_SUCCESS == ret)
9025 		pwrpriv->blpspg_info_up = _FALSE;
9026 
9027 	return ret;
9028 }
9029 
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)9030 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
9031 {
9032 #if 0
9033 	if (sta->cmn.ra_info.rssi_level >= 4)
9034 		sta->lps_pg_rssi_lv = 3;	/*RSSI High - 1SS_VHT_MCS7*/
9035 	else if (sta->cmn.ra_info.rssi_level >=  2)
9036 		sta->lps_pg_rssi_lv = 2;	/*RSSI Middle - 1SS_VHT_MCS3*/
9037 	else
9038 		sta->lps_pg_rssi_lv = 1;	/*RSSI Lower - Lowest_rate*/
9039 #else
9040 	sta->lps_pg_rssi_lv = 0;
9041 #endif
9042 	RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
9043 		__func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
9044 }
9045 
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)9046 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
9047 {
9048 	switch (hdl_id) {
9049 	case LPS_PG_INFO_CFG:
9050 		rtw_hal_set_lps_pg_info(adapter);
9051 		break;
9052 	case LPS_PG_REDLEMEM:
9053 		{
9054 			/*set xmit_block*/
9055 			rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
9056 			if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
9057 				rtw_warn_on(1);
9058 			/*clearn xmit_block*/
9059 			rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
9060 		}
9061 		break;
9062 
9063 	case LPS_PG_RESEND_H2C:
9064 		{
9065 			struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
9066 			struct sta_info *sta;
9067 			int i;
9068 
9069 			for (i = 0; i < MACID_NUM_SW_LIMIT; i++) {
9070 				sta = macid_ctl->sta[i];
9071 				if (sta && !is_broadcast_mac_addr(sta->cmn.mac_addr)) {
9072 					rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
9073 					set_sta_rate(adapter, sta);
9074 					sta->lps_pg_rssi_lv = 0;
9075 				}
9076 			}
9077 		}
9078 		break;
9079 
9080 	default:
9081 		break;
9082 	}
9083 }
9084 
9085 #endif /*CONFIG_LPS_PG*/
9086 
9087 /*
9088  * Description: Fill the reserved packets that FW will use to RSVD page.
9089  *			Now we just send 4 types packet to rsvd page.
9090  *			(1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
9091  * Input:
9092  * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
9093  *		    so we need to set the packet length to total lengh.
9094  *	      TRUE: At the second time, we should send the first packet (default:beacon)
9095  *		    to Hw again and set the lengh in descriptor to the real beacon lengh.
9096  * page_num - The amount of reserved page which driver need.
9097  *	      If this is not NULL, this function doesn't real download reserved
9098  *	      page, but just count the number of reserved page.
9099  *
9100  * 2009.10.15 by tynli.
9101  * 2017.06.20 modified by Lucas.
9102  *
9103  * Page Size = 128: 8188e, 8723a/b, 8192c/d,
9104  * Page Size = 256: 8192e, 8821a
9105  * Page Size = 512: 8812a
9106  */
9107 
9108 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)9109 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
9110 {
9111 	PHAL_DATA_TYPE pHalData;
9112 	struct xmit_frame	*pcmdframe = NULL;
9113 	struct pkt_attrib	*pattrib;
9114 	struct xmit_priv	*pxmitpriv;
9115 	struct mlme_ext_priv	*pmlmeext;
9116 	struct mlme_ext_info	*pmlmeinfo;
9117 	struct pwrctrl_priv *pwrctl;
9118 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
9119 	struct hal_ops *pHalFunc = &adapter->hal_func;
9120 	u32	BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
9121 	u32	NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
9122 	u32	ProbeReqLength = 0, NullFunctionDataLength = 0;
9123 	u8	TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
9124 	u8	TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
9125 	u8	*ReservedPagePacket;
9126 	u16	BufIndex = 0;
9127 	u32	TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
9128 	RSVDPAGE_LOC	RsvdPageLoc;
9129 
9130 #ifdef DBG_CONFIG_ERROR_DETECT
9131 	struct sreset_priv *psrtpriv;
9132 #endif /* DBG_CONFIG_ERROR_DETECT */
9133 
9134 #ifdef CONFIG_MCC_MODE
9135 	u8 dl_mcc_page = _FAIL;
9136 #endif /* CONFIG_MCC_MODE */
9137 
9138 	pHalData = GET_HAL_DATA(adapter);
9139 #ifdef DBG_CONFIG_ERROR_DETECT
9140 	psrtpriv = &pHalData->srestpriv;
9141 #endif
9142 	pxmitpriv = &adapter->xmitpriv;
9143 	pmlmeext = &adapter->mlmeextpriv;
9144 	pmlmeinfo = &pmlmeext->mlmext_info;
9145 	pwrctl = adapter_to_pwrctl(adapter);
9146 
9147 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
9148 
9149 	if (PageSize == 0) {
9150 		RTW_INFO("[Error]: %s, PageSize is zero!!\n", __func__);
9151 		return;
9152 	}
9153 
9154 	/* Prepare ReservedPagePacket */
9155 	if (page_num) {
9156 		ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
9157 		if (!ReservedPagePacket) {
9158 			RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
9159 			*page_num = 0xFF;
9160 			return;
9161 		}
9162 	} else {
9163 		if (pwrctl->wowlan_mode == _TRUE || pwrctl->wowlan_ap_mode == _TRUE)
9164 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
9165 		else
9166 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
9167 
9168 		RTW_INFO("%s PageSize: %d, RsvdPageNUm: %d\n", __func__, PageSize, RsvdPageNum);
9169 
9170 		MaxRsvdPageBufSize = RsvdPageNum * PageSize;
9171 		if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
9172 			RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
9173 				 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
9174 			rtw_warn_on(1);
9175 			return;
9176 		}
9177 
9178 		pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
9179 		if (pcmdframe == NULL) {
9180 			RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
9181 			return;
9182 		}
9183 
9184 		ReservedPagePacket = pcmdframe->buf_addr;
9185 	}
9186 
9187 	_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
9188 
9189 	/* beacon * 1 pages */
9190 	BufIndex = TxDescOffset;
9191 	rtw_hal_construct_beacon(adapter,
9192 				 &ReservedPagePacket[BufIndex], &BeaconLength);
9193 
9194 	/*
9195 	* When we count the first page size, we need to reserve description size for the RSVD
9196 	* packet, it will be filled in front of the packet in TXPKTBUF.
9197 	*/
9198 	CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
9199 
9200 	TotalPageNum += CurtPktPageNum;
9201 
9202 	BufIndex += (CurtPktPageNum * PageSize);
9203 
9204 	if (pwrctl->wowlan_ap_mode == _TRUE) {
9205 		/* (4) probe response*/
9206 		RsvdPageLoc.LocProbeRsp = TotalPageNum;
9207 		rtw_hal_construct_ProbeRsp(
9208 			adapter, &ReservedPagePacket[BufIndex],
9209 			&ProbeRspLength,
9210 			get_my_bssid(&pmlmeinfo->network), _FALSE);
9211 		rtw_hal_fill_fake_txdesc(adapter,
9212 				 &ReservedPagePacket[BufIndex - TxDescLen],
9213 				 ProbeRspLength, _FALSE, _FALSE, _FALSE);
9214 
9215 		CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
9216 		TotalPageNum += CurtPktPageNum;
9217 		TotalPacketLen = BufIndex + ProbeRspLength;
9218 		BufIndex += (CurtPktPageNum * PageSize);
9219 		goto download_page;
9220 	}
9221 
9222 	/* ps-poll * 1 page */
9223 	RsvdPageLoc.LocPsPoll = TotalPageNum;
9224 	RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
9225 	rtw_hal_construct_PSPoll(adapter,
9226 				 &ReservedPagePacket[BufIndex], &PSPollLength);
9227 	rtw_hal_fill_fake_txdesc(adapter,
9228 				 &ReservedPagePacket[BufIndex - TxDescLen],
9229 				 PSPollLength, _TRUE, _FALSE, _FALSE);
9230 
9231 	CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
9232 
9233 	TotalPageNum += CurtPktPageNum;
9234 
9235 	BufIndex += (CurtPktPageNum * PageSize);
9236 
9237 #ifdef CONFIG_BT_COEXIST
9238 	if (pwrctl->wowlan_mode == _FALSE ||
9239 		pwrctl->wowlan_in_resume == _TRUE) {
9240 		/* BT Qos null data * 1 page */
9241 		RsvdPageLoc.LocBTQosNull = TotalPageNum;
9242 
9243 		RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
9244 
9245 		rtw_hal_construct_NullFunctionData(adapter,
9246 					&ReservedPagePacket[BufIndex],
9247 					&BTQosNullLength,
9248 					get_my_bssid(&pmlmeinfo->network),
9249 					_TRUE, 0, 0, _FALSE);
9250 
9251 		rtw_hal_fill_fake_txdesc(adapter,
9252 				&ReservedPagePacket[BufIndex - TxDescLen],
9253 				BTQosNullLength, _FALSE, _TRUE, _FALSE);
9254 
9255 		CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
9256 					     PageSize);
9257 
9258 		TotalPageNum += CurtPktPageNum;
9259 		BufIndex += (CurtPktPageNum * PageSize);
9260 	}
9261 #endif /* CONFIG_BT_COEXIT */
9262 
9263 #ifdef CONFIG_MCC_MODE
9264 	if (MCC_EN(adapter)) {
9265 		dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
9266 				&BufIndex, TxDescLen, PageSize,
9267 				&TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
9268 	} else {
9269 		dl_mcc_page = _FAIL;
9270 	}
9271 
9272 	if (dl_mcc_page == _FAIL)
9273 #endif /* CONFIG_MCC_MODE */
9274 	{
9275 		/* null data * 1 page */
9276 		RsvdPageLoc.LocNullData = TotalPageNum;
9277 		RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
9278 		rtw_hal_construct_NullFunctionData(
9279 			adapter,
9280 			&ReservedPagePacket[BufIndex],
9281 			&NullDataLength,
9282 			get_my_bssid(&pmlmeinfo->network),
9283 			_FALSE, 0, 0, _FALSE);
9284 		rtw_hal_fill_fake_txdesc(adapter,
9285 				 &ReservedPagePacket[BufIndex - TxDescLen],
9286 				 NullDataLength, _FALSE, _FALSE, _FALSE);
9287 
9288 		CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
9289 
9290 		TotalPageNum += CurtPktPageNum;
9291 
9292 		BufIndex += (CurtPktPageNum * PageSize);
9293 	}
9294 
9295 	if (pwrctl->wowlan_mode == _FALSE ||
9296 		pwrctl->wowlan_in_resume == _TRUE) {
9297 		/* Qos null data * 1 page */
9298 		RsvdPageLoc.LocQosNull = TotalPageNum;
9299 		RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
9300 		rtw_hal_construct_NullFunctionData(adapter,
9301 					&ReservedPagePacket[BufIndex],
9302 					&QosNullLength,
9303 					get_my_bssid(&pmlmeinfo->network),
9304 					_TRUE, 0, 0, _FALSE);
9305 		rtw_hal_fill_fake_txdesc(adapter,
9306 				 &ReservedPagePacket[BufIndex - TxDescLen],
9307 				 QosNullLength, _FALSE, _FALSE, _FALSE);
9308 
9309 		CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
9310 					     PageSize);
9311 
9312 		TotalPageNum += CurtPktPageNum;
9313 
9314 		BufIndex += (CurtPktPageNum * PageSize);
9315 	}
9316 
9317 	TotalPacketLen = BufIndex + QosNullLength;
9318 
9319 #ifdef CONFIG_WOWLAN
9320 	if (pwrctl->wowlan_mode == _TRUE &&
9321 		pwrctl->wowlan_in_resume == _FALSE) {
9322 		rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
9323 					     BufIndex, TxDescLen, PageSize,
9324 			     &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
9325 	}
9326 #endif /* CONFIG_WOWLAN */
9327 
9328 #ifdef CONFIG_P2P_WOWLAN
9329 	if (_TRUE == pwrctl->wowlan_p2p_mode) {
9330 		rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
9331 						 BufIndex, TxDescLen, PageSize,
9332 				 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
9333 	}
9334 #endif /* CONFIG_P2P_WOWLAN */
9335 
9336 #ifdef CONFIG_LPS_PG
9337 	/* must reserved last 1 x page for LPS PG Info*/
9338 	pwrctl->lpspg_rsvd_page_locate = TotalPageNum;
9339 	pwrctl->blpspg_info_up = _TRUE;
9340 	if (page_num)
9341 		TotalPageNum += LPS_PG_INFO_RSVD_PAGE_NUM;
9342 #endif
9343 
9344 download_page:
9345 	if (page_num) {
9346 		*page_num = TotalPageNum;
9347 		rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
9348 		ReservedPagePacket = NULL;
9349 		return;
9350 	}
9351 
9352 	/* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
9353 	RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
9354 		 __func__, TotalPageNum, TotalPacketLen);
9355 
9356 #ifdef CONFIG_LPS_PG
9357 	if ((TotalPacketLen + (LPS_PG_INFO_RSVD_PAGE_NUM * PageSize)) > MaxRsvdPageBufSize) {
9358 		pwrctl->lpspg_rsvd_page_locate = 0;
9359 		pwrctl->blpspg_info_up = _FALSE;
9360 
9361 		RTW_ERR("%s rsvd page size is not enough!!TotalPacketLen+LPS_PG_INFO_LEN %d, MaxRsvdPageBufSize %d\n",
9362 			 __func__, (TotalPacketLen + (LPS_PG_INFO_RSVD_PAGE_NUM * PageSize)), MaxRsvdPageBufSize);
9363 		rtw_warn_on(1);
9364 	}
9365 #endif
9366 
9367 	if (TotalPacketLen > MaxRsvdPageBufSize) {
9368 		RTW_ERR("%s(ERROR): rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
9369 			 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
9370 		rtw_warn_on(1);
9371 		goto error;
9372 	} else {
9373 		/* update attribute */
9374 		pattrib = &pcmdframe->attrib;
9375 		update_mgntframe_attrib(adapter, pattrib);
9376 		pattrib->qsel = QSLT_BEACON;
9377 		pattrib->pktlen = TotalPacketLen - TxDescOffset;
9378 		pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
9379 #ifdef CONFIG_PCI_HCI
9380 		dump_mgntframe(adapter, pcmdframe);
9381 #else
9382 		dump_mgntframe_and_wait(adapter, pcmdframe, 100);
9383 #endif
9384 	}
9385 
9386 	RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
9387 		 __func__, TotalPacketLen, TotalPageNum);
9388 #ifdef DBG_DUMP_SET_RSVD_PAGE
9389 	RTW_INFO(" ==================================================\n");
9390 	RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
9391 	RTW_INFO(" ==================================================\n");
9392 #endif
9393 	if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
9394 		rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
9395 #ifdef CONFIG_WOWLAN
9396 		if (pwrctl->wowlan_mode == _TRUE &&
9397 			pwrctl->wowlan_in_resume == _FALSE)
9398 			rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
9399 #endif /* CONFIG_WOWLAN */
9400 #ifdef CONFIG_AP_WOWLAN
9401 		if (pwrctl->wowlan_ap_mode == _TRUE)
9402 			rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
9403 #endif /* CONFIG_AP_WOWLAN */
9404 	} else if (pwrctl->wowlan_pno_enable) {
9405 #ifdef CONFIG_PNO_SUPPORT
9406 		rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
9407 		if (pwrctl->wowlan_in_resume)
9408 			rtw_hal_set_scan_offload_info_cmd(adapter,
9409 							  &RsvdPageLoc, 0);
9410 		else
9411 			rtw_hal_set_scan_offload_info_cmd(adapter,
9412 							  &RsvdPageLoc, 1);
9413 #endif /* CONFIG_PNO_SUPPORT */
9414 	}
9415 
9416 #ifdef CONFIG_P2P_WOWLAN
9417 	if (_TRUE == pwrctl->wowlan_p2p_mode)
9418 		rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
9419 #endif /* CONFIG_P2P_WOWLAN */
9420 
9421 	return;
9422 error:
9423 	rtw_free_xmitframe(pxmitpriv, pcmdframe);
9424 }
9425 
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)9426 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
9427 {
9428 	_rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
9429 }
9430 
9431 /**
9432  * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
9433  * @adapter:	struct _ADAPTER*
9434  *
9435  * Caculate needed reserved page number.
9436  * In different state would get different number, for example normal mode and
9437  * WOW mode would need different reserved page size.
9438  *
9439  * Return the number of reserved page which driver need.
9440  */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)9441 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
9442 {
9443 	u8 num = 0;
9444 
9445 
9446 	_rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
9447 
9448 	return num;
9449 }
9450 
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 variable,u8 * val)9451 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 variable, u8 *val)
9452 {
9453 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
9454 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
9455 	u16 value_rxfltmap2;
9456 	int i;
9457 	_adapter *iface;
9458 
9459 #ifdef DBG_IFACE_STATUS
9460 	DBG_IFACE_STATUS_DUMP(adapter);
9461 #endif
9462 
9463 #ifdef CONFIG_FIND_BEST_CHANNEL
9464 	/* Receive all data frames */
9465 	value_rxfltmap2 = 0xFFFF;
9466 #else
9467 	/* not to receive data frame */
9468 	value_rxfltmap2 = 0;
9469 #endif
9470 
9471 	if (*((u8 *)val)) { /* under sitesurvey */
9472 		/*
9473 		* 1. configure REG_RXFLTMAP2
9474 		* 2. disable TSF update &  buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
9475 		* 3. config RCR to receive different BSSID BCN or probe rsp
9476 		*/
9477 		rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
9478 
9479 #ifdef CONFIG_MI_WITH_MBSSID_CAM
9480 		/*do nothing~~*/
9481 #else
9482 
9483 		/* disable update TSF */
9484 		for (i = 0; i < dvobj->iface_nums; i++) {
9485 			iface = dvobj->padapters[i];
9486 			if (!iface)
9487 				continue;
9488 
9489 			if (rtw_linked_check(iface)
9490 				&& !MLME_IS_AP(iface) && !MLME_IS_MESH(iface)
9491 			) {
9492 				if (iface->hw_port == HW_PORT1)
9493 					rtw_write8(iface, REG_BCN_CTRL_1, rtw_read8(iface, REG_BCN_CTRL_1) | DIS_TSF_UDT);
9494 				else
9495 					rtw_write8(iface, REG_BCN_CTRL, rtw_read8(iface, REG_BCN_CTRL) | DIS_TSF_UDT);
9496 
9497 				iface->mlmeextpriv.en_hw_update_tsf = _FALSE;
9498 			}
9499 		}
9500 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
9501 
9502 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
9503 
9504 		/* Save orignal RRSR setting. needed? */
9505 		hal_data->RegRRSR = rtw_read16(adapter, REG_RRSR);
9506 
9507 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
9508 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
9509 			/* set 718[1:0]=2'b00 to avoid BF scan hang */
9510 			hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
9511 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
9512 		}
9513 		#endif
9514 
9515 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
9516 			StopTxBeacon(adapter);
9517 	} else { /* sitesurvey done */
9518 		/*
9519 		* 1. enable rx data frame
9520 		* 2. config RCR not to receive different BSSID BCN or probe rsp
9521 		* 3. doesn't enable TSF update &  buddy TSF right now to avoid HW conflict
9522 		*	 so, we enable TSF update when rx first BCN after sitesurvey done
9523 		*/
9524 		if (rtw_mi_check_fwstate(adapter, _FW_LINKED | WIFI_AP_STATE | WIFI_MESH_STATE)) {
9525 			/* enable to rx data frame */
9526 			rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
9527 		}
9528 
9529 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
9530 
9531 #ifdef CONFIG_MI_WITH_MBSSID_CAM
9532 		/*if ((rtw_mi_get_assoced_sta_num(adapter) == 1) && (!rtw_mi_check_status(adapter, MI_AP_MODE)))
9533 			rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)&(~DIS_TSF_UDT));*/
9534 #else
9535 
9536 		for (i = 0; i < dvobj->iface_nums; i++) {
9537 			iface = dvobj->padapters[i];
9538 			if (!iface)
9539 				continue;
9540 			if (rtw_linked_check(iface)
9541 				&& !MLME_IS_AP(iface) && !MLME_IS_MESH(iface)
9542 			) {
9543 				/* enable HW TSF update when recive beacon*/
9544 				/*if (iface->hw_port == HW_PORT1)
9545 					rtw_write8(iface, REG_BCN_CTRL_1, rtw_read8(iface, REG_BCN_CTRL_1)&(~(DIS_TSF_UDT)));
9546 				else
9547 					rtw_write8(iface, REG_BCN_CTRL, rtw_read8(iface, REG_BCN_CTRL)&(~(DIS_TSF_UDT)));
9548 				*/
9549 				iface->mlmeextpriv.en_hw_update_tsf = _TRUE;
9550 			}
9551 		}
9552 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
9553 
9554 		/* Restore orignal RRSR setting. needed? */
9555 		rtw_write16(adapter, REG_RRSR, hal_data->RegRRSR);
9556 
9557 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
9558 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
9559 			/* Restore orignal 0x718 setting*/
9560 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
9561 		}
9562 		#endif
9563 
9564 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
9565 			ResumeTxBeacon(adapter);
9566 			rtw_mi_tx_beacon_hdl(adapter);
9567 		}
9568 	}
9569 }
9570 
9571 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)9572 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
9573 {
9574 	u8 buf[2];
9575 	int ret;
9576 
9577 	if (reset_port == HW_PORT0) {
9578 		buf[0] = 0x1;
9579 		buf[1] = 0;
9580 	} else {
9581 		buf[0] = 0x0;
9582 		buf[1] = 0x1;
9583 	}
9584 
9585 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
9586 
9587 	return ret;
9588 }
9589 
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)9590 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
9591 {
9592 	u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
9593 	u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
9594 				REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
9595 	int ret;
9596 
9597 	/* site survey will cause reset tsf fail */
9598 	rtw_mi_buddy_scan_abort(adapter, _FALSE);
9599 	reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
9600 	ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
9601 	if (ret != _SUCCESS)
9602 		return ret;
9603 
9604 	while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
9605 		rtw_msleep_os(100);
9606 		loop_cnt++;
9607 		reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
9608 	}
9609 
9610 	return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
9611 }
9612 #endif /* CONFIG_TSF_RESET_OFFLOAD */
9613 
rtw_hal_set_hw_update_tsf(PADAPTER padapter)9614 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
9615 {
9616 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9617 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9618 
9619 #if defined(CONFIG_RTL8822B) || defined(CONFIG_MI_WITH_MBSSID_CAM)
9620 	RTW_INFO("[Warn] %s "ADPT_FMT" enter func\n", __func__, ADPT_ARG(padapter));
9621 	rtw_warn_on(1);
9622 	return;
9623 #endif
9624 
9625 	if (!pmlmeext->en_hw_update_tsf)
9626 		return;
9627 
9628 	/* check RCR */
9629 	if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
9630 		return;
9631 
9632 	/* enable hw update tsf function for non-AP and non-Mesh */
9633 	if (rtw_linked_check(padapter)
9634 		&& !MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter)
9635 	) {
9636 #ifdef CONFIG_CONCURRENT_MODE
9637 		if (padapter->hw_port == HW_PORT1)
9638 			rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~DIS_TSF_UDT));
9639 		else
9640 #endif
9641 			rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~DIS_TSF_UDT));
9642 	}
9643 	pmlmeext->en_hw_update_tsf = _FALSE;
9644 }
9645 
hw_var_set_correct_tsf(_adapter * adapter)9646 static void hw_var_set_correct_tsf(_adapter *adapter)
9647 {
9648 #ifdef CONFIG_MI_WITH_MBSSID_CAM
9649 	/*do nothing*/
9650 #else
9651 	u64 tsf;
9652 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
9653 	struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
9654 
9655 	tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
9656 
9657 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
9658 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
9659 		StopTxBeacon(adapter);
9660 
9661 	rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
9662 
9663 #ifdef CONFIG_CONCURRENT_MODE
9664 	/* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
9665 	if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
9666 		&& (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
9667 	) {
9668 		struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
9669 		int i;
9670 		_adapter *iface;
9671 
9672 		for (i = 0; i < dvobj->iface_nums; i++) {
9673 			iface = dvobj->padapters[i];
9674 			if (!iface)
9675 				continue;
9676 			if (iface == adapter)
9677 				continue;
9678 
9679 			if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
9680 				&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
9681 			) {
9682 				rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
9683 				#ifdef CONFIG_TSF_RESET_OFFLOAD
9684 				if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
9685 					RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
9686 						, __func__, ADPT_ARG(iface), iface->hw_port);
9687 				#endif	/* CONFIG_TSF_RESET_OFFLOAD*/
9688 			}
9689 		}
9690 	}
9691 #endif /* CONFIG_CONCURRENT_MODE */
9692 
9693 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
9694 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
9695 		ResumeTxBeacon(adapter);
9696 
9697 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
9698 }
9699 
9700 #ifdef CONFIG_TDLS
9701 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)9702 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
9703 {
9704 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
9705 	u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
9706 
9707 
9708 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
9709 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
9710 	switch (bwmode) {
9711 	case CHANNEL_WIDTH_40:
9712 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
9713 		break;
9714 	case CHANNEL_WIDTH_80:
9715 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
9716 		break;
9717 	case CHANNEL_WIDTH_20:
9718 	default:
9719 		break;
9720 	}
9721 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
9722 
9723 	return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
9724 }
9725 #endif
9726 #endif
9727 
9728 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)9729 void rtw_hal_update_uapsd_tid(_adapter *adapter)
9730 {
9731 	struct mlme_priv		*pmlmepriv = &adapter->mlmepriv;
9732 	struct qos_priv		*pqospriv = &pmlmepriv->qospriv;
9733 
9734 	/* write complement of pqospriv->uapsd_tid to mac register 0x693 because
9735 	    it's designed  for "0" represents "enable" and "1" represents "disable" */
9736 	rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
9737 }
9738 #endif /* CONFIG_WMMPS_STA */
9739 
9740 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
9741 /* 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)9742 s32 rtw_hal_set_wifi_port_id_cmd(_adapter *adapter)
9743 {
9744 	u8 port_id = 0;
9745 	u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
9746 
9747 	SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, adapter->hw_port);
9748 	return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
9749 }
9750 #endif
9751 
SetHwReg(_adapter * adapter,u8 variable,u8 * val)9752 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
9753 {
9754 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
9755 	u8 ret = _SUCCESS;
9756 
9757 	switch (variable) {
9758 	case HW_VAR_MEDIA_STATUS: {
9759 		u8 net_type = *((u8 *)val);
9760 
9761 		rtw_hal_set_msr(adapter, net_type);
9762 	}
9763 	break;
9764 	case HW_VAR_MAC_ADDR:
9765 #ifdef CONFIG_MI_WITH_MBSSID_CAM
9766 		rtw_hal_set_macaddr_mbid(adapter, val);
9767 #else
9768 		rtw_hal_set_macaddr_port(adapter, val);
9769 #endif
9770 		break;
9771 	case HW_VAR_BSSID:
9772 		rtw_hal_set_bssid(adapter, val);
9773 		break;
9774 	case HW_VAR_RCR:
9775 		ret = hw_var_rcr_config(adapter, *((u32 *)val));
9776 		break;
9777 	case HW_VAR_ON_RCR_AM:
9778 		hw_var_set_rcr_am(adapter, 1);
9779 		break;
9780 	case HW_VAR_OFF_RCR_AM:
9781 		hw_var_set_rcr_am(adapter, 0);
9782 		break;
9783 	case HW_VAR_BEACON_INTERVAL:
9784 		hw_var_set_bcn_interval(adapter, *(u16 *)val);
9785 		break;
9786 #ifdef CONFIG_MBSSID_CAM
9787 	case HW_VAR_MBSSID_CAM_WRITE: {
9788 		u32	cmd = 0;
9789 		u32	*cam_val = (u32 *)val;
9790 
9791 		rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
9792 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
9793 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
9794 	}
9795 		break;
9796 	case HW_VAR_MBSSID_CAM_CLEAR: {
9797 		u32 cmd;
9798 		u8 entry_id = *(u8 *)val;
9799 
9800 		rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
9801 
9802 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
9803 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
9804 	}
9805 		break;
9806 	case HW_VAR_RCR_MBSSID_EN:
9807 		if (*((u8 *)val))
9808 			rtw_hal_rcr_add(adapter, RCR_ENMBID);
9809 		else
9810 			rtw_hal_rcr_clear(adapter, RCR_ENMBID);
9811 		break;
9812 #endif
9813 	case HW_VAR_PORT_SWITCH:
9814 		hw_var_port_switch(adapter);
9815 		break;
9816 	case HW_VAR_INIT_RTS_RATE: {
9817 		u16 brate_cfg = *((u16 *)val);
9818 		u8 rate_index = 0;
9819 		HAL_VERSION *hal_ver = &hal_data->version_id;
9820 
9821 		if (IS_8188E(*hal_ver)) {
9822 
9823 			while (brate_cfg > 0x1) {
9824 				brate_cfg = (brate_cfg >> 1);
9825 				rate_index++;
9826 			}
9827 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
9828 		} else
9829 			rtw_warn_on(1);
9830 	}
9831 		break;
9832 	case HW_VAR_SEC_CFG: {
9833 		u16 reg_scr_ori;
9834 		u16 reg_scr;
9835 
9836 		reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
9837 		reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
9838 
9839 		if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
9840 			reg_scr |= SCR_CHK_BMC;
9841 
9842 		if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
9843 			reg_scr |= SCR_NoSKMC;
9844 
9845 		if (reg_scr != reg_scr_ori)
9846 			rtw_write16(adapter, REG_SECCFG, reg_scr);
9847 	}
9848 		break;
9849 	case HW_VAR_SEC_DK_CFG: {
9850 		struct security_priv *sec = &adapter->securitypriv;
9851 		u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
9852 
9853 		if (val) { /* Enable default key related setting */
9854 			reg_scr |= SCR_TXBCUSEDK;
9855 			if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
9856 				reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
9857 		} else /* Disable default key related setting */
9858 			reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
9859 
9860 		rtw_write8(adapter, REG_SECCFG, reg_scr);
9861 	}
9862 		break;
9863 
9864 	case HW_VAR_ASIX_IOT:
9865 		/* enable  ASIX IOT function */
9866 		if (*((u8 *)val) == _TRUE) {
9867 			/* 0xa2e[0]=0 (disable rake receiver) */
9868 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
9869 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
9870 			/* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
9871 			rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
9872 		} else {
9873 			/* restore reg:0xa2e,   reg:0xa1c */
9874 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
9875 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
9876 			rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
9877 		}
9878 		break;
9879 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
9880 	case HW_VAR_WOWLAN: {
9881 		struct wowlan_ioctl_param *poidparam;
9882 
9883 		poidparam = (struct wowlan_ioctl_param *)val;
9884 		switch (poidparam->subcode) {
9885 #ifdef CONFIG_WOWLAN
9886 		case WOWLAN_PATTERN_CLEAN:
9887 			rtw_hal_dl_pattern(adapter, 2);
9888 			break;
9889 		case WOWLAN_ENABLE:
9890 			rtw_hal_wow_enable(adapter);
9891 			break;
9892 		case WOWLAN_DISABLE:
9893 			rtw_hal_wow_disable(adapter);
9894 			break;
9895 #endif /*CONFIG_WOWLAN*/
9896 #ifdef CONFIG_AP_WOWLAN
9897 		case WOWLAN_AP_ENABLE:
9898 			rtw_hal_ap_wow_enable(adapter);
9899 			break;
9900 		case WOWLAN_AP_DISABLE:
9901 			rtw_hal_ap_wow_disable(adapter);
9902 			break;
9903 #endif /*CONFIG_AP_WOWLAN*/
9904 		default:
9905 			break;
9906 		}
9907 	}
9908 		break;
9909 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
9910 
9911 	case HW_VAR_MLME_SITESURVEY:
9912 		hw_var_set_mlme_sitesurvey(adapter, variable, val);
9913 		#ifdef CONFIG_BT_COEXIST
9914 		if (hal_data->EEPROMBluetoothCoexist == 1)
9915 			rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
9916 		#endif
9917 		break;
9918 
9919 	case HW_VAR_EN_HW_UPDATE_TSF:
9920 		rtw_hal_set_hw_update_tsf(adapter);
9921 		break;
9922 
9923 	case HW_VAR_CORRECT_TSF:
9924 		hw_var_set_correct_tsf(adapter);
9925 		break;
9926 
9927 	case HW_VAR_APFM_ON_MAC:
9928 		hal_data->bMacPwrCtrlOn = *val;
9929 		RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
9930 		break;
9931 #ifdef CONFIG_WMMPS_STA
9932 	case  HW_VAR_UAPSD_TID:
9933 		rtw_hal_update_uapsd_tid(adapter);
9934 		break;
9935 #endif /* CONFIG_WMMPS_STA */
9936 #ifdef CONFIG_LPS_PG
9937 	case HW_VAR_LPS_PG_HANDLE:
9938 		rtw_hal_lps_pg_handler(adapter, *val);
9939 		break;
9940 #endif
9941 #ifdef CONFIG_LPS_LCLK_WD_TIMER
9942 	case HW_VAR_DM_IN_LPS_LCLK:
9943 		rtw_phydm_wd_lps_lclk_hdl(adapter);
9944 		break;
9945 #endif
9946 	default:
9947 		if (0)
9948 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
9949 				  FUNC_ADPT_ARG(adapter), variable);
9950 		ret = _FAIL;
9951 		break;
9952 	}
9953 
9954 	return ret;
9955 }
9956 
GetHwReg(_adapter * adapter,u8 variable,u8 * val)9957 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
9958 {
9959 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
9960 
9961 
9962 	switch (variable) {
9963 	case HW_VAR_MAC_ADDR:
9964 		rtw_hal_get_macaddr_port(adapter, val);
9965 		break;
9966 	case HW_VAR_BASIC_RATE:
9967 		*((u16 *)val) = hal_data->BasicRateSet;
9968 		break;
9969 	case HW_VAR_RF_TYPE:
9970 		*((u8 *)val) = hal_data->rf_type;
9971 		break;
9972 	case HW_VAR_MEDIA_STATUS:
9973 		rtw_hal_get_msr(adapter, val);
9974 		break;
9975 	case HW_VAR_DO_IQK:
9976 		*val = hal_data->bNeedIQK;
9977 		break;
9978 	case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
9979 		if (hal_is_band_support(adapter, BAND_ON_5G))
9980 			*val = _TRUE;
9981 		else
9982 			*val = _FALSE;
9983 		break;
9984 	case HW_VAR_APFM_ON_MAC:
9985 		*val = hal_data->bMacPwrCtrlOn;
9986 		break;
9987 	case HW_VAR_RCR:
9988 		hw_var_rcr_get(adapter, (u32 *)val);
9989 		break;
9990 	case HW_VAR_FWLPS_RF_ON:
9991 		/* When we halt NIC, we should check if FW LPS is leave. */
9992 		if (rtw_is_surprise_removed(adapter)
9993 			|| (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
9994 		) {
9995 			/*
9996 			 * If it is in HW/SW Radio OFF or IPS state,
9997 			 * we do not check Fw LPS Leave,
9998 			 * because Fw is unload.
9999 			 */
10000 			*val = _TRUE;
10001 		} else {
10002 			u32 rcr = 0;
10003 
10004 			rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
10005 			if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
10006 				*val = _FALSE;
10007 			else
10008 				*val = _TRUE;
10009 		}
10010 		break;
10011 	default:
10012 		if (0)
10013 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
10014 				  FUNC_ADPT_ARG(adapter), variable);
10015 		break;
10016 	}
10017 
10018 }
10019 
_get_page_size(struct _ADAPTER * a)10020 static u32 _get_page_size(struct _ADAPTER *a)
10021 {
10022 #ifdef RTW_HALMAC
10023 	struct dvobj_priv *d;
10024 	u32 size = 0;
10025 	int err = 0;
10026 
10027 
10028 	d = adapter_to_dvobj(a);
10029 
10030 	err = rtw_halmac_get_page_size(d, &size);
10031 	if (!err)
10032 		return size;
10033 
10034 	RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
10035 		 FUNC_ADPT_ARG(a), err);
10036 #endif /* RTW_HALMAC */
10037 
10038 	return PAGE_SIZE_128;
10039 }
10040 
10041 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)10042 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
10043 {
10044 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10045 	u8 bResult = _SUCCESS;
10046 
10047 	switch (variable) {
10048 
10049 	case HAL_DEF_DBG_DUMP_RXPKT:
10050 		hal_data->bDumpRxPkt = *((u8 *)value);
10051 		break;
10052 	case HAL_DEF_DBG_DUMP_TXPKT:
10053 		hal_data->bDumpTxPkt = *((u8 *)value);
10054 		break;
10055 	case HAL_DEF_ANT_DETECT:
10056 		hal_data->AntDetection = *((u8 *)value);
10057 		break;
10058 	case HAL_DEF_DBG_DIS_PWT:
10059 		hal_data->bDisableTXPowerTraining = *((u8 *)value);
10060 		break;
10061 	default:
10062 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
10063 		bResult = _FAIL;
10064 		break;
10065 	}
10066 
10067 	return bResult;
10068 }
10069 
10070 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)10071 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
10072 {
10073 	struct registry_priv	*pregistrypriv = &adapter->registrypriv;
10074 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10075 
10076 	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)))
10077 		return pregistrypriv->beamformer_rf_num;
10078 	else if (IS_HARDWARE_TYPE_8814AE(adapter)
10079 #if 0
10080 #if defined(CONFIG_USB_HCI)
10081 		|| (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2))  /* for USB3.0 */
10082 #endif
10083 #endif
10084 		) {
10085 		/*BF cap provided by Yu Chen, Sean, 2015, 01 */
10086 		if (hal_data->rf_type == RF_3T3R)
10087 			return 2;
10088 		else if (hal_data->rf_type == RF_4T4R)
10089 			return 3;
10090 		else
10091 			return 1;
10092 	} else
10093 		return 1;
10094 
10095 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)10096 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
10097 {
10098 	struct registry_priv		*pregistrypriv = &adapter->registrypriv;
10099 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
10100 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10101 
10102 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10103 
10104 	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)))
10105 		return pregistrypriv->beamformee_rf_num;
10106 	else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
10107 		if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
10108 			return 2;
10109 		else
10110 			return 2;/*TODO: May be 3 in the future, by ChenYu. */
10111 	} else
10112 		return 1;
10113 
10114 }
10115 #endif
10116 
10117 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)10118 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
10119 {
10120 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10121 	u8 bResult = _SUCCESS;
10122 
10123 	switch (variable) {
10124 	case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
10125 		struct mlme_priv *pmlmepriv;
10126 		struct sta_priv *pstapriv;
10127 		struct sta_info *psta;
10128 
10129 		pmlmepriv = &adapter->mlmepriv;
10130 		pstapriv = &adapter->stapriv;
10131 		psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
10132 		if (psta)
10133 			*((int *)value) = psta->cmn.rssi_stat.rssi;
10134 	}
10135 	break;
10136 	case HAL_DEF_DBG_DUMP_RXPKT:
10137 		*((u8 *)value) = hal_data->bDumpRxPkt;
10138 		break;
10139 	case HAL_DEF_DBG_DUMP_TXPKT:
10140 		*((u8 *)value) = hal_data->bDumpTxPkt;
10141 		break;
10142 	case HAL_DEF_ANT_DETECT:
10143 		*((u8 *)value) = hal_data->AntDetection;
10144 		break;
10145 	case HAL_DEF_MACID_SLEEP:
10146 		*(u8 *)value = _FALSE;
10147 		break;
10148 	case HAL_DEF_TX_PAGE_SIZE:
10149 		*((u32 *)value) = _get_page_size(adapter);
10150 		break;
10151 	case HAL_DEF_DBG_DIS_PWT:
10152 		*(u8 *)value = hal_data->bDisableTXPowerTraining;
10153 		break;
10154 	case HAL_DEF_EXPLICIT_BEAMFORMER:
10155 	case HAL_DEF_EXPLICIT_BEAMFORMEE:
10156 	case HAL_DEF_VHT_MU_BEAMFORMER:
10157 	case HAL_DEF_VHT_MU_BEAMFORMEE:
10158 		*(u8 *)value = _FALSE;
10159 		break;
10160 #ifdef CONFIG_BEAMFORMING
10161 	case HAL_DEF_BEAMFORMER_CAP:
10162 		*(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
10163 		break;
10164 	case HAL_DEF_BEAMFORMEE_CAP:
10165 		*(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
10166 		break;
10167 #endif
10168 	default:
10169 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
10170 		bResult = _FAIL;
10171 		break;
10172 	}
10173 
10174 	return bResult;
10175 }
10176 
10177 
10178 BOOLEAN
eqNByte(u8 * str1,u8 * str2,u32 num)10179 eqNByte(
10180 	u8	*str1,
10181 	u8	*str2,
10182 	u32	num
10183 )
10184 {
10185 	if (num == 0)
10186 		return _FALSE;
10187 	while (num > 0) {
10188 		num--;
10189 		if (str1[num] != str2[num])
10190 			return _FALSE;
10191 	}
10192 	return _TRUE;
10193 }
10194 
10195 /*
10196  *	Description:
10197  *		Translate a character to hex digit.
10198  *   */
10199 u32
MapCharToHexDigit(IN char chTmp)10200 MapCharToHexDigit(
10201 	IN		char		chTmp
10202 )
10203 {
10204 	if (chTmp >= '0' && chTmp <= '9')
10205 		return chTmp - '0';
10206 	else if (chTmp >= 'a' && chTmp <= 'f')
10207 		return 10 + (chTmp - 'a');
10208 	else if (chTmp >= 'A' && chTmp <= 'F')
10209 		return 10 + (chTmp - 'A');
10210 	else
10211 		return 0;
10212 }
10213 
10214 
10215 
10216 /*
10217  *	Description:
10218  *		Parse hex number from the string pucStr.
10219  *   */
10220 BOOLEAN
GetHexValueFromString(IN char * szStr,IN OUT u32 * pu4bVal,IN OUT u32 * pu4bMove)10221 GetHexValueFromString(
10222 	IN		char			*szStr,
10223 	IN OUT	u32			*pu4bVal,
10224 	IN OUT	u32			*pu4bMove
10225 )
10226 {
10227 	char		*szScan = szStr;
10228 
10229 	/* Check input parameter. */
10230 	if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
10231 		RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
10232 		return _FALSE;
10233 	}
10234 
10235 	/* Initialize output. */
10236 	*pu4bMove = 0;
10237 	*pu4bVal = 0;
10238 
10239 	/* Skip leading space. */
10240 	while (*szScan != '\0' &&
10241 	       (*szScan == ' ' || *szScan == '\t')) {
10242 		szScan++;
10243 		(*pu4bMove)++;
10244 	}
10245 
10246 	/* Skip leading '0x' or '0X'. */
10247 	if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
10248 		szScan += 2;
10249 		(*pu4bMove) += 2;
10250 	}
10251 
10252 	/* Check if szScan is now pointer to a character for hex digit, */
10253 	/* if not, it means this is not a valid hex number. */
10254 	if (!IsHexDigit(*szScan))
10255 		return _FALSE;
10256 
10257 	/* Parse each digit. */
10258 	do {
10259 		(*pu4bVal) <<= 4;
10260 		*pu4bVal += MapCharToHexDigit(*szScan);
10261 
10262 		szScan++;
10263 		(*pu4bMove)++;
10264 	} while (IsHexDigit(*szScan));
10265 
10266 	return _TRUE;
10267 }
10268 
10269 BOOLEAN
GetFractionValueFromString(IN char * szStr,IN OUT u8 * pInteger,IN OUT u8 * pFraction,IN OUT u32 * pu4bMove)10270 GetFractionValueFromString(
10271 	IN		char			*szStr,
10272 	IN OUT	u8				*pInteger,
10273 	IN OUT	u8				*pFraction,
10274 	IN OUT	u32			*pu4bMove
10275 )
10276 {
10277 	char	*szScan = szStr;
10278 
10279 	/* Initialize output. */
10280 	*pu4bMove = 0;
10281 	*pInteger = 0;
10282 	*pFraction = 0;
10283 
10284 	/* Skip leading space. */
10285 	while (*szScan != '\0' &&	(*szScan == ' ' || *szScan == '\t')) {
10286 		++szScan;
10287 		++(*pu4bMove);
10288 	}
10289 
10290 	/* Parse each digit. */
10291 	do {
10292 		(*pInteger) *= 10;
10293 		*pInteger += (*szScan - '0');
10294 
10295 		++szScan;
10296 		++(*pu4bMove);
10297 
10298 		if (*szScan == '.') {
10299 			++szScan;
10300 			++(*pu4bMove);
10301 
10302 			if (*szScan < '0' || *szScan > '9')
10303 				return _FALSE;
10304 			else {
10305 				*pFraction = *szScan - '0';
10306 				++szScan;
10307 				++(*pu4bMove);
10308 				return _TRUE;
10309 			}
10310 		}
10311 	} while (*szScan >= '0' && *szScan <= '9');
10312 
10313 	return _TRUE;
10314 }
10315 
10316 /*
10317  *	Description:
10318  * Return TRUE if szStr is comment out with leading " */ /* ".
10319  *   */
10320 BOOLEAN
IsCommentString(IN char * szStr)10321 IsCommentString(
10322 	IN		char			*szStr
10323 )
10324 {
10325 	if (*szStr == '/' && *(szStr + 1) == '/')
10326 		return _TRUE;
10327 	else
10328 		return _FALSE;
10329 }
10330 
10331 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(IN char * Str,IN OUT u8 * pInt)10332 GetU1ByteIntegerFromStringInDecimal(
10333 	IN		char	*Str,
10334 	IN OUT	u8		*pInt
10335 )
10336 {
10337 	u16 i = 0;
10338 	*pInt = 0;
10339 
10340 	while (Str[i] != '\0') {
10341 		if (Str[i] >= '0' && Str[i] <= '9') {
10342 			*pInt *= 10;
10343 			*pInt += (Str[i] - '0');
10344 		} else
10345 			return _FALSE;
10346 		++i;
10347 	}
10348 
10349 	return _TRUE;
10350 }
10351 
10352 /* <20121004, Kordan> For example,
10353  * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
10354  * If RightQualifier does not exist, it will hang on in the while loop */
10355 BOOLEAN
ParseQualifiedString(IN char * In,IN OUT u32 * Start,OUT char * Out,IN char LeftQualifier,IN char RightQualifier)10356 ParseQualifiedString(
10357 	IN		char	*In,
10358 	IN OUT	u32	*Start,
10359 	OUT		char	*Out,
10360 	IN		char		LeftQualifier,
10361 	IN		char		RightQualifier
10362 )
10363 {
10364 	u32	i = 0, j = 0;
10365 	char	c = In[(*Start)++];
10366 
10367 	if (c != LeftQualifier)
10368 		return _FALSE;
10369 
10370 	i = (*Start);
10371 	c = In[(*Start)++];
10372 	while (c != RightQualifier && c != '\0')
10373 		c = In[(*Start)++];
10374 
10375 	if (c == '\0')
10376 		return _FALSE;
10377 
10378 	j = (*Start) - 2;
10379 	strncpy((char *)Out, (const char *)(In + i), j - i + 1);
10380 
10381 	return _TRUE;
10382 }
10383 
10384 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)10385 isAllSpaceOrTab(
10386 	u8	*data,
10387 	u8	size
10388 )
10389 {
10390 	u8	cnt = 0, NumOfSpaceAndTab = 0;
10391 
10392 	while (size > cnt) {
10393 		if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
10394 			++NumOfSpaceAndTab;
10395 
10396 		++cnt;
10397 	}
10398 
10399 	return size == NumOfSpaceAndTab;
10400 }
10401 
10402 
rtw_hal_check_rxfifo_full(_adapter * adapter)10403 void rtw_hal_check_rxfifo_full(_adapter *adapter)
10404 {
10405 	struct dvobj_priv *psdpriv = adapter->dvobj;
10406 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
10407 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
10408 	struct registry_priv *regsty = &adapter->registrypriv;
10409 	int save_cnt = _FALSE;
10410 
10411 	if (regsty->check_hw_status == 1) {
10412 		/* switch counter to RX fifo */
10413 		if (IS_8188E(pHalData->version_id) ||
10414 		    IS_8188F(pHalData->version_id) ||
10415 		    IS_8812_SERIES(pHalData->version_id) ||
10416 		    IS_8821_SERIES(pHalData->version_id) ||
10417 		    IS_8723B_SERIES(pHalData->version_id) ||
10418 		    IS_8192E(pHalData->version_id) ||
10419 		    IS_8703B_SERIES(pHalData->version_id) ||
10420 		    IS_8723D_SERIES(pHalData->version_id)) {
10421 			rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
10422 			save_cnt = _TRUE;
10423 		} else {
10424 			/* todo: other chips */
10425 		}
10426 
10427 
10428 		if (save_cnt) {
10429 			pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
10430 			pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
10431 			pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
10432 		} else {
10433 			/* special value to indicate no implementation */
10434 			pdbgpriv->dbg_rx_fifo_last_overflow = 1;
10435 			pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
10436 			pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
10437 		}
10438 	}
10439 }
10440 
linked_info_dump(_adapter * padapter,u8 benable)10441 void linked_info_dump(_adapter *padapter, u8 benable)
10442 {
10443 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
10444 
10445 	if (padapter->bLinkInfoDump == benable)
10446 		return;
10447 
10448 	RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
10449 
10450 	if (benable) {
10451 #ifdef CONFIG_LPS
10452 		pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
10453 		rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
10454 #endif
10455 
10456 #ifdef CONFIG_IPS
10457 		pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
10458 		rtw_pm_set_ips(padapter, IPS_NONE);
10459 #endif
10460 	} else {
10461 #ifdef CONFIG_IPS
10462 		rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
10463 #endif /* CONFIG_IPS */
10464 
10465 #ifdef CONFIG_LPS
10466 		rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
10467 #endif /* CONFIG_LPS */
10468 	}
10469 	padapter->bLinkInfoDump = benable ;
10470 }
10471 
10472 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)10473 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
10474 {
10475 	u8 isCCKrate, rf_path;
10476 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
10477 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
10478 	RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
10479 		HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
10480 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
10481 
10482 	if (isCCKrate)
10483 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
10484 
10485 	for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
10486 		RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
10487 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
10488 
10489 		if (!isCCKrate) {
10490 			RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
10491 				psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
10492 		}
10493 	}
10494 }
10495 
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)10496 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
10497 {
10498 	u8 isCCKrate, rf_path;
10499 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
10500 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
10501 	_RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
10502 	_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);
10503 
10504 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
10505 
10506 	if (isCCKrate)
10507 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
10508 
10509 	for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
10510 		_RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
10511 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
10512 
10513 		if (!isCCKrate)
10514 			_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]);
10515 		else
10516 			_RTW_PRINT_SEL(sel , "\n");
10517 
10518 	}
10519 }
10520 #endif
10521 
10522 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)10523 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
10524 {
10525 	_irqL irqL;
10526 	u8 isCCKrate, rf_path;
10527 	struct recv_priv *precvpriv = &(padapter->recvpriv);
10528 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
10529 	struct sta_priv *pstapriv = &padapter->stapriv;
10530 	struct sta_info *psta;
10531 	struct sta_recv_dframe_info *psta_dframe_info;
10532 	int i;
10533 	_list	*plist, *phead;
10534 	char *BW;
10535 	u8 bc_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
10536 	u8 null_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
10537 
10538 	if (precvpriv->store_law_data_flag) {
10539 
10540 		_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
10541 
10542 		for (i = 0; i < NUM_STA; i++) {
10543 			phead = &(pstapriv->sta_hash[i]);
10544 			plist = get_next(phead);
10545 
10546 			while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
10547 
10548 				psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
10549 				plist = get_next(plist);
10550 
10551 				if (psta) {
10552 					psta_dframe_info = &psta->sta_dframe_info;
10553 					if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, 6)  !=   _TRUE)
10554 					    && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, 6)  !=  _TRUE)
10555 					    && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), 6)  !=  _TRUE)) {
10556 
10557 
10558 						isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
10559 
10560 						switch (psta_dframe_info->sta_bw_mode) {
10561 
10562 						case CHANNEL_WIDTH_20:
10563 							BW = "20M";
10564 							break;
10565 
10566 						case CHANNEL_WIDTH_40:
10567 							BW = "40M";
10568 							break;
10569 
10570 						case CHANNEL_WIDTH_80:
10571 							BW = "80M";
10572 							break;
10573 
10574 						case CHANNEL_WIDTH_160:
10575 							BW = "160M";
10576 							break;
10577 
10578 						default:
10579 							BW = "";
10580 							break;
10581 						}
10582 
10583 						RTW_PRINT_SEL(sel, "==============================\n");
10584 						_RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
10585 						_RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", BW, psta_dframe_info->sta_sgi);
10586 						_RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
10587 
10588 						for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
10589 
10590 							if (!isCCKrate) {
10591 
10592 								_RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
10593 								_RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
10594 
10595 							} else
10596 
10597 								_RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
10598 						}
10599 					}
10600 				}
10601 			}
10602 		}
10603 		_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
10604 	}
10605 }
10606 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)10607 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
10608 {
10609 	u8 isCCKrate, rf_path , dframe_type;
10610 	u8 *ptr;
10611 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
10612 #ifdef DBG_RX_DFRAME_RAW_DATA
10613 	struct sta_recv_dframe_info *psta_dframe_info;
10614 #endif
10615 	struct recv_priv *precvpriv = &(padapter->recvpriv);
10616 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
10617 	struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
10618 	struct sta_info *psta = prframe->u.hdr.psta;
10619 	struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
10620 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
10621 	psample_pkt_rssi->data_rate = pattrib->data_rate;
10622 	ptr = prframe->u.hdr.rx_data;
10623 	dframe_type = GetFrameType(ptr);
10624 	/*RTW_INFO("=>%s\n", __FUNCTION__);*/
10625 
10626 
10627 	if (precvpriv->store_law_data_flag) {
10628 		isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
10629 
10630 		psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
10631 		psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
10632 
10633 		for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
10634 			psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
10635 			psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
10636 			if (!isCCKrate) {
10637 				psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
10638 				psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
10639 			}
10640 		}
10641 #ifdef DBG_RX_DFRAME_RAW_DATA
10642 		if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
10643 
10644 			/*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
10645 			if (psta) {
10646 				psta_dframe_info = &psta->sta_dframe_info;
10647 				/*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
10648 					__FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
10649 				if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
10650 					psta_dframe_info->sta_data_rate = pattrib->data_rate;
10651 					psta_dframe_info->sta_sgi = pattrib->sgi;
10652 					psta_dframe_info->sta_bw_mode = pattrib->bw;
10653 					for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
10654 
10655 						psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
10656 
10657 						if (!isCCKrate) {
10658 							psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
10659 							psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
10660 						}
10661 					}
10662 				}
10663 			}
10664 		}
10665 #endif
10666 	}
10667 
10668 }
10669 
10670 
check_phy_efuse_tx_power_info_valid(PADAPTER padapter)10671 int check_phy_efuse_tx_power_info_valid(PADAPTER padapter)
10672 {
10673 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
10674 	u8 *pContent = pHalData->efuse_eeprom_data;
10675 	int index = 0;
10676 	u16 tx_index_offset = 0x0000;
10677 
10678 	switch (rtw_get_chip_type(padapter)) {
10679 	case RTL8723B:
10680 		tx_index_offset = EEPROM_TX_PWR_INX_8723B;
10681 		break;
10682 	case RTL8703B:
10683 		tx_index_offset = EEPROM_TX_PWR_INX_8703B;
10684 		break;
10685 	case RTL8723D:
10686 		tx_index_offset = EEPROM_TX_PWR_INX_8723D;
10687 		break;
10688 	case RTL8188E:
10689 		tx_index_offset = EEPROM_TX_PWR_INX_88E;
10690 		break;
10691 	case RTL8188F:
10692 		tx_index_offset = EEPROM_TX_PWR_INX_8188F;
10693 		break;
10694 	case RTL8192E:
10695 		tx_index_offset = EEPROM_TX_PWR_INX_8192E;
10696 		break;
10697 	case RTL8821:
10698 		tx_index_offset = EEPROM_TX_PWR_INX_8821;
10699 		break;
10700 	case RTL8812:
10701 		tx_index_offset = EEPROM_TX_PWR_INX_8812;
10702 		break;
10703 	case RTL8814A:
10704 		tx_index_offset = EEPROM_TX_PWR_INX_8814;
10705 		break;
10706 	case RTL8822B:
10707 		tx_index_offset = EEPROM_TX_PWR_INX_8822B;
10708 		break;
10709 	case RTL8821C:
10710 		tx_index_offset = EEPROM_TX_PWR_INX_8821C;
10711 		break;
10712 	default:
10713 		tx_index_offset = 0x0010;
10714 		break;
10715 	}
10716 
10717 	/* TODO: chacking length by ICs */
10718 	for (index = 0 ; index < 11 ; index++) {
10719 		if (pContent[tx_index_offset + index] == 0xFF)
10720 			return _FALSE;
10721 	}
10722 	return _TRUE;
10723 }
10724 
hal_efuse_macaddr_offset(_adapter * adapter)10725 int hal_efuse_macaddr_offset(_adapter *adapter)
10726 {
10727 	u8 interface_type = 0;
10728 	int addr_offset = -1;
10729 
10730 	interface_type = rtw_get_intf_type(adapter);
10731 
10732 	switch (rtw_get_chip_type(adapter)) {
10733 #ifdef CONFIG_RTL8723B
10734 	case RTL8723B:
10735 		if (interface_type == RTW_USB)
10736 			addr_offset = EEPROM_MAC_ADDR_8723BU;
10737 		else if (interface_type == RTW_SDIO)
10738 			addr_offset = EEPROM_MAC_ADDR_8723BS;
10739 		else if (interface_type == RTW_PCIE)
10740 			addr_offset = EEPROM_MAC_ADDR_8723BE;
10741 		break;
10742 #endif
10743 #ifdef CONFIG_RTL8703B
10744 	case RTL8703B:
10745 		if (interface_type == RTW_USB)
10746 			addr_offset = EEPROM_MAC_ADDR_8703BU;
10747 		else if (interface_type == RTW_SDIO)
10748 			addr_offset = EEPROM_MAC_ADDR_8703BS;
10749 		break;
10750 #endif
10751 #ifdef CONFIG_RTL8723D
10752 	case RTL8723D:
10753 		if (interface_type == RTW_USB)
10754 			addr_offset = EEPROM_MAC_ADDR_8723DU;
10755 		else if (interface_type == RTW_SDIO)
10756 			addr_offset = EEPROM_MAC_ADDR_8723DS;
10757 		else if (interface_type == RTW_PCIE)
10758 			addr_offset = EEPROM_MAC_ADDR_8723DE;
10759 		break;
10760 #endif
10761 
10762 #ifdef CONFIG_RTL8188E
10763 	case RTL8188E:
10764 		if (interface_type == RTW_USB)
10765 			addr_offset = EEPROM_MAC_ADDR_88EU;
10766 		else if (interface_type == RTW_SDIO)
10767 			addr_offset = EEPROM_MAC_ADDR_88ES;
10768 		else if (interface_type == RTW_PCIE)
10769 			addr_offset = EEPROM_MAC_ADDR_88EE;
10770 		break;
10771 #endif
10772 #ifdef CONFIG_RTL8188F
10773 	case RTL8188F:
10774 		if (interface_type == RTW_USB)
10775 			addr_offset = EEPROM_MAC_ADDR_8188FU;
10776 		else if (interface_type == RTW_SDIO)
10777 			addr_offset = EEPROM_MAC_ADDR_8188FS;
10778 		break;
10779 #endif
10780 #ifdef CONFIG_RTL8812A
10781 	case RTL8812:
10782 		if (interface_type == RTW_USB)
10783 			addr_offset = EEPROM_MAC_ADDR_8812AU;
10784 		else if (interface_type == RTW_PCIE)
10785 			addr_offset = EEPROM_MAC_ADDR_8812AE;
10786 		break;
10787 #endif
10788 #ifdef CONFIG_RTL8821A
10789 	case RTL8821:
10790 		if (interface_type == RTW_USB)
10791 			addr_offset = EEPROM_MAC_ADDR_8821AU;
10792 		else if (interface_type == RTW_SDIO)
10793 			addr_offset = EEPROM_MAC_ADDR_8821AS;
10794 		else if (interface_type == RTW_PCIE)
10795 			addr_offset = EEPROM_MAC_ADDR_8821AE;
10796 		break;
10797 #endif
10798 #ifdef CONFIG_RTL8192E
10799 	case RTL8192E:
10800 		if (interface_type == RTW_USB)
10801 			addr_offset = EEPROM_MAC_ADDR_8192EU;
10802 		else if (interface_type == RTW_SDIO)
10803 			addr_offset = EEPROM_MAC_ADDR_8192ES;
10804 		else if (interface_type == RTW_PCIE)
10805 			addr_offset = EEPROM_MAC_ADDR_8192EE;
10806 		break;
10807 #endif
10808 #ifdef CONFIG_RTL8814A
10809 	case RTL8814A:
10810 		if (interface_type == RTW_USB)
10811 			addr_offset = EEPROM_MAC_ADDR_8814AU;
10812 		else if (interface_type == RTW_PCIE)
10813 			addr_offset = EEPROM_MAC_ADDR_8814AE;
10814 		break;
10815 #endif
10816 
10817 #ifdef CONFIG_RTL8822B
10818 	case RTL8822B:
10819 		if (interface_type == RTW_USB)
10820 			addr_offset = EEPROM_MAC_ADDR_8822BU;
10821 		else if (interface_type == RTW_SDIO)
10822 			addr_offset = EEPROM_MAC_ADDR_8822BS;
10823 		else if (interface_type == RTW_PCIE)
10824 			addr_offset = EEPROM_MAC_ADDR_8822BE;
10825 		break;
10826 #endif /* CONFIG_RTL8822B */
10827 
10828 #ifdef CONFIG_RTL8821C
10829 	case RTL8821C:
10830 		if (interface_type == RTW_USB)
10831 			addr_offset = EEPROM_MAC_ADDR_8821CU;
10832 		else if (interface_type == RTW_SDIO)
10833 			addr_offset = EEPROM_MAC_ADDR_8821CS;
10834 		else if (interface_type == RTW_PCIE)
10835 			addr_offset = EEPROM_MAC_ADDR_8821CE;
10836 		break;
10837 #endif /* CONFIG_RTL8821C */
10838 	}
10839 
10840 	if (addr_offset == -1) {
10841 		RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
10842 			, __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
10843 	}
10844 
10845 	return addr_offset;
10846 }
10847 
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)10848 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
10849 {
10850 	int ret = _FAIL;
10851 	int addr_offset;
10852 
10853 	addr_offset = hal_efuse_macaddr_offset(padapter);
10854 	if (addr_offset == -1)
10855 		goto exit;
10856 
10857 	ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
10858 
10859 exit:
10860 	return ret;
10861 }
10862 
rtw_dump_cur_efuse(PADAPTER padapter)10863 void rtw_dump_cur_efuse(PADAPTER padapter)
10864 {
10865 	int i =0;
10866 	int mapsize =0;
10867 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
10868 
10869 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
10870 
10871 	if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
10872 		RTW_ERR("wrong map size %d\n", mapsize);
10873 		return;
10874 	}
10875 
10876 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
10877 		RTW_INFO("EFUSE FILE\n");
10878 	else
10879 		RTW_INFO("HW EFUSE\n");
10880 
10881 #ifdef CONFIG_RTW_DEBUG
10882 	for (i = 0; i < mapsize; i++) {
10883 		if (i % 16 == 0)
10884 			RTW_PRINT_SEL(RTW_DBGDUMP, "0x%03x: ", i);
10885 
10886 		_RTW_PRINT_SEL(RTW_DBGDUMP, "%02X%s"
10887 			, hal_data->efuse_eeprom_data[i]
10888 			, ((i + 1) % 16 == 0) ? "\n" : (((i + 1) % 8 == 0) ? "    " : " ")
10889 		);
10890 	}
10891 	_RTW_PRINT_SEL(RTW_DBGDUMP, "\n");
10892 #endif
10893 }
10894 
10895 
10896 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)10897 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
10898 {
10899 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
10900 	u32 ret = _FALSE;
10901 	u32 maplen = 0;
10902 
10903 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
10904 
10905 	if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
10906 		RTW_ERR("eFuse length error :%d\n", maplen);
10907 		return _FALSE;
10908 	}
10909 
10910 	ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
10911 
10912 	hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
10913 
10914 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
10915 		rtw_dump_cur_efuse(padapter);
10916 
10917 	return ret;
10918 }
10919 
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)10920 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
10921 {
10922 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
10923 	u32 ret = _FAIL;
10924 
10925 	if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
10926 		&& rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
10927 	) {
10928 		hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
10929 		ret = _SUCCESS;
10930 	} else
10931 		hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
10932 
10933 	return ret;
10934 }
10935 #endif /* CONFIG_EFUSE_CONFIG_FILE */
10936 
hal_config_macaddr(_adapter * adapter,bool autoload_fail)10937 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
10938 {
10939 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10940 	u8 addr[ETH_ALEN];
10941 	int addr_offset = hal_efuse_macaddr_offset(adapter);
10942 	u8 *hw_addr = NULL;
10943 	int ret = _SUCCESS;
10944 
10945 	if (autoload_fail)
10946 		goto bypass_hw_pg;
10947 
10948 	if (addr_offset != -1)
10949 		hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
10950 
10951 #ifdef CONFIG_EFUSE_CONFIG_FILE
10952 	/* if the hw_addr is written by efuse file, set to NULL */
10953 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
10954 		hw_addr = NULL;
10955 #endif
10956 
10957 	if (!hw_addr) {
10958 		/* try getting hw pg data */
10959 		if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
10960 			hw_addr = addr;
10961 	}
10962 
10963 	/* check hw pg data */
10964 	if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
10965 		_rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
10966 		goto exit;
10967 	}
10968 
10969 bypass_hw_pg:
10970 
10971 #ifdef CONFIG_EFUSE_CONFIG_FILE
10972 	/* check wifi mac file */
10973 	if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
10974 		_rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
10975 		goto exit;
10976 	}
10977 #endif
10978 
10979 	_rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
10980 	ret = _FAIL;
10981 
10982 exit:
10983 	return ret;
10984 }
10985 
10986 #ifdef CONFIG_RF_POWER_TRIM
10987 u32 Array_kfreemap[] = {
10988 	0x08, 0xe,
10989 	0x06, 0xc,
10990 	0x04, 0xa,
10991 	0x02, 0x8,
10992 	0x00, 0x6,
10993 	0x03, 0x4,
10994 	0x05, 0x2,
10995 	0x07, 0x0,
10996 	0x09, 0x0,
10997 	0x0c, 0x0,
10998 };
10999 
rtw_bb_rf_gain_offset(_adapter * padapter)11000 void rtw_bb_rf_gain_offset(_adapter *padapter)
11001 {
11002 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
11003 	struct registry_priv  *registry_par = &padapter->registrypriv;
11004 	struct kfree_data_t *kfree_data = &pHalData->kfree_data;
11005 	u8		value = pHalData->EEPROMRFGainOffset;
11006 	u8		tmp = 0x3e;
11007 	u32		res, i = 0;
11008 	u4Byte		ArrayLen	= sizeof(Array_kfreemap) / sizeof(u32);
11009 	pu4Byte		Array	= Array_kfreemap;
11010 	u4Byte		v1 = 0, v2 = 0, GainValue = 0, target = 0;
11011 
11012 	if (registry_par->RegPwrTrimEnable == 2) {
11013 		RTW_INFO("Registry kfree default force disable.\n");
11014 		return;
11015 	}
11016 
11017 #if defined(CONFIG_RTL8723B)
11018 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
11019 		RTW_INFO("Offset RF Gain.\n");
11020 		RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
11021 
11022 		if (pHalData->EEPROMRFGainVal != 0xff) {
11023 
11024 			if (pHalData->ant_path == RF_PATH_A)
11025 				GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
11026 
11027 			else
11028 				GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
11029 			RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
11030 
11031 			for (i = 0; i < ArrayLen; i += 2) {
11032 				/* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
11033 				v1 = Array[i];
11034 				v2 = Array[i + 1];
11035 				if (v1 == GainValue) {
11036 					RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
11037 					target = v2;
11038 					break;
11039 				}
11040 			}
11041 			RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
11042 
11043 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
11044 			RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
11045 			phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
11046 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
11047 
11048 			RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
11049 
11050 		} else
11051 
11052 			RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x	!= 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
11053 	} else
11054 		RTW_INFO("Using the default RF gain.\n");
11055 
11056 #elif defined(CONFIG_RTL8188E)
11057 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
11058 		RTW_INFO("8188ES Offset RF Gain.\n");
11059 		RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
11060 			 pHalData->EEPROMRFGainVal);
11061 
11062 		if (pHalData->EEPROMRFGainVal != 0xff) {
11063 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
11064 					 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
11065 
11066 			RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
11067 			res &= 0xfff87fff;
11068 
11069 			res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
11070 			RTW_INFO("Offset RF Gain. res=0x%x\n", res);
11071 
11072 			rtw_hal_write_rfreg(padapter, RF_PATH_A,
11073 					    REG_RF_BB_GAIN_OFFSET,
11074 					    RF_GAIN_OFFSET_MASK, res);
11075 		} else {
11076 			RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
11077 				 pHalData->EEPROMRFGainVal);
11078 		}
11079 	} else
11080 		RTW_INFO("Using the default RF gain.\n");
11081 #else
11082 	/* TODO: call this when channel switch */
11083 	if (kfree_data->flag & KFREE_FLAG_ON)
11084 		rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
11085 #endif
11086 
11087 }
11088 #endif /*CONFIG_RF_POWER_TRIM */
11089 
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)11090 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
11091 {
11092 #ifdef CONFIG_RF_POWER_TRIM
11093 	int i, j;
11094 
11095 	for (i = 0; i < BB_GAIN_NUM; i++)
11096 		for (j = 0; j < RF_PATH_MAX; j++)
11097 			if (data->bb_gain[i][j] != 0)
11098 				return 0;
11099 #endif
11100 	return 1;
11101 }
11102 
11103 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)11104 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
11105 {
11106 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
11107 	if (cur_wireless_mode < WIRELESS_11_24N
11108 	    && cur_wireless_mode > 0) { /* ABG mode */
11109 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
11110 		u32 remainder = 0;
11111 		u8 quotient = 0;
11112 
11113 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
11114 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
11115 
11116 		if (quotient > 5) {
11117 			pHalData->rxagg_usb_size = 0x6;
11118 			pHalData->rxagg_usb_timeout = 0x10;
11119 		} else {
11120 			if (remainder >= 2048) {
11121 				pHalData->rxagg_usb_size = quotient;
11122 				pHalData->rxagg_usb_timeout = 0x10;
11123 			} else {
11124 				pHalData->rxagg_usb_size = (quotient - 1);
11125 				pHalData->rxagg_usb_timeout = 0x10;
11126 			}
11127 		}
11128 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
11129 		if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
11130 			pHalData->rxagg_usb_size = 0x6;
11131 			pHalData->rxagg_usb_timeout = 0x10;
11132 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
11133 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
11134 		}
11135 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
11136 
11137 	} else if (cur_wireless_mode >= WIRELESS_11_24N
11138 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
11139 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
11140 		u32 remainder = 0;
11141 		u8 quotient = 0;
11142 
11143 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
11144 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
11145 
11146 		if (quotient > 5) {
11147 			pHalData->rxagg_usb_size = 0x5;
11148 			pHalData->rxagg_usb_timeout = 0x20;
11149 		} else {
11150 			if (remainder >= 2048) {
11151 				pHalData->rxagg_usb_size = quotient;
11152 				pHalData->rxagg_usb_timeout = 0x10;
11153 			} else {
11154 				pHalData->rxagg_usb_size = (quotient - 1);
11155 				pHalData->rxagg_usb_timeout = 0x10;
11156 			}
11157 		}
11158 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
11159 		if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
11160 			pHalData->rxagg_usb_size = 0x5;
11161 			pHalData->rxagg_usb_timeout = 0x20;
11162 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
11163 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
11164 		}
11165 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
11166 
11167 	} else {
11168 		/* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
11169 	}
11170 }
11171 
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)11172 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
11173 {
11174 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
11175 
11176 	if (cur_wireless_mode < WIRELESS_11_24N
11177 	    && cur_wireless_mode > 0) { /* ABG mode */
11178 		if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
11179 		    || 0x10 != pHalData->rxagg_usb_timeout) {
11180 			pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
11181 			pHalData->rxagg_usb_timeout = 0x10;
11182 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
11183 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
11184 		}
11185 	} else if (cur_wireless_mode >= WIRELESS_11_24N
11186 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
11187 		if (UsbDmaSize != pHalData->rxagg_usb_size
11188 		    || 0x20 != pHalData->rxagg_usb_timeout) {
11189 			pHalData->rxagg_usb_size = UsbDmaSize;
11190 			pHalData->rxagg_usb_timeout = 0x20;
11191 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
11192 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
11193 		}
11194 	} else {
11195 		/* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
11196 	}
11197 }
11198 
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)11199 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
11200 {
11201 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
11202 	rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
11203 	return;
11204 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
11205 
11206 	rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
11207 }
11208 #endif /* CONFIG_USB_RX_AGGREGATION */
11209 
11210 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)11211 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
11212 {
11213 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
11214 	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
11215 	struct registry_priv *registry_par = &padapter->registrypriv;
11216 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
11217 	u8 cur_wireless_mode = WIRELESS_INVALID;
11218 
11219 #ifdef CONFIG_USB_RX_AGGREGATION
11220 	if (!registry_par->dynamic_agg_enable)
11221 		return;
11222 
11223 #ifdef RTW_HALMAC
11224 	if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter))
11225 		rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
11226 #else /* !RTW_HALMAC */
11227 	if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
11228 		/* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
11229 		if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
11230 			if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
11231 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
11232 			else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
11233 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
11234 			else
11235 				rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
11236 
11237 			/* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
11238 		}
11239 	} else if (IS_HARDWARE_TYPE_8812(padapter)) {
11240 #ifdef CONFIG_CONCURRENT_MODE
11241 		u8 i;
11242 		_adapter *iface;
11243 		u8 bassocaed = _FALSE;
11244 		struct mlme_ext_priv *mlmeext;
11245 
11246 		for (i = 0; i < pdvobjpriv->iface_nums; i++) {
11247 			iface = pdvobjpriv->padapters[i];
11248 			mlmeext = &iface->mlmeextpriv;
11249 			if (rtw_linked_check(iface) == _TRUE) {
11250 				if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
11251 					cur_wireless_mode = mlmeext->cur_wireless_mode;
11252 				bassocaed = _TRUE;
11253 			}
11254 		}
11255 		if (bassocaed)
11256 #endif
11257 			rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
11258 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
11259 	} else {
11260 		rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
11261 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
11262 	}
11263 #endif /* RTW_HALMAC */
11264 #endif /* CONFIG_USB_RX_AGGREGATION */
11265 
11266 }
11267 
11268 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)11269 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
11270 {
11271 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11272 	u8 chk_rst = _SUCCESS;
11273 
11274 	if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
11275 		return chk_rst;
11276 
11277 	/* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
11278 	/*	return chk_rst; */
11279 
11280 	if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
11281 	    && (pre_qsel != next_qsel)) {
11282 		/* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
11283 		/*	pre_qsel,next_qsel); */
11284 		chk_rst = _FAIL;
11285 	}
11286 	return chk_rst;
11287 }
11288 
11289 /*
11290  * Description:
11291  * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
11292  * contant.
11293  *
11294  * Input:
11295  * adapter: adapter pointer.
11296  * page_num: The max. page number that user want to dump.
11297  * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
11298  */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)11299 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
11300 {
11301 
11302 	int i;
11303 	u8 val = 0;
11304 	u8 base = 0;
11305 	u32 addr = 0;
11306 	u32 count = (page_size / 8);
11307 
11308 	if (page_num <= 0) {
11309 		RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
11310 		return;
11311 	}
11312 
11313 	if (page_size < 128 || page_size > 512) {
11314 		RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
11315 		return;
11316 	}
11317 
11318 	RTW_INFO("+%s+\n", __func__);
11319 	val = rtw_read8(padapter, 0x106);
11320 	rtw_write8(padapter, 0x106, 0x69);
11321 	RTW_INFO("0x106: 0x%02x\n", val);
11322 	base = rtw_read8(padapter, 0x209);
11323 	RTW_INFO("0x209: 0x%02x\n", base);
11324 
11325 	addr = ((base)*page_size) / 8;
11326 	for (i = 0 ; i < page_num * count ; i += 2) {
11327 		rtw_write32(padapter, 0x140, addr + i);
11328 		printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
11329 		rtw_write32(padapter, 0x140, addr + i + 1);
11330 		printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
11331 	}
11332 }
11333 
11334 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)11335 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
11336 {
11337 	u8 value = 0;
11338 	u8 direction = 0;
11339 	u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
11340 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
11341 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
11342 	u8 gpio_num_to_set = gpio_num;
11343 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11344 
11345 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
11346 		return value;
11347 
11348 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
11349 
11350 	RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
11351 	LeaveAllPowerSaveModeDirect(adapter);
11352 
11353 	if (gpio_num > 7) {
11354 		gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
11355 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
11356 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
11357 		gpio_num_to_set = gpio_num - 8;
11358 	}
11359 
11360 	/* Read GPIO Direction */
11361 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
11362 
11363 	/* According the direction to read register value */
11364 	if (direction)
11365 		value =  (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
11366 	else
11367 		value =  (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
11368 
11369 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
11370 	RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
11371 
11372 	return value;
11373 }
11374 
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)11375 int  rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
11376 {
11377 	u8 direction = 0;
11378 	u8 res = -1;
11379 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
11380 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
11381 	u8 gpio_num_to_set = gpio_num;
11382 
11383 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
11384 		return -1;
11385 
11386 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
11387 
11388 	LeaveAllPowerSaveModeDirect(adapter);
11389 
11390 	if (gpio_num > 7) {
11391 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
11392 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
11393 		gpio_num_to_set = gpio_num - 8;
11394 	}
11395 
11396 	/* Read GPIO direction */
11397 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
11398 
11399 	/* If GPIO is output direction, setting value. */
11400 	if (direction) {
11401 		if (isHigh)
11402 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
11403 		else
11404 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
11405 
11406 		RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
11407 		res = 0;
11408 	} else {
11409 		RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
11410 		res = -1;
11411 	}
11412 
11413 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
11414 	return res;
11415 }
11416 
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)11417 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
11418 {
11419 	u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
11420 	u8 gpio_num_to_set = gpio_num;
11421 
11422 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
11423 		return -1;
11424 
11425 	RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
11426 
11427 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
11428 
11429 	LeaveAllPowerSaveModeDirect(adapter);
11430 
11431 	rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
11432 
11433 	if (gpio_num > 7) {
11434 		gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
11435 		gpio_num_to_set = gpio_num - 8;
11436 	}
11437 
11438 	if (isOutput)
11439 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
11440 	else
11441 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
11442 
11443 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
11444 
11445 	return 0;
11446 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))11447 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
11448 {
11449 	u8 value;
11450 	u8 direction;
11451 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
11452 
11453 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
11454 		if (gpio_num > 7 || gpio_num < 4) {
11455 			RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
11456 			return -1;
11457 		}
11458 	}
11459 
11460 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
11461 
11462 	LeaveAllPowerSaveModeDirect(adapter);
11463 
11464 	/* Read GPIO direction */
11465 	direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
11466 	if (direction) {
11467 		RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
11468 		return -1;
11469 	}
11470 
11471 	/* Config GPIO Mode */
11472 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
11473 
11474 	/* Register GPIO interrupt handler*/
11475 	adapter->gpiointpriv.callback[gpio_num] = callback;
11476 
11477 	/* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
11478 	value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
11479 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
11480 	rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
11481 
11482 	/* Enable GPIO interrupt */
11483 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
11484 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
11485 
11486 	rtw_hal_update_hisr_hsisr_ind(adapter, 1);
11487 
11488 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
11489 
11490 	return 0;
11491 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)11492 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
11493 {
11494 	u8 value;
11495 	u8 direction;
11496 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
11497 
11498 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
11499 		if (gpio_num > 7 || gpio_num < 4) {
11500 			RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
11501 			return -1;
11502 		}
11503 	}
11504 
11505 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
11506 
11507 	LeaveAllPowerSaveModeDirect(adapter);
11508 
11509 	/* Config GPIO Mode */
11510 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
11511 
11512 	/* Unregister GPIO interrupt handler*/
11513 	adapter->gpiointpriv.callback[gpio_num] = NULL;
11514 
11515 	/* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
11516 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
11517 	rtw_write8(adapter, REG_GPIO_INTM, 0x00);
11518 
11519 	/* Disable GPIO interrupt */
11520 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
11521 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
11522 
11523 	if (!adapter->gpiointpriv.interrupt_enable_mask)
11524 		rtw_hal_update_hisr_hsisr_ind(adapter, 0);
11525 
11526 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
11527 
11528 	return 0;
11529 }
11530 #endif
11531 
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)11532 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
11533 {
11534 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11535 	u8 i;
11536 
11537 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
11538 		if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
11539 			if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
11540 			    && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
11541 				return i;
11542 		}
11543 	}
11544 
11545 	return -1;
11546 }
11547 
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)11548 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
11549 {
11550 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11551 	s8 res;
11552 	u8 i;
11553 
11554 	/* If it's an existed record, overwrite it */
11555 	res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
11556 	if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
11557 		rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
11558 		return;
11559 	}
11560 
11561 	/* Search for the empty record to use */
11562 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
11563 		if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
11564 			rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
11565 			return;
11566 		}
11567 	}
11568 
11569 	/* Else, overwrite the oldest record */
11570 	for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
11571 		_rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
11572 
11573 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
11574 }
11575 
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)11576 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
11577 {
11578 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
11579 }
11580 
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)11581 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
11582 {
11583 	u32	mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
11584 	u32	mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
11585 	u32	mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
11586 	u32	DropPacket = 0;
11587 
11588 	if (!rx_counter) {
11589 		rtw_warn_on(1);
11590 		return;
11591 	}
11592 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
11593 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
11594 
11595 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
11596 	mac_cck_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	  */
11597 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
11598 	mac_ofdm_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
11599 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
11600 	mac_ht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
11601 	mac_vht_ok	= 0;
11602 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
11603 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
11604 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
11605 		mac_vht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
11606 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
11607 	}
11608 
11609 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
11610 	mac_cck_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
11611 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
11612 	mac_ofdm_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
11613 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
11614 	mac_ht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
11615 	mac_vht_err	= 0;
11616 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
11617 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
11618 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
11619 		mac_vht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
11620 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
11621 	}
11622 
11623 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
11624 	mac_cck_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
11625 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
11626 	mac_ofdm_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
11627 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
11628 	mac_ht_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
11629 
11630 	/* Mac_DropPacket */
11631 	rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
11632 	DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
11633 
11634 	rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
11635 	rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
11636 	rx_counter->rx_cck_fa = mac_cck_fa;
11637 	rx_counter->rx_ofdm_fa = mac_ofdm_fa;
11638 	rx_counter->rx_ht_fa = mac_ht_fa;
11639 	rx_counter->rx_pkt_drop = DropPacket;
11640 }
rtw_reset_mac_rx_counters(_adapter * padapter)11641 void rtw_reset_mac_rx_counters(_adapter *padapter)
11642 {
11643 
11644 	/* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
11645 	if (IS_HARDWARE_TYPE_8703B(padapter) ||
11646 	    IS_HARDWARE_TYPE_8723D(padapter) ||
11647 	    IS_HARDWARE_TYPE_8188F(padapter))
11648 		phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
11649 
11650 	/* reset mac counter */
11651 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
11652 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
11653 }
11654 
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)11655 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
11656 {
11657 	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;
11658 	if (!rx_counter) {
11659 		rtw_warn_on(1);
11660 		return;
11661 	}
11662 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
11663 		cckok	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF);	     /* [13:0] */
11664 		ofdmok	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF);	     /* [13:0] */
11665 		htok		= phy_query_bb_reg(padapter, 0xF10, 0x3FFF);     /* [13:0] */
11666 		vht_ok	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF);     /* [13:0] */
11667 		cckcrc	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16]	 */
11668 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
11669 		htcrc	= phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
11670 		vht_err	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
11671 		CCK_FA	= phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
11672 		OFDM_FA	= phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
11673 	} else {
11674 		cckok	= phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
11675 		ofdmok	= phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
11676 		htok		= phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
11677 		vht_ok	= 0;
11678 		cckcrc	= phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
11679 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
11680 		htcrc	= phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
11681 		vht_err	= 0;
11682 		OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
11683 			phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
11684 			phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
11685 
11686 		CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
11687 	}
11688 
11689 	rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
11690 	rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
11691 	rx_counter->rx_ofdm_fa = OFDM_FA;
11692 	rx_counter->rx_cck_fa = CCK_FA;
11693 
11694 }
11695 
rtw_reset_phy_trx_ok_counters(_adapter * padapter)11696 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
11697 {
11698 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
11699 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
11700 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
11701 	}
11702 }
rtw_reset_phy_rx_counters(_adapter * padapter)11703 void rtw_reset_phy_rx_counters(_adapter *padapter)
11704 {
11705 	/* reset phy counter */
11706 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
11707 		rtw_reset_phy_trx_ok_counters(padapter);
11708 
11709 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset  OFDA FA counter */
11710 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
11711 
11712 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
11713 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
11714 	} else {
11715 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
11716 		rtw_msleep_os(10);
11717 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
11718 
11719 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset  OFDA FA counter */
11720 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset  OFDA FA counter */
11721 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
11722 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
11723 
11724 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
11725 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
11726 	}
11727 }
11728 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)11729 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
11730 {
11731 	struct recv_priv *precvpriv = &padapter->recvpriv;
11732 	if (!rx_counter) {
11733 		rtw_warn_on(1);
11734 		return;
11735 	}
11736 	rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
11737 	rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
11738 	rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
11739 }
rtw_reset_drv_rx_counters(_adapter * padapter)11740 void rtw_reset_drv_rx_counters(_adapter *padapter)
11741 {
11742 	struct recv_priv *precvpriv = &padapter->recvpriv;
11743 	padapter->drv_rx_cnt_ok = 0;
11744 	padapter->drv_rx_cnt_crcerror = 0;
11745 	padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
11746 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)11747 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
11748 {
11749 	u8 initialgain;
11750 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
11751 
11752 	if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
11753 		rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
11754 		RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
11755 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
11756 		/*disable dynamic functions, such as high power, DIG*/
11757 		rtw_phydm_ability_backup(padapter);
11758 		rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
11759 	} else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
11760 		/* turn on phy-dynamic functions */
11761 		rtw_phydm_ability_restore(padapter);
11762 		initialgain = 0xff; /* restore RX GAIN */
11763 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
11764 
11765 	}
11766 }
11767 
rtw_dump_rx_counters(_adapter * padapter)11768 void rtw_dump_rx_counters(_adapter *padapter)
11769 {
11770 	struct dbg_rx_counter rx_counter;
11771 
11772 	if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
11773 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
11774 		rtw_dump_drv_rx_counters(padapter, &rx_counter);
11775 		RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
11776 			rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
11777 		rtw_reset_drv_rx_counters(padapter);
11778 	}
11779 
11780 	if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
11781 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
11782 		rtw_dump_mac_rx_counters(padapter, &rx_counter);
11783 		RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
11784 			 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
11785 			rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
11786 			 rx_counter.rx_pkt_drop);
11787 		rtw_reset_mac_rx_counters(padapter);
11788 	}
11789 
11790 	if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
11791 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
11792 		rtw_dump_phy_rx_counters(padapter, &rx_counter);
11793 		/* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
11794 		/* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
11795 		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,
11796 			 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
11797 		rtw_reset_phy_rx_counters(padapter);
11798 	}
11799 }
11800 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)11801 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
11802 {
11803 	u8 curr_tx_sgi = 0;
11804 	struct ra_sta_info *ra_info;
11805 
11806 	if (!psta)
11807 		return curr_tx_sgi;
11808 
11809 	ra_info = &psta->cmn.ra_info;
11810 	curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
11811 
11812 	return curr_tx_sgi;
11813 }
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)11814 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
11815 {
11816 	u8 rate_id = 0;
11817 	struct ra_sta_info *ra_info;
11818 
11819 	if (!psta)
11820 		return rate_id;
11821 
11822 	ra_info = &psta->cmn.ra_info;
11823 	rate_id = ra_info->curr_tx_rate & 0x7f;
11824 
11825 	return rate_id;
11826 }
11827 
update_IOT_info(_adapter * padapter)11828 void update_IOT_info(_adapter *padapter)
11829 {
11830 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
11831 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11832 
11833 	switch (pmlmeinfo->assoc_AP_vendor) {
11834 	case HT_IOT_PEER_MARVELL:
11835 		pmlmeinfo->turboMode_cts2self = 1;
11836 		pmlmeinfo->turboMode_rtsen = 0;
11837 		break;
11838 
11839 	case HT_IOT_PEER_RALINK:
11840 		pmlmeinfo->turboMode_cts2self = 0;
11841 		pmlmeinfo->turboMode_rtsen = 1;
11842 		break;
11843 	case HT_IOT_PEER_REALTEK:
11844 		/* rtw_write16(padapter, 0x4cc, 0xffff); */
11845 		/* rtw_write16(padapter, 0x546, 0x01c0); */
11846 		break;
11847 	default:
11848 		pmlmeinfo->turboMode_cts2self = 0;
11849 		pmlmeinfo->turboMode_rtsen = 1;
11850 		break;
11851 	}
11852 
11853 }
11854 
11855 /* TODO: merge with phydm, see odm_SetCrystalCap() */
hal_set_crystal_cap(_adapter * adapter,u8 crystal_cap)11856 void hal_set_crystal_cap(_adapter *adapter, u8 crystal_cap)
11857 {
11858 	crystal_cap = crystal_cap & 0x3F;
11859 
11860 	switch (rtw_get_chip_type(adapter)) {
11861 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F)
11862 	case RTL8188E:
11863 	case RTL8188F:
11864 		/* write 0x24[16:11] = 0x24[22:17] = CrystalCap */
11865 		phy_set_bb_reg(adapter, REG_AFE_XTAL_CTRL, 0x007FF800, (crystal_cap | (crystal_cap << 6)));
11866 		break;
11867 #endif
11868 #if defined(CONFIG_RTL8812A)
11869 	case RTL8812:
11870 		/* write 0x2C[30:25] = 0x2C[24:19] = CrystalCap */
11871 		phy_set_bb_reg(adapter, REG_MAC_PHY_CTRL, 0x7FF80000, (crystal_cap | (crystal_cap << 6)));
11872 		break;
11873 #endif
11874 #if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || \
11875 		defined(CONFIG_RTL8723D) || defined(CONFIG_RTL8821A) || \
11876 		defined(CONFIG_RTL8192E)
11877 	case RTL8723B:
11878 	case RTL8703B:
11879 	case RTL8723D:
11880 	case RTL8821:
11881 	case RTL8192E:
11882 		/* write 0x2C[23:18] = 0x2C[17:12] = CrystalCap */
11883 		phy_set_bb_reg(adapter, REG_MAC_PHY_CTRL, 0x00FFF000, (crystal_cap | (crystal_cap << 6)));
11884 		break;
11885 #endif
11886 #if defined(CONFIG_RTL8814A)
11887 	case RTL8814A:
11888 		/* write 0x2C[26:21] = 0x2C[20:15] = CrystalCap*/
11889 		phy_set_bb_reg(adapter, REG_MAC_PHY_CTRL, 0x07FF8000, (crystal_cap | (crystal_cap << 6)));
11890 		break;
11891 #endif
11892 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)
11893 
11894 	case RTL8822B:
11895 	case RTL8821C:
11896 		/* write 0x28[6:1] = 0x24[30:25] = CrystalCap */
11897 		crystal_cap = crystal_cap & 0x3F;
11898 		phy_set_bb_reg(adapter, REG_AFE_XTAL_CTRL, 0x7E000000, crystal_cap);
11899 		phy_set_bb_reg(adapter, REG_AFE_PLL_CTRL, 0x7E, crystal_cap);
11900 		break;
11901 #endif
11902 	default:
11903 		rtw_warn_on(1);
11904 	}
11905 }
11906 
hal_spec_init(_adapter * adapter)11907 int hal_spec_init(_adapter *adapter)
11908 {
11909 	u8 interface_type = 0;
11910 	int ret = _SUCCESS;
11911 
11912 	interface_type = rtw_get_intf_type(adapter);
11913 
11914 	switch (rtw_get_chip_type(adapter)) {
11915 #ifdef CONFIG_RTL8723B
11916 	case RTL8723B:
11917 		init_hal_spec_8723b(adapter);
11918 		break;
11919 #endif
11920 #ifdef CONFIG_RTL8703B
11921 	case RTL8703B:
11922 		init_hal_spec_8703b(adapter);
11923 		break;
11924 #endif
11925 #ifdef CONFIG_RTL8723D
11926 	case RTL8723D:
11927 		init_hal_spec_8723d(adapter);
11928 		break;
11929 #endif
11930 #ifdef CONFIG_RTL8188E
11931 	case RTL8188E:
11932 		init_hal_spec_8188e(adapter);
11933 		break;
11934 #endif
11935 #ifdef CONFIG_RTL8188F
11936 	case RTL8188F:
11937 		init_hal_spec_8188f(adapter);
11938 		break;
11939 #endif
11940 #ifdef CONFIG_RTL8812A
11941 	case RTL8812:
11942 		init_hal_spec_8812a(adapter);
11943 		break;
11944 #endif
11945 #ifdef CONFIG_RTL8821A
11946 	case RTL8821:
11947 		init_hal_spec_8821a(adapter);
11948 		break;
11949 #endif
11950 #ifdef CONFIG_RTL8192E
11951 	case RTL8192E:
11952 		init_hal_spec_8192e(adapter);
11953 		break;
11954 #endif
11955 #ifdef CONFIG_RTL8814A
11956 	case RTL8814A:
11957 		init_hal_spec_8814a(adapter);
11958 		break;
11959 #endif
11960 #ifdef CONFIG_RTL8822B
11961 	case RTL8822B:
11962 		rtl8822b_init_hal_spec(adapter);
11963 		break;
11964 #endif
11965 #ifdef CONFIG_RTL8821C
11966 	case RTL8821C:
11967 		init_hal_spec_rtl8821c(adapter);
11968 		break;
11969 #endif
11970 	default:
11971 		RTW_ERR("%s: unknown chip_type:%u\n"
11972 			, __func__, rtw_get_chip_type(adapter));
11973 		ret = _FAIL;
11974 		break;
11975 	}
11976 
11977 	return ret;
11978 }
11979 
11980 static const char *const _band_cap_str[] = {
11981 	/* BIT0 */"2G",
11982 	/* BIT1 */"5G",
11983 };
11984 
11985 static const char *const _bw_cap_str[] = {
11986 	/* BIT0 */"5M",
11987 	/* BIT1 */"10M",
11988 	/* BIT2 */"20M",
11989 	/* BIT3 */"40M",
11990 	/* BIT4 */"80M",
11991 	/* BIT5 */"160M",
11992 	/* BIT6 */"80_80M",
11993 };
11994 
11995 static const char *const _proto_cap_str[] = {
11996 	/* BIT0 */"b",
11997 	/* BIT1 */"g",
11998 	/* BIT2 */"n",
11999 	/* BIT3 */"ac",
12000 };
12001 
12002 static const char *const _wl_func_str[] = {
12003 	/* BIT0 */"P2P",
12004 	/* BIT1 */"MIRACAST",
12005 	/* BIT2 */"TDLS",
12006 	/* BIT3 */"FTM",
12007 };
12008 
dump_hal_spec(void * sel,_adapter * adapter)12009 void dump_hal_spec(void *sel, _adapter *adapter)
12010 {
12011 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
12012 	int i;
12013 
12014 	RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
12015 	RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
12016 	RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
12017 	RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
12018 	RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
12019 	RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
12020 	RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
12021 	RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
12022 
12023 	RTW_PRINT_SEL(sel, "band_cap:");
12024 	for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
12025 		if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
12026 			_RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
12027 	}
12028 	_RTW_PRINT_SEL(sel, "\n");
12029 
12030 	RTW_PRINT_SEL(sel, "bw_cap:");
12031 	for (i = 0; i < BW_CAP_BIT_NUM; i++) {
12032 		if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
12033 			_RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
12034 	}
12035 	_RTW_PRINT_SEL(sel, "\n");
12036 
12037 	RTW_PRINT_SEL(sel, "proto_cap:");
12038 	for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
12039 		if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
12040 			_RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
12041 	}
12042 	_RTW_PRINT_SEL(sel, "\n");
12043 
12044 	RTW_PRINT_SEL(sel, "wl_func:");
12045 	for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
12046 		if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
12047 			_RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
12048 	}
12049 	_RTW_PRINT_SEL(sel, "\n");
12050 }
12051 
hal_chk_band_cap(_adapter * adapter,u8 cap)12052 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
12053 {
12054 	return GET_HAL_SPEC(adapter)->band_cap & cap;
12055 }
12056 
hal_chk_bw_cap(_adapter * adapter,u8 cap)12057 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
12058 {
12059 	return GET_HAL_SPEC(adapter)->bw_cap & cap;
12060 }
12061 
hal_chk_proto_cap(_adapter * adapter,u8 cap)12062 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
12063 {
12064 	return GET_HAL_SPEC(adapter)->proto_cap & cap;
12065 }
12066 
hal_chk_wl_func(_adapter * adapter,u8 func)12067 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
12068 {
12069 	return GET_HAL_SPEC(adapter)->wl_func & func;
12070 }
12071 
hal_is_band_support(_adapter * adapter,u8 band)12072 inline bool hal_is_band_support(_adapter *adapter, u8 band)
12073 {
12074 	return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
12075 }
12076 
hal_is_bw_support(_adapter * adapter,u8 bw)12077 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
12078 {
12079 	return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
12080 }
12081 
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)12082 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
12083 {
12084 	u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
12085 
12086 	if (mode == WIRELESS_11B)
12087 		if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
12088 			return 1;
12089 
12090 	if (mode == WIRELESS_11G)
12091 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
12092 			return 1;
12093 
12094 	if (mode == WIRELESS_11A)
12095 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
12096 			return 1;
12097 
12098 	if (mode == WIRELESS_11_24N)
12099 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
12100 			return 1;
12101 
12102 	if (mode == WIRELESS_11_5N)
12103 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
12104 			return 1;
12105 
12106 	if (mode == WIRELESS_11AC)
12107 		if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
12108 			return 1;
12109 
12110 	return 0;
12111 }
12112 
12113 /*
12114 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
12115 * @adapter:
12116 * @in_bw: starting bw, value of enum channel_width
12117 *
12118 * Returns: value of enum channel_width
12119 */
hal_largest_bw(_adapter * adapter,u8 in_bw)12120 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
12121 {
12122 	for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
12123 		if (hal_is_bw_support(adapter, in_bw))
12124 			break;
12125 	}
12126 
12127 	if (!hal_is_bw_support(adapter, in_bw))
12128 		rtw_warn_on(1);
12129 
12130 	return in_bw;
12131 }
12132 
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)12133 void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
12134 {
12135 	if (hw_port == HW_PORT0) {
12136 		/*disable related TSF function*/
12137 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
12138 
12139 		rtw_write32(padapter, REG_TSFTR, tsf);
12140 		rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
12141 
12142 		/*enable related TSF function*/
12143 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
12144 	} else if (hw_port == HW_PORT1) {
12145 		/*disable related TSF function*/
12146 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
12147 
12148 		rtw_write32(padapter, REG_TSFTR1, tsf);
12149 		rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
12150 
12151 		/*enable related TSF function*/
12152 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
12153 	} else
12154 		RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
12155 }
12156 
ResumeTxBeacon(_adapter * padapter)12157 void ResumeTxBeacon(_adapter *padapter)
12158 {
12159 #ifdef CONFIG_MI_WITH_MBSSID_CAM
12160 #else
12161 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
12162 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
12163 
12164 #ifdef RTW_HALMAC
12165 	/* Add this for driver using HALMAC because driver doesn't have setup time init by self */
12166 	/* TBTT setup time */
12167 	rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
12168 #endif
12169 
12170 	/* TBTT hold time: 0x540[19:8] */
12171 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
12172 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
12173 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
12174 #endif
12175 }
12176 
StopTxBeacon(_adapter * padapter)12177 void StopTxBeacon(_adapter *padapter)
12178 {
12179 #ifdef CONFIG_MI_WITH_MBSSID_CAM
12180 #else
12181 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
12182 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
12183 
12184 	/* TBTT hold time: 0x540[19:8] */
12185 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
12186 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
12187 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
12188 #endif
12189 }
12190 
12191 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)12192 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
12193 {
12194 	RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
12195 
12196 	rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
12197 
12198 	/* disable Port0 TSF update*/
12199 	rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | DIS_TSF_UDT);
12200 
12201 	/* set net_type */
12202 	Set_MSR(Adapter, mode);
12203 
12204 	if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
12205 		if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
12206 			StopTxBeacon(Adapter);
12207 
12208 		rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM);/*disable atim wnd*/
12209 	} else if (mode == _HW_STATE_ADHOC_) {
12210 		ResumeTxBeacon(Adapter);
12211 		rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
12212 
12213 	} else if (mode == _HW_STATE_AP_) {
12214 		ResumeTxBeacon(Adapter);
12215 
12216 		rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
12217 
12218 		/*enable to rx data frame*/
12219 		rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
12220 
12221 		/*Beacon Control related register for first time*/
12222 		rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */
12223 
12224 		/*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
12225 		rtw_write8(Adapter, REG_ATIMWND, 0x0c); /* 12ms */
12226 		rtw_write16(Adapter, REG_BCNTCFG, 0x00);
12227 
12228 		rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
12229 
12230 		/*reset TSF*/
12231 		rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
12232 
12233 		/*enable BCN0 Function for if1*/
12234 		/*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
12235 		rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
12236 		#ifdef CONFIG_BCN_XMIT_PROTECT
12237 		rtw_write8(Adapter, REG_CCK_CHECK, rtw_read8(Adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
12238 		#endif
12239 
12240 		if (IS_HARDWARE_TYPE_8821(Adapter) || IS_HARDWARE_TYPE_8192E(Adapter))/* select BCN on port 0 for DualBeacon*/
12241 			rtw_write8(Adapter, REG_CCK_CHECK, rtw_read8(Adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
12242 
12243 	}
12244 
12245 }
12246 #endif
12247 
12248 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)12249 u8	rtw_hal_antdiv_before_linked(_adapter *padapter)
12250 {
12251 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
12252 	u8 cur_ant, change_ant;
12253 
12254 	if (!pHalData->AntDivCfg)
12255 		return _FALSE;
12256 
12257 	if (pHalData->sw_antdiv_bl_state == 0) {
12258 		pHalData->sw_antdiv_bl_state = 1;
12259 
12260 		rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
12261 		change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
12262 
12263 		return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
12264 	}
12265 
12266 	pHalData->sw_antdiv_bl_state = 0;
12267 	return _FALSE;
12268 }
12269 
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)12270 void	rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
12271 {
12272 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
12273 
12274 	if (pHalData->AntDivCfg) {
12275 		/*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
12276 		/*select optimum_antenna for before linked =>For antenna diversity*/
12277 		if (dst->Rssi >=  src->Rssi) {/*keep org parameter*/
12278 			src->Rssi = dst->Rssi;
12279 			src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
12280 		}
12281 	}
12282 }
12283 #endif
12284 
12285 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)12286 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
12287 {
12288 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
12289 	struct phy_spec_t *phy_spec = &pHalData->phy_spec;
12290 
12291 	RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
12292 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
12293 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
12294 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index	[15:8]*/
12295 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index	[7:0]*/
12296 
12297 	RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
12298 	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]*/
12299 	/*VHT STBC Rx [23:16]
12300 	0 = not support
12301 	1 = support for 1 spatial stream
12302 	2 = support for 1 or 2 spatial streams
12303 	3 = support for 1 or 2 or 3 spatial streams
12304 	4 = support for 1 or 2 or 3 or 4 spatial streams*/
12305 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
12306 	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]*/
12307 	/*HT STBC Rx [7:0]
12308 	0 = not support
12309 	1 = support for 1 spatial stream
12310 	2 = support for 1 or 2 spatial streams
12311 	3 = support for 1 or 2 or 3 spatial streams*/
12312 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
12313 
12314 	RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
12315 	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]*/
12316 	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]*/
12317 	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]*/
12318 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Rx : %s\n\n", (phy_spec->ldpc_cap & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Rx [7:0]*/
12319 	#ifdef CONFIG_BEAMFORMING
12320 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
12321 	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]*/
12322 	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]*/
12323 	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]*/
12324 	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]*/
12325 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF)  ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
12326 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
12327 
12328 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
12329 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
12330 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
12331 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
12332 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
12333 	#endif
12334 }
12335 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)12336 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
12337 {
12338 	u8 phy_cap = _FALSE;
12339 
12340 	/* STBC */
12341 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
12342 	RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12343 
12344 	phy_cap = _FALSE;
12345 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
12346 	RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12347 
12348 	/* LDPC support */
12349 	phy_cap = _FALSE;
12350 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
12351 	RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12352 
12353 	phy_cap = _FALSE;
12354 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
12355 	RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12356 
12357 	#ifdef CONFIG_BEAMFORMING
12358 	phy_cap = _FALSE;
12359 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
12360 	RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12361 
12362 	phy_cap = _FALSE;
12363 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
12364 	RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12365 
12366 	phy_cap = _FALSE;
12367 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
12368 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12369 
12370 	phy_cap = _FALSE;
12371 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
12372 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12373 	#endif
12374 }
12375 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)12376 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
12377 {
12378 	RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
12379 #ifdef CONFIG_PHY_CAPABILITY_QUERY
12380 	rtw_dump_phy_cap_by_phydmapi(sel, adapter);
12381 #else
12382 	rtw_dump_phy_cap_by_hal(sel, adapter);
12383 #endif
12384 }
12385 
translate_dbm_to_percentage(s16 signal)12386 inline s16 translate_dbm_to_percentage(s16 signal)
12387 {
12388 	if ((signal <= -100) || (signal >= 20))
12389 		return	0;
12390 	else if (signal >= 0)
12391 		return	100;
12392 	else
12393 		return 100 + signal;
12394 }
12395 
12396 #ifdef CONFIG_SWTIMER_BASED_TXBCN
12397 #ifdef CONFIG_BCN_RECOVERY
12398 #define REG_CPU_MGQ_INFO	0x041C
12399 #define BIT_BCN_POLL			BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)12400 u8 rtw_ap_bcn_recovery(_adapter *padapter)
12401 {
12402 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
12403 
12404 	if (hal_data->issue_bcn_fail >= 2) {
12405 		RTW_ERR("%s ISSUE BCN Fail\n", __func__);
12406 		rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
12407 		hal_data->issue_bcn_fail = 0;
12408 	}
12409 	return _SUCCESS;
12410 }
12411 #endif /*CONFIG_BCN_RECOVERY*/
12412 
12413 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)12414 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
12415 {
12416 	u32 start_time = rtw_get_current_time();
12417 	u8 bcn_queue_empty = _FALSE;
12418 
12419 	do {
12420 		if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
12421 			bcn_queue_empty = _TRUE;
12422 			break;
12423 		}
12424 	} while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
12425 
12426 	if (bcn_queue_empty == _FALSE)
12427 		RTW_ERR("%s BCN queue not empty\n", __func__);
12428 
12429 	return bcn_queue_empty;
12430 }
12431 #endif /*CONFIG_BCN_XMIT_PROTECT*/
12432 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
12433