• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #define _RTW_WLAN_UTIL_C_
8 
9 #include <linux/ieee80211.h>
10 
11 #include <osdep_service.h>
12 #include <drv_types.h>
13 #include <wifi.h>
14 
15 static const u8 ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f};
16 static const u8 ARTHEROS_OUI2[] = {0x00, 0x13, 0x74};
17 
18 static const u8 BROADCOM_OUI1[] = {0x00, 0x10, 0x18};
19 static const u8 BROADCOM_OUI2[] = {0x00, 0x0a, 0xf7};
20 
21 static const u8 CISCO_OUI[] = {0x00, 0x40, 0x96};
22 static const u8 MARVELL_OUI[] = {0x00, 0x50, 0x43};
23 static const u8 RALINK_OUI[] = {0x00, 0x0c, 0x43};
24 static const u8 REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
25 static const u8 AIRGOCAP_OUI[] = {0x00, 0x0a, 0xf5};
26 static const u8 EPIGRAM_OUI[] = {0x00, 0x90, 0x4c};
27 
28 u8 REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
29 
30 #define WAIT_FOR_BCN_TO_MIN	(6000)
31 #define WAIT_FOR_BCN_TO_MAX	(20000)
32 
33 static const u8 rtw_basic_rate_cck[4] = {
34 	IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK,
35 	IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
36 	IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK,
37 	IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK
38 };
39 
40 static const u8 rtw_basic_rate_ofdm[3] = {
41 	IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK,
42 	IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
43 	IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
44 };
45 
46 static const u8 rtw_basic_rate_mix[7] = {
47 	IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK,
48 	IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
49 	IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK,
50 	IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK,
51 	IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK,
52 	IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
53 	IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
54 };
55 
networktype_to_raid(unsigned char network_type)56 unsigned char networktype_to_raid(unsigned char network_type)
57 {
58 	switch (network_type) {
59 	case WIRELESS_11B:
60 		return RATR_INX_WIRELESS_B;
61 	case WIRELESS_11A:
62 	case WIRELESS_11G:
63 		return RATR_INX_WIRELESS_G;
64 	case WIRELESS_11BG:
65 		return RATR_INX_WIRELESS_GB;
66 	case WIRELESS_11_24N:
67 	case WIRELESS_11_5N:
68 		return RATR_INX_WIRELESS_N;
69 	case WIRELESS_11A_5N:
70 	case WIRELESS_11G_24N:
71 		return  RATR_INX_WIRELESS_NG;
72 	case WIRELESS_11BG_24N:
73 		return RATR_INX_WIRELESS_NGB;
74 	default:
75 		return RATR_INX_WIRELESS_GB;
76 	}
77 }
78 
judge_network_type(struct adapter * padapter,unsigned char * rate)79 u8 judge_network_type(struct adapter *padapter, unsigned char *rate)
80 {
81 	u8 network_type = 0;
82 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
83 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
84 
85 	if (pmlmeinfo->HT_enable)
86 		network_type = WIRELESS_11_24N;
87 
88 	if (rtw_is_cckratesonly_included(rate))
89 		network_type |= WIRELESS_11B;
90 	else if (rtw_is_cckrates_included(rate))
91 		network_type |= WIRELESS_11BG;
92 	else
93 		network_type |= WIRELESS_11G;
94 
95 	return network_type;
96 }
97 
ratetbl_val_2wifirate(unsigned char rate)98 static unsigned char ratetbl_val_2wifirate(unsigned char rate)
99 {
100 	switch (rate & 0x7f) {
101 	case 0:
102 		return IEEE80211_CCK_RATE_1MB;
103 	case 1:
104 		return IEEE80211_CCK_RATE_2MB;
105 	case 2:
106 		return IEEE80211_CCK_RATE_5MB;
107 	case 3:
108 		return IEEE80211_CCK_RATE_11MB;
109 	case 4:
110 		return IEEE80211_OFDM_RATE_6MB;
111 	case 5:
112 		return IEEE80211_OFDM_RATE_9MB;
113 	case 6:
114 		return IEEE80211_OFDM_RATE_12MB;
115 	case 7:
116 		return IEEE80211_OFDM_RATE_18MB;
117 	case 8:
118 		return IEEE80211_OFDM_RATE_24MB;
119 	case 9:
120 		return IEEE80211_OFDM_RATE_36MB;
121 	case 10:
122 		return IEEE80211_OFDM_RATE_48MB;
123 	case 11:
124 		return IEEE80211_OFDM_RATE_54MB;
125 	default:
126 		return 0;
127 	}
128 }
129 
is_basicrate(struct adapter * padapter,unsigned char rate)130 static bool is_basicrate(struct adapter *padapter, unsigned char rate)
131 {
132 	int i;
133 	unsigned char val;
134 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
135 
136 	for (i = 0; i < NumRates; i++) {
137 		val = pmlmeext->basicrate[i];
138 
139 		if ((val != 0xff) && (val != 0xfe)) {
140 			if (rate == ratetbl_val_2wifirate(val))
141 				return true;
142 		}
143 	}
144 	return false;
145 }
146 
ratetbl2rateset(struct adapter * padapter,unsigned char * rateset)147 static unsigned int ratetbl2rateset(struct adapter *padapter, unsigned char *rateset)
148 {
149 	int i;
150 	unsigned char rate;
151 	unsigned int len = 0;
152 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
153 
154 	for (i = 0; i < NumRates; i++) {
155 		rate = pmlmeext->datarate[i];
156 
157 		switch (rate) {
158 		case 0xff:
159 			return len;
160 		case 0xfe:
161 			continue;
162 		default:
163 			rate = ratetbl_val_2wifirate(rate);
164 
165 			if (is_basicrate(padapter, rate))
166 				rate |= IEEE80211_BASIC_RATE_MASK;
167 
168 			rateset[len] = rate;
169 			len++;
170 			break;
171 		}
172 	}
173 	return len;
174 }
175 
get_rate_set(struct adapter * padapter,unsigned char * pbssrate,int * bssrate_len)176 void get_rate_set(struct adapter *padapter, unsigned char *pbssrate, int *bssrate_len)
177 {
178 	unsigned char supportedrates[NumRates];
179 
180 	memset(supportedrates, 0, NumRates);
181 	*bssrate_len = ratetbl2rateset(padapter, supportedrates);
182 	memcpy(pbssrate, supportedrates, *bssrate_len);
183 }
184 
UpdateBrateTbl(struct adapter * Adapter,u8 * mbrate)185 void UpdateBrateTbl(struct adapter *Adapter, u8 *mbrate)
186 {
187 	u8 i;
188 	u8 rate;
189 
190 	/*  1M, 2M, 5.5M, 11M, 6M, 12M, 24M are mandatory. */
191 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
192 		rate = mbrate[i] & 0x7f;
193 		switch (rate) {
194 		case IEEE80211_CCK_RATE_1MB:
195 		case IEEE80211_CCK_RATE_2MB:
196 		case IEEE80211_CCK_RATE_5MB:
197 		case IEEE80211_CCK_RATE_11MB:
198 		case IEEE80211_OFDM_RATE_6MB:
199 		case IEEE80211_OFDM_RATE_12MB:
200 		case IEEE80211_OFDM_RATE_24MB:
201 			mbrate[i] |= IEEE80211_BASIC_RATE_MASK;
202 			break;
203 		}
204 	}
205 }
206 
UpdateBrateTblForSoftAP(u8 * bssrateset,u32 bssratelen)207 void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen)
208 {
209 	u8 i;
210 	u8 rate;
211 
212 	for (i = 0; i < bssratelen; i++) {
213 		rate = bssrateset[i] & 0x7f;
214 		switch (rate) {
215 		case IEEE80211_CCK_RATE_1MB:
216 		case IEEE80211_CCK_RATE_2MB:
217 		case IEEE80211_CCK_RATE_5MB:
218 		case IEEE80211_CCK_RATE_11MB:
219 			bssrateset[i] |= IEEE80211_BASIC_RATE_MASK;
220 			break;
221 		}
222 	}
223 }
224 
Save_DM_Func_Flag(struct adapter * padapter)225 void Save_DM_Func_Flag(struct adapter *padapter)
226 {
227 	u8 saveflag = true;
228 
229 	rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&saveflag));
230 }
231 
Restore_DM_Func_Flag(struct adapter * padapter)232 void Restore_DM_Func_Flag(struct adapter *padapter)
233 {
234 	u8 saveflag = false;
235 
236 	rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&saveflag));
237 }
238 
Switch_DM_Func(struct adapter * padapter,u32 mode,u8 enable)239 void Switch_DM_Func(struct adapter *padapter, u32 mode, u8 enable)
240 {
241 	if (enable)
242 		rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_SET, (u8 *)(&mode));
243 	else
244 		rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_CLR, (u8 *)(&mode));
245 }
246 
Set_MSR(struct adapter * padapter,u8 type)247 void Set_MSR(struct adapter *padapter, u8 type)
248 {
249 	rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type));
250 }
251 
rtw_get_oper_ch(struct adapter * adapter)252 inline u8 rtw_get_oper_ch(struct adapter *adapter)
253 {
254 	return adapter->mlmeextpriv.oper_channel;
255 }
256 
rtw_set_oper_ch(struct adapter * adapter,u8 ch)257 inline void rtw_set_oper_ch(struct adapter *adapter, u8 ch)
258 {
259 	adapter->mlmeextpriv.oper_channel = ch;
260 }
261 
rtw_set_oper_bw(struct adapter * adapter,u8 bw)262 inline void rtw_set_oper_bw(struct adapter *adapter, u8 bw)
263 {
264 	adapter->mlmeextpriv.oper_bwmode = bw;
265 }
266 
rtw_set_oper_choffset(struct adapter * adapter,u8 offset)267 inline void rtw_set_oper_choffset(struct adapter *adapter, u8 offset)
268 {
269 	adapter->mlmeextpriv.oper_ch_offset = offset;
270 }
271 
SelectChannel(struct adapter * padapter,unsigned char channel)272 void SelectChannel(struct adapter *padapter, unsigned char channel)
273 {
274 	/* saved channel info */
275 	rtw_set_oper_ch(padapter, channel);
276 	rtw_hal_set_chan(padapter, channel);
277 }
278 
SetBWMode(struct adapter * padapter,unsigned short bwmode,unsigned char channel_offset)279 void SetBWMode(struct adapter *padapter, unsigned short bwmode,
280 	       unsigned char channel_offset)
281 {
282 	/* saved bw info */
283 	rtw_set_oper_bw(padapter, bwmode);
284 	rtw_set_oper_choffset(padapter, channel_offset);
285 
286 	rtw_hal_set_bwmode(padapter, (enum ht_channel_width)bwmode, channel_offset);
287 }
288 
set_channel_bwmode(struct adapter * padapter,unsigned char channel,unsigned char channel_offset,unsigned short bwmode)289 void set_channel_bwmode(struct adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode)
290 {
291 	u8 center_ch;
292 
293 	if ((bwmode == HT_CHANNEL_WIDTH_20) ||
294 	    (channel_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)) {
295 		/* SelectChannel(padapter, channel); */
296 		center_ch = channel;
297 	} else {
298 		/* switch to the proper channel */
299 		if (channel_offset == HAL_PRIME_CHNL_OFFSET_LOWER) {
300 			/* SelectChannel(padapter, channel + 2); */
301 			center_ch = channel + 2;
302 		} else {
303 			/* SelectChannel(padapter, channel - 2); */
304 			center_ch = channel - 2;
305 		}
306 	}
307 
308 	/* set Channel */
309 	/* saved channel/bw info */
310 	rtw_set_oper_ch(padapter, channel);
311 	rtw_set_oper_bw(padapter, bwmode);
312 	rtw_set_oper_choffset(padapter, channel_offset);
313 
314 	rtw_hal_set_chan(padapter, center_ch); /*  set center channel */
315 	SetBWMode(padapter, bwmode, channel_offset);
316 }
317 
get_beacon_interval(struct wlan_bssid_ex * bss)318 u16 get_beacon_interval(struct wlan_bssid_ex *bss)
319 {
320 	__le16 val;
321 
322 	memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->ies), 2);
323 
324 	return le16_to_cpu(val);
325 }
326 
is_client_associated_to_ap(struct adapter * padapter)327 int is_client_associated_to_ap(struct adapter *padapter)
328 {
329 	struct mlme_ext_priv *pmlmeext;
330 	struct mlme_ext_info *pmlmeinfo;
331 
332 	if (!padapter)
333 		return _FAIL;
334 
335 	pmlmeext = &padapter->mlmeextpriv;
336 	pmlmeinfo = &pmlmeext->mlmext_info;
337 
338 	if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
339 	    (pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
340 		return true;
341 	else
342 		return _FAIL;
343 }
344 
is_client_associated_to_ibss(struct adapter * padapter)345 int is_client_associated_to_ibss(struct adapter *padapter)
346 {
347 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
348 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
349 
350 	if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
351 	    (pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)
352 		return true;
353 	else
354 		return _FAIL;
355 }
356 
is_IBSS_empty(struct adapter * padapter)357 int is_IBSS_empty(struct adapter *padapter)
358 {
359 	unsigned int i;
360 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
361 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
362 
363 	for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
364 		if (pmlmeinfo->FW_sta_info[i].status == 1)
365 			return _FAIL;
366 	}
367 	return true;
368 }
369 
decide_wait_for_beacon_timeout(unsigned int bcn_interval)370 unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval)
371 {
372 	if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN)
373 		return WAIT_FOR_BCN_TO_MIN;
374 	else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX)
375 		return WAIT_FOR_BCN_TO_MAX;
376 	else
377 		return bcn_interval << 2;
378 }
379 
invalidate_cam_all(struct adapter * padapter)380 void invalidate_cam_all(struct adapter *padapter)
381 {
382 	rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, NULL);
383 }
384 
write_cam(struct adapter * padapter,u8 entry,u16 ctrl,u8 * mac,u8 * key)385 void write_cam(struct adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key)
386 {
387 	unsigned int i, val, addr;
388 	int j;
389 	u32 cam_val[2];
390 
391 	addr = entry << 3;
392 
393 	for (j = 5; j >= 0; j--) {
394 		switch (j) {
395 		case 0:
396 			val = ctrl | (mac[0] << 16) | (mac[1] << 24);
397 			break;
398 		case 1:
399 			val = mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24);
400 			break;
401 		default:
402 			i = (j - 2) << 2;
403 			val = key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) |
404 			      (key[i + 3] << 24);
405 			break;
406 		}
407 
408 		cam_val[0] = val;
409 		cam_val[1] = addr + (unsigned int)j;
410 
411 		rtw_hal_set_hwreg(padapter, HW_VAR_CAM_WRITE, (u8 *)cam_val);
412 	}
413 }
414 
clear_cam_entry(struct adapter * padapter,u8 entry)415 void clear_cam_entry(struct adapter *padapter, u8 entry)
416 {
417 	u8 null_sta[ETH_ALEN] = {};
418 	u8 null_key[16] = {};
419 
420 	write_cam(padapter, entry, 0, null_sta, null_key);
421 }
422 
allocate_fw_sta_entry(struct adapter * padapter)423 int allocate_fw_sta_entry(struct adapter *padapter)
424 {
425 	unsigned int mac_id;
426 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
427 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
428 
429 	for (mac_id = IBSS_START_MAC_ID; mac_id < NUM_STA; mac_id++) {
430 		if (pmlmeinfo->FW_sta_info[mac_id].status == 0) {
431 			pmlmeinfo->FW_sta_info[mac_id].status = 1;
432 			pmlmeinfo->FW_sta_info[mac_id].retry = 0;
433 			break;
434 		}
435 	}
436 
437 	return mac_id;
438 }
439 
flush_all_cam_entry(struct adapter * padapter)440 void flush_all_cam_entry(struct adapter *padapter)
441 {
442 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
443 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
444 
445 	rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, NULL);
446 
447 	memset((u8 *)(pmlmeinfo->FW_sta_info), 0, sizeof(pmlmeinfo->FW_sta_info));
448 }
449 
WMM_param_handler(struct adapter * padapter,struct ndis_802_11_var_ie * pIE)450 int WMM_param_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
451 {
452 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
453 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
454 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
455 
456 	if (pmlmepriv->qospriv.qos_option == 0) {
457 		pmlmeinfo->WMM_enable = 0;
458 		return _FAIL;
459 	}
460 
461 	pmlmeinfo->WMM_enable = 1;
462 	memcpy(&pmlmeinfo->WMM_param, pIE->data + 6, sizeof(struct WMM_para_element));
463 	return true;
464 }
465 
WMMOnAssocRsp(struct adapter * padapter)466 void WMMOnAssocRsp(struct adapter *padapter)
467 {
468 	u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime;
469 	u8 acm_mask;
470 	u16 TXOP;
471 	u32 acParm, i;
472 	u32 edca[4], inx[4];
473 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
474 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
475 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
476 	struct registry_priv *pregpriv = &padapter->registrypriv;
477 
478 	if (pmlmeinfo->WMM_enable == 0) {
479 		padapter->mlmepriv.acm_mask = 0;
480 		return;
481 	}
482 
483 	acm_mask = 0;
484 
485 	if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
486 		aSifsTime = 10;
487 	else
488 		aSifsTime = 16;
489 
490 	for (i = 0; i < 4; i++) {
491 		ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03;
492 		ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01;
493 
494 		/* AIFS = AIFSN * slot time + SIFS - r2t phy delay */
495 		AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) * pmlmeinfo->slotTime + aSifsTime;
496 
497 		ECWMin = pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f;
498 		ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4;
499 		TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit);
500 
501 		acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
502 
503 		switch (ACI) {
504 		case 0x0:
505 			rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
506 			acm_mask |= (ACM ? BIT(1) : 0);
507 			edca[XMIT_BE_QUEUE] = acParm;
508 			break;
509 		case 0x1:
510 			rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
511 			edca[XMIT_BK_QUEUE] = acParm;
512 			break;
513 		case 0x2:
514 			rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
515 			acm_mask |= (ACM ? BIT(2) : 0);
516 			edca[XMIT_VI_QUEUE] = acParm;
517 			break;
518 		case 0x3:
519 			rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
520 			acm_mask |= (ACM ? BIT(3) : 0);
521 			edca[XMIT_VO_QUEUE] = acParm;
522 			break;
523 		}
524 
525 		DBG_88E("WMM(%x): %x, %x\n", ACI, ACM, acParm);
526 	}
527 
528 	if (padapter->registrypriv.acm_method == 1)
529 		rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask));
530 	else
531 		padapter->mlmepriv.acm_mask = acm_mask;
532 
533 	inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
534 
535 	if (pregpriv->wifi_spec == 1) {
536 		u32 j, change_inx = false;
537 
538 		/* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */
539 		for (i = 0; i < 4; i++) {
540 			for (j = i + 1; j < 4; j++) {
541 				/* compare CW and AIFS */
542 				if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF)) {
543 					change_inx = true;
544 				} else if ((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF)) {
545 					/* compare TXOP */
546 					if ((edca[j] >> 16) > (edca[i] >> 16))
547 						change_inx = true;
548 				}
549 
550 				if (change_inx) {
551 					swap(edca[i], edca[j]);
552 					swap(inx[i], inx[j]);
553 					change_inx = false;
554 				}
555 			}
556 		}
557 	}
558 
559 	for (i = 0; i < 4; i++) {
560 		pxmitpriv->wmm_para_seq[i] = inx[i];
561 		DBG_88E("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]);
562 	}
563 }
564 
bwmode_update_check(struct adapter * padapter,struct ndis_802_11_var_ie * pIE)565 static void bwmode_update_check(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
566 {
567 	unsigned char new_bwmode;
568 	unsigned char new_ch_offset;
569 	struct HT_info_element *pHT_info;
570 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
571 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
572 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
573 	struct registry_priv *pregistrypriv = &padapter->registrypriv;
574 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
575 
576 	if (!pIE)
577 		return;
578 
579 	if (!phtpriv)
580 		return;
581 
582 	if (pIE->Length > sizeof(struct HT_info_element))
583 		return;
584 
585 	pHT_info = (struct HT_info_element *)pIE->data;
586 
587 	if ((pHT_info->infos[0] & BIT(2)) && pregistrypriv->cbw40_enable) {
588 		new_bwmode = HT_CHANNEL_WIDTH_40;
589 
590 		switch (pHT_info->infos[0] & 0x3) {
591 		case 1:
592 			new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
593 			break;
594 		case 3:
595 			new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
596 			break;
597 		default:
598 			new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
599 			break;
600 		}
601 	} else {
602 		new_bwmode = HT_CHANNEL_WIDTH_20;
603 		new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
604 	}
605 
606 	if ((new_bwmode != pmlmeext->cur_bwmode) ||
607 	    (new_ch_offset != pmlmeext->cur_ch_offset)) {
608 		pmlmeinfo->bwmode_updated = true;
609 
610 		pmlmeext->cur_bwmode = new_bwmode;
611 		pmlmeext->cur_ch_offset = new_ch_offset;
612 
613 		/* update HT info also */
614 		HT_info_handler(padapter, pIE);
615 	} else {
616 		pmlmeinfo->bwmode_updated = false;
617 	}
618 
619 	if (pmlmeinfo->bwmode_updated) {
620 		struct sta_info *psta;
621 		struct wlan_bssid_ex	*cur_network = &pmlmeinfo->network;
622 		struct sta_priv	*pstapriv = &padapter->stapriv;
623 
624 		/* update ap's stainfo */
625 		psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
626 		if (psta) {
627 			struct ht_priv	*phtpriv_sta = &psta->htpriv;
628 
629 			if (phtpriv_sta->ht_option) {
630 				/*  bwmode */
631 				phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
632 				phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
633 			} else {
634 				phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
635 				phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
636 			}
637 		}
638 	}
639 }
640 
HT_caps_handler(struct adapter * padapter,struct ndis_802_11_var_ie * pIE)641 void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
642 {
643 	unsigned int i;
644 	u8 max_ampdu_len, min_mpdu_spacing;
645 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
646 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
647 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
648 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
649 	u8 *HT_cap = (u8 *)(&pmlmeinfo->HT_caps);
650 
651 	if (!pIE)
652 		return;
653 
654 	if (!phtpriv->ht_option)
655 		return;
656 
657 	pmlmeinfo->HT_caps_enable = 1;
658 
659 	for (i = 0; i < (pIE->Length); i++) {
660 		if (i != 2) {
661 			/*	Got the endian issue here. */
662 			HT_cap[i] &= (pIE->data[i]);
663 		} else {
664 			/* modify from  fw by Thomas 2010/11/17 */
665 			if ((pmlmeinfo->HT_caps.ampdu_params_info & 0x3) > (pIE->data[i] & 0x3))
666 				max_ampdu_len = pIE->data[i] & 0x3;
667 			else
668 				max_ampdu_len = pmlmeinfo->HT_caps.ampdu_params_info & 0x3;
669 
670 			if ((pmlmeinfo->HT_caps.ampdu_params_info & 0x1c) > (pIE->data[i] & 0x1c))
671 				min_mpdu_spacing = pmlmeinfo->HT_caps.ampdu_params_info & 0x1c;
672 			else
673 				min_mpdu_spacing = pIE->data[i] & 0x1c;
674 
675 			pmlmeinfo->HT_caps.ampdu_params_info = max_ampdu_len | min_mpdu_spacing;
676 		}
677 	}
678 
679 	/* update the MCS rates */
680 	for (i = 0; i < 16; i++)
681 		((u8 *)&pmlmeinfo->HT_caps.mcs)[i] &= MCS_rate_1R[i];
682 }
683 
HT_info_handler(struct adapter * padapter,struct ndis_802_11_var_ie * pIE)684 void HT_info_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
685 {
686 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
687 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
688 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
689 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
690 
691 	if (!pIE)
692 		return;
693 
694 	if (!phtpriv->ht_option)
695 		return;
696 
697 	if (pIE->Length > sizeof(struct HT_info_element))
698 		return;
699 
700 	pmlmeinfo->HT_info_enable = 1;
701 	memcpy(&pmlmeinfo->HT_info, pIE->data, pIE->Length);
702 }
703 
HTOnAssocRsp(struct adapter * padapter)704 void HTOnAssocRsp(struct adapter *padapter)
705 {
706 	u8 max_ampdu_len;
707 	u8 min_mpdu_spacing;
708 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
709 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
710 
711 	DBG_88E("%s\n", __func__);
712 
713 	if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable)) {
714 		pmlmeinfo->HT_enable = 1;
715 	} else {
716 		pmlmeinfo->HT_enable = 0;
717 		return;
718 	}
719 
720 	/* handle A-MPDU parameter field
721 	 *
722 	 * AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
723 	 * AMPDU_para [4:2]:Min MPDU Start Spacing
724 	 */
725 	max_ampdu_len = pmlmeinfo->HT_caps.ampdu_params_info & 0x03;
726 	min_mpdu_spacing = (pmlmeinfo->HT_caps.ampdu_params_info & 0x1c) >> 2;
727 
728 	rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, &min_mpdu_spacing);
729 	rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, &max_ampdu_len);
730 }
731 
ERP_IE_handler(struct adapter * padapter,struct ndis_802_11_var_ie * pIE)732 void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
733 {
734 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
735 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
736 
737 	if (pIE->Length > 1)
738 		return;
739 
740 	pmlmeinfo->ERP_enable = 1;
741 	memcpy(&pmlmeinfo->ERP_IE, pIE->data, pIE->Length);
742 }
743 
VCS_update(struct adapter * padapter,struct sta_info * psta)744 void VCS_update(struct adapter *padapter, struct sta_info *psta)
745 {
746 	struct registry_priv *pregpriv = &padapter->registrypriv;
747 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
748 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
749 
750 	switch (pregpriv->vrtl_carrier_sense) { /* 0:off 1:on 2:auto */
751 	case 0: /* off */
752 		psta->rtsen = 0;
753 		psta->cts2self = 0;
754 		break;
755 	case 1: /* on */
756 		if (pregpriv->vcs_type == 1) { /* 1:RTS/CTS 2:CTS to self */
757 			psta->rtsen = 1;
758 			psta->cts2self = 0;
759 		} else {
760 			psta->rtsen = 0;
761 			psta->cts2self = 1;
762 		}
763 		break;
764 	case 2: /* auto */
765 	default:
766 		if ((pmlmeinfo->ERP_enable) && (pmlmeinfo->ERP_IE & BIT(1))) {
767 			if (pregpriv->vcs_type == 1) {
768 				psta->rtsen = 1;
769 				psta->cts2self = 0;
770 			} else {
771 				psta->rtsen = 0;
772 				psta->cts2self = 1;
773 			}
774 		} else {
775 			psta->rtsen = 0;
776 			psta->cts2self = 0;
777 		}
778 		break;
779 	}
780 }
781 
rtw_check_bcn_info(struct adapter * Adapter,u8 * pframe,u32 packet_len)782 int rtw_check_bcn_info(struct adapter  *Adapter, u8 *pframe, u32 packet_len)
783 {
784 	unsigned int len;
785 	unsigned char *p;
786 	unsigned short val16, subtype;
787 	struct wlan_network *cur_network = &Adapter->mlmepriv.cur_network;
788 	u16 wpa_len = 0, rsn_len = 0;
789 	u8 encryp_protocol = 0;
790 	struct wlan_bssid_ex *bssid;
791 	int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0;
792 	unsigned char *pbuf;
793 	u32 wpa_ielen = 0;
794 	u8 *pbssid = GetAddr3Ptr(pframe);
795 	struct HT_info_element *pht_info = NULL;
796 	u32 bcn_channel;
797 	unsigned short ht_cap_info;
798 	unsigned char ht_info_infos_0;
799 	int ssid_len;
800 
801 	if (!is_client_associated_to_ap(Adapter))
802 		return true;
803 
804 	len = packet_len - sizeof(struct ieee80211_hdr_3addr);
805 
806 	if (len > MAX_IE_SZ) {
807 		DBG_88E("%s IE too long for survey event\n", __func__);
808 		return _FAIL;
809 	}
810 
811 	if (memcmp(cur_network->network.MacAddress, pbssid, 6)) {
812 		DBG_88E("Oops: rtw_check_network_encrypt linked but recv other bssid bcn\n%pM %pM\n",
813 			(pbssid), (cur_network->network.MacAddress));
814 		return true;
815 	}
816 
817 	bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
818 	if (!bssid)
819 		return _FAIL;
820 
821 	subtype = GetFrameSubType(pframe) >> 4;
822 
823 	if (subtype == WIFI_BEACON)
824 		bssid->Reserved[0] = 1;
825 
826 	bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
827 
828 	/* below is to copy the information element */
829 	bssid->ie_length = len;
830 	memcpy(bssid->ies, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->ie_length);
831 
832 	/* check bw and channel offset */
833 	/* parsing HT_CAP_IE */
834 	p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->ie_length - _FIXED_IE_LENGTH_);
835 	if (p && len > 0) {
836 		struct ieee80211_ht_cap *ht_cap =
837 			(struct ieee80211_ht_cap *)(p + 2);
838 
839 		ht_cap_info = le16_to_cpu(ht_cap->cap_info);
840 	} else {
841 		ht_cap_info = 0;
842 	}
843 	/* parsing HT_INFO_IE */
844 	p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->ie_length - _FIXED_IE_LENGTH_);
845 	if (p && len > 0) {
846 		pht_info = (struct HT_info_element *)(p + 2);
847 		ht_info_infos_0 = pht_info->infos[0];
848 	} else {
849 		ht_info_infos_0 = 0;
850 	}
851 	if (ht_cap_info != cur_network->BcnInfo.ht_cap_info ||
852 	    ((ht_info_infos_0 & 0x03) != (cur_network->BcnInfo.ht_info_infos_0 & 0x03))) {
853 		DBG_88E("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
854 			ht_cap_info, ht_info_infos_0);
855 		DBG_88E("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
856 			cur_network->BcnInfo.ht_cap_info, cur_network->BcnInfo.ht_info_infos_0);
857 		DBG_88E("%s bw mode change, disconnect\n", __func__);
858 		/* bcn_info_update */
859 		cur_network->BcnInfo.ht_cap_info = ht_cap_info;
860 		cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0;
861 		/* to do : need to check that whether modify related register of BB or not */
862 		/* goto _mismatch; */
863 	}
864 
865 	/* Checking for channel */
866 	p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->ie_length - _FIXED_IE_LENGTH_);
867 	if (p) {
868 		bcn_channel = *(p + 2);
869 	} else {/* In 5G, some ap do not have DSSET IE checking HT info for channel */
870 		p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->ie_length - _FIXED_IE_LENGTH_);
871 		if (pht_info) {
872 			bcn_channel = pht_info->primary_channel;
873 		} else { /* we don't find channel IE, so don't check it */
874 			DBG_88E("Oops: %s we don't find channel IE, so don't check it\n", __func__);
875 			bcn_channel = Adapter->mlmeextpriv.cur_channel;
876 		}
877 	}
878 	if (bcn_channel != Adapter->mlmeextpriv.cur_channel) {
879 		DBG_88E("%s beacon channel:%d cur channel:%d disconnect\n", __func__,
880 			bcn_channel, Adapter->mlmeextpriv.cur_channel);
881 		goto _mismatch;
882 	}
883 
884 	/* checking SSID */
885 	ssid_len = 0;
886 	p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->ie_length - _FIXED_IE_LENGTH_);
887 	if (p) {
888 		ssid_len = *(p + 1);
889 		if (ssid_len > NDIS_802_11_LENGTH_SSID)
890 			ssid_len = 0;
891 	}
892 	memcpy(bssid->ssid.ssid, (p + 2), ssid_len);
893 	bssid->ssid.ssid_length = ssid_len;
894 
895 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s bssid.ssid.ssid:%s bssid.ssid.ssid_length:%d "
896 				"cur_network->network.ssid.ssid:%s len:%d\n", __func__, bssid->ssid.ssid,
897 				bssid->ssid.ssid_length, cur_network->network.ssid.ssid,
898 				cur_network->network.ssid.ssid_length));
899 
900 	if (memcmp(bssid->ssid.ssid, cur_network->network.ssid.ssid, 32) ||
901 	    bssid->ssid.ssid_length != cur_network->network.ssid.ssid_length) {
902 		if (bssid->ssid.ssid[0] != '\0' && bssid->ssid.ssid_length != 0) { /* not hidden ssid */
903 			DBG_88E("%s(), SSID is not match return FAIL\n", __func__);
904 			goto _mismatch;
905 		}
906 	}
907 
908 	/* check encryption info */
909 	val16 = rtw_get_capability(bssid);
910 
911 	if (val16 & BIT(4))
912 		bssid->Privacy = 1;
913 	else
914 		bssid->Privacy = 0;
915 
916 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
917 		 ("%s(): cur_network->network.Privacy is %d, bssid.Privacy is %d\n",
918 		 __func__, cur_network->network.Privacy, bssid->Privacy));
919 	if (cur_network->network.Privacy != bssid->Privacy) {
920 		DBG_88E("%s(), privacy is not match return FAIL\n", __func__);
921 		goto _mismatch;
922 	}
923 
924 	rtw_get_sec_ie(bssid->ies, bssid->ie_length, NULL, &rsn_len, NULL, &wpa_len);
925 
926 	if (rsn_len > 0) {
927 		encryp_protocol = ENCRYP_PROTOCOL_WPA2;
928 	} else if (wpa_len > 0) {
929 		encryp_protocol = ENCRYP_PROTOCOL_WPA;
930 	} else {
931 		if (bssid->Privacy)
932 			encryp_protocol = ENCRYP_PROTOCOL_WEP;
933 	}
934 
935 	if (cur_network->BcnInfo.encryp_protocol != encryp_protocol) {
936 		DBG_88E("%s(): encryption protocol is not match , return FAIL\n", __func__);
937 		goto _mismatch;
938 	}
939 
940 	if (encryp_protocol == ENCRYP_PROTOCOL_WPA || encryp_protocol == ENCRYP_PROTOCOL_WPA2) {
941 		pbuf = rtw_get_wpa_ie(&bssid->ies[12], &wpa_ielen,
942 				      bssid->ie_length - 12);
943 		if (pbuf && (wpa_ielen > 0)) {
944 			if (rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is_8021x) == _SUCCESS) {
945 				RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
946 					 ("%s pnetwork->pairwise_cipher: %d, group_cipher is %d, is_8021x is %d\n", __func__,
947 					 pairwise_cipher, group_cipher, is_8021x));
948 			}
949 		} else {
950 			pbuf = rtw_get_wpa2_ie(&bssid->ies[12], &wpa_ielen,
951 					       bssid->ie_length - 12);
952 
953 			if (pbuf && (wpa_ielen > 0)) {
954 				if (rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is_8021x) == _SUCCESS) {
955 					RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
956 						 ("%s pnetwork->pairwise_cipher: %d, pnetwork->group_cipher is %d, is_802x is %d\n",
957 						  __func__, pairwise_cipher, group_cipher, is_8021x));
958 				}
959 			}
960 		}
961 
962 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
963 			 ("%s cur_network->group_cipher is %d: %d\n", __func__, cur_network->BcnInfo.group_cipher, group_cipher));
964 		if (pairwise_cipher != cur_network->BcnInfo.pairwise_cipher || group_cipher != cur_network->BcnInfo.group_cipher) {
965 			DBG_88E("%s pairwise_cipher(%x:%x) or group_cipher(%x:%x) is not match , return FAIL\n", __func__,
966 				pairwise_cipher, cur_network->BcnInfo.pairwise_cipher,
967 				group_cipher, cur_network->BcnInfo.group_cipher);
968 			goto _mismatch;
969 		}
970 
971 		if (is_8021x != cur_network->BcnInfo.is_8021x) {
972 			DBG_88E("%s authentication is not match , return FAIL\n", __func__);
973 			goto _mismatch;
974 		}
975 	}
976 
977 	kfree(bssid);
978 	return _SUCCESS;
979 
980 _mismatch:
981 	kfree(bssid);
982 	return _FAIL;
983 }
984 
update_beacon_info(struct adapter * padapter,u8 * pframe,uint pkt_len,struct sta_info * psta)985 void update_beacon_info(struct adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta)
986 {
987 	unsigned int i;
988 	unsigned int len;
989 	struct ndis_802_11_var_ie *pIE;
990 
991 	len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN);
992 
993 	for (i = 0; i < len;) {
994 		pIE = (struct ndis_802_11_var_ie *)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i);
995 
996 		switch (pIE->ElementID) {
997 		case _HT_EXTRA_INFO_IE_:	/* HT info */
998 			bwmode_update_check(padapter, pIE);
999 			break;
1000 		case _ERPINFO_IE_:
1001 			ERP_IE_handler(padapter, pIE);
1002 			VCS_update(padapter, psta);
1003 			break;
1004 		default:
1005 			break;
1006 		}
1007 
1008 		i += (pIE->Length + 2);
1009 	}
1010 }
1011 
is_ap_in_tkip(struct adapter * padapter)1012 unsigned int is_ap_in_tkip(struct adapter *padapter)
1013 {
1014 	u32 i;
1015 	struct ndis_802_11_var_ie *pIE;
1016 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1017 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1018 	struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
1019 
1020 	if (rtw_get_capability(cur_network) & WLAN_CAPABILITY_PRIVACY) {
1021 		for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.ie_length;) {
1022 			pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.ies + i);
1023 
1024 			switch (pIE->ElementID) {
1025 			case _VENDOR_SPECIFIC_IE_:
1026 				if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) && (!memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4)))
1027 					return true;
1028 				break;
1029 			case _RSN_IE_2_:
1030 				if (!memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4))
1031 					return true;
1032 			default:
1033 				break;
1034 			}
1035 
1036 			i += (pIE->Length + 2);
1037 		}
1038 		return false;
1039 	} else {
1040 		return false;
1041 	}
1042 }
1043 
wifirate2_ratetbl_inx(unsigned char rate)1044 static int wifirate2_ratetbl_inx(unsigned char rate)
1045 {
1046 	rate = rate & 0x7f;
1047 
1048 	switch (rate) {
1049 	case 108:
1050 		return 11;
1051 	case 96:
1052 		return 10;
1053 	case 72:
1054 		return 9;
1055 	case 48:
1056 		return 8;
1057 	case 36:
1058 		return 7;
1059 	case 24:
1060 		return 6;
1061 	case 18:
1062 		return 5;
1063 	case 12:
1064 		return 4;
1065 	case 22:
1066 		return 3;
1067 	case 11:
1068 		return 2;
1069 	case 4:
1070 		return 1;
1071 	case 2:
1072 		return 0;
1073 	default:
1074 		return 0;
1075 	}
1076 }
1077 
update_basic_rate(unsigned char * ptn,unsigned int ptn_sz)1078 unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz)
1079 {
1080 	unsigned int i, num_of_rate;
1081 	unsigned int mask = 0;
1082 
1083 	num_of_rate = min_t(unsigned int, ptn_sz, NumRates);
1084 
1085 	for (i = 0; i < num_of_rate; i++) {
1086 		if ((*(ptn + i)) & 0x80)
1087 			mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
1088 	}
1089 	return mask;
1090 }
1091 
update_supported_rate(unsigned char * ptn,unsigned int ptn_sz)1092 unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz)
1093 {
1094 	unsigned int i, num_of_rate;
1095 	unsigned int mask = 0;
1096 
1097 	num_of_rate = min_t(unsigned int, ptn_sz, NumRates);
1098 
1099 	for (i = 0; i < num_of_rate; i++)
1100 		mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
1101 	return mask;
1102 }
1103 
update_MSC_rate(struct ieee80211_ht_cap * pHT_caps)1104 unsigned int update_MSC_rate(struct ieee80211_ht_cap *pHT_caps)
1105 {
1106 	return (pHT_caps->mcs.rx_mask[0] << 12) |
1107 	       (pHT_caps->mcs.rx_mask[1] << 20);
1108 }
1109 
support_short_GI(struct adapter * padapter,struct ieee80211_ht_cap * pHT_caps)1110 int support_short_GI(struct adapter *padapter, struct ieee80211_ht_cap *pHT_caps)
1111 {
1112 	unsigned char bit_offset;
1113 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1114 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1115 
1116 	if (!(pmlmeinfo->HT_enable))
1117 		return _FAIL;
1118 
1119 	if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK)
1120 		return _FAIL;
1121 
1122 	bit_offset = (pmlmeext->cur_bwmode & HT_CHANNEL_WIDTH_40) ? 6 : 5;
1123 
1124 	if (__le16_to_cpu(pHT_caps->cap_info) & (0x1 << bit_offset))
1125 		return _SUCCESS;
1126 	else
1127 		return _FAIL;
1128 }
1129 
get_highest_rate_idx(u32 mask)1130 unsigned char get_highest_rate_idx(u32 mask)
1131 {
1132 	int i;
1133 	unsigned char rate_idx = 0;
1134 
1135 	for (i = 27; i >= 0; i--) {
1136 		if (mask & BIT(i)) {
1137 			rate_idx = i;
1138 			break;
1139 		}
1140 	}
1141 	return rate_idx;
1142 }
1143 
Update_RA_Entry(struct adapter * padapter,u32 mac_id)1144 void Update_RA_Entry(struct adapter *padapter, u32 mac_id)
1145 {
1146 	rtw_hal_update_ra_mask(padapter, mac_id, 0);
1147 }
1148 
set_sta_rate(struct adapter * padapter,struct sta_info * psta)1149 void set_sta_rate(struct adapter *padapter, struct sta_info *psta)
1150 {
1151 	/* rate adaptive */
1152 	Update_RA_Entry(padapter, psta->mac_id);
1153 }
1154 
1155 /*  Update RRSR and Rate for USERATE */
update_tx_basic_rate(struct adapter * padapter,u8 wirelessmode)1156 void update_tx_basic_rate(struct adapter *padapter, u8 wirelessmode)
1157 {
1158 	unsigned char supported_rates[NDIS_802_11_LENGTH_RATES_EX];
1159 
1160 	memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
1161 
1162 	if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B))
1163 		memcpy(supported_rates, rtw_basic_rate_cck, 4);
1164 	else if (wirelessmode & WIRELESS_11B)
1165 		memcpy(supported_rates, rtw_basic_rate_mix, 7);
1166 	else
1167 		memcpy(supported_rates, rtw_basic_rate_ofdm, 3);
1168 
1169 	if (wirelessmode & WIRELESS_11B)
1170 		update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
1171 	else
1172 		update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
1173 
1174 	rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, supported_rates);
1175 }
1176 
check_assoc_AP(u8 * pframe,uint len)1177 unsigned char check_assoc_AP(u8 *pframe, uint len)
1178 {
1179 	unsigned int i;
1180 	struct ndis_802_11_var_ie *pIE;
1181 	u8 epigram_vendor_flag;
1182 	u8 ralink_vendor_flag;
1183 
1184 	epigram_vendor_flag = 0;
1185 	ralink_vendor_flag = 0;
1186 
1187 	for (i = sizeof(struct ndis_802_11_fixed_ie); i < len;) {
1188 		pIE = (struct ndis_802_11_var_ie *)(pframe + i);
1189 
1190 		switch (pIE->ElementID) {
1191 		case _VENDOR_SPECIFIC_IE_:
1192 			if ((!memcmp(pIE->data, ARTHEROS_OUI1, 3)) ||
1193 			    (!memcmp(pIE->data, ARTHEROS_OUI2, 3))) {
1194 				DBG_88E("link to Artheros AP\n");
1195 				return HT_IOT_PEER_ATHEROS;
1196 			} else if ((!memcmp(pIE->data, BROADCOM_OUI1, 3)) ||
1197 				   (!memcmp(pIE->data, BROADCOM_OUI2, 3))) {
1198 				DBG_88E("link to Broadcom AP\n");
1199 				return HT_IOT_PEER_BROADCOM;
1200 			} else if (!memcmp(pIE->data, MARVELL_OUI, 3)) {
1201 				DBG_88E("link to Marvell AP\n");
1202 				return HT_IOT_PEER_MARVELL;
1203 			} else if (!memcmp(pIE->data, RALINK_OUI, 3)) {
1204 				if (!ralink_vendor_flag) {
1205 					ralink_vendor_flag = 1;
1206 				} else {
1207 					DBG_88E("link to Ralink AP\n");
1208 					return HT_IOT_PEER_RALINK;
1209 				}
1210 			} else if (!memcmp(pIE->data, CISCO_OUI, 3)) {
1211 				DBG_88E("link to Cisco AP\n");
1212 				return HT_IOT_PEER_CISCO;
1213 			} else if (!memcmp(pIE->data, REALTEK_OUI, 3)) {
1214 				DBG_88E("link to Realtek 96B\n");
1215 				return HT_IOT_PEER_REALTEK;
1216 			} else if (!memcmp(pIE->data, AIRGOCAP_OUI, 3)) {
1217 				DBG_88E("link to Airgo Cap\n");
1218 				return HT_IOT_PEER_AIRGO;
1219 			} else if (!memcmp(pIE->data, EPIGRAM_OUI, 3)) {
1220 				epigram_vendor_flag = 1;
1221 				if (ralink_vendor_flag) {
1222 					DBG_88E("link to Tenda W311R AP\n");
1223 					return HT_IOT_PEER_TENDA;
1224 				}
1225 				DBG_88E("Capture EPIGRAM_OUI\n");
1226 			} else {
1227 				break;
1228 			}
1229 
1230 		default:
1231 			break;
1232 		}
1233 		i += (pIE->Length + 2);
1234 	}
1235 
1236 	if (ralink_vendor_flag && !epigram_vendor_flag) {
1237 		DBG_88E("link to Ralink AP\n");
1238 		return HT_IOT_PEER_RALINK;
1239 	} else if (ralink_vendor_flag && epigram_vendor_flag) {
1240 		DBG_88E("link to Tenda W311R AP\n");
1241 		return HT_IOT_PEER_TENDA;
1242 	}
1243 	DBG_88E("link to new AP\n");
1244 	return HT_IOT_PEER_UNKNOWN;
1245 }
1246 
update_IOT_info(struct adapter * padapter)1247 void update_IOT_info(struct adapter *padapter)
1248 {
1249 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1250 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1251 
1252 	switch (pmlmeinfo->assoc_AP_vendor) {
1253 	case HT_IOT_PEER_MARVELL:
1254 		pmlmeinfo->turboMode_cts2self = 1;
1255 		pmlmeinfo->turboMode_rtsen = 0;
1256 		break;
1257 	case HT_IOT_PEER_RALINK:
1258 		pmlmeinfo->turboMode_cts2self = 0;
1259 		pmlmeinfo->turboMode_rtsen = 1;
1260 		/* disable high power */
1261 		Switch_DM_Func(padapter, (u32)(~DYNAMIC_BB_DYNAMIC_TXPWR),
1262 			       false);
1263 		break;
1264 	case HT_IOT_PEER_REALTEK:
1265 		/* disable high power */
1266 		Switch_DM_Func(padapter, (u32)(~DYNAMIC_BB_DYNAMIC_TXPWR),
1267 			       false);
1268 		break;
1269 	default:
1270 		pmlmeinfo->turboMode_cts2self = 0;
1271 		pmlmeinfo->turboMode_rtsen = 1;
1272 		break;
1273 	}
1274 }
1275 
update_capinfo(struct adapter * Adapter,u16 updateCap)1276 void update_capinfo(struct adapter *Adapter, u16 updateCap)
1277 {
1278 	struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
1279 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1280 	bool ShortPreamble;
1281 
1282 	/*  Check preamble mode, 2005.01.06, by rcnjko. */
1283 	/*  Mark to update preamble value forever, 2008.03.18 by lanhsin */
1284 
1285 	if (updateCap & cShortPreamble) { /*  Short Preamble */
1286 		if (pmlmeinfo->preamble_mode != PREAMBLE_SHORT) { /*  PREAMBLE_LONG or PREAMBLE_AUTO */
1287 			ShortPreamble = true;
1288 			pmlmeinfo->preamble_mode = PREAMBLE_SHORT;
1289 			rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble);
1290 		}
1291 	} else { /*  Long Preamble */
1292 		if (pmlmeinfo->preamble_mode != PREAMBLE_LONG) {  /*  PREAMBLE_SHORT or PREAMBLE_AUTO */
1293 			ShortPreamble = false;
1294 			pmlmeinfo->preamble_mode = PREAMBLE_LONG;
1295 			rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble);
1296 		}
1297 	}
1298 
1299 	if (updateCap & cIBSS) {
1300 		/* Filen: See 802.11-2007 p.91 */
1301 		pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
1302 	} else { /* Filen: See 802.11-2007 p.90 */
1303 		if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11_24N)) {
1304 			if (updateCap & cShortSlotTime) { /*  Short Slot Time */
1305 				if (pmlmeinfo->slotTime != SHORT_SLOT_TIME)
1306 					pmlmeinfo->slotTime = SHORT_SLOT_TIME;
1307 			} else { /*  Long Slot Time */
1308 				if (pmlmeinfo->slotTime != NON_SHORT_SLOT_TIME)
1309 					pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
1310 			}
1311 		} else if (pmlmeext->cur_wireless_mode & (WIRELESS_11A | WIRELESS_11_5N)) {
1312 			pmlmeinfo->slotTime = SHORT_SLOT_TIME;
1313 		} else {
1314 			/* B Mode */
1315 			pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
1316 		}
1317 	}
1318 
1319 	rtw_hal_set_hwreg(Adapter, HW_VAR_SLOT_TIME, &pmlmeinfo->slotTime);
1320 }
1321 
update_wireless_mode(struct adapter * padapter)1322 void update_wireless_mode(struct adapter *padapter)
1323 {
1324 	int network_type = 0;
1325 	u32 SIFS_Timer;
1326 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1327 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1328 	struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
1329 	unsigned char *rate = cur_network->SupportedRates;
1330 
1331 	if (pmlmeinfo->HT_info_enable && pmlmeinfo->HT_caps_enable)
1332 		pmlmeinfo->HT_enable = 1;
1333 
1334 	if (pmlmeinfo->HT_enable)
1335 		network_type = WIRELESS_11_24N;
1336 
1337 	if (rtw_is_cckratesonly_included(rate))
1338 		network_type |= WIRELESS_11B;
1339 	else if (rtw_is_cckrates_included(rate))
1340 		network_type |= WIRELESS_11BG;
1341 	else
1342 		network_type |= WIRELESS_11G;
1343 
1344 	pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode;
1345 
1346 	SIFS_Timer = 0x0a0a0808;/* 0x0808 -> for CCK, 0x0a0a -> for OFDM */
1347 				/* change this value if having IOT issues. */
1348 
1349 	rtw_hal_set_hwreg(padapter, HW_VAR_RESP_SIFS,  (u8 *)&SIFS_Timer);
1350 
1351 	update_mgnt_tx_rate(padapter,
1352 			    pmlmeext->cur_wireless_mode & WIRELESS_11B ?
1353 			    IEEE80211_CCK_RATE_1MB : IEEE80211_OFDM_RATE_6MB);
1354 }
1355 
update_bmc_sta_support_rate(struct adapter * padapter,u32 mac_id)1356 void update_bmc_sta_support_rate(struct adapter *padapter, u32 mac_id)
1357 {
1358 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1359 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1360 
1361 	if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
1362 		/*  Only B, B/G, and B/G/N AP could use CCK rate */
1363 		memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates), rtw_basic_rate_cck, 4);
1364 	} else {
1365 		memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates), rtw_basic_rate_ofdm, 3);
1366 	}
1367 }
1368 
update_sta_support_rate(struct adapter * padapter,u8 * pvar_ie,uint var_ie_len,int cam_idx)1369 int update_sta_support_rate(struct adapter *padapter, u8 *pvar_ie, uint var_ie_len, int cam_idx)
1370 {
1371 	unsigned int ie_len;
1372 	struct ndis_802_11_var_ie *pIE;
1373 	int supportRateNum = 0;
1374 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1375 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1376 
1377 	pIE = (struct ndis_802_11_var_ie *)rtw_get_ie(pvar_ie, _SUPPORTEDRATES_IE_, &ie_len, var_ie_len);
1378 	if (!pIE)
1379 		return _FAIL;
1380 	if (ie_len > NDIS_802_11_LENGTH_RATES_EX)
1381 		return _FAIL;
1382 
1383 	memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates, pIE->data, ie_len);
1384 	supportRateNum = ie_len;
1385 
1386 	pIE = (struct ndis_802_11_var_ie *)rtw_get_ie(pvar_ie, _EXT_SUPPORTEDRATES_IE_, &ie_len, var_ie_len);
1387 	if (pIE) {
1388 		if (supportRateNum + ie_len > NDIS_802_11_LENGTH_RATES_EX)
1389 			return _FAIL;
1390 		memcpy((pmlmeinfo->FW_sta_info[cam_idx].SupportedRates + supportRateNum), pIE->data, ie_len);
1391 	}
1392 
1393 	return _SUCCESS;
1394 }
1395 
process_addba_req(struct adapter * padapter,u8 * paddba_req,u8 * addr)1396 void process_addba_req(struct adapter *padapter, u8 *paddba_req, u8 *addr)
1397 {
1398 	struct sta_info *psta;
1399 	u16 tid;
1400 	u16 param;
1401 	struct recv_reorder_ctrl *preorder_ctrl;
1402 	struct sta_priv *pstapriv = &padapter->stapriv;
1403 	struct ADDBA_request *preq = (struct ADDBA_request *)paddba_req;
1404 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1405 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1406 
1407 	psta = rtw_get_stainfo(pstapriv, addr);
1408 
1409 	if (psta) {
1410 		param = le16_to_cpu(preq->BA_para_set);
1411 		tid = (param >> 2) & 0x0f;
1412 		preorder_ctrl = &psta->recvreorder_ctrl[tid];
1413 		preorder_ctrl->indicate_seq = 0xffff;
1414 		preorder_ctrl->enable = pmlmeinfo->accept_addba_req;
1415 	}
1416 }
1417 
update_TSF(struct mlme_ext_priv * pmlmeext,u8 * pframe,uint len)1418 void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len)
1419 {
1420 	u8 *pIE;
1421 	__le32 *pbuf;
1422 
1423 	pIE = pframe + sizeof(struct ieee80211_hdr_3addr);
1424 	pbuf = (__le32 *)pIE;
1425 
1426 	pmlmeext->TSFValue = le32_to_cpu(*(pbuf + 1));
1427 
1428 	pmlmeext->TSFValue = pmlmeext->TSFValue << 32;
1429 
1430 	pmlmeext->TSFValue |= le32_to_cpu(*pbuf);
1431 }
1432 
correct_TSF(struct adapter * padapter,struct mlme_ext_priv * pmlmeext)1433 void correct_TSF(struct adapter *padapter, struct mlme_ext_priv *pmlmeext)
1434 {
1435 	rtw_hal_set_hwreg(padapter, HW_VAR_CORRECT_TSF, NULL);
1436 }
1437