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