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