1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15 #define _RTW_WLAN_UTIL_C_
16 
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 #include <linux/ieee80211.h>
20 #include <wifi.h>
21 #include <rtl8723a_spec.h>
22 
23 static unsigned char ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f};
24 static unsigned char ARTHEROS_OUI2[] = {0x00, 0x13, 0x74};
25 
26 static unsigned char BROADCOM_OUI1[] = {0x00, 0x10, 0x18};
27 static unsigned char BROADCOM_OUI2[] = {0x00, 0x0a, 0xf7};
28 
29 static unsigned char CISCO_OUI[] = {0x00, 0x40, 0x96};
30 static unsigned char MARVELL_OUI[] = {0x00, 0x50, 0x43};
31 static unsigned char RALINK_OUI[] = {0x00, 0x0c, 0x43};
32 static unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
33 static unsigned char AIRGOCAP_OUI[] = {0x00, 0x0a, 0xf5};
34 static unsigned char EPIGRAM_OUI[] = {0x00, 0x90, 0x4c};
35 
36 static unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
37 static unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
38 
39 #define R2T_PHY_DELAY		0
40 
41 /* define WAIT_FOR_BCN_TO_MIN	3000 */
42 #define WAIT_FOR_BCN_TO_MIN	6000
43 #define WAIT_FOR_BCN_TO_MAX	20000
44 
45 static u8 rtw_basic_rate_cck[4] = {
46 	IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK,
47 	IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
48 	IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK,
49 	IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK
50 };
51 
52 static u8 rtw_basic_rate_ofdm[3] = {
53 	IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK,
54 	IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
55 	IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
56 };
57 
58 static u8 rtw_basic_rate_mix[7] = {
59 	IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK,
60 	IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
61 	IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK,
62 	IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK,
63 	IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK,
64 	IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
65 	IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
66 };
67 
cckrates_included23a(unsigned char * rate,int ratelen)68 int cckrates_included23a(unsigned char *rate, int ratelen)
69 {
70 	int	i;
71 
72 	for (i = 0; i < ratelen; i++) {
73 		if  (((rate[i]) & 0x7f) == 2 || ((rate[i]) & 0x7f) == 4 ||
74 		     ((rate[i]) & 0x7f) == 11  || ((rate[i]) & 0x7f) == 22)
75 			return true;
76 	}
77 
78 	return false;
79 }
80 
cckratesonly_included23a(unsigned char * rate,int ratelen)81 int cckratesonly_included23a(unsigned char *rate, int ratelen)
82 {
83 	int	i;
84 
85 	for (i = 0; i < ratelen; i++) {
86 		if  (((rate[i]) & 0x7f) != 2 && ((rate[i]) & 0x7f) != 4 &&
87 		     ((rate[i]) & 0x7f) != 11 && ((rate[i]) & 0x7f) != 22)
88 		return false;
89 	}
90 
91 	return true;
92 }
93 
networktype_to_raid23a(unsigned char network_type)94 unsigned char networktype_to_raid23a(unsigned char network_type)
95 {
96 	unsigned char raid;
97 
98 	switch (network_type) {
99 	case WIRELESS_11B:
100 		raid = RATR_INX_WIRELESS_B;
101 		break;
102 	case WIRELESS_11A:
103 	case WIRELESS_11G:
104 		raid = RATR_INX_WIRELESS_G;
105 		break;
106 	case WIRELESS_11BG:
107 		raid = RATR_INX_WIRELESS_GB;
108 		break;
109 	case WIRELESS_11_24N:
110 	case WIRELESS_11_5N:
111 		raid = RATR_INX_WIRELESS_N;
112 		break;
113 	case WIRELESS_11A_5N:
114 	case WIRELESS_11G_24N:
115 		raid = RATR_INX_WIRELESS_NG;
116 		break;
117 	case WIRELESS_11BG_24N:
118 		raid = RATR_INX_WIRELESS_NGB;
119 		break;
120 	default:
121 		raid = RATR_INX_WIRELESS_GB;
122 		break;
123 	}
124 	return raid;
125 }
126 
judge_network_type23a(struct rtw_adapter * padapter,unsigned char * rate,int ratelen)127 u8 judge_network_type23a(struct rtw_adapter *padapter,
128 			 unsigned char *rate, int ratelen)
129 {
130 	u8 network_type = 0;
131 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
132 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
133 
134 	if (pmlmeext->cur_channel > 14) {
135 		if (pmlmeinfo->HT_enable)
136 			network_type = WIRELESS_11_5N;
137 		network_type |= WIRELESS_11A;
138 	} else {
139 		if (pmlmeinfo->HT_enable)
140 			network_type = WIRELESS_11_24N;
141 
142 		if ((cckratesonly_included23a(rate, ratelen)) == true)
143 			network_type |= WIRELESS_11B;
144 		else if ((cckrates_included23a(rate, ratelen)) == true)
145 			network_type |= WIRELESS_11BG;
146 		else
147 			network_type |= WIRELESS_11G;
148 	}
149 	return	network_type;
150 }
151 
ratetbl_val_2wifirate(unsigned char rate)152 static unsigned char ratetbl_val_2wifirate(unsigned char rate)
153 {
154 	unsigned char val = 0;
155 
156 	switch (rate & 0x7f) {
157 	case 0:
158 		val = IEEE80211_CCK_RATE_1MB;
159 		break;
160 	case 1:
161 		val = IEEE80211_CCK_RATE_2MB;
162 		break;
163 	case 2:
164 		val = IEEE80211_CCK_RATE_5MB;
165 		break;
166 	case 3:
167 		val = IEEE80211_CCK_RATE_11MB;
168 		break;
169 	case 4:
170 		val = IEEE80211_OFDM_RATE_6MB;
171 		break;
172 	case 5:
173 		val = IEEE80211_OFDM_RATE_9MB;
174 		break;
175 	case 6:
176 		val = IEEE80211_OFDM_RATE_12MB;
177 		break;
178 	case 7:
179 		val = IEEE80211_OFDM_RATE_18MB;
180 		break;
181 	case 8:
182 		val = IEEE80211_OFDM_RATE_24MB;
183 		break;
184 	case 9:
185 		val = IEEE80211_OFDM_RATE_36MB;
186 		break;
187 	case 10:
188 		val = IEEE80211_OFDM_RATE_48MB;
189 		break;
190 	case 11:
191 		val = IEEE80211_OFDM_RATE_54MB;
192 		break;
193 	}
194 	return val;
195 }
196 
is_basicrate(struct rtw_adapter * padapter,unsigned char rate)197 static int is_basicrate(struct rtw_adapter *padapter, unsigned char rate)
198 {
199 	int i;
200 	unsigned char val;
201 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
202 
203 	for (i = 0; i < NumRates; i++) {
204 		val = pmlmeext->basicrate[i];
205 
206 		if (val != 0xff && val != 0xfe) {
207 			if (rate == ratetbl_val_2wifirate(val))
208 				return true;
209 		}
210 	}
211 
212 	return false;
213 }
214 
ratetbl2rateset(struct rtw_adapter * padapter,unsigned char * rateset)215 static unsigned int ratetbl2rateset(struct rtw_adapter *padapter,
216 				    unsigned char *rateset)
217 {
218 	int i;
219 	unsigned char rate;
220 	unsigned int len = 0;
221 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
222 
223 	for (i = 0; i < NumRates; i++) {
224 		rate = pmlmeext->datarate[i];
225 
226 		switch (rate) {
227 		case 0xff:
228 			return len;
229 		case 0xfe:
230 			continue;
231 		default:
232 			rate = ratetbl_val_2wifirate(rate);
233 
234 			if (is_basicrate(padapter, rate) == true)
235 				rate |= IEEE80211_BASIC_RATE_MASK;
236 
237 			rateset[len] = rate;
238 			len++;
239 			break;
240 		}
241 	}
242 	return len;
243 }
244 
get_rate_set23a(struct rtw_adapter * padapter,unsigned char * pbssrate,int * bssrate_len)245 void get_rate_set23a(struct rtw_adapter *padapter,
246 		     unsigned char *pbssrate, int *bssrate_len)
247 {
248 	unsigned char supportedrates[NumRates];
249 
250 	memset(supportedrates, 0, NumRates);
251 	*bssrate_len = ratetbl2rateset(padapter, supportedrates);
252 	memcpy(pbssrate, supportedrates, *bssrate_len);
253 }
254 
UpdateBrateTbl23a(struct rtw_adapter * Adapter,u8 * mBratesOS)255 void UpdateBrateTbl23a(struct rtw_adapter *Adapter, u8 *mBratesOS)
256 {
257 	u8 i;
258 	u8 rate;
259 
260 	/*  1M, 2M, 5.5M, 11M, 6M, 12M, 24M are mandatory. */
261 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
262 		rate = mBratesOS[i] & 0x7f;
263 		switch (rate) {
264 		case IEEE80211_CCK_RATE_1MB:
265 		case IEEE80211_CCK_RATE_2MB:
266 		case IEEE80211_CCK_RATE_5MB:
267 		case IEEE80211_CCK_RATE_11MB:
268 		case IEEE80211_OFDM_RATE_6MB:
269 		case IEEE80211_OFDM_RATE_12MB:
270 		case IEEE80211_OFDM_RATE_24MB:
271 			mBratesOS[i] |= IEEE80211_BASIC_RATE_MASK;
272 			break;
273 		default:
274 			break;
275 		}
276 	}
277 }
278 
Update23aTblForSoftAP(u8 * bssrateset,u32 bssratelen)279 void Update23aTblForSoftAP(u8 *bssrateset, u32 bssratelen)
280 {
281 	u8 i;
282 	u8 rate;
283 
284 	for (i = 0; i < bssratelen; i++) {
285 		rate = bssrateset[i] & 0x7f;
286 		switch (rate) {
287 		case IEEE80211_CCK_RATE_1MB:
288 		case IEEE80211_CCK_RATE_2MB:
289 		case IEEE80211_CCK_RATE_5MB:
290 		case IEEE80211_CCK_RATE_11MB:
291 			bssrateset[i] |= IEEE80211_BASIC_RATE_MASK;
292 			break;
293 		}
294 	}
295 }
296 
rtw_get_oper_ch23a(struct rtw_adapter * adapter)297 inline u8 rtw_get_oper_ch23a(struct rtw_adapter *adapter)
298 {
299 	return adapter_to_dvobj(adapter)->oper_channel;
300 }
301 
rtw_set_oper_ch23a(struct rtw_adapter * adapter,u8 ch)302 inline void rtw_set_oper_ch23a(struct rtw_adapter *adapter, u8 ch)
303 {
304 	adapter_to_dvobj(adapter)->oper_channel = ch;
305 }
306 
rtw_get_oper_bw23a(struct rtw_adapter * adapter)307 inline u8 rtw_get_oper_bw23a(struct rtw_adapter *adapter)
308 {
309 	return adapter_to_dvobj(adapter)->oper_bwmode;
310 }
311 
rtw_set_oper_bw23a(struct rtw_adapter * adapter,u8 bw)312 inline void rtw_set_oper_bw23a(struct rtw_adapter *adapter, u8 bw)
313 {
314 	adapter_to_dvobj(adapter)->oper_bwmode = bw;
315 }
316 
rtw_get_oper_ch23aoffset(struct rtw_adapter * adapter)317 inline u8 rtw_get_oper_ch23aoffset(struct rtw_adapter *adapter)
318 {
319 	return adapter_to_dvobj(adapter)->oper_ch_offset;
320 }
321 
rtw_set_oper_ch23aoffset23a(struct rtw_adapter * adapter,u8 offset)322 inline void rtw_set_oper_ch23aoffset23a(struct rtw_adapter *adapter, u8 offset)
323 {
324 	adapter_to_dvobj(adapter)->oper_ch_offset = offset;
325 }
326 
SelectChannel23a(struct rtw_adapter * padapter,unsigned char channel)327 void SelectChannel23a(struct rtw_adapter *padapter, unsigned char channel)
328 {
329 	mutex_lock(&adapter_to_dvobj(padapter)->setch_mutex);
330 
331 	/* saved channel info */
332 	rtw_set_oper_ch23a(padapter, channel);
333 
334 	PHY_SwChnl8723A(padapter, channel);
335 
336 	mutex_unlock(&adapter_to_dvobj(padapter)->setch_mutex);
337 }
338 
set_bwmode(struct rtw_adapter * padapter,unsigned short bwmode,unsigned char channel_offset)339 static void set_bwmode(struct rtw_adapter *padapter, unsigned short bwmode,
340 		       unsigned char channel_offset)
341 {
342 	mutex_lock(&adapter_to_dvobj(padapter)->setbw_mutex);
343 
344 	/* saved bw info */
345 	rtw_set_oper_bw23a(padapter, bwmode);
346 	rtw_set_oper_ch23aoffset23a(padapter, channel_offset);
347 
348 	PHY_SetBWMode23a8723A(padapter, (enum ht_channel_width)bwmode,
349 			      channel_offset);
350 
351 	mutex_unlock(&adapter_to_dvobj(padapter)->setbw_mutex);
352 }
353 
set_channel_bwmode23a(struct rtw_adapter * padapter,unsigned char channel,unsigned char channel_offset,unsigned short bwmode)354 void set_channel_bwmode23a(struct rtw_adapter *padapter, unsigned char channel,
355 			   unsigned char channel_offset, unsigned short bwmode)
356 {
357 	u8 center_ch;
358 
359 	if (bwmode == HT_CHANNEL_WIDTH_20 ||
360 	    channel_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) {
361 		/* SelectChannel23a(padapter, channel); */
362 		center_ch = channel;
363 	} else {
364 		/* switch to the proper channel */
365 		if (channel_offset == HAL_PRIME_CHNL_OFFSET_LOWER) {
366 			/* SelectChannel23a(padapter, channel + 2); */
367 			center_ch = channel + 2;
368 		} else {
369 			/* SelectChannel23a(padapter, channel - 2); */
370 			center_ch = channel - 2;
371 		}
372 	}
373 
374 	/* set Channel */
375 	mutex_lock(&adapter_to_dvobj(padapter)->setch_mutex);
376 
377 	/* saved channel/bw info */
378 	rtw_set_oper_ch23a(padapter, channel);
379 	rtw_set_oper_bw23a(padapter, bwmode);
380 	rtw_set_oper_ch23aoffset23a(padapter, channel_offset);
381 
382 	PHY_SwChnl8723A(padapter, center_ch); /*  set center channel */
383 
384 	mutex_unlock(&adapter_to_dvobj(padapter)->setch_mutex);
385 
386 	set_bwmode(padapter, bwmode, channel_offset);
387 }
388 
get_my_bssid23a(struct wlan_bssid_ex * pnetwork)389 inline u8 *get_my_bssid23a(struct wlan_bssid_ex *pnetwork)
390 {
391 	return pnetwork->MacAddress;
392 }
393 
is_client_associated_to_ap23a(struct rtw_adapter * padapter)394 bool is_client_associated_to_ap23a(struct rtw_adapter *padapter)
395 {
396 	struct mlme_ext_priv *pmlmeext;
397 	struct mlme_ext_info *pmlmeinfo;
398 
399 	if (!padapter)
400 		return false;
401 
402 	pmlmeext = &padapter->mlmeextpriv;
403 	pmlmeinfo = &pmlmeext->mlmext_info;
404 
405 	if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS &&
406 	    (pmlmeinfo->state & 0x03) == MSR_INFRA)
407 		return true;
408 	else
409 		return false;
410 }
411 
is_client_associated_to_ibss23a(struct rtw_adapter * padapter)412 bool is_client_associated_to_ibss23a(struct rtw_adapter *padapter)
413 {
414 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
415 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
416 
417 	if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS &&
418 	    (pmlmeinfo->state & 0x03) == MSR_ADHOC)
419 		return true;
420 	else
421 		return false;
422 }
423 
is_IBSS_empty23a(struct rtw_adapter * padapter)424 bool is_IBSS_empty23a(struct rtw_adapter *padapter)
425 {
426 	unsigned int i;
427 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
428 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
429 
430 	for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
431 		if (pmlmeinfo->FW_sta_info[i].status == 1)
432 			return false;
433 	}
434 
435 	return true;
436 }
437 
decide_wait_for_beacon_timeout23a(unsigned int bcn_interval)438 unsigned int decide_wait_for_beacon_timeout23a(unsigned int bcn_interval)
439 {
440 	if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN)
441 		return WAIT_FOR_BCN_TO_MIN;
442 	else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX)
443 		return WAIT_FOR_BCN_TO_MAX;
444 	else
445 		return bcn_interval << 2;
446 }
447 
clear_cam_entry23a(struct rtw_adapter * padapter,u8 entry)448 void clear_cam_entry23a(struct rtw_adapter *padapter, u8 entry)
449 {
450 	unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
451 
452 	unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453 				    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454 				    0x00, 0x00, 0x00, 0x00};
455 
456 	rtl8723a_cam_write(padapter, entry, 0, null_sta, null_key);
457 }
458 
allocate_fw_sta_entry23a(struct rtw_adapter * padapter)459 int allocate_fw_sta_entry23a(struct rtw_adapter *padapter)
460 {
461 	unsigned int mac_id;
462 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
463 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
464 
465 	for (mac_id = IBSS_START_MAC_ID; mac_id < NUM_STA; mac_id++) {
466 		if (pmlmeinfo->FW_sta_info[mac_id].status == 0) {
467 			pmlmeinfo->FW_sta_info[mac_id].status = 1;
468 			pmlmeinfo->FW_sta_info[mac_id].retry = 0;
469 			break;
470 		}
471 	}
472 
473 	return mac_id;
474 }
475 
flush_all_cam_entry23a(struct rtw_adapter * padapter)476 void flush_all_cam_entry23a(struct rtw_adapter *padapter)
477 {
478 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
479 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
480 
481 	rtl8723a_cam_invalidate_all(padapter);
482 
483 	memset(pmlmeinfo->FW_sta_info, 0, sizeof(pmlmeinfo->FW_sta_info));
484 }
485 
WMM_param_handler23a(struct rtw_adapter * padapter,const u8 * p)486 int WMM_param_handler23a(struct rtw_adapter *padapter, const u8 *p)
487 {
488 	/* struct registry_priv	*pregpriv = &padapter->registrypriv; */
489 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
490 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
491 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
492 
493 	if (pmlmepriv->qos_option == 0) {
494 		pmlmeinfo->WMM_enable = 0;
495 		return _FAIL;
496 	}
497 
498 	pmlmeinfo->WMM_enable = 1;
499 	memcpy(&pmlmeinfo->WMM_param, p + 2 + 6,
500 	       sizeof(struct WMM_para_element));
501 	return true;
502 }
503 
WMMOnAssocRsp23a(struct rtw_adapter * padapter)504 void WMMOnAssocRsp23a(struct rtw_adapter *padapter)
505 {
506 	u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime;
507 	u8 acm_mask;
508 	u16 TXOP;
509 	u32 acParm, i;
510 	u32 edca[4], inx[4];
511 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
512 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
513 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
514 	struct registry_priv *pregpriv = &padapter->registrypriv;
515 
516 	if (pmlmeinfo->WMM_enable == 0) {
517 		padapter->mlmepriv.acm_mask = 0;
518 		return;
519 	}
520 
521 	acm_mask = 0;
522 
523 	if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
524 		aSifsTime = 10;
525 	else
526 		aSifsTime = 16;
527 
528 	for (i = 0; i < 4; i++) {
529 		ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03;
530 		ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01;
531 
532 		/* AIFS = AIFSN * slot time + SIFS - r2t phy delay */
533 		AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) *
534 			pmlmeinfo->slotTime + aSifsTime;
535 
536 		ECWMin = pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f;
537 		ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4;
538 		TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit);
539 
540 		acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
541 
542 		switch (ACI) {
543 		case 0x0:
544 			rtl8723a_set_ac_param_be(padapter, acParm);
545 			acm_mask |= (ACM? BIT(1):0);
546 			edca[XMIT_BE_QUEUE] = acParm;
547 			break;
548 		case 0x1:
549 			rtl8723a_set_ac_param_bk(padapter, acParm);
550 			/* acm_mask |= (ACM? BIT(0):0); */
551 			edca[XMIT_BK_QUEUE] = acParm;
552 			break;
553 		case 0x2:
554 			rtl8723a_set_ac_param_vi(padapter, acParm);
555 			acm_mask |= (ACM? BIT(2):0);
556 			edca[XMIT_VI_QUEUE] = acParm;
557 			break;
558 		case 0x3:
559 			rtl8723a_set_ac_param_vo(padapter, acParm);
560 			acm_mask |= (ACM? BIT(3):0);
561 			edca[XMIT_VO_QUEUE] = acParm;
562 			break;
563 		}
564 
565 		DBG_8723A("WMM(%x): %x, %x\n", ACI, ACM, acParm);
566 	}
567 
568 	if (padapter->registrypriv.acm_method == 1)
569 		rtl8723a_set_acm_ctrl(padapter, acm_mask);
570 	else
571 		padapter->mlmepriv.acm_mask = acm_mask;
572 
573 	inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
574 
575 	if (pregpriv->wifi_spec == 1) {
576 		u32 j, change_inx = false;
577 
578 		/* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */
579 		for (i = 0; i < 4; i++) {
580 			for (j = i+1; j < 4; j++) {
581 				/* compare CW and AIFS */
582 				if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF)) {
583 					change_inx = true;
584 				} else if ((edca[j] & 0xFFFF) ==
585 					   (edca[i] & 0xFFFF)) {
586 					/* compare TXOP */
587 					if ((edca[j] >> 16) > (edca[i] >> 16))
588 						change_inx = true;
589 				}
590 
591 				if (change_inx) {
592 					swap(edca[i], edca[j]);
593 					swap(inx[i], inx[j]);
594 					change_inx = false;
595 				}
596 			}
597 		}
598 	}
599 
600 	for (i = 0; i<4; i++) {
601 		pxmitpriv->wmm_para_seq[i] = inx[i];
602 		DBG_8723A("wmm_para_seq(%d): %d\n", i,
603 			  pxmitpriv->wmm_para_seq[i]);
604 	}
605 }
606 
bwmode_update_check(struct rtw_adapter * padapter,const u8 * p)607 static void bwmode_update_check(struct rtw_adapter *padapter, const u8 *p)
608 {
609 	struct ieee80211_ht_operation *pHT_info;
610 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
611 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
612 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
613 	struct registry_priv *pregistrypriv = &padapter->registrypriv;
614 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
615 	unsigned char new_bwmode;
616 	unsigned char new_ch_offset;
617 
618 	if (!p)
619 		return;
620 	if (!phtpriv->ht_option)
621 		return;
622 	if (p[1] != sizeof(struct ieee80211_ht_operation))
623 		return;
624 
625 	pHT_info = (struct ieee80211_ht_operation *)(p + 2);
626 
627 	if ((pHT_info->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) &&
628 	    pregistrypriv->cbw40_enable) {
629 		new_bwmode = HT_CHANNEL_WIDTH_40;
630 
631 		switch (pHT_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET){
632 		case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
633 			new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
634 			break;
635 		case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
636 			new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
637 			break;
638 		default:
639 			new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
640 			break;
641 		}
642 	} else {
643 		new_bwmode = HT_CHANNEL_WIDTH_20;
644 		new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
645 	}
646 
647 	if (new_bwmode != pmlmeext->cur_bwmode ||
648 	    new_ch_offset != pmlmeext->cur_ch_offset) {
649 		pmlmeinfo->bwmode_updated = true;
650 
651 		pmlmeext->cur_bwmode = new_bwmode;
652 		pmlmeext->cur_ch_offset = new_ch_offset;
653 
654 		/* update HT info also */
655 		HT_info_handler23a(padapter, p);
656 	} else
657 		pmlmeinfo->bwmode_updated = false;
658 
659 	if (pmlmeinfo->bwmode_updated) {
660 		struct sta_info *psta;
661 		struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
662 		struct sta_priv	*pstapriv = &padapter->stapriv;
663 
664 		/* set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
665 		   pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
666 
667 		/* update ap's stainfo */
668 		psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
669 		if (psta) {
670 			struct ht_priv *phtpriv_sta = &psta->htpriv;
671 
672 			if (phtpriv_sta->ht_option) {
673 				/*  bwmode */
674 				phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
675 				phtpriv_sta->ch_offset =
676 					pmlmeext->cur_ch_offset;
677 			} else {
678 				phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
679 				phtpriv_sta->ch_offset =
680 					HAL_PRIME_CHNL_OFFSET_DONT_CARE;
681 			}
682 		}
683 	}
684 }
685 
HT_caps_handler23a(struct rtw_adapter * padapter,const u8 * p)686 void HT_caps_handler23a(struct rtw_adapter *padapter, const u8 *p)
687 {
688 	unsigned int i;
689 	u8 rf_type;
690 	u8 max_AMPDU_len, min_MPDU_spacing;
691 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
692 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
693 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
694 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
695 	struct ieee80211_ht_cap *cap;
696 	u8 *dstcap;
697 
698 	if (!p)
699 		return;
700 
701 	if (!phtpriv->ht_option)
702 		return;
703 
704 	pmlmeinfo->HT_caps_enable = 1;
705 
706 	cap = &pmlmeinfo->ht_cap;
707 	dstcap = (u8 *)cap;
708 	for (i = 0; i < p[1]; i++) {
709 		if (i != 2) {
710 			dstcap[i] &= p[i + 2];
711 		} else {
712 			/* modify from  fw by Thomas 2010/11/17 */
713 			if ((cap->ampdu_params_info &
714 			     IEEE80211_HT_AMPDU_PARM_FACTOR) >
715 			    (p[i + 2] & IEEE80211_HT_AMPDU_PARM_FACTOR))
716 				max_AMPDU_len = p[i + 2] &
717 					IEEE80211_HT_AMPDU_PARM_FACTOR;
718 			else
719 				max_AMPDU_len = cap->ampdu_params_info &
720 					IEEE80211_HT_AMPDU_PARM_FACTOR;
721 
722 			if ((cap->ampdu_params_info &
723 			     IEEE80211_HT_AMPDU_PARM_DENSITY) >
724 			    (p[i + 2] & IEEE80211_HT_AMPDU_PARM_DENSITY))
725 				min_MPDU_spacing = cap->ampdu_params_info &
726 					IEEE80211_HT_AMPDU_PARM_DENSITY;
727 			else
728 				min_MPDU_spacing = p[i + 2] &
729 					IEEE80211_HT_AMPDU_PARM_DENSITY;
730 
731 			cap->ampdu_params_info =
732 				max_AMPDU_len | min_MPDU_spacing;
733 		}
734 	}
735 
736 	rf_type = rtl8723a_get_rf_type(padapter);
737 
738 	/* update the MCS rates */
739 	for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
740 		if (rf_type == RF_1T1R || rf_type == RF_1T2R)
741 			cap->mcs.rx_mask[i] &= MCS_rate_1R23A[i];
742 		else
743 			cap->mcs.rx_mask[i] &= MCS_rate_2R23A[i];
744 	}
745 }
746 
HT_info_handler23a(struct rtw_adapter * padapter,const u8 * p)747 void HT_info_handler23a(struct rtw_adapter *padapter, const u8 *p)
748 {
749 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
750 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
751 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
752 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
753 
754 	if (!p)
755 		return;
756 
757 	if (!phtpriv->ht_option)
758 		return;
759 
760 	if (p[1] != sizeof(struct ieee80211_ht_operation))
761 		return;
762 
763 	pmlmeinfo->HT_info_enable = 1;
764 	memcpy(&pmlmeinfo->HT_info, p + 2, p[1]);
765 }
766 
HTOnAssocRsp23a(struct rtw_adapter * padapter)767 void HTOnAssocRsp23a(struct rtw_adapter *padapter)
768 {
769 	unsigned char max_AMPDU_len;
770 	unsigned char min_MPDU_spacing;
771 	/* struct registry_priv	 *pregpriv = &padapter->registrypriv; */
772 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
773 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
774 
775 	DBG_8723A("%s\n", __func__);
776 
777 	if (pmlmeinfo->HT_info_enable && pmlmeinfo->HT_caps_enable)
778 		pmlmeinfo->HT_enable = 1;
779 	else {
780 		pmlmeinfo->HT_enable = 0;
781 		/* set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
782 		   pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
783 		return;
784 	}
785 
786 	/* handle A-MPDU parameter field */
787 	/*
788 		AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
789 		AMPDU_para [4:2]:Min MPDU Start Spacing
790 	*/
791 	max_AMPDU_len = pmlmeinfo->ht_cap.ampdu_params_info &
792 		IEEE80211_HT_AMPDU_PARM_FACTOR;
793 
794 	min_MPDU_spacing =
795 		(pmlmeinfo->ht_cap.ampdu_params_info &
796 		 IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2;
797 
798 	rtl8723a_set_ampdu_min_space(padapter, min_MPDU_spacing);
799 	rtl8723a_set_ampdu_factor(padapter, max_AMPDU_len);
800 }
801 
ERP_IE_handler23a(struct rtw_adapter * padapter,const u8 * p)802 void ERP_IE_handler23a(struct rtw_adapter *padapter, const u8 *p)
803 {
804 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
805 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
806 
807 	if (p[1] > 1)
808 		return;
809 
810 	pmlmeinfo->ERP_enable = 1;
811 	memcpy(&pmlmeinfo->ERP_IE, p + 2, p[1]);
812 }
813 
VCS_update23a(struct rtw_adapter * padapter,struct sta_info * psta)814 void VCS_update23a(struct rtw_adapter *padapter, struct sta_info *psta)
815 {
816 	struct registry_priv *pregpriv = &padapter->registrypriv;
817 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
818 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
819 
820 	switch (pregpriv->vrtl_carrier_sense) { /* 0:off 1:on 2:auto */
821 	case 0: /* off */
822 		psta->rtsen = 0;
823 		psta->cts2self = 0;
824 		break;
825 	case 1: /* on */
826 		if (pregpriv->vcs_type == RTS_CTS) {
827 			psta->rtsen = 1;
828 			psta->cts2self = 0;
829 		} else {
830 			psta->rtsen = 0;
831 			psta->cts2self = 1;
832 		}
833 		break;
834 	case 2: /* auto */
835 	default:
836 		if (pmlmeinfo->ERP_enable && pmlmeinfo->ERP_IE & BIT(1)) {
837 			if (pregpriv->vcs_type == RTS_CTS) {
838 				psta->rtsen = 1;
839 				psta->cts2self = 0;
840 			} else {
841 				psta->rtsen = 0;
842 				psta->cts2self = 1;
843 			}
844 		} else {
845 			psta->rtsen = 0;
846 			psta->cts2self = 0;
847 		}
848 		break;
849 	}
850 }
851 
rtw_check_bcn_info23a(struct rtw_adapter * Adapter,struct ieee80211_mgmt * mgmt,u32 pkt_len)852 int rtw_check_bcn_info23a(struct rtw_adapter *Adapter,
853 			  struct ieee80211_mgmt *mgmt, u32 pkt_len)
854 {
855 	struct wlan_network *cur_network = &Adapter->mlmepriv.cur_network;
856 	struct ieee80211_ht_operation *pht_info;
857 	unsigned short val16;
858 	u8 crypto, bcn_channel;
859 	int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0, r;
860 	int pie_len, ssid_len, privacy;
861 	const u8 *p, *ssid;
862 
863 	if (!is_client_associated_to_ap23a(Adapter))
864 		return _SUCCESS;
865 
866 	if (unlikely(!ieee80211_is_beacon(mgmt->frame_control))) {
867 		printk(KERN_WARNING "%s: received a non beacon frame!\n",
868 		       __func__);
869 		return _FAIL;
870 	}
871 
872 	if (!ether_addr_equal(cur_network->network.MacAddress, mgmt->bssid)) {
873 		DBG_8723A("%s: linked but recv other bssid bcn %pM %pM\n",
874 			  __func__, mgmt->bssid,
875 			  cur_network->network.MacAddress);
876 		return _FAIL;
877 	}
878 
879 	/* check bw and channel offset */
880 	/* parsing HT_CAP_IE */
881 	pie_len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
882 
883 	/* Checking for channel */
884 	p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, mgmt->u.beacon.variable,
885 			     pie_len);
886 	if (p)
887 		bcn_channel = p[2];
888 	else {
889 		/* In 5G, some ap do not have DSSET IE checking HT
890 		   info for channel */
891 		p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
892 				     mgmt->u.beacon.variable, pie_len);
893 
894 		if (p && p[1] > 0) {
895 			pht_info = (struct ieee80211_ht_operation *)(p + 2);
896 			bcn_channel = pht_info->primary_chan;
897 		} else { /* we don't find channel IE, so don't check it */
898 			DBG_8723A("Oops: %s we don't find channel IE, so don't "
899 				  "check it\n", __func__);
900 			bcn_channel = Adapter->mlmeextpriv.cur_channel;
901 		}
902 	}
903 	if (bcn_channel != Adapter->mlmeextpriv.cur_channel) {
904 		DBG_8723A("%s beacon channel:%d cur channel:%d disconnect\n",
905 			  __func__, bcn_channel,
906 			  Adapter->mlmeextpriv.cur_channel);
907 		goto _mismatch;
908 	}
909 
910 	/* checking SSID */
911 	p = cfg80211_find_ie(WLAN_EID_SSID, mgmt->u.beacon.variable, pie_len);
912 	if (p && p[1]) {
913 		ssid = p + 2;
914 		ssid_len = p[1];
915 	} else {
916 		DBG_8723A("%s marc: cannot find SSID for survey event\n",
917 			  __func__);
918 		ssid = NULL;
919 		ssid_len = 0;
920 	}
921 
922 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
923 		 "%s bssid.Ssid.Ssid:%s bssid.Ssid.SsidLength:%d cur_network->network.Ssid.Ssid:%s len:%d\n",
924 		 __func__, ssid, ssid_len, cur_network->network.Ssid.ssid,
925 		 cur_network->network.Ssid.ssid_len);
926 
927 	if (ssid_len != cur_network->network.Ssid.ssid_len || ssid_len > 32 ||
928 	    (ssid_len &&
929 	     memcmp(ssid, cur_network->network.Ssid.ssid, ssid_len))) {
930 		DBG_8723A("%s(), SSID is not match return FAIL\n", __func__);
931 		goto _mismatch;
932 	}
933 
934 	/* check encryption info */
935 	val16 = le16_to_cpu(mgmt->u.beacon.capab_info);
936 
937 	if (val16 & WLAN_CAPABILITY_PRIVACY)
938 		privacy = 1;
939 	else
940 		privacy = 0;
941 
942 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
943 		 "%s(): cur_network->network.Privacy is %d, bssid.Privacy is %d\n",
944 		 __func__, cur_network->network.Privacy, privacy);
945 	if (cur_network->network.Privacy != privacy) {
946 		DBG_8723A("%s(), privacy is not match return FAIL\n", __func__);
947 		goto _mismatch;
948 	}
949 
950 	p = cfg80211_find_ie(WLAN_EID_RSN, mgmt->u.beacon.variable, pie_len);
951 	if (p && p[1]) {
952 		crypto = ENCRYP_PROTOCOL_WPA2;
953 		if (p && p[1]) {
954 			r = rtw_parse_wpa2_ie23a(p, p[1] + 2, &group_cipher,
955 						 &pairwise_cipher, &is_8021x);
956 			if (r == _SUCCESS)
957 				RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
958 					 "%s pnetwork->pairwise_cipher: %d, pnetwork->group_cipher: %d, is_802x : %d\n",
959 					 __func__, pairwise_cipher,
960 					 group_cipher, is_8021x);
961 			}
962 	} else {
963 		p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
964 					    WLAN_OUI_TYPE_MICROSOFT_WPA,
965 					    mgmt->u.beacon.variable, pie_len);
966 		if (p && p[1]) {
967 			crypto = ENCRYP_PROTOCOL_WPA;
968 			r = rtw_parse_wpa_ie23a(p, p[1] + 2, &group_cipher,
969 						&pairwise_cipher, &is_8021x);
970 			if (r == _SUCCESS)
971 				RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
972 					 "%s pnetwork->pairwise_cipher: %d, group_cipher is %d, is_8021x is %d\n",
973 					 __func__, pairwise_cipher,
974 					 group_cipher, is_8021x);
975 		} else {
976 			if (privacy)
977 				crypto = ENCRYP_PROTOCOL_WEP;
978 			else
979 				crypto = ENCRYP_PROTOCOL_OPENSYS;
980 		}
981 	}
982 
983 	if (cur_network->BcnInfo.encryp_protocol != crypto) {
984 		DBG_8723A("%s(): encryption mismatch, return FAIL\n", __func__);
985 		goto _mismatch;
986 	}
987 
988 	if (crypto == ENCRYP_PROTOCOL_WPA || crypto == ENCRYP_PROTOCOL_WPA2) {
989 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
990 			 "%s cur_network->group_cipher is %d: %d\n", __func__,
991 			 cur_network->BcnInfo.group_cipher, group_cipher);
992 		if (pairwise_cipher != cur_network->BcnInfo.pairwise_cipher ||
993 		    group_cipher != cur_network->BcnInfo.group_cipher) {
994 			DBG_8723A("%s pairwise_cipher(%x:%x) or group_cipher "
995 				  "(%x:%x) is not match, return FAIL\n",
996 				  __func__, pairwise_cipher,
997 				  cur_network->BcnInfo.pairwise_cipher,
998 				  group_cipher,
999 				  cur_network->BcnInfo.group_cipher);
1000 			goto _mismatch;
1001 		}
1002 
1003 		if (is_8021x != cur_network->BcnInfo.is_8021x) {
1004 			DBG_8723A("%s authentication is not match, return "
1005 				  "FAIL\n", __func__);
1006 			goto _mismatch;
1007 		}
1008 	}
1009 
1010 	return _SUCCESS;
1011 
1012 _mismatch:
1013 
1014 	return _FAIL;
1015 }
1016 
update_beacon23a_info(struct rtw_adapter * padapter,struct ieee80211_mgmt * mgmt,uint pkt_len,struct sta_info * psta)1017 void update_beacon23a_info(struct rtw_adapter *padapter,
1018 			   struct ieee80211_mgmt *mgmt,
1019 			   uint pkt_len, struct sta_info *psta)
1020 {
1021 	unsigned int len;
1022 	const u8 *p;
1023 
1024 	len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
1025 
1026 	p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, mgmt->u.beacon.variable,
1027 			     len);
1028 	if (p)
1029 		bwmode_update_check(padapter, p);
1030 
1031 	p = cfg80211_find_ie(WLAN_EID_ERP_INFO, mgmt->u.beacon.variable, len);
1032 	if (p) {
1033 		ERP_IE_handler23a(padapter, p);
1034 		VCS_update23a(padapter, psta);
1035 	}
1036 }
1037 
is_ap_in_tkip23a(struct rtw_adapter * padapter)1038 bool is_ap_in_tkip23a(struct rtw_adapter *padapter)
1039 {
1040 	u32 i;
1041 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1042 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1043 	struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
1044 	const u8 *p;
1045 
1046 	if (cur_network->capability & WLAN_CAPABILITY_PRIVACY) {
1047 		for (i = 0; i < pmlmeinfo->network.IELength;) {
1048 			p = pmlmeinfo->network.IEs + i;
1049 
1050 			switch (p[0]) {
1051 			case WLAN_EID_VENDOR_SPECIFIC:
1052 				if (!memcmp(p + 2, RTW_WPA_OUI23A_TYPE, 4) &&
1053 				    !memcmp(p + 2 + 12, WPA_TKIP_CIPHER, 4))
1054 					return true;
1055 				break;
1056 			case WLAN_EID_RSN:
1057 				if (!memcmp(p + 2 + 8, RSN_TKIP_CIPHER, 4))
1058 					return true;
1059 				break;
1060 			default:
1061 				break;
1062 			}
1063 			i += (p[1] + 2);
1064 		}
1065 		return false;
1066 	} else
1067 		return false;
1068 }
1069 
should_forbid_n_rate23a(struct rtw_adapter * padapter)1070 bool should_forbid_n_rate23a(struct rtw_adapter *padapter)
1071 {
1072 	u32 i;
1073 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1074 	struct wlan_bssid_ex  *cur_network = &pmlmepriv->cur_network.network;
1075 	const u8 *p;
1076 
1077 	if (cur_network->capability & WLAN_CAPABILITY_PRIVACY) {
1078 		for (i = 0; i < cur_network->IELength;) {
1079 			p = cur_network->IEs + i;
1080 
1081 			switch (p[0]) {
1082 			case WLAN_EID_VENDOR_SPECIFIC:
1083 				if (!memcmp(p + 2, RTW_WPA_OUI23A_TYPE, 4) &&
1084 				    (!memcmp(p + 2 + 12,
1085 					     WPA_CIPHER_SUITE_CCMP23A, 4) ||
1086 				     !memcmp(p + 2 + 16,
1087 					     WPA_CIPHER_SUITE_CCMP23A, 4)))
1088 					return false;
1089 				break;
1090 			case WLAN_EID_RSN:
1091 				if (!memcmp(p + 2 + 8,
1092 					    RSN_CIPHER_SUITE_CCMP23A, 4) ||
1093 				    !memcmp(p + 2 + 12,
1094 					    RSN_CIPHER_SUITE_CCMP23A, 4))
1095 				return false;
1096 			default:
1097 				break;
1098 			}
1099 
1100 			i += (p[1] + 2);
1101 		}
1102 		return true;
1103 	} else {
1104 		return false;
1105 	}
1106 }
1107 
is_ap_in_wep23a(struct rtw_adapter * padapter)1108 bool is_ap_in_wep23a(struct rtw_adapter *padapter)
1109 {
1110 	u32 i;
1111 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1112 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1113 	struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
1114 	const u8 *p;
1115 
1116 	if (cur_network->capability & WLAN_CAPABILITY_PRIVACY) {
1117 		for (i = 0; i < pmlmeinfo->network.IELength;) {
1118 			p = pmlmeinfo->network.IEs + i;
1119 
1120 			switch (p[0]) {
1121 			case WLAN_EID_VENDOR_SPECIFIC:
1122 				if (!memcmp(p + 2, RTW_WPA_OUI23A_TYPE, 4))
1123 					return false;
1124 				break;
1125 			case WLAN_EID_RSN:
1126 				return false;
1127 
1128 			default:
1129 				break;
1130 			}
1131 
1132 			i += (p[1] + 2);
1133 		}
1134 
1135 		return true;
1136 	} else
1137 		return false;
1138 }
1139 
wifirate2_ratetbl_inx23a(unsigned char rate)1140 static int wifirate2_ratetbl_inx23a(unsigned char rate)
1141 {
1142 	int inx = 0;
1143 
1144 	rate = rate & 0x7f;
1145 
1146 	switch (rate) {
1147 	case 54*2:
1148 		inx = 11;
1149 		break;
1150 	case 48*2:
1151 		inx = 10;
1152 		break;
1153 	case 36*2:
1154 		inx = 9;
1155 		break;
1156 	case 24*2:
1157 		inx = 8;
1158 		break;
1159 	case 18*2:
1160 		inx = 7;
1161 		break;
1162 	case 12*2:
1163 		inx = 6;
1164 		break;
1165 	case 9*2:
1166 		inx = 5;
1167 		break;
1168 	case 6*2:
1169 		inx = 4;
1170 		break;
1171 	case 11*2:
1172 		inx = 3;
1173 		break;
1174 	case 11:
1175 		inx = 2;
1176 		break;
1177 	case 2*2:
1178 		inx = 1;
1179 		break;
1180 	case 1*2:
1181 		inx = 0;
1182 		break;
1183 	}
1184 	return inx;
1185 }
1186 
update_basic_rate23a(unsigned char * ptn,unsigned int ptn_sz)1187 unsigned int update_basic_rate23a(unsigned char *ptn, unsigned int ptn_sz)
1188 {
1189 	unsigned int i, num_of_rate;
1190 	unsigned int mask = 0;
1191 
1192 	num_of_rate = (ptn_sz > NumRates)? NumRates: ptn_sz;
1193 
1194 	for (i = 0; i < num_of_rate; i++) {
1195 		if ((*(ptn + i)) & 0x80)
1196 			mask |= 0x1 << wifirate2_ratetbl_inx23a(*(ptn + i));
1197 	}
1198 	return mask;
1199 }
1200 
update_supported_rate23a(unsigned char * ptn,unsigned int ptn_sz)1201 unsigned int update_supported_rate23a(unsigned char *ptn, unsigned int ptn_sz)
1202 {
1203 	unsigned int i, num_of_rate;
1204 	unsigned int mask = 0;
1205 
1206 	num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz;
1207 
1208 	for (i = 0; i < num_of_rate; i++)
1209 		mask |= 0x1 << wifirate2_ratetbl_inx23a(*(ptn + i));
1210 	return mask;
1211 }
1212 
update_MSC_rate23a(struct ieee80211_ht_cap * pHT_caps)1213 unsigned int update_MSC_rate23a(struct ieee80211_ht_cap *pHT_caps)
1214 {
1215 	unsigned int mask;
1216 
1217 	mask = pHT_caps->mcs.rx_mask[0] << 12 |
1218 		pHT_caps->mcs.rx_mask[1] << 20;
1219 
1220 	return mask;
1221 }
1222 
support_short_GI23a(struct rtw_adapter * padapter,struct ieee80211_ht_cap * pHT_caps)1223 int support_short_GI23a(struct rtw_adapter *padapter,
1224 			struct ieee80211_ht_cap *pHT_caps)
1225 {
1226 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1227 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1228 	unsigned char bit_offset;
1229 
1230 	if (!pmlmeinfo->HT_enable)
1231 		return _FAIL;
1232 	if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK)
1233 		return _FAIL;
1234 	bit_offset = (pmlmeext->cur_bwmode & HT_CHANNEL_WIDTH_40)? 6: 5;
1235 
1236 	if (pHT_caps->cap_info & cpu_to_le16(0x1 << bit_offset))
1237 		return _SUCCESS;
1238 	else
1239 		return _FAIL;
1240 }
1241 
get_highest_rate_idx23a(u32 mask)1242 unsigned char get_highest_rate_idx23a(u32 mask)
1243 {
1244 	int i;
1245 	unsigned char rate_idx = 0;
1246 
1247 	for (i = 27; i >= 0; i--) {
1248 		if (mask & BIT(i)) {
1249 			rate_idx = i;
1250 			break;
1251 		}
1252 	}
1253 	return rate_idx;
1254 }
1255 
Update_RA_Entry23a(struct rtw_adapter * padapter,struct sta_info * psta)1256 void Update_RA_Entry23a(struct rtw_adapter *padapter, struct sta_info *psta)
1257 {
1258 	rtw_hal_update_ra_mask23a(psta, 0);
1259 }
1260 
enable_rate_adaptive(struct rtw_adapter * padapter,struct sta_info * psta)1261 static void enable_rate_adaptive(struct rtw_adapter *padapter,
1262 				 struct sta_info *psta)
1263 {
1264 	Update_RA_Entry23a(padapter, psta);
1265 }
1266 
set_sta_rate23a(struct rtw_adapter * padapter,struct sta_info * psta)1267 void set_sta_rate23a(struct rtw_adapter *padapter, struct sta_info *psta)
1268 {
1269 	/* rate adaptive */
1270 	enable_rate_adaptive(padapter, psta);
1271 }
1272 
1273 /*  Update RRSR and Rate for USERATE */
update_tx_basic_rate23a(struct rtw_adapter * padapter,u8 wirelessmode)1274 void update_tx_basic_rate23a(struct rtw_adapter *padapter, u8 wirelessmode)
1275 {
1276 	unsigned char supported_rates[NDIS_802_11_LENGTH_RATES_EX];
1277 
1278 	memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
1279 
1280 	if (wirelessmode == WIRELESS_11B) {
1281 		memcpy(supported_rates, rtw_basic_rate_cck, 4);
1282 	} else if (wirelessmode & WIRELESS_11B) {
1283 		memcpy(supported_rates, rtw_basic_rate_mix, 7);
1284 	} else {
1285 		memcpy(supported_rates, rtw_basic_rate_ofdm, 3);
1286 	}
1287 
1288 	if (wirelessmode & WIRELESS_11B)
1289 		update_mgnt_tx_rate23a(padapter, IEEE80211_CCK_RATE_1MB);
1290 	else
1291 		update_mgnt_tx_rate23a(padapter, IEEE80211_OFDM_RATE_6MB);
1292 
1293 	HalSetBrateCfg23a(padapter, supported_rates);
1294 }
1295 
check_assoc_AP23a(u8 * pframe,uint len)1296 unsigned char check_assoc_AP23a(u8 *pframe, uint len)
1297 {
1298 	int i;
1299 	u8 epigram_vendor_flag;
1300 	u8 ralink_vendor_flag;
1301 	const u8 *p;
1302 
1303 	epigram_vendor_flag = 0;
1304 	ralink_vendor_flag = 0;
1305 
1306 	for (i = 0; i < len;) {
1307 		p = pframe + i;
1308 
1309 		switch (p[0]) {
1310 		case WLAN_EID_VENDOR_SPECIFIC:
1311 			if (!memcmp(p + 2, ARTHEROS_OUI1, 3) ||
1312 			    !memcmp(p + 2, ARTHEROS_OUI2, 3)) {
1313 				DBG_8723A("link to Artheros AP\n");
1314 				return HT_IOT_PEER_ATHEROS;
1315 			} else if (!memcmp(p + 2, BROADCOM_OUI1, 3) ||
1316 				   !memcmp(p + 2, BROADCOM_OUI2, 3)) {
1317 				DBG_8723A("link to Broadcom AP\n");
1318 				return HT_IOT_PEER_BROADCOM;
1319 			} else if (!memcmp(p + 2, MARVELL_OUI, 3)) {
1320 				DBG_8723A("link to Marvell AP\n");
1321 				return HT_IOT_PEER_MARVELL;
1322 			} else if (!memcmp(p + 2, RALINK_OUI, 3)) {
1323 				if (!ralink_vendor_flag)
1324 					ralink_vendor_flag = 1;
1325 				else {
1326 					DBG_8723A("link to Ralink AP\n");
1327 					return HT_IOT_PEER_RALINK;
1328 				}
1329 			} else if (!memcmp(p + 2, CISCO_OUI, 3)) {
1330 				DBG_8723A("link to Cisco AP\n");
1331 				return HT_IOT_PEER_CISCO;
1332 			} else if (!memcmp(p + 2, REALTEK_OUI, 3)) {
1333 				DBG_8723A("link to Realtek 96B\n");
1334 				return HT_IOT_PEER_REALTEK;
1335 			} else if (!memcmp(p + 2, AIRGOCAP_OUI, 3)) {
1336 				DBG_8723A("link to Airgo Cap\n");
1337 				return HT_IOT_PEER_AIRGO;
1338 			} else if (!memcmp(p + 2, EPIGRAM_OUI, 3)) {
1339 				epigram_vendor_flag = 1;
1340 				if (ralink_vendor_flag) {
1341 					DBG_8723A("link to Tenda W311R AP\n");
1342 					return HT_IOT_PEER_TENDA;
1343 				} else
1344 					DBG_8723A("Capture EPIGRAM_OUI\n");
1345 			} else
1346 				break;
1347 		default:
1348 			break;
1349 		}
1350 
1351 		i += (p[1] + 2);
1352 	}
1353 
1354 	if (ralink_vendor_flag && !epigram_vendor_flag) {
1355 		DBG_8723A("link to Ralink AP\n");
1356 		return HT_IOT_PEER_RALINK;
1357 	} else if (ralink_vendor_flag && epigram_vendor_flag) {
1358 		DBG_8723A("link to Tenda W311R AP\n");
1359 		return HT_IOT_PEER_TENDA;
1360 	} else {
1361 		DBG_8723A("link to new AP\n");
1362 		return HT_IOT_PEER_UNKNOWN;
1363 	}
1364 }
1365 
update_IOT_info23a(struct rtw_adapter * padapter)1366 void update_IOT_info23a(struct rtw_adapter *padapter)
1367 {
1368 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1369 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1370 
1371 	switch (pmlmeinfo->assoc_AP_vendor) {
1372 	case HT_IOT_PEER_MARVELL:
1373 		pmlmeinfo->turboMode_cts2self = 1;
1374 		pmlmeinfo->turboMode_rtsen = 0;
1375 		break;
1376 	case HT_IOT_PEER_RALINK:
1377 		pmlmeinfo->turboMode_cts2self = 0;
1378 		pmlmeinfo->turboMode_rtsen = 1;
1379 		/* disable high power */
1380 		rtl8723a_odm_support_ability_clr(padapter, (u32)
1381 						 ~DYNAMIC_BB_DYNAMIC_TXPWR);
1382 		break;
1383 	case HT_IOT_PEER_REALTEK:
1384 		/* rtw_write16(padapter, 0x4cc, 0xffff); */
1385 		/* rtw_write16(padapter, 0x546, 0x01c0); */
1386 		/* disable high power */
1387 		rtl8723a_odm_support_ability_clr(padapter, (u32)
1388 						 ~DYNAMIC_BB_DYNAMIC_TXPWR);
1389 		break;
1390 	default:
1391 		pmlmeinfo->turboMode_cts2self = 0;
1392 		pmlmeinfo->turboMode_rtsen = 1;
1393 		break;
1394 	}
1395 }
1396 
update_capinfo23a(struct rtw_adapter * Adapter,u16 updateCap)1397 void update_capinfo23a(struct rtw_adapter *Adapter, u16 updateCap)
1398 {
1399 	struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
1400 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1401 
1402 	if (updateCap & cShortPreamble) {
1403 		/*  Short Preamble */
1404 		if (pmlmeinfo->preamble_mode != PREAMBLE_SHORT) {
1405 			/*  PREAMBLE_LONG or PREAMBLE_AUTO */
1406 			pmlmeinfo->preamble_mode = PREAMBLE_SHORT;
1407 			rtl8723a_ack_preamble(Adapter, true);
1408 		}
1409 	} else { /*  Long Preamble */
1410 		if (pmlmeinfo->preamble_mode != PREAMBLE_LONG) {
1411 			/*  PREAMBLE_SHORT or PREAMBLE_AUTO */
1412 			pmlmeinfo->preamble_mode = PREAMBLE_LONG;
1413 			rtl8723a_ack_preamble(Adapter, false);
1414 		}
1415 	}
1416 	if (updateCap & cIBSS) {
1417 		/* Filen: See 802.11-2007 p.91 */
1418 		pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
1419 	} else {
1420 		/* Filen: See 802.11-2007 p.90 */
1421 		if (pmlmeext->cur_wireless_mode &
1422 		    (WIRELESS_11G | WIRELESS_11_24N)) {
1423 			if (updateCap & cShortSlotTime) { /*  Short Slot Time */
1424 				if (pmlmeinfo->slotTime != SHORT_SLOT_TIME)
1425 					pmlmeinfo->slotTime = SHORT_SLOT_TIME;
1426 			} else { /*  Long Slot Time */
1427 				if (pmlmeinfo->slotTime != NON_SHORT_SLOT_TIME)
1428 					pmlmeinfo->slotTime =
1429 						NON_SHORT_SLOT_TIME;
1430 			}
1431 		} else if (pmlmeext->cur_wireless_mode &
1432 			   (WIRELESS_11A | WIRELESS_11_5N)) {
1433 			pmlmeinfo->slotTime = SHORT_SLOT_TIME;
1434 		} else {
1435 			/* B Mode */
1436 			pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
1437 		}
1438 	}
1439 	rtl8723a_set_slot_time(Adapter, pmlmeinfo->slotTime);
1440 }
1441 
update_wireless_mode23a(struct rtw_adapter * padapter)1442 void update_wireless_mode23a(struct rtw_adapter *padapter)
1443 {
1444 	int ratelen, network_type = 0;
1445 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1446 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1447 	struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
1448 	unsigned char *rate = cur_network->SupportedRates;
1449 
1450 	ratelen = rtw_get_rateset_len23a(cur_network->SupportedRates);
1451 
1452 	if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
1453 		pmlmeinfo->HT_enable = 1;
1454 
1455 	if (pmlmeext->cur_channel > 14) {
1456 		if (pmlmeinfo->HT_enable)
1457 			network_type = WIRELESS_11_5N;
1458 		network_type |= WIRELESS_11A;
1459 	} else {
1460 		if (pmlmeinfo->HT_enable)
1461 			network_type = WIRELESS_11_24N;
1462 
1463 		if (cckratesonly_included23a(rate, ratelen) == true)
1464 			network_type |= WIRELESS_11B;
1465 		else if (cckrates_included23a(rate, ratelen) == true)
1466 			network_type |= WIRELESS_11BG;
1467 		else
1468 			network_type |= WIRELESS_11G;
1469 	}
1470 
1471 	pmlmeext->cur_wireless_mode =
1472 		network_type & padapter->registrypriv.wireless_mode;
1473 
1474 	/* 0x0808 -> for CCK, 0x0a0a -> for OFDM */
1475 	/* change this value if having IOT issues. */
1476 	rtl8723a_set_resp_sifs(padapter, 0x08, 0x08, 0x0a, 0x0a);
1477 
1478 	if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
1479 		update_mgnt_tx_rate23a(padapter, IEEE80211_CCK_RATE_1MB);
1480 	 else
1481 		update_mgnt_tx_rate23a(padapter, IEEE80211_OFDM_RATE_6MB);
1482 }
1483 
update_bmc_sta_support_rate23a(struct rtw_adapter * padapter,u32 mac_id)1484 void update_bmc_sta_support_rate23a(struct rtw_adapter *padapter, u32 mac_id)
1485 {
1486 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1487 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1488 
1489 	if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
1490 		/*  Only B, B/G, and B/G/N AP could use CCK rate */
1491 		memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates),
1492 		       rtw_basic_rate_cck, 4);
1493 	} else {
1494 		memcpy(pmlmeinfo->FW_sta_info[mac_id].SupportedRates,
1495 		       rtw_basic_rate_ofdm, 3);
1496 	}
1497 }
1498 
update_sta_support_rate23a(struct rtw_adapter * padapter,u8 * pvar_ie,uint var_ie_len,int cam_idx)1499 int update_sta_support_rate23a(struct rtw_adapter *padapter, u8 *pvar_ie,
1500 			       uint var_ie_len, int cam_idx)
1501 {
1502 	int supportRateNum = 0;
1503 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1504 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1505 	const u8 *p;
1506 
1507 	p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, pvar_ie, var_ie_len);
1508 	if (!p)
1509 		return _FAIL;
1510 
1511 	memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates, p + 2, p[1]);
1512 	supportRateNum = p[1];
1513 
1514 	p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, pvar_ie, var_ie_len);
1515 	if (p)
1516 		memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates +
1517 		       supportRateNum, p + 2, p[1]);
1518 	return _SUCCESS;
1519 }
1520 
process_addba_req23a(struct rtw_adapter * padapter,u8 * paddba_req,u8 * addr)1521 void process_addba_req23a(struct rtw_adapter *padapter,
1522 			  u8 *paddba_req, u8 *addr)
1523 {
1524 	struct sta_info *psta;
1525 	u16 tid, start_seq, param;
1526 	struct recv_reorder_ctrl *preorder_ctrl;
1527 	struct sta_priv *pstapriv = &padapter->stapriv;
1528 	struct ADDBA_request *preq = (struct ADDBA_request *)paddba_req;
1529 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1530 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1531 
1532 	psta = rtw_get_stainfo23a(pstapriv, addr);
1533 
1534 	if (psta) {
1535 		start_seq = le16_to_cpu(preq->BA_starting_seqctrl) >> 4;
1536 
1537 		param = le16_to_cpu(preq->BA_para_set);
1538 		tid = (param >> 2) & 0x0f;
1539 
1540 		preorder_ctrl = &psta->recvreorder_ctrl[tid];
1541 
1542 		preorder_ctrl->indicate_seq = 0xffff;
1543 
1544 		preorder_ctrl->enable = (pmlmeinfo->bAcceptAddbaReq == true) ?
1545 			true : false;
1546 	}
1547 }
1548