1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2017 Realtek Corporation.
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 <drv_types.h>
18 #include <hal_data.h>
19
20 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
21 #include <linux/inetdevice.h>
22 #define ETH_TYPE_OFFSET 12
23 #define PROTOCOL_OFFSET 23
24 #define IP_OFFSET 30
25 #define IPv6_OFFSET 38
26 #define IPv6_PROTOCOL_OFFSET 20
27 #endif
28
29 unsigned char ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f};
30 unsigned char ARTHEROS_OUI2[] = {0x00, 0x13, 0x74};
31
32 unsigned char BROADCOM_OUI1[] = {0x00, 0x10, 0x18};
33 unsigned char BROADCOM_OUI2[] = {0x00, 0x0a, 0xf7};
34 unsigned char BROADCOM_OUI3[] = {0x00, 0x05, 0xb5};
35
36
37 unsigned char CISCO_OUI[] = {0x00, 0x40, 0x96};
38 unsigned char MARVELL_OUI[] = {0x00, 0x50, 0x43};
39 unsigned char RALINK_OUI[] = {0x00, 0x0c, 0x43};
40 unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
41 unsigned char AIRGOCAP_OUI[] = {0x00, 0x0a, 0xf5};
42
43 unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
44
45 extern unsigned char RTW_WPA_OUI[];
46 extern unsigned char WPA_TKIP_CIPHER[4];
47 extern unsigned char RSN_TKIP_CIPHER[4];
48
49 #define R2T_PHY_DELAY (0)
50
51 /* #define WAIT_FOR_BCN_TO_MIN (3000) */
52 #define WAIT_FOR_BCN_TO_MIN (6000)
53 #define WAIT_FOR_BCN_TO_MAX (20000)
54
55 static u8 rtw_basic_rate_cck[4] = {
56 IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
57 IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK
58 };
59
60 static u8 rtw_basic_rate_ofdm[3] = {
61 IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
62 IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
63 };
64
65 static u8 rtw_basic_rate_mix[7] = {
66 IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
67 IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK,
68 IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
69 IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
70 };
71
72 extern u8 WIFI_CCKRATES[];
rtw_is_cck_rate(u8 rate)73 bool rtw_is_cck_rate(u8 rate)
74 {
75 int i;
76
77 for (i = 0; i < 4; i++)
78 if ((WIFI_CCKRATES[i] & 0x7F) == (rate & 0x7F))
79 return 1;
80 return 0;
81 }
82
83 extern u8 WIFI_OFDMRATES[];
rtw_is_ofdm_rate(u8 rate)84 bool rtw_is_ofdm_rate(u8 rate)
85 {
86 int i;
87
88 for (i = 0; i < 8; i++)
89 if ((WIFI_OFDMRATES[i] & 0x7F) == (rate & 0x7F))
90 return 1;
91 return 0;
92 }
93
94 /* test if rate is defined in rtw_basic_rate_cck */
rtw_is_basic_rate_cck(u8 rate)95 bool rtw_is_basic_rate_cck(u8 rate)
96 {
97 int i;
98
99 for (i = 0; i < 4; i++)
100 if ((rtw_basic_rate_cck[i] & 0x7F) == (rate & 0x7F))
101 return 1;
102 return 0;
103 }
104
105 /* test if rate is defined in rtw_basic_rate_ofdm */
rtw_is_basic_rate_ofdm(u8 rate)106 bool rtw_is_basic_rate_ofdm(u8 rate)
107 {
108 int i;
109
110 for (i = 0; i < 3; i++)
111 if ((rtw_basic_rate_ofdm[i] & 0x7F) == (rate & 0x7F))
112 return 1;
113 return 0;
114 }
115
116 /* test if rate is defined in rtw_basic_rate_mix */
rtw_is_basic_rate_mix(u8 rate)117 bool rtw_is_basic_rate_mix(u8 rate)
118 {
119 int i;
120
121 for (i = 0; i < 7; i++)
122 if ((rtw_basic_rate_mix[i] & 0x7F) == (rate & 0x7F))
123 return 1;
124 return 0;
125 }
126 #ifdef CONFIG_BCN_CNT_CONFIRM_HDL
127 int new_bcn_max = 3;
128 #endif
cckrates_included(unsigned char * rate,int ratelen)129 int cckrates_included(unsigned char *rate, int ratelen)
130 {
131 int i;
132
133 for (i = 0; i < ratelen; i++) {
134 if ((((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) ||
135 (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22))
136 return _TRUE;
137 }
138
139 return _FALSE;
140
141 }
142
cckratesonly_included(unsigned char * rate,int ratelen)143 int cckratesonly_included(unsigned char *rate, int ratelen)
144 {
145 int i;
146
147 for (i = 0; i < ratelen; i++) {
148 if ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
149 (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22))
150 return _FALSE;
151 }
152
153 return _TRUE;
154 }
155
rtw_get_sta_rx_nss(_adapter * adapter,struct sta_info * psta)156 s8 rtw_get_sta_rx_nss(_adapter *adapter, struct sta_info *psta)
157 {
158 s8 nss = 1;
159
160 if (!psta)
161 return nss;
162
163 nss = GET_HAL_RX_NSS(adapter);
164
165 #ifdef CONFIG_80211N_HT
166 #ifdef CONFIG_80211AC_VHT
167 if (psta->vhtpriv.vht_option)
168 nss = rtw_min(nss, rtw_vht_mcsmap_to_nss(psta->vhtpriv.vht_mcs_map));
169 else
170 #endif /* CONFIG_80211AC_VHT */
171 if (psta->htpriv.ht_option)
172 nss = rtw_min(nss, rtw_ht_mcsset_to_nss(psta->htpriv.ht_cap.supp_mcs_set));
173 #endif /*CONFIG_80211N_HT*/
174 RTW_INFO("%s: %d ss\n", __func__, nss);
175 return nss;
176 }
177
rtw_get_sta_tx_nss(_adapter * adapter,struct sta_info * psta)178 s8 rtw_get_sta_tx_nss(_adapter *adapter, struct sta_info *psta)
179 {
180 s8 nss = 1;
181
182 if (!psta)
183 return nss;
184
185 nss = GET_HAL_TX_NSS(adapter);
186
187 #ifdef CONFIG_80211N_HT
188 #ifdef CONFIG_80211AC_VHT
189 if (psta->vhtpriv.vht_option)
190 nss = rtw_min(nss, rtw_vht_mcsmap_to_nss(psta->vhtpriv.vht_mcs_map));
191 else
192 #endif /* CONFIG_80211AC_VHT */
193 if (psta->htpriv.ht_option)
194 nss = rtw_min(nss, rtw_ht_mcsset_to_nss(psta->htpriv.ht_cap.supp_mcs_set));
195 #endif /*CONFIG_80211N_HT*/
196 RTW_INFO("%s: %d SS\n", __func__, nss);
197 return nss;
198 }
199
judge_network_type(_adapter * padapter,unsigned char * rate,int ratelen)200 u8 judge_network_type(_adapter *padapter, unsigned char *rate, int ratelen)
201 {
202 u8 network_type = 0;
203 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
204 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
205
206
207 if (pmlmeext->cur_channel > 14) {
208 if (pmlmeinfo->VHT_enable)
209 network_type = WIRELESS_11AC;
210 else if (pmlmeinfo->HT_enable)
211 network_type = WIRELESS_11_5N;
212
213 network_type |= WIRELESS_11A;
214 } else {
215 if (pmlmeinfo->HT_enable)
216 network_type = WIRELESS_11_24N;
217
218 if ((cckratesonly_included(rate, ratelen)) == _TRUE)
219 network_type |= WIRELESS_11B;
220 else if ((cckrates_included(rate, ratelen)) == _TRUE)
221 network_type |= WIRELESS_11BG;
222 else
223 network_type |= WIRELESS_11G;
224 }
225
226 return network_type;
227 }
228
229 unsigned char ratetbl_val_2wifirate(unsigned char rate);
ratetbl_val_2wifirate(unsigned char rate)230 unsigned char ratetbl_val_2wifirate(unsigned char rate)
231 {
232 unsigned char val = 0;
233
234 switch (rate & 0x7f) {
235 case 0:
236 val = IEEE80211_CCK_RATE_1MB;
237 break;
238
239 case 1:
240 val = IEEE80211_CCK_RATE_2MB;
241 break;
242
243 case 2:
244 val = IEEE80211_CCK_RATE_5MB;
245 break;
246
247 case 3:
248 val = IEEE80211_CCK_RATE_11MB;
249 break;
250
251 case 4:
252 val = IEEE80211_OFDM_RATE_6MB;
253 break;
254
255 case 5:
256 val = IEEE80211_OFDM_RATE_9MB;
257 break;
258
259 case 6:
260 val = IEEE80211_OFDM_RATE_12MB;
261 break;
262
263 case 7:
264 val = IEEE80211_OFDM_RATE_18MB;
265 break;
266
267 case 8:
268 val = IEEE80211_OFDM_RATE_24MB;
269 break;
270
271 case 9:
272 val = IEEE80211_OFDM_RATE_36MB;
273 break;
274
275 case 10:
276 val = IEEE80211_OFDM_RATE_48MB;
277 break;
278
279 case 11:
280 val = IEEE80211_OFDM_RATE_54MB;
281 break;
282
283 }
284
285 return val;
286
287 }
288
289 int is_basicrate(_adapter *padapter, unsigned char rate);
is_basicrate(_adapter * padapter,unsigned char rate)290 int is_basicrate(_adapter *padapter, unsigned char rate)
291 {
292 int i;
293 unsigned char val;
294 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
295
296 for (i = 0; i < NumRates; i++) {
297 val = pmlmeext->basicrate[i];
298
299 if ((val != 0xff) && (val != 0xfe)) {
300 if (rate == ratetbl_val_2wifirate(val))
301 return _TRUE;
302 }
303 }
304
305 return _FALSE;
306 }
307
308 unsigned int ratetbl2rateset(_adapter *padapter, unsigned char *rateset);
ratetbl2rateset(_adapter * padapter,unsigned char * rateset)309 unsigned int ratetbl2rateset(_adapter *padapter, unsigned char *rateset)
310 {
311 int i;
312 unsigned char rate;
313 unsigned int len = 0;
314 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
315
316 for (i = 0; i < NumRates; i++) {
317 rate = pmlmeext->datarate[i];
318
319 if (rtw_get_oper_ch(padapter) > 14 && rate < _6M_RATE_) /*5G no support CCK rate*/
320 continue;
321
322 switch (rate) {
323 case 0xff:
324 return len;
325
326 case 0xfe:
327 continue;
328
329 default:
330 rate = ratetbl_val_2wifirate(rate);
331
332 if (is_basicrate(padapter, rate) == _TRUE)
333 rate |= IEEE80211_BASIC_RATE_MASK;
334
335 rateset[len] = rate;
336 len++;
337 break;
338 }
339 }
340 return len;
341 }
342
get_rate_set(_adapter * padapter,unsigned char * pbssrate,int * bssrate_len)343 void get_rate_set(_adapter *padapter, unsigned char *pbssrate, int *bssrate_len)
344 {
345 unsigned char supportedrates[NumRates];
346
347 _rtw_memset(supportedrates, 0, NumRates);
348 *bssrate_len = ratetbl2rateset(padapter, supportedrates);
349 _rtw_memcpy(pbssrate, supportedrates, *bssrate_len);
350 }
351
set_mcs_rate_by_mask(u8 * mcs_set,u32 mask)352 void set_mcs_rate_by_mask(u8 *mcs_set, u32 mask)
353 {
354 u8 mcs_rate_1r = (u8)(mask & 0xff);
355 u8 mcs_rate_2r = (u8)((mask >> 8) & 0xff);
356 u8 mcs_rate_3r = (u8)((mask >> 16) & 0xff);
357 u8 mcs_rate_4r = (u8)((mask >> 24) & 0xff);
358
359 mcs_set[0] &= mcs_rate_1r;
360 mcs_set[1] &= mcs_rate_2r;
361 mcs_set[2] &= mcs_rate_3r;
362 mcs_set[3] &= mcs_rate_4r;
363 }
364
UpdateBrateTbl(PADAPTER Adapter,u8 * mBratesOS)365 void UpdateBrateTbl(
366 PADAPTER Adapter,
367 u8 *mBratesOS
368 )
369 {
370 u8 i;
371 u8 rate;
372
373 /* 1M, 2M, 5.5M, 11M, 6M, 12M, 24M are mandatory. */
374 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
375 rate = mBratesOS[i] & 0x7f;
376 switch (rate) {
377 case IEEE80211_CCK_RATE_1MB:
378 case IEEE80211_CCK_RATE_2MB:
379 case IEEE80211_CCK_RATE_5MB:
380 case IEEE80211_CCK_RATE_11MB:
381 case IEEE80211_OFDM_RATE_6MB:
382 case IEEE80211_OFDM_RATE_12MB:
383 case IEEE80211_OFDM_RATE_24MB:
384 mBratesOS[i] |= IEEE80211_BASIC_RATE_MASK;
385 break;
386 }
387 }
388
389 }
390
UpdateBrateTblForSoftAP(u8 * bssrateset,u32 bssratelen)391 void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen)
392 {
393 u8 i;
394 u8 rate;
395
396 for (i = 0; i < bssratelen; i++) {
397 rate = bssrateset[i] & 0x7f;
398 switch (rate) {
399 case IEEE80211_CCK_RATE_1MB:
400 case IEEE80211_CCK_RATE_2MB:
401 case IEEE80211_CCK_RATE_5MB:
402 case IEEE80211_CCK_RATE_11MB:
403 bssrateset[i] |= IEEE80211_BASIC_RATE_MASK;
404 break;
405 }
406 }
407
408 }
Set_MSR(_adapter * padapter,u8 type)409 void Set_MSR(_adapter *padapter, u8 type)
410 {
411 rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type));
412 }
413
rtw_get_oper_ch(_adapter * adapter)414 inline u8 rtw_get_oper_ch(_adapter *adapter)
415 {
416 return adapter_to_dvobj(adapter)->oper_channel;
417 }
418
rtw_set_oper_ch(_adapter * adapter,u8 ch)419 inline void rtw_set_oper_ch(_adapter *adapter, u8 ch)
420 {
421 #ifdef DBG_CH_SWITCH
422 const int len = 128;
423 char msg[128] = {0};
424 int cnt = 0;
425 int i = 0;
426 #endif /* DBG_CH_SWITCH */
427 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
428
429 if (dvobj->oper_channel != ch) {
430 dvobj->on_oper_ch_time = rtw_get_current_time();
431
432 #ifdef DBG_CH_SWITCH
433 cnt += snprintf(msg + cnt, len - cnt, "switch to ch %3u", ch);
434
435 for (i = 0; i < dvobj->iface_nums; i++) {
436 _adapter *iface = dvobj->padapters[i];
437 cnt += snprintf(msg + cnt, len - cnt, " ["ADPT_FMT":", ADPT_ARG(iface));
438 if (iface->mlmeextpriv.cur_channel == ch)
439 cnt += snprintf(msg + cnt, len - cnt, "C");
440 else
441 cnt += snprintf(msg + cnt, len - cnt, "_");
442 if (iface->wdinfo.listen_channel == ch && !rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_NONE))
443 cnt += snprintf(msg + cnt, len - cnt, "L");
444 else
445 cnt += snprintf(msg + cnt, len - cnt, "_");
446 cnt += snprintf(msg + cnt, len - cnt, "]");
447 }
448
449 RTW_INFO(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(adapter), msg);
450 #endif /* DBG_CH_SWITCH */
451 }
452
453 dvobj->oper_channel = ch;
454 }
455
rtw_get_oper_bw(_adapter * adapter)456 inline u8 rtw_get_oper_bw(_adapter *adapter)
457 {
458 return adapter_to_dvobj(adapter)->oper_bwmode;
459 }
460
rtw_set_oper_bw(_adapter * adapter,u8 bw)461 inline void rtw_set_oper_bw(_adapter *adapter, u8 bw)
462 {
463 adapter_to_dvobj(adapter)->oper_bwmode = bw;
464 }
465
rtw_get_oper_choffset(_adapter * adapter)466 inline u8 rtw_get_oper_choffset(_adapter *adapter)
467 {
468 return adapter_to_dvobj(adapter)->oper_ch_offset;
469 }
470
rtw_set_oper_choffset(_adapter * adapter,u8 offset)471 inline void rtw_set_oper_choffset(_adapter *adapter, u8 offset)
472 {
473 adapter_to_dvobj(adapter)->oper_ch_offset = offset;
474 }
475
rtw_get_on_oper_ch_time(_adapter * adapter)476 inline systime rtw_get_on_oper_ch_time(_adapter *adapter)
477 {
478 return adapter_to_dvobj(adapter)->on_oper_ch_time;
479 }
480
rtw_get_on_cur_ch_time(_adapter * adapter)481 inline systime rtw_get_on_cur_ch_time(_adapter *adapter)
482 {
483 if (adapter->mlmeextpriv.cur_channel == adapter_to_dvobj(adapter)->oper_channel)
484 return adapter_to_dvobj(adapter)->on_oper_ch_time;
485 else
486 return 0;
487 }
488
set_channel_bwmode(_adapter * padapter,unsigned char channel,unsigned char channel_offset,unsigned short bwmode)489 void set_channel_bwmode(_adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode)
490 {
491 u8 center_ch, chnl_offset80 = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
492 #if (defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)) || defined(CONFIG_MCC_MODE)
493 u8 iqk_info_backup = _FALSE;
494 #endif
495
496 if (padapter->bNotifyChannelChange)
497 RTW_INFO("[%s] ch = %d, offset = %d, bwmode = %d\n", __FUNCTION__, channel, channel_offset, bwmode);
498
499 center_ch = rtw_get_center_ch(channel, bwmode, channel_offset);
500
501 if (bwmode == CHANNEL_WIDTH_80) {
502 if (center_ch > channel)
503 chnl_offset80 = HAL_PRIME_CHNL_OFFSET_LOWER;
504 else if (center_ch < channel)
505 chnl_offset80 = HAL_PRIME_CHNL_OFFSET_UPPER;
506 else
507 chnl_offset80 = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
508 }
509 _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
510
511 #ifdef CONFIG_MCC_MODE
512 if (MCC_EN(padapter)) {
513 /* driver doesn't set channel setting reg under MCC */
514 if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
515 RTW_INFO("Warning: Do not set channel setting reg MCC mode\n");
516 }
517 #endif
518
519 #ifdef CONFIG_DFS_MASTER
520 {
521 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
522 bool ori_overlap_radar_detect_ch = rtw_rfctl_overlap_radar_detect_ch(rfctl);
523 bool new_overlap_radar_detect_ch = _rtw_rfctl_overlap_radar_detect_ch(rfctl, channel, bwmode, channel_offset);
524
525 if (new_overlap_radar_detect_ch && IS_CH_WAITING(rfctl)) {
526 u8 pause = 0xFF;
527
528 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause);
529 }
530 #endif /* CONFIG_DFS_MASTER */
531
532 /* set Channel */
533 /* saved channel/bw info */
534 rtw_set_oper_ch(padapter, channel);
535 rtw_set_oper_bw(padapter, bwmode);
536 rtw_set_oper_choffset(padapter, channel_offset);
537
538 #if (defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)) || defined(CONFIG_MCC_MODE)
539 /* To check if we need to backup iqk info after switch chnl & bw */
540 {
541 u8 take_care_iqk, do_iqk;
542
543 rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
544 rtw_hal_get_hwreg(padapter, HW_VAR_DO_IQK, &do_iqk);
545 if ((take_care_iqk == _TRUE) && (do_iqk == _TRUE))
546 iqk_info_backup = _TRUE;
547 }
548 #endif
549
550 rtw_hal_set_chnl_bw(padapter, center_ch, bwmode, channel_offset, chnl_offset80); /* set center channel */
551
552 #if (defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)) || defined(CONFIG_MCC_MODE)
553 if (iqk_info_backup == _TRUE)
554 rtw_hal_ch_sw_iqk_info_backup(padapter);
555 #endif
556
557 rtw_odm_adaptivity_update(adapter_to_dvobj(padapter));
558
559 #ifdef CONFIG_DFS_MASTER
560 if (new_overlap_radar_detect_ch)
561 rtw_odm_radar_detect_enable(padapter);
562 else if (ori_overlap_radar_detect_ch) {
563 u8 pause = 0x00;
564
565 rtw_odm_radar_detect_disable(padapter);
566 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause);
567 }
568 }
569 #endif /* CONFIG_DFS_MASTER */
570
571 _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
572 }
573
get_my_bssid(WLAN_BSSID_EX * pnetwork)574 __inline u8 *get_my_bssid(WLAN_BSSID_EX *pnetwork)
575 {
576 return pnetwork->MacAddress;
577 }
578
get_beacon_interval(WLAN_BSSID_EX * bss)579 u16 get_beacon_interval(WLAN_BSSID_EX *bss)
580 {
581 unsigned short val;
582 _rtw_memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->IEs), 2);
583
584 return le16_to_cpu(val);
585
586 }
587
is_client_associated_to_ap(_adapter * padapter)588 int is_client_associated_to_ap(_adapter *padapter)
589 {
590 struct mlme_ext_priv *pmlmeext;
591 struct mlme_ext_info *pmlmeinfo;
592
593 if (!padapter)
594 return _FAIL;
595
596 pmlmeext = &padapter->mlmeextpriv;
597 pmlmeinfo = &(pmlmeext->mlmext_info);
598
599 if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE))
600 return _TRUE;
601 else
602 return _FAIL;
603 }
604
is_client_associated_to_ibss(_adapter * padapter)605 int is_client_associated_to_ibss(_adapter *padapter)
606 {
607 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
608 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
609
610 if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE))
611 return _TRUE;
612 else
613 return _FAIL;
614 }
615
is_IBSS_empty(_adapter * padapter)616 int is_IBSS_empty(_adapter *padapter)
617 {
618 int i;
619 struct macid_ctl_t *macid_ctl = &padapter->dvobj->macid_ctl;
620
621 for (i = 0; i < macid_ctl->num; i++) {
622 if (!rtw_macid_is_used(macid_ctl, i))
623 continue;
624 if (!rtw_macid_is_iface_specific(macid_ctl, i, padapter))
625 continue;
626 if (!GET_H2CCMD_MSRRPT_PARM_OPMODE(&macid_ctl->h2c_msr[i]))
627 continue;
628 if (GET_H2CCMD_MSRRPT_PARM_ROLE(&macid_ctl->h2c_msr[i]) == H2C_MSR_ROLE_ADHOC)
629 return _FAIL;
630 }
631
632 return _TRUE;
633 }
634
decide_wait_for_beacon_timeout(unsigned int bcn_interval)635 unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval)
636 {
637 if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN)
638 return WAIT_FOR_BCN_TO_MIN;
639 else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX)
640 return WAIT_FOR_BCN_TO_MAX;
641 else
642 return bcn_interval << 2;
643 }
644
invalidate_cam_all(_adapter * padapter)645 void invalidate_cam_all(_adapter *padapter)
646 {
647 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
648 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
649 u8 bmc_id = rtw_iface_bcmc_id_get(padapter);
650 _irqL irqL;
651 u8 val8 = 0;
652
653 rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, &val8);
654
655 _enter_critical_bh(&cam_ctl->lock, &irqL);
656
657 rtw_sec_cam_map_clr_all(&cam_ctl->used);
658
659 #ifndef SEC_DEFAULT_KEY_SEARCH
660 /* for BMC data TX with force camid */
661 if (bmc_id != INVALID_SEC_MAC_CAM_ID) {
662 rtw_sec_cam_map_set(&cam_ctl->used, bmc_id);
663 if (_rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_EXTRA_SEC))
664 rtw_sec_cam_map_set(&cam_ctl->used, bmc_id + 1);
665 }
666 #endif
667
668 _rtw_memset(dvobj->cam_cache, 0, sizeof(struct sec_cam_ent) * SEC_CAM_ENT_NUM_SW_LIMIT);
669 _exit_critical_bh(&cam_ctl->lock, &irqL);
670
671 #ifdef SEC_DEFAULT_KEY_SEARCH//!BMC TX force camid
672 /* clear default key related key search setting */
673 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_FALSE);
674 #endif
675 }
676
_clear_cam_entry(_adapter * padapter,u8 entry)677 void _clear_cam_entry(_adapter *padapter, u8 entry)
678 {
679 unsigned char null_sta[6] = {0};
680 unsigned char null_key[32] = {0};
681
682 rtw_sec_write_cam_ent(padapter, entry, 0, null_sta, null_key);
683 }
684
_write_cam(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)685 inline void _write_cam(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
686 {
687 #ifdef CONFIG_WRITE_CACHE_ONLY
688 write_cam_cache(adapter, id , ctrl, mac, key);
689 #else
690 rtw_sec_write_cam_ent(adapter, id, ctrl, mac, key);
691 write_cam_cache(adapter, id , ctrl, mac, key);
692 #endif
693 }
694
write_cam(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)695 inline void write_cam(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
696 {
697 if (ctrl & BIT(9)) {
698 _write_cam(adapter, id, ctrl, mac, key);
699 _write_cam(adapter, (id + 1), ctrl | BIT(5), mac, (key + 16));
700 RTW_INFO_DUMP("key-0: ", key, 16);
701 RTW_INFO_DUMP("key-1: ", (key + 16), 16);
702 } else
703 _write_cam(adapter, id, ctrl, mac, key);
704 }
705
clear_cam_entry(_adapter * adapter,u8 id)706 inline void clear_cam_entry(_adapter *adapter, u8 id)
707 {
708 _clear_cam_entry(adapter, id);
709 clear_cam_cache(adapter, id);
710 }
711
write_cam_from_cache(_adapter * adapter,u8 id)712 inline void write_cam_from_cache(_adapter *adapter, u8 id)
713 {
714 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
715 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
716 _irqL irqL;
717 struct sec_cam_ent cache;
718
719 _enter_critical_bh(&cam_ctl->lock, &irqL);
720 _rtw_memcpy(&cache, &dvobj->cam_cache[id], sizeof(struct sec_cam_ent));
721 _exit_critical_bh(&cam_ctl->lock, &irqL);
722
723 rtw_sec_write_cam_ent(adapter, id, cache.ctrl, cache.mac, cache.key);
724 }
write_cam_cache(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)725 void write_cam_cache(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
726 {
727 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
728 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
729 _irqL irqL;
730
731 _enter_critical_bh(&cam_ctl->lock, &irqL);
732
733 dvobj->cam_cache[id].ctrl = ctrl;
734 _rtw_memcpy(dvobj->cam_cache[id].mac, mac, ETH_ALEN);
735 _rtw_memcpy(dvobj->cam_cache[id].key, key, 16);
736
737 _exit_critical_bh(&cam_ctl->lock, &irqL);
738 }
739
clear_cam_cache(_adapter * adapter,u8 id)740 void clear_cam_cache(_adapter *adapter, u8 id)
741 {
742 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
743 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
744 _irqL irqL;
745
746 _enter_critical_bh(&cam_ctl->lock, &irqL);
747
748 _rtw_memset(&(dvobj->cam_cache[id]), 0, sizeof(struct sec_cam_ent));
749
750 _exit_critical_bh(&cam_ctl->lock, &irqL);
751 }
752
_rtw_camctl_chk_cap(_adapter * adapter,u8 cap)753 inline bool _rtw_camctl_chk_cap(_adapter *adapter, u8 cap)
754 {
755 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
756 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
757
758 if (cam_ctl->sec_cap & cap)
759 return _TRUE;
760 return _FALSE;
761 }
762
_rtw_camctl_set_flags(_adapter * adapter,u32 flags)763 inline void _rtw_camctl_set_flags(_adapter *adapter, u32 flags)
764 {
765 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
766 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
767
768 cam_ctl->flags |= flags;
769 }
770
rtw_camctl_set_flags(_adapter * adapter,u32 flags)771 inline void rtw_camctl_set_flags(_adapter *adapter, u32 flags)
772 {
773 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
774 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
775 _irqL irqL;
776
777 _enter_critical_bh(&cam_ctl->lock, &irqL);
778 _rtw_camctl_set_flags(adapter, flags);
779 _exit_critical_bh(&cam_ctl->lock, &irqL);
780 }
781
_rtw_camctl_clr_flags(_adapter * adapter,u32 flags)782 inline void _rtw_camctl_clr_flags(_adapter *adapter, u32 flags)
783 {
784 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
785 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
786
787 cam_ctl->flags &= ~flags;
788 }
789
rtw_camctl_clr_flags(_adapter * adapter,u32 flags)790 inline void rtw_camctl_clr_flags(_adapter *adapter, u32 flags)
791 {
792 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
793 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
794 _irqL irqL;
795
796 _enter_critical_bh(&cam_ctl->lock, &irqL);
797 _rtw_camctl_clr_flags(adapter, flags);
798 _exit_critical_bh(&cam_ctl->lock, &irqL);
799 }
800
_rtw_camctl_chk_flags(_adapter * adapter,u32 flags)801 inline bool _rtw_camctl_chk_flags(_adapter *adapter, u32 flags)
802 {
803 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
804 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
805
806 if (cam_ctl->flags & flags)
807 return _TRUE;
808 return _FALSE;
809 }
810
dump_sec_cam_map(void * sel,struct sec_cam_bmp * map,u8 max_num)811 void dump_sec_cam_map(void *sel, struct sec_cam_bmp *map, u8 max_num)
812 {
813 RTW_PRINT_SEL(sel, "0x%08x\n", map->m0);
814 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
815 if (max_num && max_num > 32)
816 RTW_PRINT_SEL(sel, "0x%08x\n", map->m1);
817 #endif
818 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
819 if (max_num && max_num > 64)
820 RTW_PRINT_SEL(sel, "0x%08x\n", map->m2);
821 #endif
822 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
823 if (max_num && max_num > 96)
824 RTW_PRINT_SEL(sel, "0x%08x\n", map->m3);
825 #endif
826 }
827
rtw_sec_camid_is_set(struct sec_cam_bmp * map,u8 id)828 inline bool rtw_sec_camid_is_set(struct sec_cam_bmp *map, u8 id)
829 {
830 if (id < 32)
831 return map->m0 & BIT(id);
832 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
833 else if (id < 64)
834 return map->m1 & BIT(id - 32);
835 #endif
836 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
837 else if (id < 96)
838 return map->m2 & BIT(id - 64);
839 #endif
840 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
841 else if (id < 128)
842 return map->m3 & BIT(id - 96);
843 #endif
844 else
845 rtw_warn_on(1);
846
847 return 0;
848 }
849
rtw_sec_cam_map_set(struct sec_cam_bmp * map,u8 id)850 inline void rtw_sec_cam_map_set(struct sec_cam_bmp *map, u8 id)
851 {
852 if (id < 32)
853 map->m0 |= BIT(id);
854 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
855 else if (id < 64)
856 map->m1 |= BIT(id - 32);
857 #endif
858 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
859 else if (id < 96)
860 map->m2 |= BIT(id - 64);
861 #endif
862 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
863 else if (id < 128)
864 map->m3 |= BIT(id - 96);
865 #endif
866 else
867 rtw_warn_on(1);
868 }
869
rtw_sec_cam_map_clr(struct sec_cam_bmp * map,u8 id)870 inline void rtw_sec_cam_map_clr(struct sec_cam_bmp *map, u8 id)
871 {
872 if (id < 32)
873 map->m0 &= ~BIT(id);
874 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
875 else if (id < 64)
876 map->m1 &= ~BIT(id - 32);
877 #endif
878 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
879 else if (id < 96)
880 map->m2 &= ~BIT(id - 64);
881 #endif
882 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
883 else if (id < 128)
884 map->m3 &= ~BIT(id - 96);
885 #endif
886 else
887 rtw_warn_on(1);
888 }
889
rtw_sec_cam_map_clr_all(struct sec_cam_bmp * map)890 inline void rtw_sec_cam_map_clr_all(struct sec_cam_bmp *map)
891 {
892 map->m0 = 0;
893 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
894 map->m1 = 0;
895 #endif
896 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
897 map->m2 = 0;
898 #endif
899 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
900 map->m3 = 0;
901 #endif
902 }
903
rtw_sec_camid_is_drv_forbid(struct cam_ctl_t * cam_ctl,u8 id)904 inline bool rtw_sec_camid_is_drv_forbid(struct cam_ctl_t *cam_ctl, u8 id)
905 {
906 struct sec_cam_bmp forbid_map;
907
908 forbid_map.m0 = 0x00000ff0;
909 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
910 forbid_map.m1 = 0x00000000;
911 #endif
912 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
913 forbid_map.m2 = 0x00000000;
914 #endif
915 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
916 forbid_map.m3 = 0x00000000;
917 #endif
918
919 if (id < 32)
920 return forbid_map.m0 & BIT(id);
921 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
922 else if (id < 64)
923 return forbid_map.m1 & BIT(id - 32);
924 #endif
925 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
926 else if (id < 96)
927 return forbid_map.m2 & BIT(id - 64);
928 #endif
929 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
930 else if (id < 128)
931 return forbid_map.m3 & BIT(id - 96);
932 #endif
933 else
934 rtw_warn_on(1);
935
936 return 1;
937 }
938
_rtw_sec_camid_is_used(struct cam_ctl_t * cam_ctl,u8 id)939 bool _rtw_sec_camid_is_used(struct cam_ctl_t *cam_ctl, u8 id)
940 {
941 bool ret = _FALSE;
942
943 if (id >= cam_ctl->num) {
944 rtw_warn_on(1);
945 goto exit;
946 }
947
948 #if 0 /* for testing */
949 if (rtw_sec_camid_is_drv_forbid(cam_ctl, id)) {
950 ret = _TRUE;
951 goto exit;
952 }
953 #endif
954
955 ret = rtw_sec_camid_is_set(&cam_ctl->used, id);
956
957 exit:
958 return ret;
959 }
960
rtw_sec_camid_is_used(struct cam_ctl_t * cam_ctl,u8 id)961 inline bool rtw_sec_camid_is_used(struct cam_ctl_t *cam_ctl, u8 id)
962 {
963 _irqL irqL;
964 bool ret;
965
966 _enter_critical_bh(&cam_ctl->lock, &irqL);
967 ret = _rtw_sec_camid_is_used(cam_ctl, id);
968 _exit_critical_bh(&cam_ctl->lock, &irqL);
969
970 return ret;
971 }
rtw_get_sec_camid(_adapter * adapter,u8 max_bk_key_num,u8 * sec_key_id)972 u8 rtw_get_sec_camid(_adapter *adapter, u8 max_bk_key_num, u8 *sec_key_id)
973 {
974 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
975 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
976 int i;
977 _irqL irqL;
978 u8 sec_cam_num = 0;
979
980 _enter_critical_bh(&cam_ctl->lock, &irqL);
981 for (i = 0; i < cam_ctl->num; i++) {
982 if (_rtw_sec_camid_is_used(cam_ctl, i)) {
983 sec_key_id[sec_cam_num++] = i;
984 if (sec_cam_num == max_bk_key_num)
985 break;
986 }
987 }
988 _exit_critical_bh(&cam_ctl->lock, &irqL);
989
990 return sec_cam_num;
991 }
992
_rtw_camid_is_gk(_adapter * adapter,u8 cam_id)993 inline bool _rtw_camid_is_gk(_adapter *adapter, u8 cam_id)
994 {
995 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
996 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
997 bool ret = _FALSE;
998
999 if (cam_id >= cam_ctl->num) {
1000 rtw_warn_on(1);
1001 goto exit;
1002 }
1003
1004 if (_rtw_sec_camid_is_used(cam_ctl, cam_id) == _FALSE)
1005 goto exit;
1006
1007 ret = (dvobj->cam_cache[cam_id].ctrl & BIT6) ? _TRUE : _FALSE;
1008
1009 exit:
1010 return ret;
1011 }
1012
rtw_camid_is_gk(_adapter * adapter,u8 cam_id)1013 inline bool rtw_camid_is_gk(_adapter *adapter, u8 cam_id)
1014 {
1015 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1016 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1017 _irqL irqL;
1018 bool ret;
1019
1020 _enter_critical_bh(&cam_ctl->lock, &irqL);
1021 ret = _rtw_camid_is_gk(adapter, cam_id);
1022 _exit_critical_bh(&cam_ctl->lock, &irqL);
1023
1024 return ret;
1025 }
1026
cam_cache_chk(_adapter * adapter,u8 id,u8 * addr,s16 kid,s8 gk)1027 bool cam_cache_chk(_adapter *adapter, u8 id, u8 *addr, s16 kid, s8 gk)
1028 {
1029 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1030 bool ret = _FALSE;
1031
1032 if (addr && _rtw_memcmp(dvobj->cam_cache[id].mac, addr, ETH_ALEN) == _FALSE)
1033 goto exit;
1034 if (kid >= 0 && kid != (dvobj->cam_cache[id].ctrl & 0x03))
1035 goto exit;
1036 if (gk != -1 && (gk ? _TRUE : _FALSE) != _rtw_camid_is_gk(adapter, id))
1037 goto exit;
1038
1039 ret = _TRUE;
1040
1041 exit:
1042 return ret;
1043 }
1044
_rtw_camid_search(_adapter * adapter,u8 * addr,s16 kid,s8 gk)1045 s16 _rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk)
1046 {
1047 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1048 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1049 int i;
1050 s16 cam_id = -1;
1051
1052 for (i = 0; i < cam_ctl->num; i++) {
1053 if (cam_cache_chk(adapter, i, addr, kid, gk)) {
1054 cam_id = i;
1055 break;
1056 }
1057 }
1058
1059 if (0) {
1060 if (addr)
1061 RTW_INFO(FUNC_ADPT_FMT" addr:"MAC_FMT" kid:%d, gk:%d, return cam_id:%d\n"
1062 , FUNC_ADPT_ARG(adapter), MAC_ARG(addr), kid, gk, cam_id);
1063 else
1064 RTW_INFO(FUNC_ADPT_FMT" addr:%p kid:%d, gk:%d, return cam_id:%d\n"
1065 , FUNC_ADPT_ARG(adapter), addr, kid, gk, cam_id);
1066 }
1067
1068 return cam_id;
1069 }
1070
rtw_camid_search(_adapter * adapter,u8 * addr,s16 kid,s8 gk)1071 s16 rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk)
1072 {
1073 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1074 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1075 _irqL irqL;
1076 s16 cam_id = -1;
1077
1078 _enter_critical_bh(&cam_ctl->lock, &irqL);
1079 cam_id = _rtw_camid_search(adapter, addr, kid, gk);
1080 _exit_critical_bh(&cam_ctl->lock, &irqL);
1081
1082 return cam_id;
1083 }
1084
rtw_get_camid(_adapter * adapter,u8 * addr,s16 kid,u8 gk,bool ext_sec)1085 s16 rtw_get_camid(_adapter *adapter, u8 *addr, s16 kid, u8 gk, bool ext_sec)
1086 {
1087 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1088 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1089 int i;
1090 #if 0 /* for testing */
1091 static u8 start_id = 0;
1092 #else
1093 u8 start_id = 0;
1094 #endif
1095 s16 cam_id = -1;
1096
1097 if (addr == NULL) {
1098 RTW_PRINT(FUNC_ADPT_FMT" mac_address is NULL\n"
1099 , FUNC_ADPT_ARG(adapter));
1100 rtw_warn_on(1);
1101 goto _exit;
1102 }
1103
1104 /* find cam entry which has the same addr, kid (, gk bit) */
1105 if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC) == _TRUE)
1106 i = _rtw_camid_search(adapter, addr, kid, gk);
1107 else
1108 i = _rtw_camid_search(adapter, addr, kid, -1);
1109
1110 if (i >= 0) {
1111 cam_id = i;
1112 goto _exit;
1113 }
1114
1115 for (i = 0; i < cam_ctl->num; i++) {
1116 /* bypass default key which is allocated statically */
1117 #ifdef SEC_DEFAULT_KEY_SEARCH
1118 if (((i + start_id) % cam_ctl->num) < 4)
1119 continue;
1120 #endif
1121 if (_rtw_sec_camid_is_used(cam_ctl, ((i + start_id) % cam_ctl->num)) == _FALSE) {
1122 if (ext_sec) {
1123 /* look out continue slot */
1124 if (((i + 1) < cam_ctl->num) &&
1125 (_rtw_sec_camid_is_used(cam_ctl, (((i + 1) + start_id) % cam_ctl->num)) == _FALSE))
1126 break;
1127 else
1128 continue;
1129 } else
1130 break;
1131 }
1132 }
1133
1134 if (i == cam_ctl->num) {
1135 RTW_PRINT(FUNC_ADPT_FMT" %s key with "MAC_FMT" id:%u no room\n"
1136 , FUNC_ADPT_ARG(adapter), gk ? "group" : "pairwise", MAC_ARG(addr), kid);
1137 rtw_warn_on(1);
1138 goto _exit;
1139 }
1140
1141 cam_id = ((i + start_id) % cam_ctl->num);
1142 start_id = ((i + start_id + 1) % cam_ctl->num);
1143
1144 _exit:
1145 return cam_id;
1146 }
1147
rtw_camid_alloc(_adapter * adapter,struct sta_info * sta,u8 kid,u8 gk,bool ext_sec,bool * used)1148 s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, u8 gk, bool ext_sec, bool *used)
1149 {
1150 struct mlme_ext_info *mlmeinfo = &adapter->mlmeextpriv.mlmext_info;
1151 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1152 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1153 _irqL irqL;
1154 s16 cam_id = -1;
1155
1156 *used = _FALSE;
1157
1158 _enter_critical_bh(&cam_ctl->lock, &irqL);
1159
1160 if ((((mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE))
1161 && !sta) {
1162 /*
1163 * 1. non-STA mode WEP key
1164 * 2. group TX key
1165 */
1166 #ifdef SEC_DEFAULT_KEY_SEARCH
1167 /* static alloction to default key by key ID when concurrent is not defined */
1168 if (kid > 3) {
1169 RTW_PRINT(FUNC_ADPT_FMT" group key with invalid key id:%u\n"
1170 , FUNC_ADPT_ARG(adapter), kid);
1171 rtw_warn_on(1);
1172 goto bitmap_handle;
1173 }
1174 cam_id = kid;
1175 #else
1176 u8 *addr = adapter_mac_addr(adapter);
1177
1178 cam_id = rtw_get_camid(adapter, addr, kid, gk, ext_sec);
1179 if (1)
1180 RTW_PRINT(FUNC_ADPT_FMT" group key with "MAC_FMT" assigned cam_id:%u\n"
1181 , FUNC_ADPT_ARG(adapter), MAC_ARG(addr), cam_id);
1182 #endif
1183 } else {
1184 /*
1185 * 1. STA mode WEP key
1186 * 2. STA mode group RX key
1187 * 3. sta key (pairwise, group RX)
1188 */
1189 u8 *addr = sta ? sta->cmn.mac_addr : NULL;
1190
1191 if (!sta) {
1192 if (!(mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
1193 /* bypass STA mode group key setting before connected(ex:WEP) because bssid is not ready */
1194 goto bitmap_handle;
1195 }
1196 addr = get_bssid(&adapter->mlmepriv);/*A2*/
1197 }
1198 cam_id = rtw_get_camid(adapter, addr, kid, gk, ext_sec);
1199 }
1200
1201
1202 bitmap_handle:
1203 if (cam_id >= 0) {
1204 *used = _rtw_sec_camid_is_used(cam_ctl, cam_id);
1205 rtw_sec_cam_map_set(&cam_ctl->used, cam_id);
1206 if (ext_sec)
1207 rtw_sec_cam_map_set(&cam_ctl->used, cam_id + 1);
1208 }
1209
1210 _exit_critical_bh(&cam_ctl->lock, &irqL);
1211
1212 return cam_id;
1213 }
1214
rtw_camid_set(_adapter * adapter,u8 cam_id)1215 void rtw_camid_set(_adapter *adapter, u8 cam_id)
1216 {
1217 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1218 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1219 _irqL irqL;
1220
1221 _enter_critical_bh(&cam_ctl->lock, &irqL);
1222
1223 if (cam_id < cam_ctl->num)
1224 rtw_sec_cam_map_set(&cam_ctl->used, cam_id);
1225
1226 _exit_critical_bh(&cam_ctl->lock, &irqL);
1227 }
1228
rtw_camid_free(_adapter * adapter,u8 cam_id)1229 void rtw_camid_free(_adapter *adapter, u8 cam_id)
1230 {
1231 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1232 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1233 _irqL irqL;
1234
1235 _enter_critical_bh(&cam_ctl->lock, &irqL);
1236
1237 if (cam_id < cam_ctl->num)
1238 rtw_sec_cam_map_clr(&cam_ctl->used, cam_id);
1239
1240 _exit_critical_bh(&cam_ctl->lock, &irqL);
1241 }
1242
1243 /*Must pause TX/RX before use this API*/
rtw_sec_cam_swap(_adapter * adapter,u8 cam_id_a,u8 cam_id_b)1244 inline void rtw_sec_cam_swap(_adapter *adapter, u8 cam_id_a, u8 cam_id_b)
1245 {
1246 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1247 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1248 struct sec_cam_ent cache_a, cache_b;
1249 _irqL irqL;
1250 bool cam_a_used, cam_b_used;
1251
1252 if (1)
1253 RTW_INFO(ADPT_FMT" - sec_cam %d,%d swap\n", ADPT_ARG(adapter), cam_id_a, cam_id_b);
1254
1255 if (cam_id_a == cam_id_b)
1256 return;
1257
1258 rtw_mi_update_ap_bmc_camid(adapter, cam_id_a, cam_id_b);
1259
1260 /*setp-1. backup org cam_info*/
1261 _enter_critical_bh(&cam_ctl->lock, &irqL);
1262
1263 cam_a_used = _rtw_sec_camid_is_used(cam_ctl, cam_id_a);
1264 cam_b_used = _rtw_sec_camid_is_used(cam_ctl, cam_id_b);
1265
1266 if (cam_a_used)
1267 _rtw_memcpy(&cache_a, &dvobj->cam_cache[cam_id_a], sizeof(struct sec_cam_ent));
1268
1269 if (cam_b_used)
1270 _rtw_memcpy(&cache_b, &dvobj->cam_cache[cam_id_b], sizeof(struct sec_cam_ent));
1271
1272 _exit_critical_bh(&cam_ctl->lock, &irqL);
1273
1274 /*setp-2. clean cam_info*/
1275 if (cam_a_used) {
1276 rtw_camid_free(adapter, cam_id_a);
1277 clear_cam_entry(adapter, cam_id_a);
1278 }
1279 if (cam_b_used) {
1280 rtw_camid_free(adapter, cam_id_b);
1281 clear_cam_entry(adapter, cam_id_b);
1282 }
1283
1284 /*setp-3. set cam_info*/
1285 if (cam_a_used) {
1286 write_cam(adapter, cam_id_b, cache_a.ctrl, cache_a.mac, cache_a.key);
1287 rtw_camid_set(adapter, cam_id_b);
1288 }
1289
1290 if (cam_b_used) {
1291 write_cam(adapter, cam_id_a, cache_b.ctrl, cache_b.mac, cache_b.key);
1292 rtw_camid_set(adapter, cam_id_a);
1293 }
1294 }
1295
rtw_get_empty_cam_entry(_adapter * adapter,u8 start_camid)1296 s16 rtw_get_empty_cam_entry(_adapter *adapter, u8 start_camid)
1297 {
1298 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1299 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1300 _irqL irqL;
1301 int i;
1302 s16 cam_id = -1;
1303
1304 _enter_critical_bh(&cam_ctl->lock, &irqL);
1305 for (i = start_camid; i < cam_ctl->num; i++) {
1306 if (_FALSE == _rtw_sec_camid_is_used(cam_ctl, i)) {
1307 cam_id = i;
1308 break;
1309 }
1310 }
1311 _exit_critical_bh(&cam_ctl->lock, &irqL);
1312
1313 return cam_id;
1314 }
rtw_clean_dk_section(_adapter * adapter)1315 void rtw_clean_dk_section(_adapter *adapter)
1316 {
1317 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1318 struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj);
1319 s16 ept_cam_id;
1320 int i;
1321
1322 for (i = 0; i < 4; i++) {
1323 if (rtw_sec_camid_is_used(cam_ctl, i)) {
1324 ept_cam_id = rtw_get_empty_cam_entry(adapter, 4);
1325 if (ept_cam_id > 0)
1326 rtw_sec_cam_swap(adapter, i, ept_cam_id);
1327 }
1328 }
1329 }
rtw_clean_hw_dk_cam(_adapter * adapter)1330 void rtw_clean_hw_dk_cam(_adapter *adapter)
1331 {
1332 int i;
1333
1334 for (i = 0; i < 4; i++) {
1335 if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_WRITE_CAM_NEW_RULE))
1336 _clear_cam_entry(adapter, i);
1337 else
1338 rtw_sec_clr_cam_ent(adapter, i);
1339 }
1340 }
1341
flush_all_cam_entry(_adapter * padapter)1342 void flush_all_cam_entry(_adapter *padapter)
1343 {
1344 #ifdef CONFIG_CONCURRENT_MODE
1345 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1346 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1347 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1348
1349 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1350 struct sta_priv *pstapriv = &padapter->stapriv;
1351 struct sta_info *psta;
1352
1353 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
1354 if (psta) {
1355 if (psta->state & WIFI_AP_STATE) {
1356 /*clear cam when ap free per sta_info*/
1357 } else
1358 rtw_clearstakey_cmd(padapter, psta, _FALSE);
1359 }
1360 } else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) {
1361 #ifdef CONFIG_AP_MODE
1362 #ifndef SEC_DEFAULT_KEY_SEARCH
1363 int cam_id = -1;
1364 u8 *addr = adapter_mac_addr(padapter);
1365 u8 bmc_id = rtw_iface_bcmc_id_get(padapter);
1366
1367 while ((cam_id = rtw_camid_search(padapter, addr, -1, -1)) >= 0) {
1368 RTW_PRINT("clear wep or group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), cam_id);
1369 clear_cam_entry(padapter, cam_id);
1370 /* clear cam_ctl.used bit for data BMC TX force camid in rtw_release_macid() */
1371 if (bmc_id == INVALID_SEC_MAC_CAM_ID || cam_id != bmc_id)
1372 rtw_camid_free(padapter, cam_id);
1373 }
1374 #else
1375 /* clear default key */
1376 int i, cam_id;
1377 u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
1378
1379 for (i = 0; i < 4; i++) {
1380 cam_id = rtw_camid_search(padapter, null_addr, i, -1);
1381 if (cam_id >= 0) {
1382 clear_cam_entry(padapter, cam_id);
1383 rtw_camid_free(padapter, cam_id);
1384 }
1385 }
1386 /* clear default key related key search setting */
1387 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_FALSE);
1388 #endif
1389 #endif /* CONFIG_AP_MODE */
1390 }
1391
1392 #else /*NON CONFIG_CONCURRENT_MODE*/
1393
1394 invalidate_cam_all(padapter);
1395 #endif
1396 }
1397
1398 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
rtw_process_wfd_ie(_adapter * adapter,u8 * wfd_ie,u8 wfd_ielen,const char * tag)1399 void rtw_process_wfd_ie(_adapter *adapter, u8 *wfd_ie, u8 wfd_ielen, const char *tag)
1400 {
1401 struct wifidirect_info *wdinfo = &adapter->wdinfo;
1402
1403 u8 *attr_content;
1404 u32 attr_contentlen = 0;
1405
1406 if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
1407 return;
1408
1409 RTW_INFO("[%s] Found WFD IE\n", tag);
1410 attr_content = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &attr_contentlen);
1411 if (attr_content && attr_contentlen) {
1412 wdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16(attr_content + 2);
1413 RTW_INFO("[%s] Peer PORT NUM = %d\n", tag, wdinfo->wfd_info->peer_rtsp_ctrlport);
1414 }
1415 }
1416
rtw_process_wfd_ies(_adapter * adapter,u8 * ies,u8 ies_len,const char * tag)1417 void rtw_process_wfd_ies(_adapter *adapter, u8 *ies, u8 ies_len, const char *tag)
1418 {
1419 u8 *wfd_ie;
1420 u32 wfd_ielen;
1421
1422 if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
1423 return;
1424
1425 wfd_ie = rtw_get_wfd_ie(ies, ies_len, NULL, &wfd_ielen);
1426 while (wfd_ie) {
1427 rtw_process_wfd_ie(adapter, wfd_ie, wfd_ielen, tag);
1428 wfd_ie = rtw_get_wfd_ie(wfd_ie + wfd_ielen, (ies + ies_len) - (wfd_ie + wfd_ielen), NULL, &wfd_ielen);
1429 }
1430 }
1431 #endif /* defined(CONFIG_P2P) && defined(CONFIG_WFD) */
1432
WMM_param_handler(_adapter * padapter,PNDIS_802_11_VARIABLE_IEs pIE)1433 int WMM_param_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1434 {
1435 /* struct registry_priv *pregpriv = &padapter->registrypriv; */
1436 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1437 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1438 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1439
1440 if (pmlmepriv->qospriv.qos_option == 0) {
1441 pmlmeinfo->WMM_enable = 0;
1442 return _FALSE;
1443 }
1444
1445 if (_rtw_memcmp(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element)))
1446 return _FALSE;
1447 else
1448 _rtw_memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element));
1449 pmlmeinfo->WMM_enable = 1;
1450 return _TRUE;
1451
1452 #if 0
1453 if (pregpriv->wifi_spec == 1) {
1454 if (pmlmeinfo->WMM_enable == 1) {
1455 /* todo: compare the parameter set count & decide wheher to update or not */
1456 return _FAIL;
1457 } else {
1458 pmlmeinfo->WMM_enable = 1;
1459 _rtw_rtw_memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element));
1460 return _TRUE;
1461 }
1462 } else {
1463 pmlmeinfo->WMM_enable = 0;
1464 return _FAIL;
1465 }
1466 #endif
1467
1468 }
1469
1470 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
rtw_is_tbtx_capabilty(u8 * p,u8 len)1471 u8 rtw_is_tbtx_capabilty(u8 *p, u8 len){
1472 int i;
1473 u8 tbtx_cap_ie[8] = {0x00, 0xe0, 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00};
1474
1475 for (i = 0; i < len; i++) {
1476 if (*(p + i) != tbtx_cap_ie[i])
1477 return _FALSE;
1478 else
1479 continue;
1480 }
1481 return _TRUE;
1482 }
1483 #endif
1484
WMMOnAssocRsp(_adapter * padapter)1485 void WMMOnAssocRsp(_adapter *padapter)
1486 {
1487 u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime;
1488 u8 acm_mask;
1489 u16 TXOP;
1490 u32 acParm, i;
1491 u32 edca[4], inx[4];
1492 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1493 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1494 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1495 struct registry_priv *pregpriv = &padapter->registrypriv;
1496 #ifdef CONFIG_WMMPS_STA
1497 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1498 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1499 #endif /* CONFIG_WMMPS_STA */
1500
1501 acm_mask = 0;
1502
1503 if (is_supported_5g(pmlmeext->cur_wireless_mode) ||
1504 (pmlmeext->cur_wireless_mode & WIRELESS_11_24N))
1505 aSifsTime = 16;
1506 else
1507 aSifsTime = 10;
1508
1509 if (pmlmeinfo->WMM_enable == 0) {
1510 padapter->mlmepriv.acm_mask = 0;
1511
1512 AIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
1513
1514 if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11A)) {
1515 ECWMin = 4;
1516 ECWMax = 10;
1517 } else if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
1518 ECWMin = 5;
1519 ECWMax = 10;
1520 } else {
1521 ECWMin = 4;
1522 ECWMax = 10;
1523 }
1524
1525 TXOP = 0;
1526 acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1527 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
1528 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
1529 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
1530
1531 ECWMin = 2;
1532 ECWMax = 3;
1533 TXOP = 0x2f;
1534 acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1535 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
1536 } else {
1537 edca[0] = edca[1] = edca[2] = edca[3] = 0;
1538
1539 for (i = 0; i < 4; i++) {
1540 ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03;
1541 ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01;
1542
1543 /* AIFS = AIFSN * slot time + SIFS - r2t phy delay */
1544 AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) * pmlmeinfo->slotTime + aSifsTime;
1545
1546 ECWMin = (pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f);
1547 ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4;
1548 TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit);
1549
1550 acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1551
1552 switch (ACI) {
1553 case 0x0:
1554 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
1555 acm_mask |= (ACM ? BIT(1) : 0);
1556 edca[XMIT_BE_QUEUE] = acParm;
1557 break;
1558
1559 case 0x1:
1560 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
1561 /* acm_mask |= (ACM? BIT(0):0); */
1562 edca[XMIT_BK_QUEUE] = acParm;
1563 break;
1564
1565 case 0x2:
1566 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
1567 acm_mask |= (ACM ? BIT(2) : 0);
1568 edca[XMIT_VI_QUEUE] = acParm;
1569 break;
1570
1571 case 0x3:
1572 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
1573 acm_mask |= (ACM ? BIT(3) : 0);
1574 edca[XMIT_VO_QUEUE] = acParm;
1575 break;
1576 }
1577
1578 RTW_INFO("WMM(%x): %x, %x\n", ACI, ACM, acParm);
1579 }
1580
1581 if (padapter->registrypriv.acm_method == 1)
1582 rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask));
1583 else
1584 padapter->mlmepriv.acm_mask = acm_mask;
1585
1586 inx[0] = 0;
1587 inx[1] = 1;
1588 inx[2] = 2;
1589 inx[3] = 3;
1590
1591 if (pregpriv->wifi_spec == 1) {
1592 u32 j, tmp, change_inx = _FALSE;
1593
1594 /* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */
1595 for (i = 0; i < 4; i++) {
1596 for (j = i + 1; j < 4; j++) {
1597 /* compare CW and AIFS */
1598 if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF))
1599 change_inx = _TRUE;
1600 else if ((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF)) {
1601 /* compare TXOP */
1602 if ((edca[j] >> 16) > (edca[i] >> 16))
1603 change_inx = _TRUE;
1604 }
1605
1606 if (change_inx) {
1607 tmp = edca[i];
1608 edca[i] = edca[j];
1609 edca[j] = tmp;
1610
1611 tmp = inx[i];
1612 inx[i] = inx[j];
1613 inx[j] = tmp;
1614
1615 change_inx = _FALSE;
1616 }
1617 }
1618 }
1619 }
1620
1621 for (i = 0; i < 4; i++) {
1622 pxmitpriv->wmm_para_seq[i] = inx[i];
1623 RTW_INFO("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]);
1624 }
1625
1626 #ifdef CONFIG_WMMPS_STA
1627 /* if AP supports UAPSD function, driver must set each uapsd TID to coresponding mac register 0x693 */
1628 if (pmlmeinfo->WMM_param.QoS_info & AP_SUPPORTED_UAPSD) {
1629 pqospriv->uapsd_ap_supported = 1;
1630 rtw_hal_set_hwreg(padapter, HW_VAR_UAPSD_TID, NULL);
1631 }
1632 #endif /* CONFIG_WMMPS_STA */
1633 }
1634 }
1635
bwmode_update_check(_adapter * padapter,PNDIS_802_11_VARIABLE_IEs pIE)1636 static void bwmode_update_check(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1637 {
1638 #ifdef CONFIG_80211N_HT
1639 unsigned char new_bwmode;
1640 unsigned char new_ch_offset;
1641 struct HT_info_element *pHT_info;
1642 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1643 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1644 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1645 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1646 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1647 u8 cbw40_enable = 0;
1648
1649 if (!pIE)
1650 return;
1651
1652 if (phtpriv->ht_option == _FALSE)
1653 return;
1654
1655 if (pmlmeext->cur_bwmode >= CHANNEL_WIDTH_80)
1656 return;
1657
1658 if (pIE->Length > sizeof(struct HT_info_element))
1659 return;
1660
1661 pHT_info = (struct HT_info_element *)pIE->data;
1662
1663 if (hal_chk_bw_cap(padapter, BW_CAP_40M)) {
1664 if (pmlmeext->cur_channel > 14) {
1665 if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
1666 cbw40_enable = 1;
1667 } else {
1668 if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
1669 cbw40_enable = 1;
1670 }
1671 }
1672
1673 if ((pHT_info->infos[0] & BIT(2)) && cbw40_enable) {
1674 new_bwmode = CHANNEL_WIDTH_40;
1675
1676 switch (pHT_info->infos[0] & 0x3) {
1677 case 1:
1678 new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
1679 break;
1680
1681 case 3:
1682 new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
1683 break;
1684
1685 default:
1686 new_bwmode = CHANNEL_WIDTH_20;
1687 new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1688 break;
1689 }
1690 } else {
1691 new_bwmode = CHANNEL_WIDTH_20;
1692 new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1693 }
1694
1695
1696 if ((new_bwmode != pmlmeext->cur_bwmode || new_ch_offset != pmlmeext->cur_ch_offset)
1697 && new_bwmode < pmlmeext->cur_bwmode
1698 ) {
1699 pmlmeinfo->bwmode_updated = _TRUE;
1700
1701 pmlmeext->cur_bwmode = new_bwmode;
1702 pmlmeext->cur_ch_offset = new_ch_offset;
1703
1704 /* update HT info also */
1705 HT_info_handler(padapter, pIE);
1706 } else
1707 pmlmeinfo->bwmode_updated = _FALSE;
1708
1709
1710 if (_TRUE == pmlmeinfo->bwmode_updated) {
1711 struct sta_info *psta;
1712 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
1713 struct sta_priv *pstapriv = &padapter->stapriv;
1714
1715 /* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
1716
1717
1718 /* update ap's stainfo */
1719 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
1720 if (psta) {
1721 struct ht_priv *phtpriv_sta = &psta->htpriv;
1722
1723 if (phtpriv_sta->ht_option) {
1724 /* bwmode */
1725 psta->cmn.bw_mode = pmlmeext->cur_bwmode;
1726 phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
1727 } else {
1728 psta->cmn.bw_mode = CHANNEL_WIDTH_20;
1729 phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1730 }
1731
1732 rtw_dm_ra_mask_wk_cmd(padapter, (u8 *)psta);
1733 }
1734
1735 /* pmlmeinfo->bwmode_updated = _FALSE; */ /* bwmode_updated done, reset it! */
1736 }
1737 #endif /* CONFIG_80211N_HT */
1738 }
1739
1740 #ifdef ROKU_PRIVATE
Supported_rate_infra_ap(_adapter * padapter,PNDIS_802_11_VARIABLE_IEs pIE)1741 void Supported_rate_infra_ap(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1742 {
1743 unsigned int i;
1744 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1745 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1746
1747 if (pIE == NULL)
1748 return;
1749
1750 for (i = 0 ; i < pIE->Length; i++)
1751 pmlmeinfo->SupportedRates_infra_ap[i] = (pIE->data[i]);
1752
1753 }
1754
Extended_Supported_rate_infra_ap(_adapter * padapter,PNDIS_802_11_VARIABLE_IEs pIE)1755 void Extended_Supported_rate_infra_ap(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1756 {
1757 unsigned int i, j;
1758 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1759 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1760
1761 if (pIE == NULL)
1762 return;
1763
1764 if (pIE->Length > 0) {
1765 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
1766 if (pmlmeinfo->SupportedRates_infra_ap[i] == 0)
1767 break;
1768 }
1769 for (j = 0; j < pIE->Length; j++)
1770 pmlmeinfo->SupportedRates_infra_ap[i+j] = (pIE->data[j]);
1771 }
1772
1773 }
1774
HT_get_ss_from_mcs_set(u8 * mcs_set,u8 * Rx_ss)1775 void HT_get_ss_from_mcs_set(u8 *mcs_set, u8 *Rx_ss)
1776 {
1777 u8 i, j;
1778 u8 r_ss = 0, t_ss = 0;
1779
1780 for (i = 0; i < 4; i++) {
1781 if ((mcs_set[3-i] & 0xff) != 0x00) {
1782 r_ss = 4-i;
1783 break;
1784 }
1785 }
1786
1787 *Rx_ss = r_ss;
1788 }
1789
HT_caps_handler_infra_ap(_adapter * padapter,PNDIS_802_11_VARIABLE_IEs pIE)1790 void HT_caps_handler_infra_ap(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1791 {
1792 unsigned int i;
1793 u8 cur_stbc_cap_infra_ap = 0;
1794 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1795 struct ht_priv_infra_ap *phtpriv = &pmlmepriv->htpriv_infra_ap;
1796
1797 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1798 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1799
1800 if (pIE == NULL)
1801 return;
1802
1803 pmlmeinfo->ht_vht_received |= BIT(0);
1804
1805 /*copy MCS_SET*/
1806 for (i = 3; i < 19; i++)
1807 phtpriv->MCS_set_infra_ap[i-3] = (pIE->data[i]);
1808
1809 /*get number of stream from mcs set*/
1810 HT_get_ss_from_mcs_set(phtpriv->MCS_set_infra_ap, &phtpriv->Rx_ss_infra_ap);
1811
1812 phtpriv->rx_highest_data_rate_infra_ap = le16_to_cpu(GET_HT_CAP_ELE_RX_HIGHEST_DATA_RATE(pIE->data));
1813
1814 phtpriv->ldpc_cap_infra_ap = GET_HT_CAP_ELE_LDPC_CAP(pIE->data);
1815
1816 if (GET_HT_CAP_ELE_RX_STBC(pIE->data))
1817 SET_FLAG(cur_stbc_cap_infra_ap, STBC_HT_ENABLE_RX);
1818 if (GET_HT_CAP_ELE_TX_STBC(pIE->data))
1819 SET_FLAG(cur_stbc_cap_infra_ap, STBC_HT_ENABLE_TX);
1820 phtpriv->stbc_cap_infra_ap = cur_stbc_cap_infra_ap;
1821
1822 /*store ap info SGI 20m 40m*/
1823 phtpriv->sgi_20m_infra_ap = GET_HT_CAP_ELE_SHORT_GI20M(pIE->data);
1824 phtpriv->sgi_40m_infra_ap = GET_HT_CAP_ELE_SHORT_GI40M(pIE->data);
1825
1826 /*store ap info for supported channel bandwidth*/
1827 phtpriv->channel_width_infra_ap = GET_HT_CAP_ELE_CHL_WIDTH(pIE->data);
1828 }
1829 #endif /* ROKU_PRIVATE */
1830
HT_caps_handler(_adapter * padapter,PNDIS_802_11_VARIABLE_IEs pIE)1831 void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1832 {
1833 #ifdef CONFIG_80211N_HT
1834 unsigned int i;
1835 u8 max_AMPDU_len, min_MPDU_spacing;
1836 u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0, rx_nss = 0;
1837 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1838 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1839 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1840 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1841 #ifdef CONFIG_DISABLE_MCS13TO15
1842 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1843 #endif
1844
1845 if (pIE == NULL)
1846 return;
1847
1848 if (phtpriv->ht_option == _FALSE)
1849 return;
1850
1851 pmlmeinfo->HT_caps_enable = 1;
1852
1853 for (i = 0; i < (pIE->Length); i++) {
1854 if (i != 2) {
1855 /* Commented by Albert 2010/07/12 */
1856 /* Got the endian issue here. */
1857 pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]);
1858 } else {
1859 /* AMPDU Parameters field */
1860
1861 /* Get MIN of MAX AMPDU Length Exp */
1862 if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (pIE->data[i] & 0x3))
1863 max_AMPDU_len = (pIE->data[i] & 0x3);
1864 else
1865 max_AMPDU_len = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3);
1866
1867 /* Get MAX of MIN MPDU Start Spacing */
1868 if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) > (pIE->data[i] & 0x1c))
1869 min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c);
1870 else
1871 min_MPDU_spacing = (pIE->data[i] & 0x1c);
1872
1873 pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para = max_AMPDU_len | min_MPDU_spacing;
1874 }
1875 }
1876
1877 /* Commented by Albert 2010/07/12 */
1878 /* Have to handle the endian issue after copying. */
1879 /* HT_ext_caps didn't be used yet. */
1880 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
1881 pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps = le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps);
1882
1883 /* update the MCS set */
1884 for (i = 0; i < 16; i++)
1885 pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i];
1886
1887 rx_nss = GET_HAL_RX_NSS(padapter);
1888
1889 switch (rx_nss) {
1890 case 1:
1891 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R);
1892 break;
1893 case 2:
1894 #ifdef CONFIG_DISABLE_MCS13TO15
1895 if (pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1)
1896 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R_13TO15_OFF);
1897 else
1898 #endif
1899 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R);
1900 break;
1901 case 3:
1902 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_3R);
1903 break;
1904 case 4:
1905 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_4R);
1906 break;
1907 default:
1908 RTW_WARN("rf_type:%d or rx_nss:%u is not expected\n", GET_HAL_RFPATH(padapter), rx_nss);
1909 }
1910
1911 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1912 /* Config STBC setting */
1913 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAP_ELE_RX_STBC(pIE->data)) {
1914 SET_FLAG(cur_stbc_cap, STBC_HT_ENABLE_TX);
1915 RTW_INFO("Enable HT Tx STBC !\n");
1916 }
1917 phtpriv->stbc_cap = cur_stbc_cap;
1918
1919 #ifdef CONFIG_BEAMFORMING
1920 /* Config Tx beamforming setting */
1921 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&
1922 GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pIE->data)) {
1923 SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
1924 /* Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/
1925 SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pIE->data) << 6);
1926 }
1927
1928 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) &&
1929 GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pIE->data)) {
1930 SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
1931 /* Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/
1932 SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pIE->data) << 4);
1933 }
1934 phtpriv->beamform_cap = cur_beamform_cap;
1935 if (cur_beamform_cap)
1936 RTW_INFO("AP HT Beamforming Cap = 0x%02X\n", cur_beamform_cap);
1937 #endif /*CONFIG_BEAMFORMING*/
1938 } else {
1939 /*WIFI_STATION_STATEorI_ADHOC_STATE or WIFI_ADHOC_MASTER_STATE*/
1940 /* Config LDPC Coding Capability */
1941 if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX) && GET_HT_CAP_ELE_LDPC_CAP(pIE->data)) {
1942 SET_FLAG(cur_ldpc_cap, (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX));
1943 RTW_INFO("Enable HT Tx LDPC!\n");
1944 }
1945 phtpriv->ldpc_cap = cur_ldpc_cap;
1946
1947 /* Config STBC setting */
1948 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAP_ELE_RX_STBC(pIE->data)) {
1949 SET_FLAG(cur_stbc_cap, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX));
1950 RTW_INFO("Enable HT Tx STBC!\n");
1951 }
1952 phtpriv->stbc_cap = cur_stbc_cap;
1953
1954 #ifdef CONFIG_BEAMFORMING
1955 #ifdef RTW_BEAMFORMING_VERSION_2
1956 /* Config beamforming setting */
1957 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) &&
1958 GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pIE->data)) {
1959 SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
1960 /* Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/
1961 SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pIE->data) << 6);
1962 }
1963
1964 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&
1965 GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pIE->data)) {
1966 SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
1967 /* Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/
1968 SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pIE->data) << 4);
1969 }
1970 #else /* !RTW_BEAMFORMING_VERSION_2 */
1971 /* Config Tx beamforming setting */
1972 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) &&
1973 GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pIE->data)) {
1974 SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
1975 /* Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/
1976 SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pIE->data) << 6);
1977 }
1978
1979 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&
1980 GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pIE->data)) {
1981 SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
1982 /* Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/
1983 SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pIE->data) << 4);
1984 }
1985 #endif /* !RTW_BEAMFORMING_VERSION_2 */
1986 phtpriv->beamform_cap = cur_beamform_cap;
1987 if (cur_beamform_cap)
1988 RTW_INFO("Client HT Beamforming Cap = 0x%02X\n", cur_beamform_cap);
1989 #endif /*CONFIG_BEAMFORMING*/
1990 }
1991
1992 #endif /* CONFIG_80211N_HT */
1993 }
1994
HT_info_handler(_adapter * padapter,PNDIS_802_11_VARIABLE_IEs pIE)1995 void HT_info_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1996 {
1997 #ifdef CONFIG_80211N_HT
1998 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1999 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2000 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2001 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2002
2003 if (pIE == NULL)
2004 return;
2005
2006 if (phtpriv->ht_option == _FALSE)
2007 return;
2008
2009
2010 if (pIE->Length > sizeof(struct HT_info_element))
2011 return;
2012
2013 pmlmeinfo->HT_info_enable = 1;
2014 _rtw_memcpy(&(pmlmeinfo->HT_info), pIE->data, pIE->Length);
2015 #endif /* CONFIG_80211N_HT */
2016 return;
2017 }
2018
HTOnAssocRsp(_adapter * padapter)2019 void HTOnAssocRsp(_adapter *padapter)
2020 {
2021 unsigned char max_AMPDU_len;
2022 unsigned char min_MPDU_spacing;
2023 /* struct registry_priv *pregpriv = &padapter->registrypriv; */
2024 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2025 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2026
2027 RTW_INFO("%s\n", __FUNCTION__);
2028
2029 if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
2030 pmlmeinfo->HT_enable = 1;
2031 else {
2032 pmlmeinfo->HT_enable = 0;
2033 /* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
2034 return;
2035 }
2036
2037 /* handle A-MPDU parameter field */
2038 /*
2039 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
2040 AMPDU_para [4:2]:Min MPDU Start Spacing
2041 */
2042 max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
2043
2044 min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
2045
2046 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
2047 #ifdef CONFIG_80211N_HT
2048 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
2049 #endif /* CONFIG_80211N_HT */
2050 #if 0 /* move to rtw_update_ht_cap() */
2051 if ((pregpriv->bw_mode > 0) &&
2052 (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) &&
2053 (pmlmeinfo->HT_info.infos[0] & BIT(2))) {
2054 /* switch to the 40M Hz mode accoring to the AP */
2055 pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;
2056 switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
2057 case EXTCHNL_OFFSET_UPPER:
2058 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
2059 break;
2060
2061 case EXTCHNL_OFFSET_LOWER:
2062 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
2063 break;
2064
2065 default:
2066 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2067 break;
2068 }
2069 }
2070 #endif
2071
2072 /* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
2073
2074 #if 0 /* move to rtw_update_ht_cap() */
2075 /* */
2076 /* Config SM Power Save setting */
2077 /* */
2078 pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
2079 if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) {
2080 #if 0
2081 u8 i;
2082 /* update the MCS rates */
2083 for (i = 0; i < 16; i++)
2084 pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
2085 #endif
2086 RTW_INFO("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __FUNCTION__);
2087 }
2088
2089 /* */
2090 /* Config current HT Protection mode. */
2091 /* */
2092 pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
2093 #endif
2094
2095 }
2096
ERP_IE_handler(_adapter * padapter,PNDIS_802_11_VARIABLE_IEs pIE)2097 void ERP_IE_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
2098 {
2099 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2100 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2101
2102 if (pIE->Length > 1)
2103 return;
2104
2105 pmlmeinfo->ERP_enable = 1;
2106 _rtw_memcpy(&(pmlmeinfo->ERP_IE), pIE->data, pIE->Length);
2107 }
2108
VCS_update(_adapter * padapter,struct sta_info * psta)2109 void VCS_update(_adapter *padapter, struct sta_info *psta)
2110 {
2111 struct registry_priv *pregpriv = &padapter->registrypriv;
2112 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2113 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2114
2115 switch (pregpriv->vrtl_carrier_sense) { /* 0:off 1:on 2:auto */
2116 case 0: /* off */
2117 psta->rtsen = 0;
2118 psta->cts2self = 0;
2119 break;
2120
2121 case 1: /* on */
2122 if (pregpriv->vcs_type == 1) { /* 1:RTS/CTS 2:CTS to self */
2123 psta->rtsen = 1;
2124 psta->cts2self = 0;
2125 } else {
2126 psta->rtsen = 0;
2127 psta->cts2self = 1;
2128 }
2129 break;
2130
2131 case 2: /* auto */
2132 default:
2133 if (((pmlmeinfo->ERP_enable) && (pmlmeinfo->ERP_IE & BIT(1)))
2134 /*||(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)*/
2135 ) {
2136 if (pregpriv->vcs_type == 1) {
2137 psta->rtsen = 1;
2138 psta->cts2self = 0;
2139 } else {
2140 psta->rtsen = 0;
2141 psta->cts2self = 1;
2142 }
2143 } else {
2144 psta->rtsen = 0;
2145 psta->cts2self = 0;
2146 }
2147 break;
2148 }
2149 }
2150
update_ldpc_stbc_cap(struct sta_info * psta)2151 void update_ldpc_stbc_cap(struct sta_info *psta)
2152 {
2153 #ifdef CONFIG_80211N_HT
2154
2155 #ifdef CONFIG_80211AC_VHT
2156 if (psta->vhtpriv.vht_option) {
2157 if (TEST_FLAG(psta->vhtpriv.ldpc_cap, LDPC_VHT_ENABLE_TX))
2158 psta->cmn.ldpc_en = VHT_LDPC_EN;
2159 else
2160 psta->cmn.ldpc_en = 0;
2161
2162 if (TEST_FLAG(psta->vhtpriv.stbc_cap, STBC_VHT_ENABLE_TX))
2163 psta->cmn.stbc_en = VHT_STBC_EN;
2164 else
2165 psta->cmn.stbc_en = 0;
2166 } else
2167 #endif /* CONFIG_80211AC_VHT */
2168 if (psta->htpriv.ht_option) {
2169 if (TEST_FLAG(psta->htpriv.ldpc_cap, LDPC_HT_ENABLE_TX))
2170 psta->cmn.ldpc_en = HT_LDPC_EN;
2171 else
2172 psta->cmn.ldpc_en = 0;
2173
2174 if (TEST_FLAG(psta->htpriv.stbc_cap, STBC_HT_ENABLE_TX))
2175 psta->cmn.stbc_en = HT_STBC_EN;
2176 else
2177 psta->cmn.stbc_en = 0;
2178 } else {
2179 psta->cmn.ldpc_en = 0;
2180 psta->cmn.stbc_en = 0;
2181 }
2182
2183 #endif /* CONFIG_80211N_HT */
2184 }
2185
check_ielen(u8 * start,uint len)2186 int check_ielen(u8 *start, uint len)
2187 {
2188 int left = len;
2189 u8 *pos = start;
2190 u8 id, elen;
2191
2192 while (left >= 2) {
2193 id = *pos++;
2194 elen = *pos++;
2195 left -= 2;
2196
2197 if (elen > left) {
2198 /* RTW_INFO("IEEE 802.11 element parse failed (id=%d elen=%d left=%lu)\n",
2199 id, elen, (unsigned long) left); */
2200 return _FALSE;
2201 }
2202 if ((id == WLAN_EID_VENDOR_SPECIFIC) && (elen < 3))
2203 return _FALSE;
2204
2205 left -= elen;
2206 pos += elen;
2207 }
2208 if (left)
2209 return _FALSE;
2210
2211 return _TRUE;
2212 }
2213
validate_beacon_len(u8 * pframe,u32 len)2214 int validate_beacon_len(u8 *pframe, u32 len)
2215 {
2216 u8 ie_offset = _BEACON_IE_OFFSET_ + sizeof(struct rtw_ieee80211_hdr_3addr);
2217
2218 if (len < ie_offset) {
2219 RTW_INFO("%s: incorrect beacon length(%d)\n", __func__, len);
2220 return _FALSE;
2221 }
2222
2223 if (check_ielen(pframe + ie_offset, len - ie_offset) == _FALSE)
2224 return _FALSE;
2225
2226 return _TRUE;
2227 }
2228
2229 #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT
2230 u8 support_rate_ranges[] = {
2231 IEEE80211_CCK_RATE_1MB,
2232 IEEE80211_CCK_RATE_2MB,
2233 IEEE80211_CCK_RATE_5MB,
2234 IEEE80211_CCK_RATE_11MB,
2235 IEEE80211_OFDM_RATE_6MB,
2236 IEEE80211_OFDM_RATE_9MB,
2237 IEEE80211_OFDM_RATE_12MB,
2238 IEEE80211_OFDM_RATE_18MB,
2239 IEEE80211_PBCC_RATE_22MB,
2240 IEEE80211_FREAK_RATE_22_5MB,
2241 IEEE80211_OFDM_RATE_24MB,
2242 IEEE80211_OFDM_RATE_36MB,
2243 IEEE80211_OFDM_RATE_48MB,
2244 IEEE80211_OFDM_RATE_54MB,
2245 };
2246
match_ranges(u16 EID,u32 value)2247 inline bool match_ranges(u16 EID, u32 value)
2248 {
2249 int i;
2250 int nr_range;
2251
2252 switch (EID) {
2253 case _EXT_SUPPORTEDRATES_IE_:
2254 case _SUPPORTEDRATES_IE_:
2255 nr_range = sizeof(support_rate_ranges)/sizeof(u8);
2256 for (i = 0; i < nr_range; i++) {
2257 /* clear bit7 before searching. */
2258 value &= ~BIT(7);
2259 if (value == support_rate_ranges[i])
2260 return _TRUE;
2261 }
2262 break;
2263 default:
2264 break;
2265 };
2266 return _FALSE;
2267 }
2268
2269 /*
2270 * rtw_validate_value: validate the IE contain.
2271 *
2272 * Input :
2273 * EID : Element ID
2274 * p : IE buffer (without EID & length)
2275 * len : IE length
2276 * return:
2277 * _TRUE : All Values are validated.
2278 * _FALSE : At least one value is NOT validated.
2279 */
rtw_validate_value(u16 EID,u8 * p,u16 len)2280 bool rtw_validate_value(u16 EID, u8 *p, u16 len)
2281 {
2282 u8 rate;
2283 u32 i, nr_val;
2284
2285 switch (EID) {
2286 case _EXT_SUPPORTEDRATES_IE_:
2287 case _SUPPORTEDRATES_IE_:
2288 nr_val = len;
2289 for (i=0; i<nr_val; i++) {
2290 rate = *(p+i);
2291 if (match_ranges(EID, rate) == _FALSE)
2292 return _FALSE;
2293 }
2294 break;
2295 default:
2296 break;
2297 };
2298 return _TRUE;
2299 }
2300 #endif /* CONFIG_CHECK_SPECIFIC_IE_CONTENT */
2301
is_hidden_ssid(char * ssid,int len)2302 bool is_hidden_ssid(char *ssid, int len)
2303 {
2304 return len == 0 || is_all_null(ssid, len) == _TRUE;
2305 }
2306
hidden_ssid_ap(WLAN_BSSID_EX * snetwork)2307 inline bool hidden_ssid_ap(WLAN_BSSID_EX *snetwork)
2308 {
2309 return is_hidden_ssid(snetwork->Ssid.Ssid, snetwork->Ssid.SsidLength);
2310 }
2311
2312 /*
2313 Get SSID if this ilegal frame(probe resp) comes from a hidden SSID AP.
2314 Update the SSID to the corresponding pnetwork in scan queue.
2315 */
rtw_absorb_ssid_ifneed(_adapter * padapter,WLAN_BSSID_EX * bssid,u8 * pframe)2316 void rtw_absorb_ssid_ifneed(_adapter *padapter, WLAN_BSSID_EX *bssid, u8 *pframe)
2317 {
2318 struct wlan_network *scanned = NULL;
2319 WLAN_BSSID_EX *snetwork;
2320 u8 ie_offset, *p=NULL, *next_ie=NULL, *mac = get_addr2_ptr(pframe);
2321 sint ssid_len_ori;
2322 u32 remain_len = 0;
2323 u8 backupIE[MAX_IE_SZ];
2324 u16 subtype = get_frame_sub_type(pframe);
2325 _irqL irqL;
2326
2327 if (subtype == WIFI_BEACON) {
2328 bssid->Reserved[0] = BSS_TYPE_BCN;
2329 ie_offset = _BEACON_IE_OFFSET_;
2330 } else {
2331 /* FIXME : more type */
2332 if (subtype == WIFI_PROBERSP) {
2333 ie_offset = _PROBERSP_IE_OFFSET_;
2334 bssid->Reserved[0] = BSS_TYPE_PROB_RSP;
2335 } else if (subtype == WIFI_PROBEREQ) {
2336 ie_offset = _PROBEREQ_IE_OFFSET_;
2337 bssid->Reserved[0] = BSS_TYPE_PROB_REQ;
2338 } else {
2339 bssid->Reserved[0] = BSS_TYPE_UNDEF;
2340 ie_offset = _FIXED_IE_LENGTH_;
2341 }
2342 }
2343
2344 _enter_critical_bh(&padapter->mlmepriv.scanned_queue.lock, &irqL);
2345 scanned = _rtw_find_network(&padapter->mlmepriv.scanned_queue, mac);
2346 if (!scanned) {
2347 _exit_critical_bh(&padapter->mlmepriv.scanned_queue.lock, &irqL);
2348 return;
2349 }
2350
2351 snetwork = &(scanned->network);
2352 /* scan queue records as Hidden SSID && Input frame is NOT Hidden SSID */
2353 if (hidden_ssid_ap(snetwork) && !hidden_ssid_ap(bssid)) {
2354 p = rtw_get_ie(snetwork->IEs+ie_offset, _SSID_IE_, &ssid_len_ori, snetwork->IELength-ie_offset);
2355 if (!p) {
2356 _exit_critical_bh(&padapter->mlmepriv.scanned_queue.lock, &irqL);
2357 return;
2358 }
2359 next_ie = p + 2 + ssid_len_ori;
2360 remain_len = snetwork->IELength - (next_ie - snetwork->IEs);
2361 scanned->network.Ssid.SsidLength = bssid->Ssid.SsidLength;
2362 _rtw_memcpy(scanned->network.Ssid.Ssid, bssid->Ssid.Ssid, bssid->Ssid.SsidLength);
2363
2364 //update pnetwork->ssid, pnetwork->ssidlen
2365 _rtw_memcpy(backupIE, next_ie, remain_len);
2366 *(p+1) = bssid->Ssid.SsidLength;
2367 _rtw_memcpy(p+2, bssid->Ssid.Ssid, bssid->Ssid.SsidLength);
2368 _rtw_memcpy(p+2+bssid->Ssid.SsidLength, backupIE, remain_len);
2369 snetwork->IELength += bssid->Ssid.SsidLength;
2370 }
2371 _exit_critical_bh(&padapter->mlmepriv.scanned_queue.lock, &irqL);
2372 }
2373
2374 #ifdef DBG_RX_BCN
rtw_debug_rx_bcn(_adapter * adapter,u8 * pframe,u32 packet_len)2375 void rtw_debug_rx_bcn(_adapter *adapter, u8 *pframe, u32 packet_len)
2376 {
2377 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
2378 struct mlme_ext_info *mlmeinfo = &(pmlmeext->mlmext_info);
2379 u16 sn = ((struct rtw_ieee80211_hdr_3addr *)pframe)->seq_ctl >> 4;
2380 u64 tsf, tsf_offset;
2381 u8 dtim_cnt, dtim_period, tim_bmap, tim_pvbit;
2382
2383 update_TSF(pmlmeext, pframe, packet_len);
2384 tsf = pmlmeext->TSFValue;
2385 tsf_offset = rtw_modular64(pmlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024));
2386
2387 /*get TIM IE*/
2388 /*DTIM Count*/
2389 dtim_cnt = pmlmeext->tim[0];
2390 /*DTIM Period*/
2391 dtim_period = pmlmeext->tim[1];
2392 /*Bitmap*/
2393 tim_bmap = pmlmeext->tim[2];
2394 /*Partial VBitmap AID 0 ~ 7*/
2395 tim_pvbit = pmlmeext->tim[3];
2396
2397 RTW_INFO("[BCN] SN-%d, TSF-%lld(us), offset-%lld, bcn_interval-%d DTIM-%d[%d] bitmap-0x%02x-0x%02x\n",
2398 sn, tsf, tsf_offset, mlmeinfo->bcn_interval, dtim_period, dtim_cnt, tim_bmap, tim_pvbit);
2399 }
2400 #endif
2401
2402 /*
2403 * rtw_get_bcn_keys: get beacon keys from recv frame
2404 *
2405 * TODO:
2406 * WLAN_EID_COUNTRY
2407 * WLAN_EID_ERP_INFO
2408 * WLAN_EID_CHANNEL_SWITCH
2409 * WLAN_EID_PWR_CONSTRAINT
2410 */
_rtw_get_bcn_keys(u8 * cap_info,u32 buf_len,u8 def_ch,ADAPTER * adapter,struct beacon_keys * recv_beacon)2411 int _rtw_get_bcn_keys(u8 *cap_info, u32 buf_len, u8 def_ch, ADAPTER *adapter
2412 , struct beacon_keys *recv_beacon)
2413 {
2414 int left;
2415 u16 capability;
2416 unsigned char *pos;
2417 struct rtw_ieee802_11_elems elems;
2418
2419 _rtw_memset(recv_beacon, 0, sizeof(*recv_beacon));
2420
2421 /* checking capabilities */
2422 capability = le16_to_cpu(*(unsigned short *)(cap_info));
2423
2424 /* checking IEs */
2425 left = buf_len - 2;
2426 pos = cap_info + 2;
2427 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed)
2428 return _FALSE;
2429
2430 if (elems.ht_capabilities) {
2431 if (elems.ht_capabilities_len != 26)
2432 return _FALSE;
2433 }
2434
2435 if (elems.ht_operation) {
2436 if (elems.ht_operation_len != 22)
2437 return _FALSE;
2438 }
2439
2440 if (elems.vht_capabilities) {
2441 if (elems.vht_capabilities_len != 12)
2442 return _FALSE;
2443 }
2444
2445 if (elems.vht_operation) {
2446 if (elems.vht_operation_len != 5)
2447 return _FALSE;
2448 }
2449
2450 if (rtw_ies_get_supported_rate(pos, left, recv_beacon->rate_set, &recv_beacon->rate_num) == _FAIL)
2451 return _FALSE;
2452
2453 if (cckratesonly_included(recv_beacon->rate_set, recv_beacon->rate_num) == _TRUE)
2454 recv_beacon->proto_cap |= PROTO_CAP_11B;
2455 else if (cckrates_included(recv_beacon->rate_set, recv_beacon->rate_num) == _TRUE)
2456 recv_beacon->proto_cap |= PROTO_CAP_11B | PROTO_CAP_11G;
2457 else
2458 recv_beacon->proto_cap |= PROTO_CAP_11G;
2459
2460 if (elems.ht_capabilities && elems.ht_operation)
2461 recv_beacon->proto_cap |= PROTO_CAP_11N;
2462
2463 if (elems.vht_capabilities && elems.vht_operation)
2464 recv_beacon->proto_cap |= PROTO_CAP_11AC;
2465
2466 /* check bw and channel offset */
2467 rtw_ies_get_chbw(pos, left, &recv_beacon->ch, &recv_beacon->bw, &recv_beacon->offset, 1, 1);
2468 if (!recv_beacon->ch)
2469 recv_beacon->ch = def_ch;
2470
2471 /* checking SSID */
2472 if (elems.ssid) {
2473 if (elems.ssid_len > sizeof(recv_beacon->ssid))
2474 return _FALSE;
2475
2476 _rtw_memcpy(recv_beacon->ssid, elems.ssid, elems.ssid_len);
2477 recv_beacon->ssid_len = elems.ssid_len;
2478 }
2479
2480 /* checking RSN first */
2481 if (elems.rsn_ie && elems.rsn_ie_len) {
2482 recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA2;
2483 rtw_parse_wpa2_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
2484 &recv_beacon->group_cipher, &recv_beacon->pairwise_cipher,
2485 NULL, &recv_beacon->akm, NULL, NULL);
2486 }
2487 /* checking WPA secon */
2488 else if (elems.wpa_ie && elems.wpa_ie_len) {
2489 recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA;
2490 rtw_parse_wpa_ie(elems.wpa_ie - 2, elems.wpa_ie_len + 2,
2491 &recv_beacon->group_cipher, &recv_beacon->pairwise_cipher,
2492 &recv_beacon->akm);
2493 } else if (capability & BIT(4))
2494 recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WEP;
2495
2496 if (adapter) {
2497 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
2498
2499 if (elems.tim && elems.tim_len) {
2500 #ifdef DBG_RX_BCN
2501 _rtw_memcpy(pmlmeext->tim, elems.tim, 4);
2502 #endif
2503 pmlmeext->dtim = elems.tim[1];
2504 }
2505
2506 /* checking RTW TBTX */
2507 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
2508 if (elems.tbtx_cap && elems.tbtx_cap_len) {
2509 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2510
2511 if (rtw_is_tbtx_capabilty(elems.tbtx_cap, elems.tbtx_cap_len))
2512 RTW_DBG("AP support TBTX\n");
2513 }
2514 #endif
2515 }
2516
2517 return _TRUE;
2518 }
2519
rtw_get_bcn_keys(_adapter * adapter,u8 * whdr,u32 flen,struct beacon_keys * bcn_keys)2520 int rtw_get_bcn_keys(_adapter *adapter, u8 *whdr, u32 flen, struct beacon_keys *bcn_keys)
2521 {
2522 return _rtw_get_bcn_keys(
2523 whdr + WLAN_HDR_A3_LEN + 10
2524 , flen - WLAN_HDR_A3_LEN - 10
2525 , adapter->mlmeextpriv.cur_channel, adapter
2526 , bcn_keys);
2527 }
2528
rtw_get_bcn_keys_from_bss(WLAN_BSSID_EX * bss,struct beacon_keys * bcn_keys)2529 int rtw_get_bcn_keys_from_bss(WLAN_BSSID_EX *bss, struct beacon_keys *bcn_keys)
2530 {
2531 return _rtw_get_bcn_keys(
2532 bss->IEs + 10
2533 , bss->IELength - 10
2534 , bss->Configuration.DSConfig, NULL
2535 , bcn_keys);
2536 }
2537
rtw_update_bcn_keys_of_network(struct wlan_network * network)2538 int rtw_update_bcn_keys_of_network(struct wlan_network *network)
2539 {
2540 network->bcn_keys_valid = rtw_get_bcn_keys_from_bss(&network->network, &network->bcn_keys);
2541 return network->bcn_keys_valid;
2542 }
2543
rtw_dump_bcn_keys(void * sel,struct beacon_keys * recv_beacon)2544 void rtw_dump_bcn_keys(void *sel, struct beacon_keys *recv_beacon)
2545 {
2546 #if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG)
2547 u8 ssid[IW_ESSID_MAX_SIZE + 1];
2548
2549 _rtw_memcpy(ssid, recv_beacon->ssid, recv_beacon->ssid_len);
2550 ssid[recv_beacon->ssid_len] = '\0';
2551
2552 RTW_PRINT_SEL(sel, "ssid = %s (len = %u)\n", ssid, recv_beacon->ssid_len);
2553 RTW_PRINT_SEL(sel, "ch = %u,%u,%u\n"
2554 , recv_beacon->ch, recv_beacon->bw, recv_beacon->offset);
2555 RTW_PRINT_SEL(sel, "proto_cap = 0x%02x\n", recv_beacon->proto_cap);
2556 RTW_MAP_DUMP_SEL(sel, "rate_set = "
2557 , recv_beacon->rate_set, recv_beacon->rate_num);
2558 RTW_PRINT_SEL(sel, "sec = %d, group = 0x%x, pair = 0x%x, akm = 0x%08x\n"
2559 , recv_beacon->encryp_protocol, recv_beacon->group_cipher
2560 , recv_beacon->pairwise_cipher, recv_beacon->akm);
2561 #endif
2562 }
2563
rtw_bcn_key_err_fix(struct beacon_keys * cur,struct beacon_keys * recv)2564 void rtw_bcn_key_err_fix(struct beacon_keys *cur, struct beacon_keys *recv)
2565 {
2566 if ((recv->ch == cur->ch) && (recv->bw == cur->bw) && (recv->bw > CHANNEL_WIDTH_20)) {
2567 if ((recv->offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
2568 && (cur->offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE)) {
2569 RTW_DBG("recv_bcn offset = %d is invalid, try to use cur_bcn offset = %d to replace it !\n", recv->offset, cur->offset);
2570 recv->offset = cur->offset;
2571 }
2572 }
2573 }
2574
rtw_bcn_key_compare(struct beacon_keys * cur,struct beacon_keys * recv)2575 bool rtw_bcn_key_compare(struct beacon_keys *cur, struct beacon_keys *recv)
2576 {
2577 #define BCNKEY_VERIFY_PROTO_CAP 0
2578 #define BCNKEY_VERIFY_WHOLE_RATE_SET 0
2579
2580 struct beacon_keys tmp;
2581 bool ret = _FALSE;
2582
2583 if (!rtw_is_chbw_grouped(cur->ch, cur->bw, cur->offset
2584 , recv->ch, recv->bw, recv->offset))
2585 goto exit;
2586
2587 _rtw_memcpy(&tmp, cur, sizeof(tmp));
2588
2589 /* check fields excluding below */
2590 tmp.ch = recv->ch;
2591 tmp.bw = recv->bw;
2592 tmp.offset = recv->offset;
2593 if (!BCNKEY_VERIFY_PROTO_CAP)
2594 tmp.proto_cap = recv->proto_cap;
2595 if (!BCNKEY_VERIFY_WHOLE_RATE_SET) {
2596 tmp.rate_num = recv->rate_num;
2597 _rtw_memcpy(tmp.rate_set, recv->rate_set, 12);
2598 }
2599
2600 if (_rtw_memcmp(&tmp, recv, sizeof(*recv)) == _FALSE)
2601 goto exit;
2602
2603 ret = _TRUE;
2604
2605 exit:
2606 return ret;
2607 }
2608
rtw_check_bcn_info(ADAPTER * Adapter,u8 * pframe,u32 packet_len)2609 int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len)
2610 {
2611 u8 *pbssid = GetAddr3Ptr(pframe);
2612 struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
2613 struct wlan_network *cur_network = &(Adapter->mlmepriv.cur_network);
2614 struct beacon_keys *cur_beacon = &pmlmepriv->cur_beacon_keys;
2615 struct beacon_keys recv_beacon;
2616 int ret = 0;
2617 u8 ifbmp_m = rtw_mi_get_ap_mesh_ifbmp(Adapter);
2618 u8 ifbmp_s = rtw_mi_get_ld_sta_ifbmp(Adapter);
2619 struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter);
2620 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
2621
2622 if (is_client_associated_to_ap(Adapter) == _FALSE)
2623 goto exit_success;
2624
2625 if (rtw_get_bcn_keys(Adapter, pframe, packet_len, &recv_beacon) == _FALSE)
2626 goto exit_success; /* parsing failed => broken IE */
2627
2628 #ifdef DBG_RX_BCN
2629 rtw_debug_rx_bcn(Adapter, pframe, packet_len);
2630 #endif
2631
2632 /* hidden ssid, replace with current beacon ssid directly */
2633 if (is_hidden_ssid(recv_beacon.ssid, recv_beacon.ssid_len)) {
2634 _rtw_memcpy(recv_beacon.ssid, cur_beacon->ssid, cur_beacon->ssid_len);
2635 recv_beacon.ssid_len = cur_beacon->ssid_len;
2636 }
2637
2638 if (check_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON)) {
2639 u8 c_ch, c_bw, c_offset;
2640 bool bw_offset_changed = _FALSE;
2641 struct sta_info *psta = NULL;
2642
2643 c_ch = pmlmeext->cur_channel;
2644 c_bw = pmlmeext->cur_bwmode;
2645 c_offset = pmlmeext->cur_ch_offset;
2646
2647 /*
2648 * Case 1 : channel is different
2649 * AP doesn't udpate its beacon.
2650 * Case 2 : channel is same
2651 * AP may not update its beacon yet, so we wait 5 beacon.
2652 * Case 3 : we already wait 5 beacon
2653 * We assume that AP update its beacon.
2654 */
2655 if (c_ch != recv_beacon.ch) {
2656 goto exit_success;
2657 } else if (c_ch == recv_beacon.ch &&
2658 pmlmepriv->bcn_cnts_after_csa < 5) {
2659 pmlmepriv->bcn_cnts_after_csa += 1;
2660 goto exit_success;
2661 } else {
2662 pmlmepriv->bcn_cnts_after_csa = 0;
2663 }
2664
2665 _rtw_memcpy(cur_beacon, &recv_beacon, sizeof(recv_beacon));
2666 RTW_INFO("csa : recv_beacon ch/bw/offset = %u,%u,%u\n",
2667 recv_beacon.ch, recv_beacon.bw, recv_beacon.offset);
2668 RTW_INFO("csa : before update our bw/offset, current bw/offset = %u,%u\n",
2669 c_bw, c_offset);
2670 /* rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon); */
2671
2672 clr_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON);
2673 _cancel_timer_async(&pmlmeext->csa_timer);
2674
2675 /* Current bw/offset is different from AP */
2676 if (c_bw != recv_beacon.bw || c_offset != recv_beacon.offset) {
2677 RTW_INFO("csa : need to sync bw/offset with AP\n");
2678 bw_offset_changed = _TRUE;
2679 pmlmeext->cur_bwmode = recv_beacon.bw;
2680 pmlmeext->cur_ch_offset = recv_beacon.offset;
2681 }
2682
2683 if (rtw_adjust_chbw(Adapter, pmlmeext->cur_channel,
2684 &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset)) {
2685 RTW_INFO("csa : limit bandwith by sw capability\n");
2686 bw_offset_changed = _TRUE;
2687 }
2688
2689 if (bw_offset_changed) {
2690 c_bw = pmlmeext->cur_bwmode;
2691 c_offset = pmlmeext->cur_ch_offset;
2692
2693 #ifdef CONFIG_AP_MODE
2694 if (ifbmp_m) {
2695 rtw_change_bss_chbw_cmd(dvobj_get_primary_adapter(dvobj), 0
2696 , ifbmp_m, 0, recv_beacon.ch, REQ_BW_ORI, REQ_OFFSET_NONE);
2697 } else
2698 #endif
2699 {
2700 #ifdef CONFIG_DFS_MASTER
2701 rtw_dfs_rd_en_decision(dvobj_get_primary_adapter(dvobj), MLME_OPCH_SWITCH, 0);
2702 #endif
2703 rtw_set_chbw_cmd(Adapter, c_ch, c_bw, c_offset, 0);
2704 }
2705 RTW_INFO("csa : after update bw/offset, new bw/offset = %u,%u\n", c_bw, c_offset);
2706 } else {
2707 RTW_INFO("csa : our bw/offset is same as AP\n");
2708 }
2709
2710 rtw_iqk_cmd(Adapter, 0);
2711 psta = rtw_get_stainfo(&Adapter->stapriv, get_bssid(&Adapter->mlmepriv));
2712 if (psta)
2713 rtw_dm_ra_mask_wk_cmd(Adapter, (u8 *)psta);
2714
2715 RTW_INFO("csa : update beacon done, WIFI_CSA_UPDATE_BEACON is clear\n");
2716 }
2717
2718 #ifdef CONFIG_BCN_CNT_CONFIRM_HDL
2719 if (_rtw_memcmp(&recv_beacon, cur_beacon, sizeof(recv_beacon)) == _TRUE)
2720 pmlmepriv->new_beacon_cnts = 0;
2721 else if ((pmlmepriv->new_beacon_cnts == 0) ||
2722 _rtw_memcmp(&recv_beacon, &pmlmepriv->new_beacon_keys, sizeof(recv_beacon)) == _FALSE) {
2723 RTW_DBG("%s: start new beacon (seq=%d)\n", __func__, GetSequence(pframe));
2724
2725 if (pmlmepriv->new_beacon_cnts == 0) {
2726 RTW_ERR("%s: cur beacon key\n", __func__);
2727 RTW_DBG_EXPR(rtw_dump_bcn_keys(RTW_DBGDUMP, cur_beacon));
2728 }
2729
2730 RTW_DBG("%s: new beacon key\n", __func__);
2731 RTW_DBG_EXPR(rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon));
2732
2733 _rtw_memcpy(&pmlmepriv->new_beacon_keys, &recv_beacon, sizeof(recv_beacon));
2734 pmlmepriv->new_beacon_cnts = 1;
2735 } else {
2736 RTW_DBG("%s: new beacon again (seq=%d)\n", __func__, GetSequence(pframe));
2737 pmlmepriv->new_beacon_cnts++;
2738 }
2739
2740 /* if counter >= max, it means beacon is changed really */
2741 if (pmlmepriv->new_beacon_cnts >= new_bcn_max)
2742 #else
2743 if (_rtw_memcmp(&recv_beacon, cur_beacon, sizeof(recv_beacon)) == _FALSE)
2744 #endif
2745 {
2746 RTW_INFO(FUNC_ADPT_FMT" new beacon occur!!\n", FUNC_ADPT_ARG(Adapter));
2747 RTW_INFO(FUNC_ADPT_FMT" cur beacon key:\n", FUNC_ADPT_ARG(Adapter));
2748 rtw_dump_bcn_keys(RTW_DBGDUMP, cur_beacon);
2749 RTW_INFO(FUNC_ADPT_FMT" new beacon key:\n", FUNC_ADPT_ARG(Adapter));
2750 rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon);
2751
2752 rtw_bcn_key_err_fix(cur_beacon, &recv_beacon);
2753
2754 if (rtw_bcn_key_compare(cur_beacon, &recv_beacon) == _FALSE)
2755 goto exit;
2756
2757 _rtw_memcpy(cur_beacon, &recv_beacon, sizeof(recv_beacon));
2758 #ifdef CONFIG_BCN_CNT_CONFIRM_HDL
2759 pmlmepriv->new_beacon_cnts = 0;
2760 #endif
2761 }
2762
2763 exit_success:
2764 ret = 1;
2765
2766 exit:
2767 return ret;
2768 }
2769
update_beacon_info(_adapter * padapter,u8 * pframe,uint pkt_len,struct sta_info * psta)2770 void update_beacon_info(_adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta)
2771 {
2772 unsigned int i;
2773 unsigned int len;
2774 PNDIS_802_11_VARIABLE_IEs pIE;
2775
2776 #ifdef CONFIG_TDLS
2777 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
2778 u8 tdls_prohibited[] = { 0x00, 0x00, 0x00, 0x00, 0x10 }; /* bit(38): TDLS_prohibited */
2779 #endif /* CONFIG_TDLS */
2780
2781 len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN);
2782
2783 for (i = 0; i < len;) {
2784 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i);
2785
2786 switch (pIE->ElementID) {
2787 case _VENDOR_SPECIFIC_IE_:
2788 /* to update WMM paramter set while receiving beacon */
2789 if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6) && pIE->Length == WLAN_WMM_LEN) /* WMM */
2790 (WMM_param_handler(padapter, pIE)) ? report_wmm_edca_update(padapter) : 0;
2791
2792 break;
2793
2794 case _HT_EXTRA_INFO_IE_: /* HT info */
2795 /* HT_info_handler(padapter, pIE); */
2796 bwmode_update_check(padapter, pIE);
2797 break;
2798 #ifdef CONFIG_80211AC_VHT
2799 case EID_OpModeNotification:
2800 rtw_process_vht_op_mode_notify(padapter, pIE->data, psta);
2801 break;
2802 #endif /* CONFIG_80211AC_VHT */
2803 case _ERPINFO_IE_:
2804 ERP_IE_handler(padapter, pIE);
2805 VCS_update(padapter, psta);
2806 break;
2807
2808 #ifdef CONFIG_TDLS
2809 case WLAN_EID_EXT_CAP:
2810 if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
2811 ptdlsinfo->ap_prohibited = _TRUE;
2812 if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
2813 ptdlsinfo->ch_switch_prohibited = _TRUE;
2814 break;
2815 #endif /* CONFIG_TDLS */
2816 default:
2817 break;
2818 }
2819
2820 i += (pIE->Length + 2);
2821 }
2822 }
2823
2824 #if CONFIG_DFS
process_csa_ie(_adapter * padapter,u8 * ies,uint ies_len)2825 void process_csa_ie(_adapter *padapter, u8 *ies, uint ies_len)
2826 {
2827 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
2828 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2829 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2830 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2831 unsigned int i, j, countdown;
2832 PNDIS_802_11_VARIABLE_IEs pIE, sub_pie;
2833 u8 ch = 0, csa_ch_offset = 0, csa_ch_width = 0, csa_ch_freq_seg0 = 0, csa_ch_freq_seg1 = 0, csa_switch_cnt = 0;
2834
2835 /* compare with scheduling CSA to block incoming CSA IE */
2836 if (rfctl->csa_ch || check_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON))
2837 return;
2838
2839 for (i = 0; i + 1 < ies_len;) {
2840 pIE = (PNDIS_802_11_VARIABLE_IEs)(ies + i);
2841
2842 switch (pIE->ElementID) {
2843 case WLAN_EID_CHANNEL_SWITCH:
2844 ch = *(pIE->data + 1);
2845 csa_switch_cnt = *(pIE->data + 2);
2846 break;
2847 case WLAN_EID_SECONDARY_CHANNEL_OFFSET:
2848 csa_ch_offset = *(pIE->data);
2849 break;
2850 case WLAN_EID_WIDE_BANDWIDTH_CHANNEL_SWITCH:
2851 csa_ch_width = *(pIE->data);
2852 csa_ch_freq_seg0 = *(pIE->data+1);
2853 csa_ch_freq_seg1 = *(pIE->data+2);
2854 /* RTW_INFO("bw:%02x center_freq_0:%d center_freq_1:%d, ch=%d\n"
2855 , csa_ch_width, csa_ch_freq_seg0, csa_ch_freq_seg1, ch); */
2856 break;
2857 case WLAN_EID_CHANNEL_SWITCH_WRAPPER:
2858 for(j=0; j + 1 < pIE->Length;) {
2859 sub_pie = (PNDIS_802_11_VARIABLE_IEs)(ies + i + j + 2);
2860 if(sub_pie->ElementID == WLAN_EID_WIDE_BANDWIDTH_CHANNEL_SWITCH) {
2861 csa_ch_width = *(sub_pie->data);
2862 csa_ch_freq_seg0 = *(sub_pie->data+1);
2863 csa_ch_freq_seg1 = *(sub_pie->data+2);
2864 /* RTW_INFO("2. sub_IE:%02x IE_length:%02x bw:%02x center_freq_0:%d center_freq_1:%d, ch=%d\n"
2865 , sub_pie->ElementID, sub_pie->Length, csa_ch_width, csa_ch_freq_seg0, csa_ch_freq_seg1, ch); */
2866 }
2867 j += (sub_pie->Length + 2);
2868 }
2869 break;
2870 #ifdef CONFIG_ECSA
2871 case WLAN_EID_ECSA:
2872 rfctl->ecsa_mode = *(pIE->data + 0);
2873 rfctl->ecsa_op_class = *(pIE->data + 1);
2874 ch = *(pIE->data + 2);
2875 csa_switch_cnt = *(pIE->data + 3);
2876
2877 rtw_get_bw_offset_by_op_class_ch(rfctl->ecsa_op_class,
2878 ch, &csa_ch_width,
2879 &csa_ch_offset);
2880 /* change to ieee offset */
2881 switch (csa_ch_offset) {
2882 case HAL_PRIME_CHNL_OFFSET_LOWER:
2883 csa_ch_offset = IEEE80211_HT_IE_CHA_SEC_BELOW;
2884 break;
2885 case HAL_PRIME_CHNL_OFFSET_UPPER:
2886 csa_ch_offset = IEEE80211_HT_IE_CHA_SEC_ABOVE;
2887 break;
2888 default:
2889 csa_ch_offset = IEEE80211_HT_IE_CHA_SEC_NONE;
2890 break;
2891 }
2892
2893 /* change to ieee channel width */
2894 switch(csa_ch_width) {
2895 case CHANNEL_WIDTH_20:
2896 case CHANNEL_WIDTH_40:
2897 csa_ch_width = 0;
2898 break;
2899 case CHANNEL_WIDTH_80:
2900 case CHANNEL_WIDTH_160:
2901 case CHANNEL_WIDTH_80_80:
2902 csa_ch_width = 1;
2903 break;
2904 default:
2905 csa_ch_width = 0;
2906 break;
2907 }
2908
2909 RTW_INFO("ECSA: mode=%d, class=%d, ch=%d, cnt=%d\n",
2910 rfctl->ecsa_mode, rfctl->ecsa_op_class,
2911 ch, csa_switch_cnt);
2912 break;
2913 #endif
2914 default:
2915 break;
2916 }
2917
2918 i += (pIE->Length + 2);
2919 }
2920
2921 if (ch != 0) {
2922 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
2923 _adapter *pri_adapter = dvobj_get_primary_adapter(dvobj);
2924 u8 ifbmp_m = rtw_mi_get_ap_mesh_ifbmp(pri_adapter);
2925
2926 rfctl->csa_ch = ch;
2927 rfctl->csa_switch_cnt = csa_switch_cnt;
2928 rfctl->csa_ch_offset = csa_ch_offset;
2929 rfctl->csa_ch_width = csa_ch_width;
2930 rfctl->csa_ch_freq_seg0 = csa_ch_freq_seg0;
2931 rfctl->csa_ch_freq_seg1 = csa_ch_freq_seg1;
2932
2933 #ifdef CONFIG_AP_MODE
2934 if(ifbmp_m) {
2935 rfctl->ap_csa_en = STA_RX_CSA;
2936 rfctl->ap_csa_ch = ch;
2937 rfctl->ap_csa_switch_cnt = csa_switch_cnt;
2938 rtw_set_ap_csa_cmd(pri_adapter);
2939 }
2940 #endif
2941
2942 countdown = pmlmeinfo->network.Configuration.BeaconPeriod * (csa_switch_cnt+1); /* ms */
2943 RTW_INFO("csa: set countdown timer to %d ms\n", countdown);
2944 _set_timer(&pri_adapter->mlmeextpriv.csa_timer, countdown);
2945
2946 }
2947 }
2948 #endif /* CONFIG_DFS */
2949
2950 #ifdef CONFIG_80211D
rtw_iface_accept_country_ie(_adapter * adapter)2951 bool rtw_iface_accept_country_ie(_adapter *adapter)
2952 {
2953 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
2954
2955 if (!(BIT(adapter->iface_id) & rfctl->country_ie_slave_en_ifbmp))
2956 return 0;
2957 if (!MLME_IS_STA(adapter))
2958 return 0;
2959 if (!MLME_IS_GC(adapter)) {
2960 if (!(rfctl->country_ie_slave_en_role & COUNTRY_IE_SLAVE_EN_ROLE_STA))
2961 return 0;
2962 } else {
2963 if (!(rfctl->country_ie_slave_en_role & COUNTRY_IE_SLAVE_EN_ROLE_GC))
2964 return 0;
2965 }
2966 return 1;
2967 }
2968
process_country_ie(_adapter * adapter,u8 * ies,uint ies_len)2969 void process_country_ie(_adapter *adapter, u8 *ies, uint ies_len)
2970 {
2971 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
2972
2973 if (rfctl->regd_src == REGD_SRC_RTK_PRIV
2974 && !rtw_rfctl_is_disable_sw_channel_plan(rfctl_to_dvobj(rfctl))
2975 && !rfctl->csa_ch /* don't process country ie when under CSA processing */
2976 ) {
2977 struct mlme_priv *mlme = &adapter->mlmepriv;
2978 const u8 *ie = NULL;
2979 sint ie_len = 0;
2980
2981 if (rtw_iface_accept_country_ie(adapter)) {
2982 ie = rtw_get_ie(ies, WLAN_EID_COUNTRY, &ie_len, ies_len);
2983 if (ie) {
2984 if (ie_len < 6) {
2985 ie = NULL;
2986 ie_len = 0;
2987 } else
2988 ie_len += 2;
2989 }
2990 }
2991
2992 if (!mlme->recv_country_ie && !ie)
2993 return;
2994 if (mlme->recv_country_ie_len == ie_len
2995 && _rtw_memcmp(mlme->recv_country_ie, ie, ie_len) == _TRUE)
2996 return;
2997
2998 if (!ie) {
2999 rtw_buf_free(&mlme->recv_country_ie, &mlme->recv_country_ie_len);
3000 rtw_apply_recv_country_ie_cmd(adapter, 0, 0, 0, NULL);
3001 } else {
3002 char ori_alpha2[2] = {0, 0};
3003
3004 if (mlme->recv_country_ie)
3005 _rtw_memcpy(ori_alpha2, mlme->recv_country_ie + 2, 2);
3006
3007 rtw_buf_update(&mlme->recv_country_ie, &mlme->recv_country_ie_len, ie, ie_len);
3008 /* for now only country code is used */
3009 if (_rtw_memcmp(ori_alpha2, mlme->recv_country_ie + 2, 2) == _TRUE)
3010 return;
3011 RTW_INFO(FUNC_ADPT_FMT" country_ie alpha2 changed\n", FUNC_ADPT_ARG(adapter));
3012 rtw_apply_recv_country_ie_cmd(adapter, 0
3013 , mlme->cur_beacon_keys.ch > 14 ? BAND_ON_5G : BAND_ON_2_4G
3014 , mlme->cur_beacon_keys.ch, mlme->recv_country_ie);
3015 }
3016 }
3017 }
3018 #endif /* CONFIG_80211D */
3019
parsing_eapol_packet(_adapter * padapter,u8 * key_payload,struct sta_info * psta,u8 trx_type)3020 enum eap_type parsing_eapol_packet(_adapter *padapter, u8 *key_payload, struct sta_info *psta, u8 trx_type)
3021 {
3022 struct security_priv *psecuritypriv = &(padapter->securitypriv);
3023 struct ieee802_1x_hdr *hdr;
3024 struct wpa_eapol_key *key;
3025 u16 key_info, key_data_length;
3026 char *trx_msg = trx_type ? "send" : "recv";
3027 enum eap_type eapol_type;
3028
3029 hdr = (struct ieee802_1x_hdr *) key_payload;
3030
3031 /* WPS - eapol start packet */
3032 if (hdr->type == 1 && hdr->length == 0) {
3033 RTW_INFO("%s eapol start packet\n", trx_msg);
3034 return EAPOL_START;
3035 }
3036
3037 if (hdr->type == 0) { /* WPS - eapol packet */
3038 RTW_INFO("%s eapol packet\n", trx_msg);
3039 return EAPOL_PACKET;
3040 }
3041
3042 key = (struct wpa_eapol_key *) (hdr + 1);
3043 key_info = be16_to_cpu(*((u16 *)(key->key_info)));
3044 key_data_length = be16_to_cpu(*((u16 *)(key->key_data_length)));
3045
3046 if (!(key_info & WPA_KEY_INFO_KEY_TYPE)) { /* WPA group key handshake */
3047 if (key_info & WPA_KEY_INFO_ACK) {
3048 RTW_PRINT("%s eapol packet - WPA Group Key 1/2\n", trx_msg);
3049 eapol_type = EAPOL_WPA_GROUP_KEY_1_2;
3050 } else {
3051 RTW_PRINT("%s eapol packet - WPA Group Key 2/2\n", trx_msg);
3052 eapol_type = EAPOL_WPA_GROUP_KEY_2_2;
3053
3054 /* WPA key-handshake has completed */
3055 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK)
3056 psta->state &= (~WIFI_UNDER_KEY_HANDSHAKE);
3057 }
3058 } else if (key_info & WPA_KEY_INFO_MIC) {
3059 if (key_data_length == 0) {
3060 RTW_PRINT("%s eapol packet 4/4\n", trx_msg);
3061 eapol_type = EAPOL_4_4;
3062 } else if (key_info & WPA_KEY_INFO_ACK) {
3063 RTW_PRINT("%s eapol packet 3/4\n", trx_msg);
3064 eapol_type = EAPOL_3_4;
3065 } else {
3066 RTW_PRINT("%s eapol packet 2/4\n", trx_msg);
3067 eapol_type = EAPOL_2_4;
3068 }
3069 } else {
3070 RTW_PRINT("%s eapol packet 1/4\n", trx_msg);
3071 eapol_type = EAPOL_1_4;
3072 }
3073
3074 return eapol_type;
3075 }
3076
is_ap_in_tkip(_adapter * padapter)3077 unsigned int is_ap_in_tkip(_adapter *padapter)
3078 {
3079 u32 i;
3080 PNDIS_802_11_VARIABLE_IEs pIE;
3081 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3082 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3083 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
3084
3085 if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
3086 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) {
3087 pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
3088
3089 switch (pIE->ElementID) {
3090 case _VENDOR_SPECIFIC_IE_:
3091 if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) && (_rtw_memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4)))
3092 return _TRUE;
3093 break;
3094
3095 case _RSN_IE_2_:
3096 if (_rtw_memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4))
3097 return _TRUE;
3098 break;
3099 default:
3100 break;
3101 }
3102
3103 i += (pIE->Length + 2);
3104 }
3105
3106 return _FALSE;
3107 } else
3108 return _FALSE;
3109
3110 }
3111
should_forbid_n_rate(_adapter * padapter)3112 unsigned int should_forbid_n_rate(_adapter *padapter)
3113 {
3114 u32 i;
3115 PNDIS_802_11_VARIABLE_IEs pIE;
3116 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3117 WLAN_BSSID_EX *cur_network = &pmlmepriv->cur_network.network;
3118
3119 if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
3120 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < cur_network->IELength;) {
3121 pIE = (PNDIS_802_11_VARIABLE_IEs)(cur_network->IEs + i);
3122
3123 switch (pIE->ElementID) {
3124 case _VENDOR_SPECIFIC_IE_:
3125 if (_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4) &&
3126 ((_rtw_memcmp((pIE->data + 12), WPA_CIPHER_SUITE_CCMP, 4)) ||
3127 (_rtw_memcmp((pIE->data + 16), WPA_CIPHER_SUITE_CCMP, 4))))
3128 return _FALSE;
3129 break;
3130
3131 case _RSN_IE_2_:
3132 if ((_rtw_memcmp((pIE->data + 8), RSN_CIPHER_SUITE_CCMP, 4)) ||
3133 (_rtw_memcmp((pIE->data + 12), RSN_CIPHER_SUITE_CCMP, 4)))
3134 return _FALSE;
3135 break;
3136 default:
3137 break;
3138 }
3139
3140 i += (pIE->Length + 2);
3141 }
3142
3143 return _TRUE;
3144 } else
3145 return _FALSE;
3146
3147 }
3148
3149
is_ap_in_wep(_adapter * padapter)3150 unsigned int is_ap_in_wep(_adapter *padapter)
3151 {
3152 u32 i;
3153 PNDIS_802_11_VARIABLE_IEs pIE;
3154 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3155 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3156 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
3157
3158 if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
3159 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) {
3160 pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
3161
3162 switch (pIE->ElementID) {
3163 case _VENDOR_SPECIFIC_IE_:
3164 if (_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4))
3165 return _FALSE;
3166 break;
3167
3168 case _RSN_IE_2_:
3169 return _FALSE;
3170
3171 default:
3172 break;
3173 }
3174
3175 i += (pIE->Length + 2);
3176 }
3177
3178 return _TRUE;
3179 } else
3180 return _FALSE;
3181
3182 }
3183
3184 int wifirate2_ratetbl_inx(unsigned char rate);
wifirate2_ratetbl_inx(unsigned char rate)3185 int wifirate2_ratetbl_inx(unsigned char rate)
3186 {
3187 int inx = 0;
3188 rate = rate & 0x7f;
3189
3190 switch (rate) {
3191 case 54*2:
3192 inx = 11;
3193 break;
3194
3195 case 48*2:
3196 inx = 10;
3197 break;
3198
3199 case 36*2:
3200 inx = 9;
3201 break;
3202
3203 case 24*2:
3204 inx = 8;
3205 break;
3206
3207 case 18*2:
3208 inx = 7;
3209 break;
3210
3211 case 12*2:
3212 inx = 6;
3213 break;
3214
3215 case 9*2:
3216 inx = 5;
3217 break;
3218
3219 case 6*2:
3220 inx = 4;
3221 break;
3222
3223 case 11*2:
3224 inx = 3;
3225 break;
3226 case 11:
3227 inx = 2;
3228 break;
3229
3230 case 2*2:
3231 inx = 1;
3232 break;
3233
3234 case 1*2:
3235 inx = 0;
3236 break;
3237
3238 }
3239 return inx;
3240 }
3241
update_basic_rate(unsigned char * ptn,unsigned int ptn_sz)3242 unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz)
3243 {
3244 unsigned int i, num_of_rate;
3245 unsigned int mask = 0;
3246
3247 num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz;
3248
3249 for (i = 0; i < num_of_rate; i++) {
3250 if ((*(ptn + i)) & 0x80)
3251 mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
3252 }
3253 return mask;
3254 }
3255
update_supported_rate(unsigned char * ptn,unsigned int ptn_sz)3256 unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz)
3257 {
3258 unsigned int i, num_of_rate;
3259 unsigned int mask = 0;
3260
3261 num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz;
3262
3263 for (i = 0; i < num_of_rate; i++)
3264 mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
3265
3266 return mask;
3267 }
3268
support_short_GI(_adapter * padapter,struct HT_caps_element * pHT_caps,u8 bwmode)3269 int support_short_GI(_adapter *padapter, struct HT_caps_element *pHT_caps, u8 bwmode)
3270 {
3271 unsigned char bit_offset;
3272 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3273 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3274
3275 if (!(pmlmeinfo->HT_enable))
3276 return _FAIL;
3277
3278 bit_offset = (bwmode & CHANNEL_WIDTH_40) ? 6 : 5;
3279
3280 if (pHT_caps->u.HT_cap_element.HT_caps_info & (0x1 << bit_offset))
3281 return _SUCCESS;
3282 else
3283 return _FAIL;
3284 }
3285
get_highest_rate_idx(u64 mask)3286 unsigned char get_highest_rate_idx(u64 mask)
3287 {
3288 int i;
3289 unsigned char rate_idx = 0;
3290
3291 for (i = 63; i >= 0; i--) {
3292 if ((mask >> i) & 0x01) {
3293 rate_idx = i;
3294 break;
3295 }
3296 }
3297
3298 return rate_idx;
3299 }
get_lowest_rate_idx_ex(u64 mask,int start_bit)3300 unsigned char get_lowest_rate_idx_ex(u64 mask, int start_bit)
3301 {
3302 int i;
3303 unsigned char rate_idx = 0;
3304
3305 for (i = start_bit; i < 64; i++) {
3306 if ((mask >> i) & 0x01) {
3307 rate_idx = i;
3308 break;
3309 }
3310 }
3311
3312 return rate_idx;
3313 }
3314
Update_RA_Entry(_adapter * padapter,struct sta_info * psta)3315 void Update_RA_Entry(_adapter *padapter, struct sta_info *psta)
3316 {
3317 rtw_hal_update_ra_mask(psta);
3318 }
3319
set_sta_rate(_adapter * padapter,struct sta_info * psta)3320 void set_sta_rate(_adapter *padapter, struct sta_info *psta)
3321 {
3322 /* rate adaptive */
3323 rtw_hal_update_ra_mask(psta);
3324 }
3325
3326 /* Update RRSR and Rate for USERATE */
update_tx_basic_rate(_adapter * padapter,u8 wirelessmode)3327 void update_tx_basic_rate(_adapter *padapter, u8 wirelessmode)
3328 {
3329 NDIS_802_11_RATES_EX supported_rates;
3330 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3331 #ifdef CONFIG_P2P
3332 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3333
3334 /* Added by Albert 2011/03/22 */
3335 /* In the P2P mode, the driver should not support the b mode. */
3336 /* So, the Tx packet shouldn't use the CCK rate */
3337 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3338 return;
3339 #endif /* CONFIG_P2P */
3340
3341 _rtw_memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
3342
3343 /* clear B mod if current channel is in 5G band, avoid tx cck rate in 5G band. */
3344 if (pmlmeext->cur_channel > 14)
3345 wirelessmode &= ~(WIRELESS_11B);
3346
3347 if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B))
3348 _rtw_memcpy(supported_rates, rtw_basic_rate_cck, 4);
3349 else if (wirelessmode & WIRELESS_11B)
3350 _rtw_memcpy(supported_rates, rtw_basic_rate_mix, 7);
3351 else
3352 _rtw_memcpy(supported_rates, rtw_basic_rate_ofdm, 3);
3353
3354 if (wirelessmode & WIRELESS_11B)
3355 update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
3356 else
3357 update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
3358
3359 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, supported_rates);
3360 }
3361
check_assoc_AP(u8 * pframe,uint len)3362 unsigned char check_assoc_AP(u8 *pframe, uint len)
3363 {
3364 unsigned int i;
3365 PNDIS_802_11_VARIABLE_IEs pIE;
3366
3367 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < len;) {
3368 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
3369
3370 switch (pIE->ElementID) {
3371 case _VENDOR_SPECIFIC_IE_:
3372 if ((_rtw_memcmp(pIE->data, ARTHEROS_OUI1, 3)) || (_rtw_memcmp(pIE->data, ARTHEROS_OUI2, 3))) {
3373 RTW_INFO("link to Artheros AP\n");
3374 return HT_IOT_PEER_ATHEROS;
3375 } else if ((_rtw_memcmp(pIE->data, BROADCOM_OUI1, 3))
3376 || (_rtw_memcmp(pIE->data, BROADCOM_OUI2, 3))
3377 || (_rtw_memcmp(pIE->data, BROADCOM_OUI3, 3))) {
3378 RTW_INFO("link to Broadcom AP\n");
3379 return HT_IOT_PEER_BROADCOM;
3380 } else if (_rtw_memcmp(pIE->data, MARVELL_OUI, 3)) {
3381 RTW_INFO("link to Marvell AP\n");
3382 return HT_IOT_PEER_MARVELL;
3383 } else if (_rtw_memcmp(pIE->data, RALINK_OUI, 3)) {
3384 RTW_INFO("link to Ralink AP\n");
3385 return HT_IOT_PEER_RALINK;
3386 } else if (_rtw_memcmp(pIE->data, CISCO_OUI, 3)) {
3387 RTW_INFO("link to Cisco AP\n");
3388 return HT_IOT_PEER_CISCO;
3389 } else if (_rtw_memcmp(pIE->data, REALTEK_OUI, 3)) {
3390 u32 Vender = HT_IOT_PEER_REALTEK;
3391
3392 if (pIE->Length >= 5) {
3393 if (pIE->data[4] == 1) {
3394 /* if(pIE->data[5] & RT_HT_CAP_USE_LONG_PREAMBLE) */
3395 /* bssDesc->BssHT.RT2RT_HT_Mode |= RT_HT_CAP_USE_LONG_PREAMBLE; */
3396
3397 if (pIE->data[5] & RT_HT_CAP_USE_92SE) {
3398 /* bssDesc->BssHT.RT2RT_HT_Mode |= RT_HT_CAP_USE_92SE; */
3399 Vender = HT_IOT_PEER_REALTEK_92SE;
3400 }
3401 }
3402
3403 if (pIE->data[5] & RT_HT_CAP_USE_SOFTAP)
3404 Vender = HT_IOT_PEER_REALTEK_SOFTAP;
3405
3406 if (pIE->data[4] == 2) {
3407 if (pIE->data[6] & RT_HT_CAP_USE_JAGUAR_BCUT) {
3408 Vender = HT_IOT_PEER_REALTEK_JAGUAR_BCUTAP;
3409 RTW_INFO("link to Realtek JAGUAR_BCUTAP\n");
3410 }
3411 if (pIE->data[6] & RT_HT_CAP_USE_JAGUAR_CCUT) {
3412 Vender = HT_IOT_PEER_REALTEK_JAGUAR_CCUTAP;
3413 RTW_INFO("link to Realtek JAGUAR_CCUTAP\n");
3414 }
3415 }
3416 }
3417
3418 RTW_INFO("link to Realtek AP\n");
3419 return Vender;
3420 } else if (_rtw_memcmp(pIE->data, AIRGOCAP_OUI, 3)) {
3421 RTW_INFO("link to Airgo Cap\n");
3422 return HT_IOT_PEER_AIRGO;
3423 } else
3424 break;
3425
3426 default:
3427 break;
3428 }
3429
3430 i += (pIE->Length + 2);
3431 }
3432
3433 RTW_INFO("link to new AP\n");
3434 return HT_IOT_PEER_UNKNOWN;
3435 }
3436
get_assoc_AP_Vendor(char * vendor,u8 assoc_AP_vendor)3437 void get_assoc_AP_Vendor(char *vendor, u8 assoc_AP_vendor)
3438 {
3439 switch (assoc_AP_vendor) {
3440
3441 case HT_IOT_PEER_UNKNOWN:
3442 sprintf(vendor, "%s", "unknown");
3443 break;
3444
3445 case HT_IOT_PEER_REALTEK:
3446 case HT_IOT_PEER_REALTEK_92SE:
3447 case HT_IOT_PEER_REALTEK_SOFTAP:
3448 case HT_IOT_PEER_REALTEK_JAGUAR_BCUTAP:
3449 case HT_IOT_PEER_REALTEK_JAGUAR_CCUTAP:
3450
3451 sprintf(vendor, "%s", "Realtek");
3452 break;
3453
3454 case HT_IOT_PEER_BROADCOM:
3455 sprintf(vendor, "%s", "Broadcom");
3456 break;
3457
3458 case HT_IOT_PEER_MARVELL:
3459 sprintf(vendor, "%s", "Marvell");
3460 break;
3461
3462 case HT_IOT_PEER_RALINK:
3463 sprintf(vendor, "%s", "Ralink");
3464 break;
3465
3466 case HT_IOT_PEER_CISCO:
3467 sprintf(vendor, "%s", "Cisco");
3468 break;
3469
3470 case HT_IOT_PEER_AIRGO:
3471 sprintf(vendor, "%s", "Airgo");
3472 break;
3473
3474 case HT_IOT_PEER_ATHEROS:
3475 sprintf(vendor, "%s", "Atheros");
3476 break;
3477
3478 default:
3479 sprintf(vendor, "%s", "unkown");
3480 break;
3481 }
3482
3483 }
3484 #ifdef CONFIG_RTS_FULL_BW
rtw_parse_sta_vendor_ie_8812(_adapter * adapter,struct sta_info * sta,u8 * tlv_ies,u16 tlv_ies_len)3485 void rtw_parse_sta_vendor_ie_8812(_adapter *adapter, struct sta_info *sta, u8 *tlv_ies, u16 tlv_ies_len)
3486 {
3487 unsigned char REALTEK_OUI[] = {0x00,0xe0, 0x4c};
3488 u8 *p;
3489
3490 p = rtw_get_ie_ex(tlv_ies, tlv_ies_len, WLAN_EID_VENDOR_SPECIFIC, REALTEK_OUI, 3, NULL, NULL);
3491 if (!p)
3492 goto exit;
3493 else {
3494 if(*(p+1) > 6 ) {
3495
3496 if(*(p+6) != 2)
3497 goto exit;
3498
3499 if(*(p+8) == RT_HT_CAP_USE_JAGUAR_BCUT)
3500 sta->vendor_8812 = TRUE;
3501 else if (*(p+8) == RT_HT_CAP_USE_JAGUAR_CCUT)
3502 sta->vendor_8812 = TRUE;
3503 }
3504 }
3505 exit:
3506 return;
3507 }
3508 #endif/*CONFIG_RTS_FULL_BW*/
3509
3510 #ifdef CONFIG_80211AC_VHT
get_vht_bf_cap(u8 * pframe,uint len,struct vht_bf_cap * bf_cap)3511 void get_vht_bf_cap(u8 *pframe, uint len, struct vht_bf_cap *bf_cap)
3512 {
3513 unsigned int i;
3514 PNDIS_802_11_VARIABLE_IEs pIE;
3515
3516 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < len;) {
3517 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
3518
3519 switch (pIE->ElementID) {
3520
3521 case EID_VHTCapability:
3522 bf_cap->is_mu_bfer = GET_VHT_CAPABILITY_ELE_MU_BFER(pIE->data);
3523 bf_cap->su_sound_dim = GET_VHT_CAPABILITY_ELE_SU_BFER_SOUND_DIM_NUM(pIE->data);
3524 break;
3525 default:
3526 break;
3527 }
3528 i += (pIE->Length + 2);
3529 }
3530 }
3531 #endif
3532
update_capinfo(PADAPTER Adapter,u16 updateCap)3533 void update_capinfo(PADAPTER Adapter, u16 updateCap)
3534 {
3535 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
3536 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3537 BOOLEAN ShortPreamble;
3538
3539 /* Check preamble mode, 2005.01.06, by rcnjko. */
3540 /* Mark to update preamble value forever, 2008.03.18 by lanhsin */
3541 /* if( pMgntInfo->RegPreambleMode == PREAMBLE_AUTO ) */
3542 {
3543
3544 if (updateCap & cShortPreamble) {
3545 /* Short Preamble */
3546 if (pmlmeinfo->preamble_mode != PREAMBLE_SHORT) { /* PREAMBLE_LONG or PREAMBLE_AUTO */
3547 ShortPreamble = _TRUE;
3548 pmlmeinfo->preamble_mode = PREAMBLE_SHORT;
3549 rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble);
3550 }
3551 } else {
3552 /* Long Preamble */
3553 if (pmlmeinfo->preamble_mode != PREAMBLE_LONG) { /* PREAMBLE_SHORT or PREAMBLE_AUTO */
3554 ShortPreamble = _FALSE;
3555 pmlmeinfo->preamble_mode = PREAMBLE_LONG;
3556 rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble);
3557 }
3558 }
3559 }
3560
3561 if (updateCap & cIBSS) {
3562 /* Filen: See 802.11-2007 p.91 */
3563 pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
3564 } else {
3565 /* Filen: See 802.11-2007 p.90 */
3566 if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N | WIRELESS_11A | WIRELESS_11_5N | WIRELESS_11AC))
3567 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
3568 else if (pmlmeext->cur_wireless_mode & (WIRELESS_11G)) {
3569 if ((updateCap & cShortSlotTime) /* && (!(pMgntInfo->pHTInfo->RT2RT_HT_Mode & RT_HT_CAP_USE_LONG_PREAMBLE)) */) {
3570 /* Short Slot Time */
3571 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
3572 } else {
3573 /* Long Slot Time */
3574 pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
3575 }
3576 } else {
3577 /* B Mode */
3578 pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
3579 }
3580 }
3581
3582 rtw_hal_set_hwreg(Adapter, HW_VAR_SLOT_TIME, &pmlmeinfo->slotTime);
3583
3584 }
3585
3586 /*
3587 * set adapter.mlmeextpriv.mlmext_info.HT_enable
3588 * set adapter.mlmeextpriv.cur_wireless_mode
3589 * set SIFS register
3590 * set mgmt tx rate
3591 */
update_wireless_mode(_adapter * padapter)3592 void update_wireless_mode(_adapter *padapter)
3593 {
3594 int ratelen, network_type = 0;
3595 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3596 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3597 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
3598 unsigned char *rate = cur_network->SupportedRates;
3599 #ifdef CONFIG_P2P
3600 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3601 #endif /* CONFIG_P2P */
3602
3603 ratelen = rtw_get_rateset_len(cur_network->SupportedRates);
3604
3605 if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
3606 pmlmeinfo->HT_enable = 1;
3607
3608 if (pmlmeext->cur_channel > 14) {
3609 if (pmlmeinfo->VHT_enable)
3610 network_type = WIRELESS_11AC;
3611 else if (pmlmeinfo->HT_enable)
3612 network_type = WIRELESS_11_5N;
3613
3614 network_type |= WIRELESS_11A;
3615 } else {
3616 if (pmlmeinfo->VHT_enable)
3617 network_type = WIRELESS_11AC;
3618 else if (pmlmeinfo->HT_enable)
3619 network_type = WIRELESS_11_24N;
3620
3621 if ((cckratesonly_included(rate, ratelen)) == _TRUE)
3622 network_type |= WIRELESS_11B;
3623 else if ((cckrates_included(rate, ratelen)) == _TRUE)
3624 network_type |= WIRELESS_11BG;
3625 else
3626 network_type |= WIRELESS_11G;
3627 }
3628
3629 pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode;
3630 /* RTW_INFO("network_type=%02x, padapter->registrypriv.wireless_mode=%02x\n", network_type, padapter->registrypriv.wireless_mode); */
3631
3632 #ifndef RTW_HALMAC
3633 /* HALMAC IC do not set HW_VAR_RESP_SIFS here */
3634 rtw_hal_set_hwreg(padapter, HW_VAR_RESP_SIFS, NULL);
3635 #endif
3636 if ((pmlmeext->cur_wireless_mode & WIRELESS_11B)
3637 #ifdef CONFIG_P2P
3638 && (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
3639 #ifdef CONFIG_IOCTL_CFG80211
3640 || !rtw_cfg80211_iface_has_p2p_group_cap(padapter)
3641 #endif
3642 )
3643 #endif
3644 )
3645 update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
3646 else
3647 update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
3648 }
3649
3650 void fire_write_MAC_cmd(_adapter *padapter, unsigned int addr, unsigned int value);
fire_write_MAC_cmd(_adapter * padapter,unsigned int addr,unsigned int value)3651 void fire_write_MAC_cmd(_adapter *padapter, unsigned int addr, unsigned int value)
3652 {
3653 #if 0
3654 struct cmd_obj *ph2c;
3655 struct reg_rw_parm *pwriteMacPara;
3656 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
3657
3658 ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
3659 if (ph2c == NULL)
3660 return;
3661
3662 pwriteMacPara = (struct reg_rw_parm *)rtw_malloc(sizeof(struct reg_rw_parm));
3663 if (pwriteMacPara == NULL) {
3664 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
3665 return;
3666 }
3667
3668 pwriteMacPara->rw = 1;
3669 pwriteMacPara->addr = addr;
3670 pwriteMacPara->value = value;
3671
3672 init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteMacPara, GEN_CMD_CODE(_Write_MACREG));
3673 rtw_enqueue_cmd(pcmdpriv, ph2c);
3674 #endif
3675 }
3676
update_sta_basic_rate(struct sta_info * psta,u8 wireless_mode)3677 void update_sta_basic_rate(struct sta_info *psta, u8 wireless_mode)
3678 {
3679 if (IsSupportedTxCCK(wireless_mode)) {
3680 /* Only B, B/G, and B/G/N AP could use CCK rate */
3681 _rtw_memcpy(psta->bssrateset, rtw_basic_rate_cck, 4);
3682 psta->bssratelen = 4;
3683 } else {
3684 _rtw_memcpy(psta->bssrateset, rtw_basic_rate_ofdm, 3);
3685 psta->bssratelen = 3;
3686 }
3687 }
3688
rtw_ies_get_supported_rate(u8 * ies,uint ies_len,u8 * rate_set,u8 * rate_num)3689 int rtw_ies_get_supported_rate(u8 *ies, uint ies_len, u8 *rate_set, u8 *rate_num)
3690 {
3691 u8 *ie, *p;
3692 unsigned int ie_len;
3693 int i, j;
3694
3695 struct support_rate_handler support_rate_tbl[] = {
3696 {IEEE80211_CCK_RATE_1MB, _FALSE, _FALSE},
3697 {IEEE80211_CCK_RATE_2MB, _FALSE, _FALSE},
3698 {IEEE80211_CCK_RATE_5MB, _FALSE, _FALSE},
3699 {IEEE80211_CCK_RATE_11MB, _FALSE, _FALSE},
3700 {IEEE80211_OFDM_RATE_6MB, _FALSE, _FALSE},
3701 {IEEE80211_OFDM_RATE_9MB, _FALSE, _FALSE},
3702 {IEEE80211_OFDM_RATE_12MB, _FALSE, _FALSE},
3703 {IEEE80211_OFDM_RATE_18MB, _FALSE, _FALSE},
3704 {IEEE80211_OFDM_RATE_24MB, _FALSE, _FALSE},
3705 {IEEE80211_OFDM_RATE_36MB, _FALSE, _FALSE},
3706 {IEEE80211_OFDM_RATE_48MB, _FALSE, _FALSE},
3707 {IEEE80211_OFDM_RATE_54MB, _FALSE, _FALSE},
3708 };
3709
3710 if (!rate_set || !rate_num)
3711 return _FALSE;
3712
3713 *rate_num = 0;
3714 ie = rtw_get_ie(ies, _SUPPORTEDRATES_IE_, &ie_len, ies_len);
3715 if (ie == NULL)
3716 goto ext_rate;
3717
3718 /* get valid supported rates */
3719 for (i = 0; i < 12; i++) {
3720 p = ie + 2;
3721 for (j = 0; j < ie_len; j++) {
3722 if ((*p & ~BIT(7)) == support_rate_tbl[i].rate){
3723 support_rate_tbl[i].existence = _TRUE;
3724 if ((*p) & BIT(7))
3725 support_rate_tbl[i].basic = _TRUE;
3726 }
3727 p++;
3728 }
3729 }
3730
3731 ext_rate:
3732 ie = rtw_get_ie(ies, _EXT_SUPPORTEDRATES_IE_, &ie_len, ies_len);
3733 if (ie) {
3734 /* get valid extended supported rates */
3735 for (i = 0; i < 12; i++) {
3736 p = ie + 2;
3737 for (j = 0; j < ie_len; j++) {
3738 if ((*p & ~BIT(7)) == support_rate_tbl[i].rate){
3739 support_rate_tbl[i].existence = _TRUE;
3740 if ((*p) & BIT(7))
3741 support_rate_tbl[i].basic = _TRUE;
3742 }
3743 p++;
3744 }
3745 }
3746 }
3747
3748 for (i = 0; i < 12; i++){
3749 if (support_rate_tbl[i].existence){
3750 if (support_rate_tbl[i].basic)
3751 rate_set[*rate_num] = support_rate_tbl[i].rate | IEEE80211_BASIC_RATE_MASK;
3752 else
3753 rate_set[*rate_num] = support_rate_tbl[i].rate;
3754 *rate_num += 1;
3755 }
3756 }
3757
3758 if (*rate_num == 0)
3759 return _FAIL;
3760
3761 if (0) {
3762 int i;
3763
3764 for (i = 0; i < *rate_num; i++)
3765 RTW_INFO("rate:0x%02x\n", *(rate_set + i));
3766 }
3767
3768 return _SUCCESS;
3769 }
3770
process_addba_req(_adapter * padapter,u8 * paddba_req,u8 * addr)3771 void process_addba_req(_adapter *padapter, u8 *paddba_req, u8 *addr)
3772 {
3773 struct sta_info *psta;
3774 u16 tid, start_seq, param;
3775 struct sta_priv *pstapriv = &padapter->stapriv;
3776 struct ADDBA_request *preq = (struct ADDBA_request *)paddba_req;
3777 u8 size, accept = _FALSE;
3778
3779 psta = rtw_get_stainfo(pstapriv, addr);
3780 if (!psta)
3781 goto exit;
3782
3783 start_seq = le16_to_cpu(preq->BA_starting_seqctrl) >> 4;
3784
3785 param = le16_to_cpu(preq->BA_para_set);
3786 tid = (param >> 2) & 0x0f;
3787
3788
3789 accept = rtw_rx_ampdu_is_accept(padapter);
3790 if (padapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID)
3791 size = padapter->fix_rx_ampdu_size;
3792 else {
3793 size = rtw_rx_ampdu_size(padapter);
3794 size = rtw_min(size, rx_ampdu_size_sta_limit(padapter, psta));
3795 }
3796
3797 if (accept == _TRUE)
3798 rtw_addbarsp_cmd(padapter, addr, tid, 0, size, start_seq);
3799 else
3800 rtw_addbarsp_cmd(padapter, addr, tid, 37, size, start_seq); /* reject ADDBA Req */
3801
3802 exit:
3803 return;
3804 }
3805
rtw_process_bar_frame(_adapter * padapter,union recv_frame * precv_frame)3806 void rtw_process_bar_frame(_adapter *padapter, union recv_frame *precv_frame)
3807 {
3808 struct sta_priv *pstapriv = &padapter->stapriv;
3809 u8 *pframe = precv_frame->u.hdr.rx_data;
3810 struct sta_info *psta = NULL;
3811 struct recv_reorder_ctrl *preorder_ctrl = NULL;
3812 u8 tid = 0;
3813 u16 start_seq=0;
3814
3815 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3816 if (psta == NULL)
3817 goto exit;
3818
3819 tid = ((cpu_to_le16((*(u16 *)(pframe + 16))) & 0xf000) >> 12);
3820 preorder_ctrl = &psta->recvreorder_ctrl[tid];
3821 start_seq = ((cpu_to_le16(*(u16 *)(pframe + 18))) >> 4);
3822 preorder_ctrl->indicate_seq = start_seq;
3823
3824 /* for Debug use */
3825 if (0)
3826 RTW_INFO(FUNC_ADPT_FMT" tid=%d, start_seq=%d\n", FUNC_ADPT_ARG(padapter), tid, start_seq);
3827
3828 exit:
3829 return;
3830 }
3831
update_TSF(struct mlme_ext_priv * pmlmeext,u8 * pframe,uint len)3832 void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len)
3833 {
3834 u8 *pIE;
3835 u32 *pbuf;
3836
3837 pIE = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
3838 pbuf = (u32 *)pIE;
3839
3840 pmlmeext->TSFValue = le32_to_cpu(*(pbuf + 1));
3841
3842 pmlmeext->TSFValue = pmlmeext->TSFValue << 32;
3843
3844 pmlmeext->TSFValue |= le32_to_cpu(*pbuf);
3845 }
3846
correct_TSF(_adapter * padapter,u8 mlme_state)3847 void correct_TSF(_adapter *padapter, u8 mlme_state)
3848 {
3849 u8 m_state = mlme_state;
3850
3851 rtw_hal_set_hwreg(padapter, HW_VAR_CORRECT_TSF, (u8 *)&m_state);
3852 }
3853
3854 #ifdef CONFIG_BCN_RECV_TIME
3855 /* calculate beacon receiving time
3856 1.RxBCNTime(CCK_1M) = [192us(preamble)] + [length of beacon(byte)*8us] + [10us]
3857 2.RxBCNTime(OFDM_6M) = [8us(S) + 8us(L) + 4us(L-SIG)] + [(length of beacon(byte)/3 + 1] *4us] + [10us]
3858 */
_rx_bcn_time_calculate(uint bcn_len,u8 data_rate)3859 inline u16 _rx_bcn_time_calculate(uint bcn_len, u8 data_rate)
3860 {
3861 u16 rx_bcn_time = 0;/*us*/
3862
3863 if (data_rate == DESC_RATE1M)
3864 rx_bcn_time = 192 + bcn_len * 8 + 10;
3865 else if(data_rate == DESC_RATE6M)
3866 rx_bcn_time = 8 + 8 + 4 + (bcn_len /3 + 1) * 4 + 10;
3867 /*
3868 else
3869 RTW_ERR("%s invalid data rate(0x%02x)\n", __func__, data_rate);
3870 */
3871 return rx_bcn_time;
3872 }
rtw_rx_bcn_time_update(_adapter * adapter,uint bcn_len,u8 data_rate)3873 void rtw_rx_bcn_time_update(_adapter *adapter, uint bcn_len, u8 data_rate)
3874 {
3875 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3876
3877 pmlmeext->bcn_rx_time = _rx_bcn_time_calculate(bcn_len, data_rate);
3878 }
3879 #endif
3880
beacon_timing_control(_adapter * padapter)3881 void beacon_timing_control(_adapter *padapter)
3882 {
3883 rtw_hal_bcn_related_reg_setting(padapter);
3884 }
3885
_rtw_macid_ctl_chk_cap(_adapter * adapter,u8 cap)3886 inline bool _rtw_macid_ctl_chk_cap(_adapter *adapter, u8 cap)
3887 {
3888 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3889 struct macid_ctl_t *macid_ctl = &dvobj->macid_ctl;
3890
3891 if (macid_ctl->macid_cap & cap)
3892 return _TRUE;
3893 return _FALSE;
3894 }
3895
dump_macid_map(void * sel,struct macid_bmp * map,u8 max_num)3896 void dump_macid_map(void *sel, struct macid_bmp *map, u8 max_num)
3897 {
3898 RTW_PRINT_SEL(sel, "0x%08x\n", map->m0);
3899 #if (MACID_NUM_SW_LIMIT > 32)
3900 if (max_num && max_num > 32)
3901 RTW_PRINT_SEL(sel, "0x%08x\n", map->m1);
3902 #endif
3903 #if (MACID_NUM_SW_LIMIT > 64)
3904 if (max_num && max_num > 64)
3905 RTW_PRINT_SEL(sel, "0x%08x\n", map->m2);
3906 #endif
3907 #if (MACID_NUM_SW_LIMIT > 96)
3908 if (max_num && max_num > 96)
3909 RTW_PRINT_SEL(sel, "0x%08x\n", map->m3);
3910 #endif
3911 }
3912
rtw_macid_is_set(struct macid_bmp * map,u8 id)3913 inline bool rtw_macid_is_set(struct macid_bmp *map, u8 id)
3914 {
3915 if (id < 32)
3916 return map->m0 & BIT(id);
3917 #if (MACID_NUM_SW_LIMIT > 32)
3918 else if (id < 64)
3919 return map->m1 & BIT(id - 32);
3920 #endif
3921 #if (MACID_NUM_SW_LIMIT > 64)
3922 else if (id < 96)
3923 return map->m2 & BIT(id - 64);
3924 #endif
3925 #if (MACID_NUM_SW_LIMIT > 96)
3926 else if (id < 128)
3927 return map->m3 & BIT(id - 96);
3928 #endif
3929 else
3930 rtw_warn_on(1);
3931
3932 return 0;
3933 }
3934
rtw_macid_map_set(struct macid_bmp * map,u8 id)3935 inline void rtw_macid_map_set(struct macid_bmp *map, u8 id)
3936 {
3937 if (id < 32)
3938 map->m0 |= BIT(id);
3939 #if (MACID_NUM_SW_LIMIT > 32)
3940 else if (id < 64)
3941 map->m1 |= BIT(id - 32);
3942 #endif
3943 #if (MACID_NUM_SW_LIMIT > 64)
3944 else if (id < 96)
3945 map->m2 |= BIT(id - 64);
3946 #endif
3947 #if (MACID_NUM_SW_LIMIT > 96)
3948 else if (id < 128)
3949 map->m3 |= BIT(id - 96);
3950 #endif
3951 else
3952 rtw_warn_on(1);
3953 }
3954
rtw_macid_map_clr(struct macid_bmp * map,u8 id)3955 inline void rtw_macid_map_clr(struct macid_bmp *map, u8 id)
3956 {
3957 if (id < 32)
3958 map->m0 &= ~BIT(id);
3959 #if (MACID_NUM_SW_LIMIT > 32)
3960 else if (id < 64)
3961 map->m1 &= ~BIT(id - 32);
3962 #endif
3963 #if (MACID_NUM_SW_LIMIT > 64)
3964 else if (id < 96)
3965 map->m2 &= ~BIT(id - 64);
3966 #endif
3967 #if (MACID_NUM_SW_LIMIT > 96)
3968 else if (id < 128)
3969 map->m3 &= ~BIT(id - 96);
3970 #endif
3971 else
3972 rtw_warn_on(1);
3973 }
3974
rtw_macid_is_used(struct macid_ctl_t * macid_ctl,u8 id)3975 inline bool rtw_macid_is_used(struct macid_ctl_t *macid_ctl, u8 id)
3976 {
3977 return rtw_macid_is_set(&macid_ctl->used, id);
3978 }
3979
rtw_macid_is_bmc(struct macid_ctl_t * macid_ctl,u8 id)3980 inline bool rtw_macid_is_bmc(struct macid_ctl_t *macid_ctl, u8 id)
3981 {
3982 return rtw_macid_is_set(&macid_ctl->bmc, id);
3983 }
3984
rtw_macid_get_iface_bmp(struct macid_ctl_t * macid_ctl,u8 id)3985 inline u8 rtw_macid_get_iface_bmp(struct macid_ctl_t *macid_ctl, u8 id)
3986 {
3987 int i;
3988 u8 iface_bmp = 0;
3989
3990 for (i = 0; i < CONFIG_IFACE_NUMBER; i++) {
3991 if (rtw_macid_is_set(&macid_ctl->if_g[i], id))
3992 iface_bmp |= BIT(i);
3993 }
3994 return iface_bmp;
3995 }
3996
rtw_macid_is_iface_shared(struct macid_ctl_t * macid_ctl,u8 id)3997 inline bool rtw_macid_is_iface_shared(struct macid_ctl_t *macid_ctl, u8 id)
3998 {
3999 #if CONFIG_IFACE_NUMBER >= 2
4000 int i;
4001 u8 iface_bmp = 0;
4002
4003 for (i = 0; i < CONFIG_IFACE_NUMBER; i++) {
4004 if (rtw_macid_is_set(&macid_ctl->if_g[i], id)) {
4005 if (iface_bmp)
4006 return 1;
4007 iface_bmp |= BIT(i);
4008 }
4009 }
4010 #endif
4011 return 0;
4012 }
4013
rtw_macid_is_iface_specific(struct macid_ctl_t * macid_ctl,u8 id,_adapter * adapter)4014 inline bool rtw_macid_is_iface_specific(struct macid_ctl_t *macid_ctl, u8 id, _adapter *adapter)
4015 {
4016 int i;
4017 u8 iface_bmp = 0;
4018
4019 for (i = 0; i < CONFIG_IFACE_NUMBER; i++) {
4020 if (rtw_macid_is_set(&macid_ctl->if_g[i], id)) {
4021 if (iface_bmp || i != adapter->iface_id)
4022 return 0;
4023 iface_bmp |= BIT(i);
4024 }
4025 }
4026
4027 return iface_bmp ? 1 : 0;
4028 }
4029
rtw_macid_get_ch_g(struct macid_ctl_t * macid_ctl,u8 id)4030 inline s8 rtw_macid_get_ch_g(struct macid_ctl_t *macid_ctl, u8 id)
4031 {
4032 int i;
4033
4034 for (i = 0; i < 2; i++) {
4035 if (rtw_macid_is_set(&macid_ctl->ch_g[i], id))
4036 return i;
4037 }
4038 return -1;
4039 }
4040
4041 /*Record bc's mac-id and sec-cam-id*/
rtw_iface_bcmc_id_set(_adapter * padapter,u8 mac_id)4042 inline void rtw_iface_bcmc_id_set(_adapter *padapter, u8 mac_id)
4043 {
4044 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
4045 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
4046
4047 macid_ctl->iface_bmc[padapter->iface_id] = mac_id;
4048 }
rtw_iface_bcmc_id_get(_adapter * padapter)4049 inline u8 rtw_iface_bcmc_id_get(_adapter *padapter)
4050 {
4051 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
4052 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
4053
4054 return macid_ctl->iface_bmc[padapter->iface_id];
4055 }
4056 #if defined(DBG_CONFIG_ERROR_RESET)
rtw_iface_bcmc_sec_cam_map_restore(_adapter * adapter)4057 void rtw_iface_bcmc_sec_cam_map_restore(_adapter *adapter)
4058 {
4059 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4060 struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj);
4061 int cam_id = -1;
4062
4063 cam_id = rtw_iface_bcmc_id_get(adapter);
4064 if (cam_id != INVALID_SEC_MAC_CAM_ID)
4065 rtw_sec_cam_map_set(&cam_ctl->used, cam_id);
4066 }
4067 #endif
rtw_alloc_macid(_adapter * padapter,struct sta_info * psta)4068 void rtw_alloc_macid(_adapter *padapter, struct sta_info *psta)
4069 {
4070 int i;
4071 _irqL irqL;
4072 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4073 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
4074 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
4075 struct macid_bmp *used_map = &macid_ctl->used;
4076 /* static u8 last_id = 0; for testing */
4077 u8 last_id = 0;
4078 u8 is_bc_sta = _FALSE;
4079
4080 if (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN)) {
4081 psta->cmn.mac_id = macid_ctl->num;
4082 return;
4083 }
4084
4085 if (_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN)) {
4086 is_bc_sta = _TRUE;
4087 rtw_iface_bcmc_id_set(padapter, INVALID_SEC_MAC_CAM_ID); /*init default value*/
4088 }
4089
4090 if (is_bc_sta
4091 #ifndef SEC_DEFAULT_KEY_SEARCH
4092 && (MLME_IS_STA(padapter) || MLME_IS_NULL(padapter))
4093 #endif
4094 ) {
4095 /* STA mode have no BMC data TX, shared with this macid */
4096 /* When non-concurrent, only one BMC data TX is used, shared with this macid */
4097 /* TODO: When concurrent, non-security BMC data TX may use this, but will not control by specific macid sleep */
4098 i = RTW_DEFAULT_MGMT_MACID;
4099 goto assigned;
4100 }
4101
4102 _enter_critical_bh(&macid_ctl->lock, &irqL);
4103
4104 for (i = last_id; i < macid_ctl->num; i++) {
4105 #ifdef CONFIG_MCC_MODE
4106 /* macid 0/1 reserve for mcc for mgnt queue macid */
4107 if (MCC_EN(padapter)) {
4108 if (i == MCC_ROLE_STA_GC_MGMT_QUEUE_MACID)
4109 continue;
4110 if (i == MCC_ROLE_SOFTAP_GO_MGMT_QUEUE_MACID)
4111 continue;
4112 }
4113 #endif /* CONFIG_MCC_MODE */
4114
4115 #ifndef SEC_DEFAULT_KEY_SEARCH
4116 /* for BMC data TX with force camid */
4117 if (is_bc_sta && rtw_sec_camid_is_used(dvobj_to_sec_camctl(dvobj), i))
4118 continue;
4119 #endif
4120
4121 if (!rtw_macid_is_used(macid_ctl, i))
4122 break;
4123 }
4124
4125 if (i < macid_ctl->num) {
4126
4127 rtw_macid_map_set(used_map, i);
4128
4129 #ifndef SEC_DEFAULT_KEY_SEARCH
4130 /* for BMC data TX with force camid */
4131 if (is_bc_sta) {
4132 struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj);
4133
4134 rtw_macid_map_set(&macid_ctl->bmc, i);
4135 rtw_iface_bcmc_id_set(padapter, i);
4136 rtw_sec_cam_map_set(&cam_ctl->used, i);
4137 if (_rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_EXTRA_SEC))
4138 rtw_sec_cam_map_set(&cam_ctl->used, i + 1);
4139 }
4140 #endif
4141
4142 rtw_macid_map_set(&macid_ctl->if_g[padapter->iface_id], i);
4143 macid_ctl->sta[i] = psta;
4144
4145 /* TODO ch_g? */
4146
4147 last_id++;
4148 last_id %= macid_ctl->num;
4149 }
4150
4151 _exit_critical_bh(&macid_ctl->lock, &irqL);
4152
4153 if (i >= macid_ctl->num) {
4154 psta->cmn.mac_id = macid_ctl->num;
4155 RTW_ERR(FUNC_ADPT_FMT" if%u, mac_addr:"MAC_FMT" no available macid\n"
4156 , FUNC_ADPT_ARG(padapter), padapter->iface_id + 1, MAC_ARG(psta->cmn.mac_addr));
4157 rtw_warn_on(1);
4158 goto exit;
4159 } else
4160 goto assigned;
4161
4162 assigned:
4163 psta->cmn.mac_id = i;
4164 RTW_INFO(FUNC_ADPT_FMT" if%u, mac_addr:"MAC_FMT" macid:%u\n"
4165 , FUNC_ADPT_ARG(padapter), padapter->iface_id + 1, MAC_ARG(psta->cmn.mac_addr), psta->cmn.mac_id);
4166
4167 exit:
4168 return;
4169 }
4170
rtw_release_macid(_adapter * padapter,struct sta_info * psta)4171 void rtw_release_macid(_adapter *padapter, struct sta_info *psta)
4172 {
4173 _irqL irqL;
4174 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4175 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
4176 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
4177 u8 ifbmp;
4178 int i;
4179
4180 if (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN))
4181 goto exit;
4182
4183 if (psta->cmn.mac_id >= macid_ctl->num) {
4184 RTW_WARN(FUNC_ADPT_FMT" if%u, mac_addr:"MAC_FMT" macid:%u not valid\n"
4185 , FUNC_ADPT_ARG(padapter), padapter->iface_id + 1
4186 , MAC_ARG(psta->cmn.mac_addr), psta->cmn.mac_id);
4187 rtw_warn_on(1);
4188 goto exit;
4189 }
4190
4191 if (psta->cmn.mac_id == RTW_DEFAULT_MGMT_MACID)
4192 goto msg;
4193
4194 _enter_critical_bh(&macid_ctl->lock, &irqL);
4195
4196 if (!rtw_macid_is_used(macid_ctl, psta->cmn.mac_id)) {
4197 RTW_WARN(FUNC_ADPT_FMT" if%u, mac_addr:"MAC_FMT" macid:%u not used\n"
4198 , FUNC_ADPT_ARG(padapter), padapter->iface_id + 1
4199 , MAC_ARG(psta->cmn.mac_addr), psta->cmn.mac_id);
4200 _exit_critical_bh(&macid_ctl->lock, &irqL);
4201 rtw_warn_on(1);
4202 goto exit;
4203 }
4204
4205 ifbmp = rtw_macid_get_iface_bmp(macid_ctl, psta->cmn.mac_id);
4206 if (!(ifbmp & BIT(padapter->iface_id))) {
4207 RTW_WARN(FUNC_ADPT_FMT" if%u, mac_addr:"MAC_FMT" macid:%u not used by self\n"
4208 , FUNC_ADPT_ARG(padapter), padapter->iface_id + 1
4209 , MAC_ARG(psta->cmn.mac_addr), psta->cmn.mac_id);
4210 _exit_critical_bh(&macid_ctl->lock, &irqL);
4211 rtw_warn_on(1);
4212 goto exit;
4213 }
4214
4215 if (_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN)) {
4216 struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj);
4217 u8 id = rtw_iface_bcmc_id_get(padapter);
4218
4219 if ((id != INVALID_SEC_MAC_CAM_ID) && (id < cam_ctl->num)) {
4220 rtw_sec_cam_map_clr(&cam_ctl->used, id);
4221 if (_rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_EXTRA_SEC))
4222 rtw_sec_cam_map_clr(&cam_ctl->used, id + 1);
4223 }
4224
4225 rtw_iface_bcmc_id_set(padapter, INVALID_SEC_MAC_CAM_ID);
4226 }
4227
4228 rtw_macid_map_clr(&macid_ctl->if_g[padapter->iface_id], psta->cmn.mac_id);
4229
4230 ifbmp &= ~BIT(padapter->iface_id);
4231 if (!ifbmp) { /* only used by self */
4232 rtw_macid_map_clr(&macid_ctl->used, psta->cmn.mac_id);
4233 rtw_macid_map_clr(&macid_ctl->bmc, psta->cmn.mac_id);
4234 for (i = 0; i < 2; i++)
4235 rtw_macid_map_clr(&macid_ctl->ch_g[i], psta->cmn.mac_id);
4236 macid_ctl->sta[psta->cmn.mac_id] = NULL;
4237 }
4238
4239 _exit_critical_bh(&macid_ctl->lock, &irqL);
4240
4241 msg:
4242 RTW_INFO(FUNC_ADPT_FMT" if%u, mac_addr:"MAC_FMT" macid:%u\n"
4243 , FUNC_ADPT_ARG(padapter), padapter->iface_id + 1
4244 , MAC_ARG(psta->cmn.mac_addr), psta->cmn.mac_id
4245 );
4246
4247 exit:
4248 psta->cmn.mac_id = macid_ctl->num;
4249 }
4250
4251 /* For 8188E RA */
rtw_search_max_mac_id(_adapter * padapter)4252 u8 rtw_search_max_mac_id(_adapter *padapter)
4253 {
4254 u8 max_mac_id = 0;
4255 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
4256 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
4257 int i;
4258 _irqL irqL;
4259
4260 /* TODO: Only search for connected macid? */
4261
4262 _enter_critical_bh(&macid_ctl->lock, &irqL);
4263 for (i = (macid_ctl->num - 1); i > 0 ; i--) {
4264 if (rtw_macid_is_used(macid_ctl, i))
4265 break;
4266 }
4267 _exit_critical_bh(&macid_ctl->lock, &irqL);
4268 max_mac_id = i;
4269
4270 return max_mac_id;
4271 }
4272
rtw_macid_ctl_set_h2c_msr(struct macid_ctl_t * macid_ctl,u8 id,u8 h2c_msr)4273 inline u8 rtw_macid_ctl_set_h2c_msr(struct macid_ctl_t *macid_ctl, u8 id, u8 h2c_msr)
4274 {
4275 u8 op_num_change_bmp = 0;
4276
4277 if (id >= macid_ctl->num) {
4278 rtw_warn_on(1);
4279 goto exit;
4280 }
4281
4282 if (GET_H2CCMD_MSRRPT_PARM_OPMODE(&macid_ctl->h2c_msr[id])
4283 && !GET_H2CCMD_MSRRPT_PARM_OPMODE(&h2c_msr)
4284 ) {
4285 u8 role = GET_H2CCMD_MSRRPT_PARM_ROLE(&macid_ctl->h2c_msr[id]);
4286
4287 if (role < H2C_MSR_ROLE_MAX) {
4288 macid_ctl->op_num[role]--;
4289 op_num_change_bmp |= BIT(role);
4290 }
4291 } else if (!GET_H2CCMD_MSRRPT_PARM_OPMODE(&macid_ctl->h2c_msr[id])
4292 && GET_H2CCMD_MSRRPT_PARM_OPMODE(&h2c_msr)
4293 ) {
4294 u8 role = GET_H2CCMD_MSRRPT_PARM_ROLE(&h2c_msr);
4295
4296 if (role < H2C_MSR_ROLE_MAX) {
4297 macid_ctl->op_num[role]++;
4298 op_num_change_bmp |= BIT(role);
4299 }
4300 }
4301
4302 macid_ctl->h2c_msr[id] = h2c_msr;
4303 if (0)
4304 RTW_INFO("macid:%u, h2c_msr:"H2C_MSR_FMT"\n", id, H2C_MSR_ARG(&macid_ctl->h2c_msr[id]));
4305
4306 exit:
4307 return op_num_change_bmp;
4308 }
4309
rtw_macid_ctl_set_bw(struct macid_ctl_t * macid_ctl,u8 id,u8 bw)4310 inline void rtw_macid_ctl_set_bw(struct macid_ctl_t *macid_ctl, u8 id, u8 bw)
4311 {
4312 if (id >= macid_ctl->num) {
4313 rtw_warn_on(1);
4314 return;
4315 }
4316
4317 macid_ctl->bw[id] = bw;
4318 if (0)
4319 RTW_INFO("macid:%u, bw:%s\n", id, ch_width_str(macid_ctl->bw[id]));
4320 }
4321
rtw_macid_ctl_set_vht_en(struct macid_ctl_t * macid_ctl,u8 id,u8 en)4322 inline void rtw_macid_ctl_set_vht_en(struct macid_ctl_t *macid_ctl, u8 id, u8 en)
4323 {
4324 if (id >= macid_ctl->num) {
4325 rtw_warn_on(1);
4326 return;
4327 }
4328
4329 macid_ctl->vht_en[id] = en;
4330 if (0)
4331 RTW_INFO("macid:%u, vht_en:%u\n", id, macid_ctl->vht_en[id]);
4332 }
4333
rtw_macid_ctl_set_rate_bmp0(struct macid_ctl_t * macid_ctl,u8 id,u32 bmp)4334 inline void rtw_macid_ctl_set_rate_bmp0(struct macid_ctl_t *macid_ctl, u8 id, u32 bmp)
4335 {
4336 if (id >= macid_ctl->num) {
4337 rtw_warn_on(1);
4338 return;
4339 }
4340
4341 macid_ctl->rate_bmp0[id] = bmp;
4342 if (0)
4343 RTW_INFO("macid:%u, rate_bmp0:0x%08X\n", id, macid_ctl->rate_bmp0[id]);
4344 }
4345
rtw_macid_ctl_set_rate_bmp1(struct macid_ctl_t * macid_ctl,u8 id,u32 bmp)4346 inline void rtw_macid_ctl_set_rate_bmp1(struct macid_ctl_t *macid_ctl, u8 id, u32 bmp)
4347 {
4348 if (id >= macid_ctl->num) {
4349 rtw_warn_on(1);
4350 return;
4351 }
4352
4353 macid_ctl->rate_bmp1[id] = bmp;
4354 if (0)
4355 RTW_INFO("macid:%u, rate_bmp1:0x%08X\n", id, macid_ctl->rate_bmp1[id]);
4356 }
4357
4358 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_macid_ctl_init_sleep_reg(struct macid_ctl_t * macid_ctl,u16 reg_ctrl,u16 reg_info)4359 inline void rtw_macid_ctl_init_sleep_reg(struct macid_ctl_t *macid_ctl, u16 reg_ctrl, u16 reg_info)
4360 {
4361 macid_ctl->reg_sleep_ctrl = reg_ctrl;
4362 macid_ctl->reg_sleep_info = reg_info;
4363 }
rtw_macid_ctl_init_drop_reg(struct macid_ctl_t * macid_ctl,u16 reg_ctrl,u16 reg_info)4364 inline void rtw_macid_ctl_init_drop_reg(struct macid_ctl_t *macid_ctl, u16 reg_ctrl, u16 reg_info)
4365 {
4366 macid_ctl->reg_drop_ctrl = reg_ctrl;
4367 macid_ctl->reg_drop_info = reg_info;
4368 }
4369
4370 #else
rtw_macid_ctl_init_sleep_reg(struct macid_ctl_t * macid_ctl,u16 m0,u16 m1,u16 m2,u16 m3)4371 inline void rtw_macid_ctl_init_sleep_reg(struct macid_ctl_t *macid_ctl, u16 m0, u16 m1, u16 m2, u16 m3)
4372 {
4373 macid_ctl->reg_sleep_m0 = m0;
4374 #if (MACID_NUM_SW_LIMIT > 32)
4375 macid_ctl->reg_sleep_m1 = m1;
4376 #endif
4377 #if (MACID_NUM_SW_LIMIT > 64)
4378 macid_ctl->reg_sleep_m2 = m2;
4379 #endif
4380 #if (MACID_NUM_SW_LIMIT > 96)
4381 macid_ctl->reg_sleep_m3 = m3;
4382 #endif
4383 }
4384
rtw_macid_ctl_init_drop_reg(struct macid_ctl_t * macid_ctl,u16 m0,u16 m1,u16 m2,u16 m3)4385 inline void rtw_macid_ctl_init_drop_reg(struct macid_ctl_t *macid_ctl, u16 m0, u16 m1, u16 m2, u16 m3)
4386 {
4387 macid_ctl->reg_drop_m0 = m0;
4388 #if (MACID_NUM_SW_LIMIT > 32)
4389 macid_ctl->reg_drop_m1 = m1;
4390 #endif
4391 #if (MACID_NUM_SW_LIMIT > 64)
4392 macid_ctl->reg_drop_m2 = m2;
4393 #endif
4394 #if (MACID_NUM_SW_LIMIT > 96)
4395 macid_ctl->reg_drop_m3 = m3;
4396 #endif
4397 }
4398 #endif
4399
rtw_macid_ctl_init(struct macid_ctl_t * macid_ctl)4400 inline void rtw_macid_ctl_init(struct macid_ctl_t *macid_ctl)
4401 {
4402 int i;
4403 u8 id = RTW_DEFAULT_MGMT_MACID;
4404
4405 rtw_macid_map_set(&macid_ctl->used, id);
4406 rtw_macid_map_set(&macid_ctl->bmc, id);
4407 for (i = 0; i < CONFIG_IFACE_NUMBER; i++)
4408 rtw_macid_map_set(&macid_ctl->if_g[i], id);
4409 macid_ctl->sta[id] = NULL;
4410
4411 _rtw_spinlock_init(&macid_ctl->lock);
4412 }
4413
rtw_macid_ctl_deinit(struct macid_ctl_t * macid_ctl)4414 inline void rtw_macid_ctl_deinit(struct macid_ctl_t *macid_ctl)
4415 {
4416 _rtw_spinlock_free(&macid_ctl->lock);
4417 }
4418
rtw_bmp_is_set(const u8 * bmp,u8 bmp_len,u8 id)4419 inline bool rtw_bmp_is_set(const u8 *bmp, u8 bmp_len, u8 id)
4420 {
4421 if (id / 8 >= bmp_len)
4422 return 0;
4423
4424 return bmp[id / 8] & BIT(id % 8);
4425 }
4426
rtw_bmp_set(u8 * bmp,u8 bmp_len,u8 id)4427 inline void rtw_bmp_set(u8 *bmp, u8 bmp_len, u8 id)
4428 {
4429 if (id / 8 < bmp_len)
4430 bmp[id / 8] |= BIT(id % 8);
4431 }
4432
rtw_bmp_clear(u8 * bmp,u8 bmp_len,u8 id)4433 inline void rtw_bmp_clear(u8 *bmp, u8 bmp_len, u8 id)
4434 {
4435 if (id / 8 < bmp_len)
4436 bmp[id / 8] &= ~BIT(id % 8);
4437 }
4438
rtw_bmp_not_empty(const u8 * bmp,u8 bmp_len)4439 inline bool rtw_bmp_not_empty(const u8 *bmp, u8 bmp_len)
4440 {
4441 int i;
4442
4443 for (i = 0; i < bmp_len; i++) {
4444 if (bmp[i])
4445 return 1;
4446 }
4447
4448 return 0;
4449 }
4450
rtw_bmp_not_empty_exclude_bit0(const u8 * bmp,u8 bmp_len)4451 inline bool rtw_bmp_not_empty_exclude_bit0(const u8 *bmp, u8 bmp_len)
4452 {
4453 int i;
4454
4455 for (i = 0; i < bmp_len; i++) {
4456 if (i == 0) {
4457 if (bmp[i] & 0xFE)
4458 return 1;
4459 } else {
4460 if (bmp[i])
4461 return 1;
4462 }
4463 }
4464
4465 return 0;
4466 }
4467
4468 #ifdef CONFIG_AP_MODE
4469 /* Check the id be set or not in map , if yes , return a none zero value*/
rtw_tim_map_is_set(_adapter * padapter,const u8 * map,u8 id)4470 bool rtw_tim_map_is_set(_adapter *padapter, const u8 *map, u8 id)
4471 {
4472 return rtw_bmp_is_set(map, padapter->stapriv.aid_bmp_len, id);
4473 }
4474
4475 /* Set the id into map array*/
rtw_tim_map_set(_adapter * padapter,u8 * map,u8 id)4476 void rtw_tim_map_set(_adapter *padapter, u8 *map, u8 id)
4477 {
4478 rtw_bmp_set(map, padapter->stapriv.aid_bmp_len, id);
4479 }
4480
4481 /* Clear the id from map array*/
rtw_tim_map_clear(_adapter * padapter,u8 * map,u8 id)4482 void rtw_tim_map_clear(_adapter *padapter, u8 *map, u8 id)
4483 {
4484 rtw_bmp_clear(map, padapter->stapriv.aid_bmp_len, id);
4485 }
4486
4487 /* Check have anyone bit be set , if yes return true*/
rtw_tim_map_anyone_be_set(_adapter * padapter,const u8 * map)4488 bool rtw_tim_map_anyone_be_set(_adapter *padapter, const u8 *map)
4489 {
4490 return rtw_bmp_not_empty(map, padapter->stapriv.aid_bmp_len);
4491 }
4492
4493 /* Check have anyone bit be set exclude bit0 , if yes return true*/
rtw_tim_map_anyone_be_set_exclude_aid0(_adapter * padapter,const u8 * map)4494 bool rtw_tim_map_anyone_be_set_exclude_aid0(_adapter *padapter, const u8 *map)
4495 {
4496 return rtw_bmp_not_empty_exclude_bit0(map, padapter->stapriv.aid_bmp_len);
4497 }
4498 #endif /* CONFIG_AP_MODE */
4499
4500 #if 0
4501 unsigned int setup_beacon_frame(_adapter *padapter, unsigned char *beacon_frame)
4502 {
4503 unsigned short ATIMWindow;
4504 unsigned char *pframe;
4505 struct tx_desc *ptxdesc;
4506 struct rtw_ieee80211_hdr *pwlanhdr;
4507 unsigned short *fctrl;
4508 unsigned int rate_len, len = 0;
4509 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4510 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4511 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4512 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
4513 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4514
4515 _rtw_memset(beacon_frame, 0, 256);
4516
4517 pframe = beacon_frame + TXDESC_SIZE;
4518
4519 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4520
4521 fctrl = &(pwlanhdr->frame_ctl);
4522 *(fctrl) = 0;
4523
4524 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
4525 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4526 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
4527
4528 set_frame_sub_type(pframe, WIFI_BEACON);
4529
4530 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4531 len = sizeof(struct rtw_ieee80211_hdr_3addr);
4532
4533 /* timestamp will be inserted by hardware */
4534 pframe += 8;
4535 len += 8;
4536
4537 /* beacon interval: 2 bytes */
4538 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
4539
4540 pframe += 2;
4541 len += 2;
4542
4543 /* capability info: 2 bytes */
4544 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
4545
4546 pframe += 2;
4547 len += 2;
4548
4549 /* SSID */
4550 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &len);
4551
4552 /* supported rates... */
4553 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
4554 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &len);
4555
4556 /* DS parameter set */
4557 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &len);
4558
4559 /* IBSS Parameter Set... */
4560 /* ATIMWindow = cur->Configuration.ATIMWindow; */
4561 ATIMWindow = 0;
4562 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &len);
4563
4564 /* todo: ERP IE */
4565
4566 /* EXTERNDED SUPPORTED RATE */
4567 if (rate_len > 8)
4568 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &len);
4569
4570 if ((len + TXDESC_SIZE) > 256) {
4571 /* RTW_INFO("marc: beacon frame too large\n"); */
4572 return 0;
4573 }
4574
4575 /* fill the tx descriptor */
4576 ptxdesc = (struct tx_desc *)beacon_frame;
4577
4578 /* offset 0 */
4579 ptxdesc->txdw0 |= cpu_to_le32(len & 0x0000ffff);
4580 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); /* default = 32 bytes for TX Desc */
4581
4582 /* offset 4 */
4583 ptxdesc->txdw1 |= cpu_to_le32((0x10 << QSEL_SHT) & 0x00001f00);
4584
4585 /* offset 8 */
4586 ptxdesc->txdw2 |= cpu_to_le32(BMC);
4587 ptxdesc->txdw2 |= cpu_to_le32(BK);
4588
4589 /* offset 16 */
4590 ptxdesc->txdw4 = 0x80000000;
4591
4592 /* offset 20 */
4593 ptxdesc->txdw5 = 0x00000000; /* 1M */
4594
4595 return len + TXDESC_SIZE;
4596 }
4597 #endif
4598
dvobj_get_port0_adapter(struct dvobj_priv * dvobj)4599 _adapter *dvobj_get_port0_adapter(struct dvobj_priv *dvobj)
4600 {
4601 _adapter *port0_iface = NULL;
4602 int i;
4603 for (i = 0; i < dvobj->iface_nums; i++) {
4604 if (get_hw_port(dvobj->padapters[i]) == HW_PORT0)
4605 break;
4606 }
4607
4608 if (i < 0 || i >= dvobj->iface_nums)
4609 rtw_warn_on(1);
4610 else
4611 port0_iface = dvobj->padapters[i];
4612
4613 return port0_iface;
4614 }
4615
dvobj_get_unregisterd_adapter(struct dvobj_priv * dvobj)4616 _adapter *dvobj_get_unregisterd_adapter(struct dvobj_priv *dvobj)
4617 {
4618 _adapter *adapter = NULL;
4619 int i;
4620
4621 for (i = 0; i < dvobj->iface_nums; i++) {
4622 if (dvobj->padapters[i]->registered == 0)
4623 break;
4624 }
4625
4626 if (i < dvobj->iface_nums)
4627 adapter = dvobj->padapters[i];
4628
4629 return adapter;
4630 }
4631
dvobj_get_adapter_by_addr(struct dvobj_priv * dvobj,u8 * addr)4632 _adapter *dvobj_get_adapter_by_addr(struct dvobj_priv *dvobj, u8 *addr)
4633 {
4634 _adapter *adapter = NULL;
4635 int i;
4636
4637 for (i = 0; i < dvobj->iface_nums; i++) {
4638 if (_rtw_memcmp(dvobj->padapters[i]->mac_addr, addr, ETH_ALEN) == _TRUE)
4639 break;
4640 }
4641
4642 if (i < dvobj->iface_nums)
4643 adapter = dvobj->padapters[i];
4644
4645 return adapter;
4646 }
4647
4648 #ifdef CONFIG_WOWLAN
rtw_wowlan_parser_pattern_cmd(u8 * input,char * pattern,int * pattern_len,char * bit_mask)4649 bool rtw_wowlan_parser_pattern_cmd(u8 *input, char *pattern,
4650 int *pattern_len, char *bit_mask)
4651 {
4652 char *cp = NULL;
4653 size_t len = 0;
4654 int pos = 0, mask_pos = 0, res = 0;
4655
4656 /* To get the pattern string after "=", when we use :
4657 * iwpriv wlanX pattern=XX:XX:..:XX
4658 */
4659 cp = strchr(input, '=');
4660 if (cp) {
4661 *cp = 0;
4662 cp++;
4663 input = cp;
4664 }
4665
4666 /* To take off the newline character '\n'(0x0a) at the end of pattern string,
4667 * when we use echo xxxx > /proc/xxxx
4668 */
4669 cp = strchr(input, '\n');
4670 if (cp)
4671 *cp = 0;
4672
4673 while (input) {
4674 cp = strsep((char **)(&input), ":");
4675
4676 if (bit_mask && (strcmp(cp, "-") == 0 ||
4677 strcmp(cp, "xx") == 0 ||
4678 strcmp(cp, "--") == 0)) {
4679 /* skip this byte and leave mask bit unset */
4680 } else {
4681 u8 hex;
4682
4683 if (strlen(cp) != 2) {
4684 RTW_ERR("%s:[ERROR] hex len != 2, input=[%s]\n",
4685 __func__, cp);
4686 goto error;
4687 }
4688
4689 if (hexstr2bin(cp, &hex, 1) < 0) {
4690 RTW_ERR("%s:[ERROR] pattern is invalid, input=[%s]\n",
4691 __func__, cp);
4692 goto error;
4693 }
4694
4695 pattern[pos] = hex;
4696 mask_pos = pos / 8;
4697 if (bit_mask)
4698 bit_mask[mask_pos] |= 1 << (pos % 8);
4699 }
4700
4701 pos++;
4702 }
4703
4704 (*pattern_len) = pos;
4705
4706 return _TRUE;
4707 error:
4708 return _FALSE;
4709 }
4710
rtw_wow_pattern_sw_reset(_adapter * adapter)4711 void rtw_wow_pattern_sw_reset(_adapter *adapter)
4712 {
4713 int i;
4714 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(adapter);
4715
4716 if (pwrctrlpriv->default_patterns_en == _TRUE)
4717 pwrctrlpriv->wowlan_pattern_idx = DEFAULT_PATTERN_NUM;
4718 else
4719 pwrctrlpriv->wowlan_pattern_idx = 0;
4720
4721 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
4722 _rtw_memset(pwrctrlpriv->patterns[i].content, '\0', sizeof(pwrctrlpriv->patterns[i].content));
4723 _rtw_memset(pwrctrlpriv->patterns[i].mask, '\0', sizeof(pwrctrlpriv->patterns[i].mask));
4724 pwrctrlpriv->patterns[i].len = 0;
4725 }
4726 }
4727
rtw_set_default_pattern(_adapter * adapter)4728 u8 rtw_set_default_pattern(_adapter *adapter)
4729 {
4730 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
4731 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4732 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4733 u8 index = 0;
4734 u8 multicast_addr[3] = {0x01, 0x00, 0x5e};
4735 u8 multicast_ip[4] = {0xe0, 0x28, 0x28, 0x2a};
4736
4737 u8 unicast_mask[5] = {0x3f, 0x70, 0x80, 0xc0, 0x03};
4738 u8 icmpv6_mask[7] = {0x00, 0x70, 0x10, 0x00, 0xc0, 0xc0, 0x3f};
4739 u8 multicast_mask[5] = {0x07, 0x70, 0x80, 0xc0, 0x03};
4740
4741 u8 ip_protocol[3] = {0x08, 0x00, 0x45};
4742 u8 ipv6_protocol[3] = {0x86, 0xdd, 0x60};
4743
4744 u8 *target = NULL;
4745
4746 if (pwrpriv->default_patterns_en == _FALSE)
4747 return 0;
4748
4749 for (index = 0 ; index < DEFAULT_PATTERN_NUM ; index++) {
4750 _rtw_memset(pwrpriv->patterns[index].content, 0,
4751 sizeof(pwrpriv->patterns[index].content));
4752 _rtw_memset(pwrpriv->patterns[index].mask, 0,
4753 sizeof(pwrpriv->patterns[index].mask));
4754 pwrpriv->patterns[index].len = 0;
4755 }
4756
4757 /*TCP/ICMP unicast*/
4758 for (index = 0 ; index < DEFAULT_PATTERN_NUM ; index++) {
4759 switch (index) {
4760 case 0:
4761 target = pwrpriv->patterns[index].content;
4762 _rtw_memcpy(target, adapter_mac_addr(adapter),
4763 ETH_ALEN);
4764
4765 target += ETH_TYPE_OFFSET;
4766 _rtw_memcpy(target, &ip_protocol,
4767 sizeof(ip_protocol));
4768
4769 /* TCP */
4770 target += (PROTOCOL_OFFSET - ETH_TYPE_OFFSET);
4771 _rtw_memset(target, 0x06, 1);
4772
4773 target += (IP_OFFSET - PROTOCOL_OFFSET);
4774
4775 _rtw_memcpy(target, pmlmeinfo->ip_addr,
4776 RTW_IP_ADDR_LEN);
4777
4778 _rtw_memcpy(pwrpriv->patterns[index].mask,
4779 &unicast_mask, sizeof(unicast_mask));
4780
4781 pwrpriv->patterns[index].len =
4782 IP_OFFSET + RTW_IP_ADDR_LEN;
4783 break;
4784 case 1:
4785 target = pwrpriv->patterns[index].content;
4786 _rtw_memcpy(target, adapter_mac_addr(adapter),
4787 ETH_ALEN);
4788
4789 target += ETH_TYPE_OFFSET;
4790 _rtw_memcpy(target, &ip_protocol, sizeof(ip_protocol));
4791
4792 /* ICMP */
4793 target += (PROTOCOL_OFFSET - ETH_TYPE_OFFSET);
4794 _rtw_memset(target, 0x01, 1);
4795
4796 target += (IP_OFFSET - PROTOCOL_OFFSET);
4797 _rtw_memcpy(target, pmlmeinfo->ip_addr,
4798 RTW_IP_ADDR_LEN);
4799
4800 _rtw_memcpy(pwrpriv->patterns[index].mask,
4801 &unicast_mask, sizeof(unicast_mask));
4802 pwrpriv->patterns[index].len =
4803
4804 IP_OFFSET + RTW_IP_ADDR_LEN;
4805 break;
4806 #ifdef CONFIG_IPV6
4807 case 2:
4808 if (pwrpriv->wowlan_ns_offload_en == _TRUE) {
4809 target = pwrpriv->patterns[index].content;
4810 target += ETH_TYPE_OFFSET;
4811
4812 _rtw_memcpy(target, &ipv6_protocol,
4813 sizeof(ipv6_protocol));
4814
4815 /* ICMPv6 */
4816 target += (IPv6_PROTOCOL_OFFSET -
4817 ETH_TYPE_OFFSET);
4818 _rtw_memset(target, 0x3a, 1);
4819
4820 target += (IPv6_OFFSET - IPv6_PROTOCOL_OFFSET);
4821 _rtw_memcpy(target, pmlmeinfo->ip6_addr,
4822 RTW_IPv6_ADDR_LEN);
4823
4824 _rtw_memcpy(pwrpriv->patterns[index].mask,
4825 &icmpv6_mask, sizeof(icmpv6_mask));
4826 pwrpriv->patterns[index].len =
4827 IPv6_OFFSET + RTW_IPv6_ADDR_LEN;
4828 }
4829 break;
4830 #endif /*CONFIG_IPV6*/
4831 case 3:
4832 target = pwrpriv->patterns[index].content;
4833 _rtw_memcpy(target, &multicast_addr,
4834 sizeof(multicast_addr));
4835
4836 target += ETH_TYPE_OFFSET;
4837 _rtw_memcpy(target, &ip_protocol, sizeof(ip_protocol));
4838
4839 /* UDP */
4840 target += (PROTOCOL_OFFSET - ETH_TYPE_OFFSET);
4841 _rtw_memset(target, 0x11, 1);
4842
4843 target += (IP_OFFSET - PROTOCOL_OFFSET);
4844 _rtw_memcpy(target, &multicast_ip,
4845 sizeof(multicast_ip));
4846
4847 _rtw_memcpy(pwrpriv->patterns[index].mask,
4848 &multicast_mask, sizeof(multicast_mask));
4849
4850 pwrpriv->patterns[index].len =
4851 IP_OFFSET + sizeof(multicast_ip);
4852 break;
4853 default:
4854 break;
4855 }
4856 }
4857 return index;
4858 }
4859
rtw_dump_priv_pattern(_adapter * adapter,u8 idx)4860 void rtw_dump_priv_pattern(_adapter *adapter, u8 idx)
4861 {
4862 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4863 char str_1[128];
4864 char *p_str;
4865 u8 val8 = 0;
4866 int i = 0, j = 0, len = 0, max_len = 0;
4867
4868 RTW_INFO("=========[%d]========\n", idx);
4869
4870 RTW_INFO(">>>priv_pattern_content:\n");
4871 p_str = str_1;
4872 max_len = sizeof(str_1);
4873 for (i = 0 ; i < MAX_WKFM_PATTERN_SIZE / 8 ; i++) {
4874 _rtw_memset(p_str, 0, max_len);
4875 len = 0;
4876 for (j = 0 ; j < 8 ; j++) {
4877 val8 = pwrctl->patterns[idx].content[i * 8 + j];
4878 len += snprintf(p_str + len, max_len - len,
4879 "%02x ", val8);
4880 }
4881 RTW_INFO("%s\n", p_str);
4882 }
4883
4884 RTW_INFO(">>>priv_pattern_mask:\n");
4885 for (i = 0 ; i < MAX_WKFM_SIZE / 8 ; i++) {
4886 _rtw_memset(p_str, 0, max_len);
4887 len = 0;
4888 for (j = 0 ; j < 8 ; j++) {
4889 val8 = pwrctl->patterns[idx].mask[i * 8 + j];
4890 len += snprintf(p_str + len, max_len - len,
4891 "%02x ", val8);
4892 }
4893 RTW_INFO("%s\n", p_str);
4894 }
4895
4896 RTW_INFO(">>>priv_pattern_len:\n");
4897 RTW_INFO("%s: len: %d\n", __func__, pwrctl->patterns[idx].len);
4898 }
4899
rtw_wow_pattern_sw_dump(_adapter * adapter)4900 void rtw_wow_pattern_sw_dump(_adapter *adapter)
4901 {
4902 int i = 0, total = 0;
4903 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
4904 total = pwrpriv->wowlan_pattern_idx;
4905
4906 RTW_INFO("********[RTK priv-patterns]*********\n");
4907 for (i = 0 ; i < total; i++)
4908 rtw_dump_priv_pattern(adapter, i);
4909 }
4910
rtw_get_sec_iv(PADAPTER padapter,u8 * pcur_dot11txpn,u8 * StaAddr)4911 void rtw_get_sec_iv(PADAPTER padapter, u8 *pcur_dot11txpn, u8 *StaAddr)
4912 {
4913 struct sta_info *psta;
4914 struct security_priv *psecpriv = &padapter->securitypriv;
4915
4916 _rtw_memset(pcur_dot11txpn, 0, 8);
4917 if (NULL == StaAddr)
4918 return;
4919 psta = rtw_get_stainfo(&padapter->stapriv, StaAddr);
4920 RTW_INFO("%s(): StaAddr: %02x %02x %02x %02x %02x %02x\n",
4921 __func__, StaAddr[0], StaAddr[1], StaAddr[2],
4922 StaAddr[3], StaAddr[4], StaAddr[5]);
4923
4924 if (psta) {
4925 if ((psecpriv->dot11PrivacyAlgrthm == _AES_) ||
4926 (psecpriv->dot11PrivacyAlgrthm == _CCMP_256_))
4927 AES_IV(pcur_dot11txpn, psta->dot11txpn, 0);
4928 else if (psecpriv->dot11PrivacyAlgrthm == _TKIP_)
4929 TKIP_IV(pcur_dot11txpn, psta->dot11txpn, 0);
4930 else if ((psecpriv->dot11PrivacyAlgrthm == _GCMP_) ||
4931 (psecpriv->dot11PrivacyAlgrthm == _GCMP_256_))
4932 GCMP_IV(pcur_dot11txpn, psta->dot11txpn, 0);
4933
4934 RTW_INFO("%s(): CurrentIV: %02x %02x %02x %02x %02x %02x %02x %02x\n"
4935 , __func__, pcur_dot11txpn[0], pcur_dot11txpn[1],
4936 pcur_dot11txpn[2], pcur_dot11txpn[3], pcur_dot11txpn[4],
4937 pcur_dot11txpn[5], pcur_dot11txpn[6], pcur_dot11txpn[7]);
4938 }
4939 }
4940
4941 #ifdef CONFIG_WAR_OFFLOAD
4942 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
rtw_wow_war_mdns_dump_buf(struct seq_file * m,u8 * title,u8 * buf,u32 len)4943 void rtw_wow_war_mdns_dump_buf(struct seq_file *m, u8 *title, u8 *buf, u32 len)
4944 {
4945 u32 i;
4946
4947 RTW_PRINT_SEL(m, "\t%s (%d)\n\t\t", title, len);
4948 for (i = 1; i <= len; i++)
4949 {
4950 RTW_PRINT_SEL(m, "%2.2x-", *(buf + i - 1));
4951 if( (i%16 == 0) && (len != i) ) RTW_PRINT_SEL(m, "\n\t\t");
4952 }
4953 RTW_PRINT_SEL(m, "\n\n");
4954 }
4955
rtw_wow_war_mdns_dump_txt(struct seq_file * m,u8 * title,u8 * buf,u32 len)4956 void rtw_wow_war_mdns_dump_txt(struct seq_file *m, u8 *title, u8 *buf, u32 len)
4957 {
4958 u16 idx=1, offset=0; /* offset = the location of L in the Length.Value */
4959
4960 RTW_PRINT_SEL(m, "\t%s (%d)\n\t", title, len);
4961 for (; offset < len; idx++)
4962 {
4963 int item_len = buf[offset];
4964 u8 item_buf[256]={0};
4965
4966 _rtw_memcpy(item_buf, (buf + offset + 1), item_len);
4967 RTW_PRINT_SEL(m, "\t[%d] => %s (%d)\n\t", idx, item_buf, item_len);
4968 _rtw_memset(item_buf, 0, sizeof(item_buf));
4969 offset += (1+item_len);
4970 }
4971 RTW_PRINT_SEL(m, "\n\n");
4972 }
4973
rtw_wow_war_mdns_parser_pattern(u8 * input,char * target,u32 * target_len,u32 type)4974 bool rtw_wow_war_mdns_parser_pattern(u8 *input, char *target,
4975 u32 *target_len, u32 type)
4976 {
4977 char *cp = NULL, *end = NULL;
4978 size_t len = 0;
4979 int pos = 0, mask_pos = 0, res = 0;
4980 u8 member[2] = {0};
4981
4982 /* reset */
4983 _rtw_memset(target, '\0', type);
4984 (*target_len) = 0;
4985
4986 cp = strchr(input, '=');
4987 if (cp) {
4988 *cp = 0;
4989 cp++;
4990 input = cp;
4991 }
4992
4993 while (1) {
4994 cp = strchr(input, ':');
4995
4996 if (cp) {
4997 len = strlen(input) - strlen(cp);
4998 *cp = 0;
4999 cp++;
5000 } else
5001 len = 2;
5002
5003 {
5004 u8 hex,idx=0, pos_in_unit_as_4bit = 0;
5005
5006 strncpy(member, input, len);
5007 res = sscanf(member, "%02hhx", &hex);
5008
5009 target[pos] = hex;
5010
5011 /* RTW_INFO("==> in; input-member = %s, hex = %x, target[%d] = %x\n", member, hex, target[pos], pos); */
5012
5013 for(idx = 0; idx<2;idx++)
5014 {
5015 pos_in_unit_as_4bit = pos*2 + (1-idx);
5016 mask_pos = (pos_in_unit_as_4bit /8);
5017
5018 if(!IsHexDigit(member[idx]))
5019 {
5020 RTW_ERR("%s:[ERROR] pattern is invalid!!(%c)\n",__func__, member[idx]);
5021 goto error;
5022 }
5023
5024 /* RTW_INFO("==> in; pos = %d, pos_in_unit_as_4bit = %d, mask-pos = %d \n", pos, pos_in_unit_as_4bit, mask_pos);
5025 RTW_INFO("==> in; hex(0x%02x), member(%c%c) \n", pattern[pos], member[1], member[0]); */
5026 }
5027 /* RTW_INFO_DUMP("Pattern Mask: ",bit_mask, 6); */
5028 }
5029
5030 pos++;
5031 if (!cp)
5032 break;
5033 input = cp;
5034 }
5035
5036 (*target_len) = pos;
5037
5038 return _TRUE;
5039 error:
5040 return _FALSE;
5041
5042 }
5043
5044 static struct war_mdns_service_info default_sinfo[] = {
5045 /* example of default setting */
5046 RTW_MDNS_SRV_INFO("_ipp", 4, "_tcp", 4, "local", 5, 0x02, 0x77, 7200, "KM1", 3, 0),
5047 RTW_MDNS_SRV_INFO("_ipps", 5, "_tcp", 4, "local", 5, 0x02, 0x77, 7200, "KM2", 3, 0),
5048 RTW_MDNS_SRV_INFO("_http", 5, "_tcp", 4, "local", 5, 0x00, 0x50, 7200, "KM3", 3, 2),
5049 RTW_MDNS_SRV_INFO("_privet", 7, "_tcp", 4, "local", 5, 0x00, 0x50, 7200, "KM4", 3, 3),
5050 RTW_MDNS_SRV_INFO("_https", 6, "_tcp", 4, "local", 5, 0x01, 0xbb, 7200, "KM5", 3, 2),
5051 RTW_MDNS_SRV_INFO("_uscan", 6, "_tcp", 4, "local", 5, 0x1f, 0x91, 7200, "KM6", 3, 4),
5052 RTW_MDNS_SRV_INFO("_printer", 8, "_tcp", 4, "local", 5, 0x23, 0x8c, 7200, "KM7", 3, 1),
5053 RTW_MDNS_SRV_INFO("_pdl-datastream", 15, "_tcp", 4, "local", 5, 0x23, 0x8c, 7200, "KM8", 3, 1)
5054
5055 };
5056
rtw_wow_war_mdns_parms_reset(_adapter * adapter,u8 is_set_default)5057 void rtw_wow_war_mdns_parms_reset(_adapter *adapter, u8 is_set_default)
5058 {
5059 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
5060 u8 i =0;
5061 u16 offset=0;
5062 u8 default_domain_name[] = "Generic";
5063 //u8 default_machine_name[] = { 0x0a, 0x5f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x04, 0x5f, 0x73, 0x75, 0x62 };
5064 //u8 default_machine_name_len = 16;
5065 u8 default_machine_name[] = { 0x0a, 0x5f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c}; /* length : 10 name : _universal */
5066 u8 default_machine_name_len = 11;
5067
5068 /* set default txt value*/
5069 char *default_txt_rsp_0_for_serive[2] = { "_ipp", "_ipps" };
5070 char *default_txt_rsp_0[25] = {
5071 "txtvers=1", "qtotal=1", "usb_MFG=KONICA MINOLTA", "usb_MDL=C754Series",
5072 "rp=ipp/print","priority=54","tr=Generic 35c-4", "product=DriverName",
5073 "pdl=application/postscript,image/urf,application/octet-stream,image/jpeg",
5074 "adminurl=http://KM00D91C.local./wcd/a_network.xml",
5075 "note=Copy Room", "Transparent=T", "Binary=T", "TBCP=T",
5076 "URF=V1,4,w8,SRGB24,ADOBERGB24-48,DEVW8,DEVRGB24,DEVCMYK32,RS150000000,IS19-20-21,MT1-3,OB1,PQ4,DM1,FN3-14,CP255",
5077 "rfo=ipp/faxout", "Fax=T", "Scan=T", "Duplex=T", "Color=T", "air=none",
5078 "Kind=document,envelope,photo",
5079 "PaperMax=tabloid-A3", "UUID=6c183832-69ba-541b-baf6-6d947c144325", "TLS=1.2"
5080 };
5081
5082 char *default_txt_rsp_1_for_serive[2] = { "_printer", "_pdl-datastream" };
5083 char *default_txt_rsp_1[13] = {
5084 "txtvers=1", "qtotal=1", "usb_MFG=KONICA MINOLTA", "usb_MDL=C754Series",
5085 "rp=print","priority=51","tr=Generic 35c-4", "product=DriverName",
5086 "pdl=application/postscript", "note=Copy Room", "Transparent=T", "Binary=T", "TBCP=F"
5087 };
5088
5089 char *default_txt_rsp_2_for_serive[2] = { "_http", "_https" };
5090 char *default_txt_rsp_2[1] = {
5091 "Path=/"
5092 };
5093
5094 char *default_txt_rsp_3_for_serive[1] = { "_privet" };
5095 char *default_txt_rsp_3[5] = {
5096 "txtvers=1", "url=https://www.google.com/cloudprint",
5097 "type=printer", "cs=not-configured","note=Copy Room"
5098 };
5099
5100 char *default_txt_rsp_4_for_serive[1] = { "_uscan" };
5101 char *default_txt_rsp_4[11] = {
5102 "txtvers=1", "vers=2.5", "adminurl=http://KM00D91C.local./wsd/a_network_airprint.xml",
5103 "representation=http://KM00D91C.local./wcd/DeviceIcon_1283png",
5104 "rs=eSCL", "ty=KONICA MINOLTA bishub C287", "note=japan",
5105 "pdl=image/jpeg,image/tiff,application/pdf",
5106 "UUID=dd5454cc-e196-5711-aa1f-35be49a6ca9f",
5107 "cs=color,grayscale,binary", "is=platen,adf,duplex=T"
5108 };
5109
5110
5111 /* reset ===> */
5112
5113 _rtw_memset(pwrpriv->wowlan_war_offload_mdns_domain_name, 0, MAX_MDNS_DOMAIN_NAME_LEN);
5114 _rtw_memset(pwrpriv->wowlan_war_offload_mdns_mnane, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_mnane));
5115 _rtw_memset(pwrpriv->wowlan_war_offload_mdns_service, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_service));
5116 _rtw_memset(pwrpriv->wowlan_war_offload_mdns_txt_rsp, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_txt_rsp));
5117
5118 pwrpriv->wowlan_war_offload_mdns_domain_name_len = 0;
5119 pwrpriv->wowlan_war_offload_mdns_mnane_num = 0;
5120 pwrpriv->wowlan_war_offload_mdns_service_info_num = 0;
5121 pwrpriv->wowlan_war_offload_mdns_txt_rsp_num = 0;
5122 pwrpriv->wowlan_war_offload_mdns_para_cur_size = 0;
5123 pwrpriv->wowlan_war_offload_mdns_rsp_cur_size = 0;
5124
5125 /* init ===> */
5126
5127 if(is_set_default)
5128 {
5129 // domain_name
5130 pwrpriv->wowlan_war_offload_mdns_domain_name_len = strlen(default_domain_name);
5131 _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_domain_name, default_domain_name, sizeof(default_domain_name));
5132
5133 // machine name
5134 pwrpriv->wowlan_war_offload_mdns_mnane_num = 1;
5135 pwrpriv->wowlan_war_offload_mdns_mnane[0].name_len = default_machine_name_len;
5136 _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_mnane[0].name, default_machine_name, default_machine_name_len);
5137
5138 // service info
5139 pwrpriv->wowlan_war_offload_mdns_service_info_num = 8;
5140 _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_service, default_sinfo, sizeof(default_sinfo));
5141
5142 // type txt rsp 0~5
5143 // 0
5144 for(offset=0, i=0; i<25; i++)
5145 {
5146 pwrpriv->wowlan_war_offload_mdns_txt_rsp[0].txt[offset++] = strlen(default_txt_rsp_0[i]);
5147 _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[0].txt + offset, default_txt_rsp_0[i], strlen(default_txt_rsp_0[i]));
5148 offset += strlen(default_txt_rsp_0[i]);
5149 RTW_INFO("==> default_txt_rsp_0[%d]: [%s](%zu), offset(%d)\n", i, default_txt_rsp_0[i], strlen(default_txt_rsp_0[i]), offset);
5150 }
5151 pwrpriv->wowlan_war_offload_mdns_txt_rsp[0].txt_len = offset;
5152 // RTW_INFO("==> offset = %d\n\n", offset);
5153
5154
5155 // 1
5156 for(offset=0, i=0; i<13; i++)
5157 {
5158 pwrpriv->wowlan_war_offload_mdns_txt_rsp[1].txt[offset++] = strlen(default_txt_rsp_1[i]);
5159 _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[1].txt + offset, default_txt_rsp_1[i], strlen(default_txt_rsp_1[i]));
5160 offset += strlen(default_txt_rsp_1[i]);
5161 }
5162 pwrpriv->wowlan_war_offload_mdns_txt_rsp[1].txt_len = offset;
5163 // RTW_INFO("==> offset = %d\n\n", offset);
5164
5165 // 2
5166 for(offset=0, i=0; i<1; i++)
5167 {
5168 pwrpriv->wowlan_war_offload_mdns_txt_rsp[2].txt[offset++] = strlen(default_txt_rsp_2[i]);
5169 _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[2].txt + offset, default_txt_rsp_2[i], strlen(default_txt_rsp_2[i]));
5170 offset += strlen(default_txt_rsp_2[i]);
5171 }
5172 pwrpriv->wowlan_war_offload_mdns_txt_rsp[2].txt_len = offset;
5173 // RTW_INFO("==> offset = %d\n\n", offset);
5174
5175 // 3
5176 for(offset=0, i=0; i<5; i++)
5177 {
5178 pwrpriv->wowlan_war_offload_mdns_txt_rsp[3].txt[offset++] = strlen(default_txt_rsp_3[i]);
5179 _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[3].txt + offset, default_txt_rsp_3[i], strlen(default_txt_rsp_3[i]));
5180 offset += strlen(default_txt_rsp_3[i]);
5181 }
5182 pwrpriv->wowlan_war_offload_mdns_txt_rsp[3].txt_len = offset;
5183 // RTW_INFO("==> offset = %d\n\n", offset);
5184
5185 // 4
5186 for(offset=0, i=0; i<11; i++)
5187 {
5188 pwrpriv->wowlan_war_offload_mdns_txt_rsp[4].txt[offset++] = strlen(default_txt_rsp_4[i]);
5189 _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[4].txt + offset, default_txt_rsp_4[i], strlen(default_txt_rsp_4[i]));
5190 offset += strlen(default_txt_rsp_4[i]);
5191 }
5192 pwrpriv->wowlan_war_offload_mdns_txt_rsp[4].txt_len = offset;
5193 // RTW_INFO("==> offset = %d\n\n", offset);
5194
5195 /* txt_rsp_num is always as MAX_MDNS_TXT_NUM because the input mechanism(new/append) makes the entities are not in order */
5196 pwrpriv->wowlan_war_offload_mdns_txt_rsp_num = MAX_MDNS_TXT_NUM;
5197 }
5198 }
5199
5200
5201 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
5202 #endif /* CONFIG_WAR_OFFLOAD */
5203 #endif /* CONFIG_WOWLAN */
5204
_rtw_wow_chk_cap(_adapter * adapter,u8 cap)5205 inline bool _rtw_wow_chk_cap(_adapter *adapter, u8 cap)
5206 {
5207 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5208 struct wow_ctl_t *wow_ctl = &dvobj->wow_ctl;
5209
5210 if (wow_ctl->wow_cap & cap)
5211 return _TRUE;
5212 return _FALSE;
5213 }
5214
5215 #ifdef CONFIG_PNO_SUPPORT
5216 #define CSCAN_TLV_TYPE_SSID_IE 'S'
5217 #define CIPHER_IE "key_mgmt="
5218 #define CIPHER_NONE "NONE"
5219 #define CIPHER_WPA_PSK "WPA-PSK"
5220 #define CIPHER_WPA_EAP "WPA-EAP IEEE8021X"
5221 /*
5222 * SSIDs list parsing from cscan tlv list
5223 */
rtw_parse_ssid_list_tlv(char ** list_str,pno_ssid_t * ssid,int max,int * bytes_left)5224 int rtw_parse_ssid_list_tlv(char **list_str, pno_ssid_t *ssid,
5225 int max, int *bytes_left)
5226 {
5227 char *str;
5228
5229 int idx = 0;
5230
5231 if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) {
5232 RTW_INFO("%s error paramters\n", __func__);
5233 return -1;
5234 }
5235
5236 str = *list_str;
5237 while (*bytes_left > 0) {
5238
5239 if (str[0] != CSCAN_TLV_TYPE_SSID_IE) {
5240 *list_str = str;
5241 RTW_INFO("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0]);
5242 return idx;
5243 }
5244
5245 /* Get proper CSCAN_TLV_TYPE_SSID_IE */
5246 *bytes_left -= 1;
5247 str += 1;
5248
5249 if (str[0] == 0) {
5250 /* Broadcast SSID */
5251 ssid[idx].SSID_len = 0;
5252 memset((char *)ssid[idx].SSID, 0x0, WLAN_SSID_MAXLEN);
5253 *bytes_left -= 1;
5254 str += 1;
5255
5256 RTW_INFO("BROADCAST SCAN left=%d\n", *bytes_left);
5257 } else if (str[0] <= WLAN_SSID_MAXLEN) {
5258 /* Get proper SSID size */
5259 ssid[idx].SSID_len = str[0];
5260 *bytes_left -= 1;
5261 str += 1;
5262
5263 /* Get SSID */
5264 if (ssid[idx].SSID_len > *bytes_left) {
5265 RTW_INFO("%s out of memory range len=%d but left=%d\n",
5266 __func__, ssid[idx].SSID_len, *bytes_left);
5267 return -1;
5268 }
5269
5270 memcpy((char *)ssid[idx].SSID, str, ssid[idx].SSID_len);
5271
5272 *bytes_left -= ssid[idx].SSID_len;
5273 str += ssid[idx].SSID_len;
5274
5275 RTW_INFO("%s :size=%d left=%d\n",
5276 (char *)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left);
5277 } else {
5278 RTW_INFO("### SSID size more that %d\n", str[0]);
5279 return -1;
5280 }
5281
5282 if (idx++ > max) {
5283 RTW_INFO("%s number of SSIDs more that %d\n", __func__, idx);
5284 return -1;
5285 }
5286 }
5287
5288 *list_str = str;
5289 return idx;
5290 }
5291
rtw_parse_cipher_list(struct pno_nlo_info * nlo_info,char * list_str)5292 int rtw_parse_cipher_list(struct pno_nlo_info *nlo_info, char *list_str)
5293 {
5294
5295 char *pch, *pnext, *pend;
5296 u8 key_len = 0, index = 0;
5297
5298 pch = list_str;
5299
5300 if (nlo_info == NULL || list_str == NULL) {
5301 RTW_INFO("%s error paramters\n", __func__);
5302 return -1;
5303 }
5304
5305 while (strlen(pch) != 0) {
5306 pnext = strstr(pch, "key_mgmt=");
5307 if (pnext != NULL) {
5308 pch = pnext + strlen(CIPHER_IE);
5309 pend = strstr(pch, "}");
5310 if (strncmp(pch, CIPHER_NONE,
5311 strlen(CIPHER_NONE)) == 0)
5312 nlo_info->ssid_cipher_info[index] = 0x00;
5313 else if (strncmp(pch, CIPHER_WPA_PSK,
5314 strlen(CIPHER_WPA_PSK)) == 0)
5315 nlo_info->ssid_cipher_info[index] = 0x66;
5316 else if (strncmp(pch, CIPHER_WPA_EAP,
5317 strlen(CIPHER_WPA_EAP)) == 0)
5318 nlo_info->ssid_cipher_info[index] = 0x01;
5319 index++;
5320 pch = pend + 1;
5321 } else
5322 break;
5323 }
5324 return 0;
5325 }
5326
rtw_dev_nlo_info_set(struct pno_nlo_info * nlo_info,pno_ssid_t * ssid,int num,int pno_time,int pno_repeat,int pno_freq_expo_max)5327 int rtw_dev_nlo_info_set(struct pno_nlo_info *nlo_info, pno_ssid_t *ssid,
5328 int num, int pno_time, int pno_repeat, int pno_freq_expo_max)
5329 {
5330
5331 int i = 0;
5332 struct file *fp;
5333 mm_segment_t fs;
5334 loff_t pos = 0;
5335 u8 *source = NULL;
5336 long len = 0;
5337
5338 RTW_INFO("+%s+\n", __func__);
5339
5340 nlo_info->fast_scan_period = pno_time;
5341 nlo_info->ssid_num = num & BIT_LEN_MASK_32(8);
5342 nlo_info->hidden_ssid_num = num & BIT_LEN_MASK_32(8);
5343 nlo_info->slow_scan_period = (pno_time * 2);
5344 nlo_info->fast_scan_iterations = 5;
5345
5346 if (nlo_info->hidden_ssid_num > 8)
5347 nlo_info->hidden_ssid_num = 8;
5348
5349 /* TODO: channel list and probe index is all empty. */
5350 for (i = 0 ; i < num ; i++) {
5351 nlo_info->ssid_length[i]
5352 = ssid[i].SSID_len;
5353 }
5354
5355 /* cipher array */
5356 fp = filp_open("/data/misc/wifi/wpa_supplicant.conf", O_RDONLY, 0644);
5357 if (IS_ERR(fp)) {
5358 RTW_INFO("Error, wpa_supplicant.conf doesn't exist.\n");
5359 RTW_INFO("Error, cipher array using default value.\n");
5360 return 0;
5361 } else {
5362 RTW_INFO("Open wpa_supplicant.conf successfully.\n");
5363 }
5364
5365 len = i_size_read(fp->f_path.dentry->d_inode);
5366 if (len < 0 || len > 2048) {
5367 RTW_INFO("Error, file size is bigger than 2048.\n");
5368 RTW_INFO("Error, cipher array using default value.\n");
5369 return 0;
5370 }
5371
5372 fs = get_fs();
5373 set_fs(KERNEL_DS);
5374
5375 source = rtw_zmalloc(2048);
5376
5377 if (source != NULL) {
5378 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
5379 len = kernel_read(fp, source, len, &pos);
5380 #else
5381 len = vfs_read(fp, source, len, &pos);
5382 #endif
5383 rtw_parse_cipher_list(nlo_info, source);
5384 rtw_mfree(source, 2048);
5385 }
5386
5387 set_fs(fs);
5388 filp_close(fp, NULL);
5389
5390 RTW_INFO("-%s-\n", __func__);
5391 return 0;
5392 }
5393
rtw_dev_ssid_list_set(struct pno_ssid_list * pno_ssid_list,pno_ssid_t * ssid,u8 num)5394 int rtw_dev_ssid_list_set(struct pno_ssid_list *pno_ssid_list,
5395 pno_ssid_t *ssid, u8 num)
5396 {
5397
5398 int i = 0;
5399 if (num > MAX_PNO_LIST_COUNT)
5400 num = MAX_PNO_LIST_COUNT;
5401
5402 for (i = 0 ; i < num ; i++) {
5403 _rtw_memcpy(&pno_ssid_list->node[i].SSID,
5404 ssid[i].SSID, ssid[i].SSID_len);
5405 pno_ssid_list->node[i].SSID_len = ssid[i].SSID_len;
5406 }
5407 return 0;
5408 }
5409
5410 #ifndef RTW_HALMAC
rtw_dev_scan_info_set(_adapter * padapter,pno_ssid_t * ssid,unsigned char ch,unsigned char ch_offset,unsigned short bw_mode)5411 int rtw_dev_scan_info_set(_adapter *padapter, pno_ssid_t *ssid,
5412 unsigned char ch, unsigned char ch_offset, unsigned short bw_mode)
5413 {
5414
5415 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
5416 struct pno_scan_info *scan_info = pwrctl->pscan_info;
5417 u8 band = ch <= 14 ? BAND_ON_2_4G : BAND_ON_5G;
5418 int i;
5419
5420 scan_info->channel_num = MAX_SCAN_LIST_COUNT;
5421 scan_info->orig_ch = ch;
5422 scan_info->orig_bw = bw_mode;
5423 scan_info->orig_40_offset = ch_offset;
5424
5425 for (i = 0 ; i < scan_info->channel_num ; i++) {
5426 if (i < 11)
5427 scan_info->ssid_channel_info[i].active = 1;
5428 else
5429 scan_info->ssid_channel_info[i].active = 0;
5430
5431 scan_info->ssid_channel_info[i].timeout = 100;
5432
5433 scan_info->ssid_channel_info[i].tx_power =
5434 phy_get_tx_power_index_ex(padapter, 0, CCK, MGN_1M, bw_mode, band, i + 1, i + 1);
5435
5436 scan_info->ssid_channel_info[i].channel = i + 1;
5437 }
5438
5439 RTW_INFO("%s, channel_num: %d, orig_ch: %d, orig_bw: %d orig_40_offset: %d\n",
5440 __func__, scan_info->channel_num, scan_info->orig_ch,
5441 scan_info->orig_bw, scan_info->orig_40_offset);
5442 return 0;
5443 }
5444 #endif
5445
rtw_dev_pno_set(struct net_device * net,pno_ssid_t * ssid,int num,int pno_time,int pno_repeat,int pno_freq_expo_max)5446 int rtw_dev_pno_set(struct net_device *net, pno_ssid_t *ssid, int num,
5447 int pno_time, int pno_repeat, int pno_freq_expo_max)
5448 {
5449
5450 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
5451 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
5452 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5453
5454 int ret = -1;
5455
5456 if (num == 0) {
5457 RTW_INFO("%s, nssid is zero, no need to setup pno ssid list\n", __func__);
5458 return 0;
5459 }
5460
5461 if (pwrctl == NULL) {
5462 RTW_INFO("%s, ERROR: pwrctl is NULL\n", __func__);
5463 return -1;
5464 } else {
5465 pwrctl->pnlo_info =
5466 (pno_nlo_info_t *)rtw_zmalloc(sizeof(pno_nlo_info_t));
5467 pwrctl->pno_ssid_list =
5468 (pno_ssid_list_t *)rtw_zmalloc(sizeof(pno_ssid_list_t));
5469 #ifndef RTW_HALMAC
5470 pwrctl->pscan_info =
5471 (pno_scan_info_t *)rtw_zmalloc(sizeof(pno_scan_info_t));
5472 #endif
5473 }
5474
5475 if (pwrctl->pnlo_info == NULL ||
5476 #ifndef RTW_HALMAC
5477 pwrctl->pscan_info == NULL ||
5478 #endif
5479 pwrctl->pno_ssid_list == NULL) {
5480 RTW_INFO("%s, ERROR: alloc memory fail\n", __func__);
5481 goto failing;
5482 }
5483
5484 pwrctl->wowlan_in_resume = _FALSE;
5485
5486 pwrctl->pno_inited = _TRUE;
5487 /* NLO Info */
5488 ret = rtw_dev_nlo_info_set(pwrctl->pnlo_info, ssid, num,
5489 pno_time, pno_repeat, pno_freq_expo_max);
5490
5491 /* SSID Info */
5492 ret = rtw_dev_ssid_list_set(pwrctl->pno_ssid_list, ssid, num);
5493
5494 #ifndef RTW_HALMAC
5495 /* SCAN Info */
5496 ret = rtw_dev_scan_info_set(padapter, ssid, pmlmeext->cur_channel,
5497 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5498 #endif
5499
5500 RTW_INFO("+%s num: %d, pno_time: %d, pno_repeat:%d, pno_freq_expo_max:%d+\n",
5501 __func__, num, pno_time, pno_repeat, pno_freq_expo_max);
5502
5503 return 0;
5504
5505 failing:
5506 if (pwrctl->pnlo_info) {
5507 rtw_mfree((u8 *)pwrctl->pnlo_info, sizeof(pno_nlo_info_t));
5508 pwrctl->pnlo_info = NULL;
5509 }
5510 if (pwrctl->pno_ssid_list) {
5511 rtw_mfree((u8 *)pwrctl->pno_ssid_list, sizeof(pno_ssid_list_t));
5512 pwrctl->pno_ssid_list = NULL;
5513 }
5514 #ifndef RTW_HALMAC
5515 if (pwrctl->pscan_info) {
5516 rtw_mfree((u8 *)pwrctl->pscan_info, sizeof(pno_scan_info_t));
5517 pwrctl->pscan_info = NULL;
5518 }
5519 #endif
5520
5521 return -1;
5522 }
5523
5524 #ifdef CONFIG_PNO_SET_DEBUG
rtw_dev_pno_debug(struct net_device * net)5525 void rtw_dev_pno_debug(struct net_device *net)
5526 {
5527 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
5528 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
5529 int i = 0, j = 0;
5530
5531 RTW_INFO("*******NLO_INFO********\n");
5532 RTW_INFO("ssid_num: %d\n", pwrctl->pnlo_info->ssid_num);
5533 RTW_INFO("fast_scan_iterations: %d\n",
5534 pwrctl->pnlo_info->fast_scan_iterations);
5535 RTW_INFO("fast_scan_period: %d\n", pwrctl->pnlo_info->fast_scan_period);
5536 RTW_INFO("slow_scan_period: %d\n", pwrctl->pnlo_info->slow_scan_period);
5537
5538
5539
5540 for (i = 0 ; i < MAX_PNO_LIST_COUNT ; i++) {
5541 RTW_INFO("%d SSID (%s) length (%d) cipher(%x) channel(%d)\n",
5542 i, pwrctl->pno_ssid_list->node[i].SSID, pwrctl->pnlo_info->ssid_length[i],
5543 pwrctl->pnlo_info->ssid_cipher_info[i], pwrctl->pnlo_info->ssid_channel_info[i]);
5544 }
5545
5546 #ifndef RTW_HALMAC
5547 RTW_INFO("******SCAN_INFO******\n");
5548 RTW_INFO("ch_num: %d\n", pwrctl->pscan_info->channel_num);
5549 RTW_INFO("orig_ch: %d\n", pwrctl->pscan_info->orig_ch);
5550 RTW_INFO("orig bw: %d\n", pwrctl->pscan_info->orig_bw);
5551 RTW_INFO("orig 40 offset: %d\n", pwrctl->pscan_info->orig_40_offset);
5552 for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
5553 RTW_INFO("[%02d] avtive:%d, timeout:%d, tx_power:%d, ch:%02d\n",
5554 i, pwrctl->pscan_info->ssid_channel_info[i].active,
5555 pwrctl->pscan_info->ssid_channel_info[i].timeout,
5556 pwrctl->pscan_info->ssid_channel_info[i].tx_power,
5557 pwrctl->pscan_info->ssid_channel_info[i].channel);
5558 }
5559 #endif
5560 RTW_INFO("*****************\n");
5561 }
5562 #endif /* CONFIG_PNO_SET_DEBUG */
5563 #endif /* CONFIG_PNO_SUPPORT */
5564
rtw_collect_bcn_info(_adapter * adapter)5565 inline void rtw_collect_bcn_info(_adapter *adapter)
5566 {
5567 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
5568
5569 if (!is_client_associated_to_ap(adapter))
5570 return;
5571
5572 pmlmeext->cur_bcn_cnt = pmlmeext->bcn_cnt - pmlmeext->last_bcn_cnt;
5573 pmlmeext->last_bcn_cnt = pmlmeext->bcn_cnt;
5574 /*TODO get offset of bcn's timestamp*/
5575 /*pmlmeext->bcn_timestamp;*/
5576 }
5577
rtw_get_vht_bitrate(u8 mcs,u8 bw,u8 nss,u8 sgi)5578 static u32 rtw_get_vht_bitrate(u8 mcs, u8 bw, u8 nss, u8 sgi)
5579 {
5580 static const u32 base[4][10] = {
5581 { 6500000,
5582 13000000,
5583 19500000,
5584 26000000,
5585 39000000,
5586 52000000,
5587 58500000,
5588 65000000,
5589 78000000,
5590 /* not in the spec, but some devices use this: */
5591 86500000,
5592 },
5593 { 13500000,
5594 27000000,
5595 40500000,
5596 54000000,
5597 81000000,
5598 108000000,
5599 121500000,
5600 135000000,
5601 162000000,
5602 180000000,
5603 },
5604 { 29300000,
5605 58500000,
5606 87800000,
5607 117000000,
5608 175500000,
5609 234000000,
5610 263300000,
5611 292500000,
5612 351000000,
5613 390000000,
5614 },
5615 { 58500000,
5616 117000000,
5617 175500000,
5618 234000000,
5619 351000000,
5620 468000000,
5621 526500000,
5622 585000000,
5623 702000000,
5624 780000000,
5625 },
5626 };
5627 u32 bitrate;
5628 int bw_idx;
5629
5630 if (mcs > 9) {
5631 RTW_INFO("Invalid mcs = %d\n", mcs);
5632 return 0;
5633 }
5634
5635 if (nss > 4 || nss < 1) {
5636 RTW_INFO("Now only support nss = 1, 2, 3, 4\n");
5637 }
5638
5639 switch (bw) {
5640 case CHANNEL_WIDTH_160:
5641 bw_idx = 3;
5642 break;
5643 case CHANNEL_WIDTH_80:
5644 bw_idx = 2;
5645 break;
5646 case CHANNEL_WIDTH_40:
5647 bw_idx = 1;
5648 break;
5649 case CHANNEL_WIDTH_20:
5650 bw_idx = 0;
5651 break;
5652 default:
5653 RTW_INFO("bw = %d currently not supported\n", bw);
5654 return 0;
5655 }
5656
5657 bitrate = base[bw_idx][mcs];
5658 bitrate *= nss;
5659
5660 if (sgi)
5661 bitrate = (bitrate / 9) * 10;
5662
5663 /* do NOT round down here */
5664 return (bitrate + 50000) / 100000;
5665 }
5666
rtw_get_ht_bitrate(u8 mcs,u8 bw,u8 sgi)5667 static u32 rtw_get_ht_bitrate(u8 mcs, u8 bw, u8 sgi)
5668 {
5669 int modulation, streams, bitrate;
5670
5671 /* the formula below does only work for MCS values smaller than 32 */
5672 if (mcs >= 32) {
5673 RTW_INFO("Invalid mcs = %d\n", mcs);
5674 return 0;
5675 }
5676
5677 if (bw > 1) {
5678 RTW_INFO("Now HT only support bw = 0(20Mhz), 1(40Mhz)\n");
5679 return 0;
5680 }
5681
5682 modulation = mcs & 7;
5683 streams = (mcs >> 3) + 1;
5684
5685 bitrate = (bw == 1) ? 13500000 : 6500000;
5686
5687 if (modulation < 4)
5688 bitrate *= (modulation + 1);
5689 else if (modulation == 4)
5690 bitrate *= (modulation + 2);
5691 else
5692 bitrate *= (modulation + 3);
5693
5694 bitrate *= streams;
5695
5696 if (sgi)
5697 bitrate = (bitrate / 9) * 10;
5698
5699 return (bitrate + 50000) / 100000;
5700 }
5701
5702 /**
5703 * @bw: 0(20Mhz), 1(40Mhz), 2(80Mhz), 3(160Mhz)
5704 * @rate_idx: DESC_RATEXXXX & 0x7f
5705 * @sgi: DESC_RATEXXXX >> 7
5706 * Returns: bitrate in 100kbps
5707 */
rtw_desc_rate_to_bitrate(u8 bw,u8 rate_idx,u8 sgi)5708 u32 rtw_desc_rate_to_bitrate(u8 bw, u8 rate_idx, u8 sgi)
5709 {
5710 u32 bitrate;
5711
5712 if (rate_idx <= DESC_RATE54M){
5713 u16 ofdm_rate[12] = {10, 20, 55, 110,
5714 60, 90, 120, 180, 240, 360, 480, 540};
5715
5716 bitrate = ofdm_rate[rate_idx];
5717 } else if ((DESC_RATEMCS0 <= rate_idx) &&
5718 (rate_idx <= DESC_RATEMCS31)) {
5719 u8 mcs = rate_idx - DESC_RATEMCS0;
5720
5721 bitrate = rtw_get_ht_bitrate(mcs, bw, sgi);
5722 } else if ((DESC_RATEVHTSS1MCS0 <= rate_idx) &&
5723 (rate_idx <= DESC_RATEVHTSS4MCS9)) {
5724 u8 mcs = (rate_idx - DESC_RATEVHTSS1MCS0) % 10;
5725 u8 nss = ((rate_idx - DESC_RATEVHTSS1MCS0) / 10) + 1;
5726
5727 bitrate = rtw_get_vht_bitrate(mcs, bw, nss, sgi);
5728 } else {
5729 /* TODO: 60Ghz */
5730 bitrate = 1;
5731 }
5732
5733 return bitrate;
5734 }
5735
5736 #ifdef CONFIG_RTW_MULTI_AP
rtw_get_ch_utilization(_adapter * adapter)5737 u8 rtw_get_ch_utilization(_adapter *adapter)
5738 {
5739 u16 clm = rtw_phydm_clm_ratio(adapter);
5740 u16 nhm = rtw_phydm_nhm_ratio(adapter);
5741 u16 ch_util;
5742
5743 ch_util = clm / 3 + (2 * (nhm / 3));
5744 /* For Multi-AP, scaling 0-100 to 0-255 */
5745 ch_util = 255 * ch_util / 100;
5746
5747 return (u8)ch_util;
5748 }
5749
rtw_ch_util_rpt(_adapter * adapter)5750 void rtw_ch_util_rpt(_adapter *adapter)
5751 {
5752 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5753 _adapter *iface;
5754 int i, j;
5755 u8 i_rpts = 0;
5756 u8 *ch_util;
5757 u8 **bssid;
5758 u8 threshold = GET_PRIMARY_ADAPTER(adapter)->ch_util_threshold;
5759 u8 need_rpt = 0;
5760
5761 if (threshold == 0)
5762 return;
5763
5764 ch_util = rtw_zmalloc(sizeof(u8) * dvobj->iface_nums);
5765 if (!ch_util)
5766 goto err_out;
5767 bssid = (u8 **) rtw_zmalloc(sizeof(u8 *) * dvobj->iface_nums);
5768 if (!bssid)
5769 goto err_out1;
5770 for (j = 0; j < dvobj->iface_nums; j++) {
5771 *(bssid + j) = (u8 *) rtw_zmalloc(sizeof(u8) * ETH_ALEN);
5772 if (!(*(bssid + j)))
5773 goto err_out2;
5774 }
5775
5776 for (i = 0; i < dvobj->iface_nums; i++) {
5777 iface = dvobj->padapters[i];
5778 if ((iface) && MLME_IS_AP(iface)) {
5779 *(ch_util + i_rpts) = rtw_get_ch_utilization(iface);
5780 _rtw_memcpy(*(bssid + i_rpts), iface->mac_addr, ETH_ALEN);
5781
5782 if (*(ch_util + i_rpts) > threshold)
5783 need_rpt = 1;
5784
5785 i_rpts++;
5786 }
5787 }
5788
5789 if (need_rpt)
5790 rtw_nlrtw_ch_util_rpt(adapter, i_rpts, ch_util, bssid);
5791
5792 rtw_mfree(ch_util, sizeof(u8) * dvobj->iface_nums);
5793 for (i = 0; i < dvobj->iface_nums; i++)
5794 rtw_mfree(*(bssid + i), ETH_ALEN);
5795 rtw_mfree(bssid, sizeof(u8 *) * dvobj->iface_nums);
5796
5797 return;
5798
5799 err_out2:
5800 for (i = 0; i < j; i++)
5801 rtw_mfree(*(bssid + i), sizeof(u8) * ETH_ALEN);
5802 rtw_mfree(bssid, sizeof(sizeof(u8 *) * dvobj->iface_nums));
5803 err_out1:
5804 rtw_mfree(ch_util, sizeof(u8) * dvobj->iface_nums);
5805 err_out:
5806 RTW_INFO("[%s] rtw_zmalloc fail\n", __func__);
5807 }
5808 #endif
5809
rtw_rx_dbg_monitor_condition_chk(_adapter * padapter,u8 * ip,u32 port,u8 condition)5810 inline u8 rtw_rx_dbg_monitor_condition_chk(
5811 _adapter *padapter, u8 *ip, u32 port, u8 condition)
5812 {
5813 struct recv_priv *precvpriv = &(padapter->recvpriv);
5814 u8 need_chk = _FALSE;
5815
5816 if (precvpriv->ip_statistic.enabled == _FALSE)
5817 goto exit;
5818
5819 switch (condition) {
5820 case 1:
5821 if (ip && _rtw_memcmp(precvpriv->ip_statistic.ip, ip, 4))
5822 need_chk = _TRUE;
5823 break;
5824 case 2:
5825 if (precvpriv->ip_statistic.dst_port == port)
5826 need_chk = _TRUE;
5827 break;
5828 default:
5829 break;
5830 }
5831
5832 exit:
5833 return need_chk;
5834 }
5835
rtw_dbg_rx_iperf_udp_data_chk(_adapter * padapter,u8 * pdata)5836 void rtw_dbg_rx_iperf_udp_data_chk(_adapter *padapter, u8 *pdata)
5837 {
5838 struct recv_priv *precvpriv = &(padapter->recvpriv);
5839 struct rtw_ip_dbg_cnt_statistic *st = &(precvpriv->ip_statistic);
5840 u8 iperf_start_seq, iperf_seq_offset;
5841 u16 udp_data_len;
5842 u32 cur_iperf_seq, end_boundary = 0xffff;
5843
5844 /* no application data */
5845 udp_data_len = __be16_to_cpu(*((u16 *)(pdata + 4)));
5846 if (udp_data_len < 16)
5847 return;
5848
5849 /* RTW_INFO_DUMP("iperf data : ", pdata, 24); */
5850 if ((st->iperf_ver & 0x7f) >= 3) {
5851 iperf_seq_offset = 16;
5852 iperf_start_seq = 1 ;
5853 } else {
5854 iperf_seq_offset = 8;
5855 iperf_start_seq = 0 ;
5856 }
5857
5858 cur_iperf_seq = __be32_to_cpu(*((u32 *)(pdata + iperf_seq_offset)));
5859 if (cur_iperf_seq >= (st->iperf_seq + end_boundary)) {
5860 RTW_INFO("%s : terminate for end/abnormal of iperf pkt\n", __func__);
5861 return;
5862 }
5863
5864 if (cur_iperf_seq >= (iudp_ip_seq_get(st) + 1)) {
5865 if (cur_iperf_seq > (iudp_ip_seq_get(st) + 1))
5866 iudp_err_cnt_update(st, cur_iperf_seq);
5867 iudp_ip_seq_set(st, cur_iperf_seq);
5868 } else
5869 iperf_out_of_order_cnt_inc(st, cur_iperf_seq);
5870 }
5871
rtw_rx_dbg_monitor_ip_statistic(_adapter * padapter,_pkt * pkt)5872 void rtw_rx_dbg_monitor_ip_statistic(_adapter *padapter, _pkt *pkt)
5873 {
5874 struct recv_priv *precvpriv = &(padapter->recvpriv);
5875 u8 *ip_hdr, frag_flag, src_ip[4], frag_drop = _FALSE;
5876 u16 ip_seq, frag_offset, sport = 0 , dport = 0;
5877 u32 i;
5878
5879 if (pkt->protocol != __constant_htons(ETH_P_IP))
5880 return;
5881
5882 /* RTW_INFO_DUMP("ip hdr :", pkt->data, 32); */
5883 ip_hdr = pkt->data;
5884 if ((GET_IPV4_PROTOCOL(ip_hdr) != 0x6) &&
5885 (GET_IPV4_PROTOCOL(ip_hdr) != 0x11)) {
5886 /* filter all non-tcp/udp packets */
5887 return;
5888 }
5889
5890 for (i=0; i<=3; i++)
5891 src_ip[i] = *IPV4_SRC(ip_hdr + i);
5892
5893 if (!rtw_rx_dbg_monitor_condition_chk(padapter, src_ip, 0, 1)) {
5894 /* filter all unmatched-packets by source-ip */
5895 return;
5896 }
5897
5898 ip_seq = be16_to_cpu(*((u16 *)(ip_hdr + 4)));
5899 frag_offset = be16_to_cpu(*((u16 *)(ip_hdr + 6)));
5900 frag_flag = frag_offset >> 13;
5901 frag_offset &= 0x1fff;
5902
5903 /* no-fragments or 1st-fragment */
5904 if ((frag_flag & BIT(1)) || (frag_offset == 0)) {
5905 sport = GET_UDP_SRC(ip_hdr + 20);
5906 dport = GET_UDP_DST(ip_hdr + 20);
5907
5908 if (!rtw_rx_dbg_monitor_condition_chk(padapter, NULL, dport, 2)) {
5909 /* filter all unmatched-packets by destination-port */
5910 return;
5911 }
5912
5913 /* 1st-fragment */
5914 if (frag_flag & BIT(0)) {
5915 frag_cnt_inc(&precvpriv->ip_statistic);
5916 if (need_to_chk_iudp_cnt(ip_hdr, &precvpriv->ip_statistic)) {
5917 if (iudp_defrag_done_get(&precvpriv->ip_statistic) == _FALSE)
5918 iudp_err_cnt_inc(&precvpriv->ip_statistic, "last-frag");
5919
5920 iudp_defrag_done_set(&precvpriv->ip_statistic, _FALSE);
5921 iudp_ip_seq_chk_set(&precvpriv->ip_statistic, ip_seq);
5922 iudp_frag_offset_chk_set(&precvpriv->ip_statistic, frag_offset);
5923 iudp_max_frag_offset_chk_set(&precvpriv->ip_statistic, frag_offset);
5924 }
5925 }
5926
5927 ip_cnt_inc(&precvpriv->ip_statistic);
5928 tcp_udp_cnt_inc(ip_hdr, &precvpriv->ip_statistic);
5929 if (need_to_chk_iudp_cnt(ip_hdr, &precvpriv->ip_statistic))
5930 rtw_dbg_rx_iperf_udp_data_chk(padapter, (ip_hdr + 20));
5931
5932 } else if (((frag_flag & BIT(0)) || (frag_flag == 0)) \
5933 && (frag_offset > 0)) {
5934 /* more-or-last fragment */
5935 frag_cnt_inc(&precvpriv->ip_statistic);
5936 if (need_to_chk_iudp_cnt(ip_hdr, &precvpriv->ip_statistic)) {
5937 /* fragment-lenth in 8byte-blocks without ip-header */
5938 iudp_frag_offset_chk_set(&precvpriv->ip_statistic,
5939 (iudp_frag_offset_chk_get(&precvpriv->ip_statistic) + ((pkt->len - 20)/8)));
5940 iudp_max_frag_offset_chk_set(&precvpriv->ip_statistic,
5941 (iudp_max_frag_offset_chk_get(&precvpriv->ip_statistic) + ((1500 - 20)/8)));
5942
5943 /* more-frag check */
5944 if (frag_flag & BIT(0)) {
5945 if ((ip_seq == iudp_ip_seq_chk_get(&precvpriv->ip_statistic))
5946 && (iudp_defrag_done_get(&precvpriv->ip_statistic) == _FALSE) \
5947 && (frag_offset > iudp_frag_offset_chk_get(&precvpriv->ip_statistic))) {
5948 iudp_defrag_done_set(&precvpriv->ip_statistic, _TRUE);
5949 iudp_err_cnt_inc(&precvpriv->ip_statistic, "more-frag");
5950 }
5951 } else {
5952 if ((ip_seq == iudp_ip_seq_chk_get(&precvpriv->ip_statistic))
5953 && (iudp_defrag_done_get(&precvpriv->ip_statistic) == _FALSE)) {
5954 iudp_defrag_done_set(&precvpriv->ip_statistic, _TRUE);
5955 if (frag_offset > iudp_max_frag_offset_chk_get(&precvpriv->ip_statistic))
5956 iudp_err_cnt_inc(&precvpriv->ip_statistic, "more-frag");
5957 }
5958 }
5959 }
5960
5961 tcp_udp_cnt_inc(ip_hdr, &precvpriv->ip_statistic);
5962 }
5963 }
5964
5965