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