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