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