Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/ALFA-W1F1/RTL8814AU/core/rtw_wlan_util.c
1307 views
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[];
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[];
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 */
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 */
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 */
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
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
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
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
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
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);
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);
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);
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
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
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
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
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
}
409
void Set_MSR(_adapter *padapter, u8 type)
410
{
411
rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type));
412
}
413
414
inline u8 rtw_get_oper_ch(_adapter *adapter)
415
{
416
return adapter_to_dvobj(adapter)->oper_channel;
417
}
418
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
456
inline u8 rtw_get_oper_bw(_adapter *adapter)
457
{
458
return adapter_to_dvobj(adapter)->oper_bwmode;
459
}
460
461
inline void rtw_set_oper_bw(_adapter *adapter, u8 bw)
462
{
463
adapter_to_dvobj(adapter)->oper_bwmode = bw;
464
}
465
466
inline u8 rtw_get_oper_choffset(_adapter *adapter)
467
{
468
return adapter_to_dvobj(adapter)->oper_ch_offset;
469
}
470
471
inline void rtw_set_oper_choffset(_adapter *adapter, u8 offset)
472
{
473
adapter_to_dvobj(adapter)->oper_ch_offset = offset;
474
}
475
476
u8 rtw_get_offset_by_chbw(u8 ch, u8 bw, u8 *r_offset)
477
{
478
u8 valid = 1;
479
u8 offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
480
481
if (bw == CHANNEL_WIDTH_20)
482
goto exit;
483
484
if (bw >= CHANNEL_WIDTH_80 && ch <= 14) {
485
valid = 0;
486
goto exit;
487
}
488
489
if (ch >= 1 && ch <= 4)
490
offset = HAL_PRIME_CHNL_OFFSET_LOWER;
491
else if (ch >= 5 && ch <= 9) {
492
if (*r_offset == HAL_PRIME_CHNL_OFFSET_LOWER || *r_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
493
offset = *r_offset; /* both lower and upper is valid, obey input value */
494
else
495
offset = HAL_PRIME_CHNL_OFFSET_UPPER; /* default use upper */
496
} else if (ch >= 10 && ch <= 13)
497
offset = HAL_PRIME_CHNL_OFFSET_UPPER;
498
else if (ch == 14) {
499
valid = 0; /* ch14 doesn't support 40MHz bandwidth */
500
goto exit;
501
} else if (ch >= 36 && ch <= 177) {
502
switch (ch) {
503
case 36:
504
case 44:
505
case 52:
506
case 60:
507
case 100:
508
case 108:
509
case 116:
510
case 124:
511
case 132:
512
case 140:
513
case 149:
514
case 157:
515
case 165:
516
case 173:
517
offset = HAL_PRIME_CHNL_OFFSET_LOWER;
518
break;
519
case 40:
520
case 48:
521
case 56:
522
case 64:
523
case 104:
524
case 112:
525
case 120:
526
case 128:
527
case 136:
528
case 144:
529
case 153:
530
case 161:
531
case 169:
532
case 177:
533
offset = HAL_PRIME_CHNL_OFFSET_UPPER;
534
break;
535
default:
536
valid = 0;
537
break;
538
}
539
} else
540
valid = 0;
541
542
exit:
543
if (valid && r_offset)
544
*r_offset = offset;
545
return valid;
546
}
547
548
u8 rtw_get_center_ch(u8 channel, u8 chnl_bw, u8 chnl_offset)
549
{
550
u8 center_ch = channel;
551
552
if (chnl_bw == CHANNEL_WIDTH_80) {
553
if (channel == 36 || channel == 40 || channel == 44 || channel == 48)
554
center_ch = 42;
555
else if (channel == 52 || channel == 56 || channel == 60 || channel == 64)
556
center_ch = 58;
557
else if (channel == 100 || channel == 104 || channel == 108 || channel == 112)
558
center_ch = 106;
559
else if (channel == 116 || channel == 120 || channel == 124 || channel == 128)
560
center_ch = 122;
561
else if (channel == 132 || channel == 136 || channel == 140 || channel == 144)
562
center_ch = 138;
563
else if (channel == 149 || channel == 153 || channel == 157 || channel == 161)
564
center_ch = 155;
565
else if (channel == 165 || channel == 169 || channel == 173 || channel == 177)
566
center_ch = 171;
567
else if (channel <= 14)
568
center_ch = 7;
569
} else if (chnl_bw == CHANNEL_WIDTH_40) {
570
if (chnl_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
571
center_ch = channel + 2;
572
else
573
center_ch = channel - 2;
574
} else if (chnl_bw == CHANNEL_WIDTH_20)
575
center_ch = channel;
576
else
577
rtw_warn_on(1);
578
579
return center_ch;
580
}
581
582
inline systime rtw_get_on_oper_ch_time(_adapter *adapter)
583
{
584
return adapter_to_dvobj(adapter)->on_oper_ch_time;
585
}
586
587
inline systime rtw_get_on_cur_ch_time(_adapter *adapter)
588
{
589
if (adapter->mlmeextpriv.cur_channel == adapter_to_dvobj(adapter)->oper_channel)
590
return adapter_to_dvobj(adapter)->on_oper_ch_time;
591
else
592
return 0;
593
}
594
595
void set_channel_bwmode(_adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode)
596
{
597
u8 center_ch, chnl_offset80 = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
598
#if (defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)) || defined(CONFIG_MCC_MODE)
599
u8 iqk_info_backup = _FALSE;
600
#endif
601
602
if (padapter->bNotifyChannelChange)
603
RTW_INFO("[%s] ch = %d, offset = %d, bwmode = %d\n", __FUNCTION__, channel, channel_offset, bwmode);
604
605
center_ch = rtw_get_center_ch(channel, bwmode, channel_offset);
606
607
if (bwmode == CHANNEL_WIDTH_80) {
608
if (center_ch > channel)
609
chnl_offset80 = HAL_PRIME_CHNL_OFFSET_LOWER;
610
else if (center_ch < channel)
611
chnl_offset80 = HAL_PRIME_CHNL_OFFSET_UPPER;
612
else
613
chnl_offset80 = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
614
}
615
_enter_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
616
617
#ifdef CONFIG_MCC_MODE
618
if (MCC_EN(padapter)) {
619
/* driver doesn't set channel setting reg under MCC */
620
if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
621
RTW_INFO("Warning: Do not set channel setting reg MCC mode\n");
622
}
623
#endif
624
625
#ifdef CONFIG_DFS_MASTER
626
{
627
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
628
bool ori_overlap_radar_detect_ch = rtw_rfctl_overlap_radar_detect_ch(rfctl);
629
bool new_overlap_radar_detect_ch = _rtw_rfctl_overlap_radar_detect_ch(rfctl, channel, bwmode, channel_offset);
630
631
if (new_overlap_radar_detect_ch && IS_CH_WAITING(rfctl)) {
632
u8 pause = 0xFF;
633
634
rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause);
635
}
636
#endif /* CONFIG_DFS_MASTER */
637
638
/* set Channel */
639
/* saved channel/bw info */
640
rtw_set_oper_ch(padapter, channel);
641
rtw_set_oper_bw(padapter, bwmode);
642
rtw_set_oper_choffset(padapter, channel_offset);
643
644
#if (defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)) || defined(CONFIG_MCC_MODE)
645
/* To check if we need to backup iqk info after switch chnl & bw */
646
{
647
u8 take_care_iqk, do_iqk;
648
649
rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
650
rtw_hal_get_hwreg(padapter, HW_VAR_DO_IQK, &do_iqk);
651
if ((take_care_iqk == _TRUE) && (do_iqk == _TRUE))
652
iqk_info_backup = _TRUE;
653
}
654
#endif
655
656
rtw_hal_set_chnl_bw(padapter, center_ch, bwmode, channel_offset, chnl_offset80); /* set center channel */
657
658
#if (defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)) || defined(CONFIG_MCC_MODE)
659
if (iqk_info_backup == _TRUE)
660
rtw_hal_ch_sw_iqk_info_backup(padapter);
661
#endif
662
663
#ifdef CONFIG_DFS_MASTER
664
if (new_overlap_radar_detect_ch)
665
rtw_odm_radar_detect_enable(padapter);
666
else if (ori_overlap_radar_detect_ch) {
667
u8 pause = 0x00;
668
669
rtw_odm_radar_detect_disable(padapter);
670
rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause);
671
}
672
}
673
#endif /* CONFIG_DFS_MASTER */
674
675
_exit_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
676
}
677
678
__inline u8 *get_my_bssid(WLAN_BSSID_EX *pnetwork)
679
{
680
return pnetwork->MacAddress;
681
}
682
683
u16 get_beacon_interval(WLAN_BSSID_EX *bss)
684
{
685
unsigned short val;
686
_rtw_memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->IEs), 2);
687
688
return le16_to_cpu(val);
689
690
}
691
692
int is_client_associated_to_ap(_adapter *padapter)
693
{
694
struct mlme_ext_priv *pmlmeext;
695
struct mlme_ext_info *pmlmeinfo;
696
697
if (!padapter)
698
return _FAIL;
699
700
pmlmeext = &padapter->mlmeextpriv;
701
pmlmeinfo = &(pmlmeext->mlmext_info);
702
703
if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE))
704
return _TRUE;
705
else
706
return _FAIL;
707
}
708
709
int is_client_associated_to_ibss(_adapter *padapter)
710
{
711
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
712
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
713
714
if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE))
715
return _TRUE;
716
else
717
return _FAIL;
718
}
719
720
int is_IBSS_empty(_adapter *padapter)
721
{
722
int i;
723
struct macid_ctl_t *macid_ctl = &padapter->dvobj->macid_ctl;
724
725
for (i = 0; i < macid_ctl->num; i++) {
726
if (!rtw_macid_is_used(macid_ctl, i))
727
continue;
728
if (!rtw_macid_is_iface_specific(macid_ctl, i, padapter))
729
continue;
730
if (!GET_H2CCMD_MSRRPT_PARM_OPMODE(&macid_ctl->h2c_msr[i]))
731
continue;
732
if (GET_H2CCMD_MSRRPT_PARM_ROLE(&macid_ctl->h2c_msr[i]) == H2C_MSR_ROLE_ADHOC)
733
return _FAIL;
734
}
735
736
return _TRUE;
737
}
738
739
unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval)
740
{
741
if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN)
742
return WAIT_FOR_BCN_TO_MIN;
743
else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX)
744
return WAIT_FOR_BCN_TO_MAX;
745
else
746
return bcn_interval << 2;
747
}
748
749
void invalidate_cam_all(_adapter *padapter)
750
{
751
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
752
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
753
_irqL irqL;
754
u8 val8 = 0;
755
756
rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, &val8);
757
758
_enter_critical_bh(&cam_ctl->lock, &irqL);
759
rtw_sec_cam_map_clr_all(&cam_ctl->used);
760
_rtw_memset(dvobj->cam_cache, 0, sizeof(struct sec_cam_ent) * SEC_CAM_ENT_NUM_SW_LIMIT);
761
_exit_critical_bh(&cam_ctl->lock, &irqL);
762
}
763
764
void _clear_cam_entry(_adapter *padapter, u8 entry)
765
{
766
unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
767
unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
768
769
rtw_sec_write_cam_ent(padapter, entry, 0, null_sta, null_key);
770
}
771
772
inline void write_cam(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
773
{
774
#ifdef CONFIG_WRITE_CACHE_ONLY
775
write_cam_cache(adapter, id , ctrl, mac, key);
776
#else
777
rtw_sec_write_cam_ent(adapter, id, ctrl, mac, key);
778
write_cam_cache(adapter, id , ctrl, mac, key);
779
#endif
780
}
781
782
inline void clear_cam_entry(_adapter *adapter, u8 id)
783
{
784
_clear_cam_entry(adapter, id);
785
clear_cam_cache(adapter, id);
786
}
787
788
inline void write_cam_from_cache(_adapter *adapter, u8 id)
789
{
790
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
791
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
792
_irqL irqL;
793
struct sec_cam_ent cache;
794
795
_enter_critical_bh(&cam_ctl->lock, &irqL);
796
_rtw_memcpy(&cache, &dvobj->cam_cache[id], sizeof(struct sec_cam_ent));
797
_exit_critical_bh(&cam_ctl->lock, &irqL);
798
799
rtw_sec_write_cam_ent(adapter, id, cache.ctrl, cache.mac, cache.key);
800
}
801
void write_cam_cache(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
802
{
803
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
804
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
805
_irqL irqL;
806
807
_enter_critical_bh(&cam_ctl->lock, &irqL);
808
809
dvobj->cam_cache[id].ctrl = ctrl;
810
_rtw_memcpy(dvobj->cam_cache[id].mac, mac, ETH_ALEN);
811
_rtw_memcpy(dvobj->cam_cache[id].key, key, 16);
812
813
_exit_critical_bh(&cam_ctl->lock, &irqL);
814
}
815
816
void clear_cam_cache(_adapter *adapter, u8 id)
817
{
818
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
819
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
820
_irqL irqL;
821
822
_enter_critical_bh(&cam_ctl->lock, &irqL);
823
824
_rtw_memset(&(dvobj->cam_cache[id]), 0, sizeof(struct sec_cam_ent));
825
826
_exit_critical_bh(&cam_ctl->lock, &irqL);
827
}
828
829
inline bool _rtw_camctl_chk_cap(_adapter *adapter, u8 cap)
830
{
831
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
832
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
833
834
if (cam_ctl->sec_cap & cap)
835
return _TRUE;
836
return _FALSE;
837
}
838
839
inline void _rtw_camctl_set_flags(_adapter *adapter, u32 flags)
840
{
841
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
842
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
843
844
cam_ctl->flags |= flags;
845
}
846
847
inline void rtw_camctl_set_flags(_adapter *adapter, u32 flags)
848
{
849
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
850
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
851
_irqL irqL;
852
853
_enter_critical_bh(&cam_ctl->lock, &irqL);
854
_rtw_camctl_set_flags(adapter, flags);
855
_exit_critical_bh(&cam_ctl->lock, &irqL);
856
}
857
858
inline void _rtw_camctl_clr_flags(_adapter *adapter, u32 flags)
859
{
860
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
861
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
862
863
cam_ctl->flags &= ~flags;
864
}
865
866
inline void rtw_camctl_clr_flags(_adapter *adapter, u32 flags)
867
{
868
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
869
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
870
_irqL irqL;
871
872
_enter_critical_bh(&cam_ctl->lock, &irqL);
873
_rtw_camctl_clr_flags(adapter, flags);
874
_exit_critical_bh(&cam_ctl->lock, &irqL);
875
}
876
877
inline bool _rtw_camctl_chk_flags(_adapter *adapter, u32 flags)
878
{
879
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
880
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
881
882
if (cam_ctl->flags & flags)
883
return _TRUE;
884
return _FALSE;
885
}
886
887
void dump_sec_cam_map(void *sel, struct sec_cam_bmp *map, u8 max_num)
888
{
889
RTW_PRINT_SEL(sel, "0x%08x\n", map->m0);
890
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
891
if (max_num && max_num > 32)
892
RTW_PRINT_SEL(sel, "0x%08x\n", map->m1);
893
#endif
894
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
895
if (max_num && max_num > 64)
896
RTW_PRINT_SEL(sel, "0x%08x\n", map->m2);
897
#endif
898
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
899
if (max_num && max_num > 96)
900
RTW_PRINT_SEL(sel, "0x%08x\n", map->m3);
901
#endif
902
}
903
904
inline bool rtw_sec_camid_is_set(struct sec_cam_bmp *map, u8 id)
905
{
906
if (id < 32)
907
return map->m0 & BIT(id);
908
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
909
else if (id < 64)
910
return map->m1 & BIT(id - 32);
911
#endif
912
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
913
else if (id < 96)
914
return map->m2 & BIT(id - 64);
915
#endif
916
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
917
else if (id < 128)
918
return map->m3 & BIT(id - 96);
919
#endif
920
else
921
rtw_warn_on(1);
922
923
return 0;
924
}
925
926
inline void rtw_sec_cam_map_set(struct sec_cam_bmp *map, u8 id)
927
{
928
if (id < 32)
929
map->m0 |= BIT(id);
930
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
931
else if (id < 64)
932
map->m1 |= BIT(id - 32);
933
#endif
934
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
935
else if (id < 96)
936
map->m2 |= BIT(id - 64);
937
#endif
938
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
939
else if (id < 128)
940
map->m3 |= BIT(id - 96);
941
#endif
942
else
943
rtw_warn_on(1);
944
}
945
946
inline void rtw_sec_cam_map_clr(struct sec_cam_bmp *map, u8 id)
947
{
948
if (id < 32)
949
map->m0 &= ~BIT(id);
950
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
951
else if (id < 64)
952
map->m1 &= ~BIT(id - 32);
953
#endif
954
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
955
else if (id < 96)
956
map->m2 &= ~BIT(id - 64);
957
#endif
958
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
959
else if (id < 128)
960
map->m3 &= ~BIT(id - 96);
961
#endif
962
else
963
rtw_warn_on(1);
964
}
965
966
inline void rtw_sec_cam_map_clr_all(struct sec_cam_bmp *map)
967
{
968
map->m0 = 0;
969
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
970
map->m1 = 0;
971
#endif
972
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
973
map->m2 = 0;
974
#endif
975
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
976
map->m3 = 0;
977
#endif
978
}
979
980
inline bool rtw_sec_camid_is_drv_forbid(struct cam_ctl_t *cam_ctl, u8 id)
981
{
982
struct sec_cam_bmp forbid_map;
983
984
forbid_map.m0 = 0x00000ff0;
985
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
986
forbid_map.m1 = 0x00000000;
987
#endif
988
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
989
forbid_map.m2 = 0x00000000;
990
#endif
991
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
992
forbid_map.m3 = 0x00000000;
993
#endif
994
995
if (id < 32)
996
return forbid_map.m0 & BIT(id);
997
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
998
else if (id < 64)
999
return forbid_map.m1 & BIT(id - 32);
1000
#endif
1001
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
1002
else if (id < 96)
1003
return forbid_map.m2 & BIT(id - 64);
1004
#endif
1005
#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
1006
else if (id < 128)
1007
return forbid_map.m3 & BIT(id - 96);
1008
#endif
1009
else
1010
rtw_warn_on(1);
1011
1012
return 1;
1013
}
1014
1015
bool _rtw_sec_camid_is_used(struct cam_ctl_t *cam_ctl, u8 id)
1016
{
1017
bool ret = _FALSE;
1018
1019
if (id >= cam_ctl->num) {
1020
rtw_warn_on(1);
1021
goto exit;
1022
}
1023
1024
#if 0 /* for testing */
1025
if (rtw_sec_camid_is_drv_forbid(cam_ctl, id)) {
1026
ret = _TRUE;
1027
goto exit;
1028
}
1029
#endif
1030
1031
ret = rtw_sec_camid_is_set(&cam_ctl->used, id);
1032
1033
exit:
1034
return ret;
1035
}
1036
1037
inline bool rtw_sec_camid_is_used(struct cam_ctl_t *cam_ctl, u8 id)
1038
{
1039
_irqL irqL;
1040
bool ret;
1041
1042
_enter_critical_bh(&cam_ctl->lock, &irqL);
1043
ret = _rtw_sec_camid_is_used(cam_ctl, id);
1044
_exit_critical_bh(&cam_ctl->lock, &irqL);
1045
1046
return ret;
1047
}
1048
u8 rtw_get_sec_camid(_adapter *adapter, u8 max_bk_key_num, u8 *sec_key_id)
1049
{
1050
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1051
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1052
int i;
1053
_irqL irqL;
1054
u8 sec_cam_num = 0;
1055
1056
_enter_critical_bh(&cam_ctl->lock, &irqL);
1057
for (i = 0; i < cam_ctl->num; i++) {
1058
if (_rtw_sec_camid_is_used(cam_ctl, i)) {
1059
sec_key_id[sec_cam_num++] = i;
1060
if (sec_cam_num == max_bk_key_num)
1061
break;
1062
}
1063
}
1064
_exit_critical_bh(&cam_ctl->lock, &irqL);
1065
1066
return sec_cam_num;
1067
}
1068
1069
inline bool _rtw_camid_is_gk(_adapter *adapter, u8 cam_id)
1070
{
1071
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1072
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1073
bool ret = _FALSE;
1074
1075
if (cam_id >= cam_ctl->num) {
1076
rtw_warn_on(1);
1077
goto exit;
1078
}
1079
1080
if (_rtw_sec_camid_is_used(cam_ctl, cam_id) == _FALSE)
1081
goto exit;
1082
1083
ret = (dvobj->cam_cache[cam_id].ctrl & BIT6) ? _TRUE : _FALSE;
1084
1085
exit:
1086
return ret;
1087
}
1088
1089
inline bool rtw_camid_is_gk(_adapter *adapter, u8 cam_id)
1090
{
1091
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1092
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1093
_irqL irqL;
1094
bool ret;
1095
1096
_enter_critical_bh(&cam_ctl->lock, &irqL);
1097
ret = _rtw_camid_is_gk(adapter, cam_id);
1098
_exit_critical_bh(&cam_ctl->lock, &irqL);
1099
1100
return ret;
1101
}
1102
1103
bool cam_cache_chk(_adapter *adapter, u8 id, u8 *addr, s16 kid, s8 gk)
1104
{
1105
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1106
bool ret = _FALSE;
1107
1108
if (addr && _rtw_memcmp(dvobj->cam_cache[id].mac, addr, ETH_ALEN) == _FALSE)
1109
goto exit;
1110
if (kid >= 0 && kid != (dvobj->cam_cache[id].ctrl & 0x03))
1111
goto exit;
1112
if (gk != -1 && (gk ? _TRUE : _FALSE) != _rtw_camid_is_gk(adapter, id))
1113
goto exit;
1114
1115
ret = _TRUE;
1116
1117
exit:
1118
return ret;
1119
}
1120
1121
s16 _rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk)
1122
{
1123
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1124
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1125
int i;
1126
s16 cam_id = -1;
1127
1128
for (i = 0; i < cam_ctl->num; i++) {
1129
if (cam_cache_chk(adapter, i, addr, kid, gk)) {
1130
cam_id = i;
1131
break;
1132
}
1133
}
1134
1135
if (0) {
1136
if (addr)
1137
RTW_INFO(FUNC_ADPT_FMT" addr:"MAC_FMT" kid:%d, gk:%d, return cam_id:%d\n"
1138
, FUNC_ADPT_ARG(adapter), MAC_ARG(addr), kid, gk, cam_id);
1139
else
1140
RTW_INFO(FUNC_ADPT_FMT" addr:%p kid:%d, gk:%d, return cam_id:%d\n"
1141
, FUNC_ADPT_ARG(adapter), addr, kid, gk, cam_id);
1142
}
1143
1144
return cam_id;
1145
}
1146
1147
s16 rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk)
1148
{
1149
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1150
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1151
_irqL irqL;
1152
s16 cam_id = -1;
1153
1154
_enter_critical_bh(&cam_ctl->lock, &irqL);
1155
cam_id = _rtw_camid_search(adapter, addr, kid, gk);
1156
_exit_critical_bh(&cam_ctl->lock, &irqL);
1157
1158
return cam_id;
1159
}
1160
1161
s16 rtw_get_camid(_adapter *adapter, u8 *addr, s16 kid, u8 gk)
1162
{
1163
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1164
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1165
int i;
1166
#if 0 /* for testing */
1167
static u8 start_id = 0;
1168
#else
1169
u8 start_id = 0;
1170
#endif
1171
s16 cam_id = -1;
1172
1173
if (addr == NULL) {
1174
RTW_PRINT(FUNC_ADPT_FMT" mac_address is NULL\n"
1175
, FUNC_ADPT_ARG(adapter));
1176
rtw_warn_on(1);
1177
goto _exit;
1178
}
1179
1180
/* find cam entry which has the same addr, kid (, gk bit) */
1181
if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC) == _TRUE)
1182
i = _rtw_camid_search(adapter, addr, kid, gk);
1183
else
1184
i = _rtw_camid_search(adapter, addr, kid, -1);
1185
1186
if (i >= 0) {
1187
cam_id = i;
1188
goto _exit;
1189
}
1190
1191
for (i = 0; i < cam_ctl->num; i++) {
1192
/* bypass default key which is allocated statically */
1193
#ifndef CONFIG_CONCURRENT_MODE
1194
if (((i + start_id) % cam_ctl->num) < 4)
1195
continue;
1196
#endif
1197
if (_rtw_sec_camid_is_used(cam_ctl, ((i + start_id) % cam_ctl->num)) == _FALSE)
1198
break;
1199
}
1200
1201
if (i == cam_ctl->num) {
1202
RTW_PRINT(FUNC_ADPT_FMT" %s key with "MAC_FMT" id:%u no room\n"
1203
, FUNC_ADPT_ARG(adapter), gk ? "group" : "pairwise", MAC_ARG(addr), kid);
1204
rtw_warn_on(1);
1205
goto _exit;
1206
}
1207
1208
cam_id = ((i + start_id) % cam_ctl->num);
1209
start_id = ((i + start_id + 1) % cam_ctl->num);
1210
1211
_exit:
1212
return cam_id;
1213
}
1214
1215
s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, u8 gk, bool *used)
1216
{
1217
struct mlme_ext_info *mlmeinfo = &adapter->mlmeextpriv.mlmext_info;
1218
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1219
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1220
_irqL irqL;
1221
s16 cam_id = -1;
1222
1223
*used = _FALSE;
1224
1225
_enter_critical_bh(&cam_ctl->lock, &irqL);
1226
1227
if ((((mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE))
1228
&& !sta) {
1229
/*
1230
* 1. non-STA mode WEP key
1231
* 2. group TX key
1232
*/
1233
#ifndef CONFIG_CONCURRENT_MODE
1234
/* static alloction to default key by key ID when concurrent is not defined */
1235
if (kid > 3) {
1236
RTW_PRINT(FUNC_ADPT_FMT" group key with invalid key id:%u\n"
1237
, FUNC_ADPT_ARG(adapter), kid);
1238
rtw_warn_on(1);
1239
goto bitmap_handle;
1240
}
1241
cam_id = kid;
1242
#else
1243
u8 *addr = adapter_mac_addr(adapter);
1244
1245
cam_id = rtw_get_camid(adapter, addr, kid, gk);
1246
if (1)
1247
RTW_PRINT(FUNC_ADPT_FMT" group key with "MAC_FMT" assigned cam_id:%u\n"
1248
, FUNC_ADPT_ARG(adapter), MAC_ARG(addr), cam_id);
1249
#endif
1250
} else {
1251
/*
1252
* 1. STA mode WEP key
1253
* 2. STA mode group RX key
1254
* 3. sta key (pairwise, group RX)
1255
*/
1256
u8 *addr = sta ? sta->cmn.mac_addr : NULL;
1257
1258
if (!sta) {
1259
if (!(mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
1260
/* bypass STA mode group key setting before connected(ex:WEP) because bssid is not ready */
1261
goto bitmap_handle;
1262
}
1263
addr = get_bssid(&adapter->mlmepriv);/*A2*/
1264
}
1265
cam_id = rtw_get_camid(adapter, addr, kid, gk);
1266
}
1267
1268
1269
bitmap_handle:
1270
if (cam_id >= 0) {
1271
*used = _rtw_sec_camid_is_used(cam_ctl, cam_id);
1272
rtw_sec_cam_map_set(&cam_ctl->used, cam_id);
1273
}
1274
1275
_exit_critical_bh(&cam_ctl->lock, &irqL);
1276
1277
return cam_id;
1278
}
1279
1280
void rtw_camid_set(_adapter *adapter, u8 cam_id)
1281
{
1282
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1283
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1284
_irqL irqL;
1285
1286
_enter_critical_bh(&cam_ctl->lock, &irqL);
1287
1288
if (cam_id < cam_ctl->num)
1289
rtw_sec_cam_map_set(&cam_ctl->used, cam_id);
1290
1291
_exit_critical_bh(&cam_ctl->lock, &irqL);
1292
}
1293
1294
void rtw_camid_free(_adapter *adapter, u8 cam_id)
1295
{
1296
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1297
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1298
_irqL irqL;
1299
1300
_enter_critical_bh(&cam_ctl->lock, &irqL);
1301
1302
if (cam_id < cam_ctl->num)
1303
rtw_sec_cam_map_clr(&cam_ctl->used, cam_id);
1304
1305
_exit_critical_bh(&cam_ctl->lock, &irqL);
1306
}
1307
1308
/*Must pause TX/RX before use this API*/
1309
inline void rtw_sec_cam_swap(_adapter *adapter, u8 cam_id_a, u8 cam_id_b)
1310
{
1311
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1312
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1313
struct sec_cam_ent cache_a, cache_b;
1314
_irqL irqL;
1315
bool cam_a_used, cam_b_used;
1316
1317
if (1)
1318
RTW_INFO(ADPT_FMT" - sec_cam %d,%d swap\n", ADPT_ARG(adapter), cam_id_a, cam_id_b);
1319
1320
if (cam_id_a == cam_id_b)
1321
return;
1322
1323
#ifdef CONFIG_CONCURRENT_MODE
1324
rtw_mi_update_ap_bmc_camid(adapter, cam_id_a, cam_id_b);
1325
#endif
1326
1327
/*setp-1. backup org cam_info*/
1328
_enter_critical_bh(&cam_ctl->lock, &irqL);
1329
1330
cam_a_used = _rtw_sec_camid_is_used(cam_ctl, cam_id_a);
1331
cam_b_used = _rtw_sec_camid_is_used(cam_ctl, cam_id_b);
1332
1333
if (cam_a_used)
1334
_rtw_memcpy(&cache_a, &dvobj->cam_cache[cam_id_a], sizeof(struct sec_cam_ent));
1335
1336
if (cam_b_used)
1337
_rtw_memcpy(&cache_b, &dvobj->cam_cache[cam_id_b], sizeof(struct sec_cam_ent));
1338
1339
_exit_critical_bh(&cam_ctl->lock, &irqL);
1340
1341
/*setp-2. clean cam_info*/
1342
if (cam_a_used) {
1343
rtw_camid_free(adapter, cam_id_a);
1344
clear_cam_entry(adapter, cam_id_a);
1345
}
1346
if (cam_b_used) {
1347
rtw_camid_free(adapter, cam_id_b);
1348
clear_cam_entry(adapter, cam_id_b);
1349
}
1350
1351
/*setp-3. set cam_info*/
1352
if (cam_a_used) {
1353
write_cam(adapter, cam_id_b, cache_a.ctrl, cache_a.mac, cache_a.key);
1354
rtw_camid_set(adapter, cam_id_b);
1355
}
1356
1357
if (cam_b_used) {
1358
write_cam(adapter, cam_id_a, cache_b.ctrl, cache_b.mac, cache_b.key);
1359
rtw_camid_set(adapter, cam_id_a);
1360
}
1361
}
1362
1363
s16 rtw_get_empty_cam_entry(_adapter *adapter, u8 start_camid)
1364
{
1365
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1366
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1367
_irqL irqL;
1368
int i;
1369
s16 cam_id = -1;
1370
1371
_enter_critical_bh(&cam_ctl->lock, &irqL);
1372
for (i = start_camid; i < cam_ctl->num; i++) {
1373
if (_FALSE == _rtw_sec_camid_is_used(cam_ctl, i)) {
1374
cam_id = i;
1375
break;
1376
}
1377
}
1378
_exit_critical_bh(&cam_ctl->lock, &irqL);
1379
1380
return cam_id;
1381
}
1382
void rtw_clean_dk_section(_adapter *adapter)
1383
{
1384
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1385
struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj);
1386
s16 ept_cam_id;
1387
int i;
1388
1389
for (i = 0; i < 4; i++) {
1390
if (rtw_sec_camid_is_used(cam_ctl, i)) {
1391
ept_cam_id = rtw_get_empty_cam_entry(adapter, 4);
1392
if (ept_cam_id > 0)
1393
rtw_sec_cam_swap(adapter, i, ept_cam_id);
1394
}
1395
}
1396
}
1397
void rtw_clean_hw_dk_cam(_adapter *adapter)
1398
{
1399
int i;
1400
1401
for (i = 0; i < 4; i++)
1402
rtw_sec_clr_cam_ent(adapter, i);
1403
/*_clear_cam_entry(adapter, i);*/
1404
}
1405
1406
void flush_all_cam_entry(_adapter *padapter)
1407
{
1408
#ifdef CONFIG_CONCURRENT_MODE
1409
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1410
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1411
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1412
1413
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1414
struct sta_priv *pstapriv = &padapter->stapriv;
1415
struct sta_info *psta;
1416
1417
psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
1418
if (psta) {
1419
if (psta->state & WIFI_AP_STATE) {
1420
/*clear cam when ap free per sta_info*/
1421
} else
1422
rtw_clearstakey_cmd(padapter, psta, _FALSE);
1423
}
1424
} else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) {
1425
#if 1
1426
int cam_id = -1;
1427
u8 *addr = adapter_mac_addr(padapter);
1428
1429
while ((cam_id = rtw_camid_search(padapter, addr, -1, -1)) >= 0) {
1430
RTW_PRINT("clear wep or group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), cam_id);
1431
clear_cam_entry(padapter, cam_id);
1432
rtw_camid_free(padapter, cam_id);
1433
}
1434
#else
1435
/* clear default key */
1436
int i, cam_id;
1437
u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
1438
1439
for (i = 0; i < 4; i++) {
1440
cam_id = rtw_camid_search(padapter, null_addr, i, -1);
1441
if (cam_id >= 0) {
1442
clear_cam_entry(padapter, cam_id);
1443
rtw_camid_free(padapter, cam_id);
1444
}
1445
}
1446
/* clear default key related key search setting */
1447
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_FALSE);
1448
#endif
1449
}
1450
1451
#else /*NON CONFIG_CONCURRENT_MODE*/
1452
1453
invalidate_cam_all(padapter);
1454
/* clear default key related key search setting */
1455
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_FALSE);
1456
#endif
1457
}
1458
1459
#if defined(CONFIG_P2P) && defined(CONFIG_WFD)
1460
void rtw_process_wfd_ie(_adapter *adapter, u8 *wfd_ie, u8 wfd_ielen, const char *tag)
1461
{
1462
struct wifidirect_info *wdinfo = &adapter->wdinfo;
1463
1464
u8 *attr_content;
1465
u32 attr_contentlen = 0;
1466
1467
if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
1468
return;
1469
1470
RTW_INFO("[%s] Found WFD IE\n", tag);
1471
attr_content = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &attr_contentlen);
1472
if (attr_content && attr_contentlen) {
1473
wdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16(attr_content + 2);
1474
RTW_INFO("[%s] Peer PORT NUM = %d\n", tag, wdinfo->wfd_info->peer_rtsp_ctrlport);
1475
}
1476
}
1477
1478
void rtw_process_wfd_ies(_adapter *adapter, u8 *ies, u8 ies_len, const char *tag)
1479
{
1480
u8 *wfd_ie;
1481
u32 wfd_ielen;
1482
1483
if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
1484
return;
1485
1486
wfd_ie = rtw_get_wfd_ie(ies, ies_len, NULL, &wfd_ielen);
1487
while (wfd_ie) {
1488
rtw_process_wfd_ie(adapter, wfd_ie, wfd_ielen, tag);
1489
wfd_ie = rtw_get_wfd_ie(wfd_ie + wfd_ielen, (ies + ies_len) - (wfd_ie + wfd_ielen), NULL, &wfd_ielen);
1490
}
1491
}
1492
#endif /* defined(CONFIG_P2P) && defined(CONFIG_WFD) */
1493
1494
int WMM_param_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1495
{
1496
/* struct registry_priv *pregpriv = &padapter->registrypriv; */
1497
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1498
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1499
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1500
1501
if (pmlmepriv->qospriv.qos_option == 0) {
1502
pmlmeinfo->WMM_enable = 0;
1503
return _FALSE;
1504
}
1505
1506
if (_rtw_memcmp(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element)))
1507
return _FALSE;
1508
else
1509
_rtw_memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element));
1510
pmlmeinfo->WMM_enable = 1;
1511
return _TRUE;
1512
1513
#if 0
1514
if (pregpriv->wifi_spec == 1) {
1515
if (pmlmeinfo->WMM_enable == 1) {
1516
/* todo: compare the parameter set count & decide wheher to update or not */
1517
return _FAIL;
1518
} else {
1519
pmlmeinfo->WMM_enable = 1;
1520
_rtw_rtw_memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element));
1521
return _TRUE;
1522
}
1523
} else {
1524
pmlmeinfo->WMM_enable = 0;
1525
return _FAIL;
1526
}
1527
#endif
1528
1529
}
1530
1531
void WMMOnAssocRsp(_adapter *padapter)
1532
{
1533
u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime;
1534
u8 acm_mask;
1535
u16 TXOP;
1536
u32 acParm, i;
1537
u32 edca[4], inx[4];
1538
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1539
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1540
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1541
struct registry_priv *pregpriv = &padapter->registrypriv;
1542
#ifdef CONFIG_WMMPS_STA
1543
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1544
struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1545
#endif /* CONFIG_WMMPS_STA */
1546
1547
acm_mask = 0;
1548
1549
if (is_supported_5g(pmlmeext->cur_wireless_mode) ||
1550
(pmlmeext->cur_wireless_mode & WIRELESS_11_24N))
1551
aSifsTime = 16;
1552
else
1553
aSifsTime = 10;
1554
1555
if (pmlmeinfo->WMM_enable == 0) {
1556
padapter->mlmepriv.acm_mask = 0;
1557
1558
AIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
1559
1560
if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11A)) {
1561
ECWMin = 4;
1562
ECWMax = 10;
1563
} else if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
1564
ECWMin = 5;
1565
ECWMax = 10;
1566
} else {
1567
ECWMin = 4;
1568
ECWMax = 10;
1569
}
1570
1571
TXOP = 0;
1572
acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1573
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
1574
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
1575
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
1576
1577
ECWMin = 2;
1578
ECWMax = 3;
1579
TXOP = 0x2f;
1580
acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1581
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
1582
} else {
1583
edca[0] = edca[1] = edca[2] = edca[3] = 0;
1584
1585
for (i = 0; i < 4; i++) {
1586
ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03;
1587
ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01;
1588
1589
/* AIFS = AIFSN * slot time + SIFS - r2t phy delay */
1590
AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) * pmlmeinfo->slotTime + aSifsTime;
1591
1592
ECWMin = (pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f);
1593
ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4;
1594
TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit);
1595
1596
acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1597
1598
switch (ACI) {
1599
case 0x0:
1600
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
1601
acm_mask |= (ACM ? BIT(1) : 0);
1602
edca[XMIT_BE_QUEUE] = acParm;
1603
break;
1604
1605
case 0x1:
1606
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
1607
/* acm_mask |= (ACM? BIT(0):0); */
1608
edca[XMIT_BK_QUEUE] = acParm;
1609
break;
1610
1611
case 0x2:
1612
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
1613
acm_mask |= (ACM ? BIT(2) : 0);
1614
edca[XMIT_VI_QUEUE] = acParm;
1615
break;
1616
1617
case 0x3:
1618
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
1619
acm_mask |= (ACM ? BIT(3) : 0);
1620
edca[XMIT_VO_QUEUE] = acParm;
1621
break;
1622
}
1623
1624
RTW_INFO("WMM(%x): %x, %x\n", ACI, ACM, acParm);
1625
}
1626
1627
if (padapter->registrypriv.acm_method == 1)
1628
rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask));
1629
else
1630
padapter->mlmepriv.acm_mask = acm_mask;
1631
1632
inx[0] = 0;
1633
inx[1] = 1;
1634
inx[2] = 2;
1635
inx[3] = 3;
1636
1637
if (pregpriv->wifi_spec == 1) {
1638
u32 j, tmp, change_inx = _FALSE;
1639
1640
/* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */
1641
for (i = 0; i < 4; i++) {
1642
for (j = i + 1; j < 4; j++) {
1643
/* compare CW and AIFS */
1644
if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF))
1645
change_inx = _TRUE;
1646
else if ((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF)) {
1647
/* compare TXOP */
1648
if ((edca[j] >> 16) > (edca[i] >> 16))
1649
change_inx = _TRUE;
1650
}
1651
1652
if (change_inx) {
1653
tmp = edca[i];
1654
edca[i] = edca[j];
1655
edca[j] = tmp;
1656
1657
tmp = inx[i];
1658
inx[i] = inx[j];
1659
inx[j] = tmp;
1660
1661
change_inx = _FALSE;
1662
}
1663
}
1664
}
1665
}
1666
1667
for (i = 0; i < 4; i++) {
1668
pxmitpriv->wmm_para_seq[i] = inx[i];
1669
RTW_INFO("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]);
1670
}
1671
1672
#ifdef CONFIG_WMMPS_STA
1673
/* if AP supports UAPSD function, driver must set each uapsd TID to coresponding mac register 0x693 */
1674
if (pmlmeinfo->WMM_param.QoS_info & AP_SUPPORTED_UAPSD) {
1675
pqospriv->uapsd_ap_supported = 1;
1676
rtw_hal_set_hwreg(padapter, HW_VAR_UAPSD_TID, NULL);
1677
}
1678
#endif /* CONFIG_WMMPS_STA */
1679
}
1680
}
1681
1682
static void bwmode_update_check(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1683
{
1684
#ifdef CONFIG_80211N_HT
1685
unsigned char new_bwmode;
1686
unsigned char new_ch_offset;
1687
struct HT_info_element *pHT_info;
1688
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1689
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1690
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1691
struct registry_priv *pregistrypriv = &padapter->registrypriv;
1692
struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1693
u8 cbw40_enable = 0;
1694
1695
if (!pIE)
1696
return;
1697
1698
if (phtpriv->ht_option == _FALSE)
1699
return;
1700
1701
if (pmlmeext->cur_bwmode >= CHANNEL_WIDTH_80)
1702
return;
1703
1704
if (pIE->Length > sizeof(struct HT_info_element))
1705
return;
1706
1707
pHT_info = (struct HT_info_element *)pIE->data;
1708
1709
if (hal_chk_bw_cap(padapter, BW_CAP_40M)) {
1710
if (pmlmeext->cur_channel > 14) {
1711
if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
1712
cbw40_enable = 1;
1713
} else {
1714
if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
1715
cbw40_enable = 1;
1716
}
1717
}
1718
1719
if ((pHT_info->infos[0] & BIT(2)) && cbw40_enable) {
1720
new_bwmode = CHANNEL_WIDTH_40;
1721
1722
switch (pHT_info->infos[0] & 0x3) {
1723
case 1:
1724
new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
1725
break;
1726
1727
case 3:
1728
new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
1729
break;
1730
1731
default:
1732
new_bwmode = CHANNEL_WIDTH_20;
1733
new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1734
break;
1735
}
1736
} else {
1737
new_bwmode = CHANNEL_WIDTH_20;
1738
new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1739
}
1740
1741
1742
if ((new_bwmode != pmlmeext->cur_bwmode || new_ch_offset != pmlmeext->cur_ch_offset)
1743
&& new_bwmode < pmlmeext->cur_bwmode
1744
) {
1745
pmlmeinfo->bwmode_updated = _TRUE;
1746
1747
pmlmeext->cur_bwmode = new_bwmode;
1748
pmlmeext->cur_ch_offset = new_ch_offset;
1749
1750
/* update HT info also */
1751
HT_info_handler(padapter, pIE);
1752
} else
1753
pmlmeinfo->bwmode_updated = _FALSE;
1754
1755
1756
if (_TRUE == pmlmeinfo->bwmode_updated) {
1757
struct sta_info *psta;
1758
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
1759
struct sta_priv *pstapriv = &padapter->stapriv;
1760
1761
/* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
1762
1763
1764
/* update ap's stainfo */
1765
psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
1766
if (psta) {
1767
struct ht_priv *phtpriv_sta = &psta->htpriv;
1768
1769
if (phtpriv_sta->ht_option) {
1770
/* bwmode */
1771
psta->cmn.bw_mode = pmlmeext->cur_bwmode;
1772
phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
1773
} else {
1774
psta->cmn.bw_mode = CHANNEL_WIDTH_20;
1775
phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1776
}
1777
1778
rtw_dm_ra_mask_wk_cmd(padapter, (u8 *)psta);
1779
}
1780
1781
/* pmlmeinfo->bwmode_updated = _FALSE; */ /* bwmode_updated done, reset it! */
1782
}
1783
#endif /* CONFIG_80211N_HT */
1784
}
1785
1786
#ifdef ROKU_PRIVATE
1787
void Supported_rate_infra_ap(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1788
{
1789
unsigned int i;
1790
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1791
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1792
1793
if (pIE == NULL)
1794
return;
1795
1796
for (i = 0 ; i < pIE->Length; i++)
1797
pmlmeinfo->SupportedRates_infra_ap[i] = (pIE->data[i]);
1798
1799
}
1800
1801
void Extended_Supported_rate_infra_ap(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1802
{
1803
unsigned int i, j;
1804
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1805
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1806
1807
if (pIE == NULL)
1808
return;
1809
1810
if (pIE->Length > 0) {
1811
for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
1812
if (pmlmeinfo->SupportedRates_infra_ap[i] == 0)
1813
break;
1814
}
1815
for (j = 0; j < pIE->Length; j++)
1816
pmlmeinfo->SupportedRates_infra_ap[i+j] = (pIE->data[j]);
1817
}
1818
1819
}
1820
1821
void HT_get_ss_from_mcs_set(u8 *mcs_set, u8 *Rx_ss)
1822
{
1823
u8 i, j;
1824
u8 r_ss = 0, t_ss = 0;
1825
1826
for (i = 0; i < 4; i++) {
1827
if ((mcs_set[3-i] & 0xff) != 0x00) {
1828
r_ss = 4-i;
1829
break;
1830
}
1831
}
1832
1833
*Rx_ss = r_ss;
1834
}
1835
1836
void HT_caps_handler_infra_ap(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1837
{
1838
unsigned int i;
1839
u8 cur_stbc_cap_infra_ap = 0;
1840
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1841
struct ht_priv_infra_ap *phtpriv = &pmlmepriv->htpriv_infra_ap;
1842
1843
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1844
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1845
1846
if (pIE == NULL)
1847
return;
1848
1849
pmlmeinfo->ht_vht_received |= BIT(0);
1850
1851
/*copy MCS_SET*/
1852
for (i = 3; i < 19; i++)
1853
phtpriv->MCS_set_infra_ap[i-3] = (pIE->data[i]);
1854
1855
/*get number of stream from mcs set*/
1856
HT_get_ss_from_mcs_set(phtpriv->MCS_set_infra_ap, &phtpriv->Rx_ss_infra_ap);
1857
1858
phtpriv->rx_highest_data_rate_infra_ap = le16_to_cpu(GET_HT_CAP_ELE_RX_HIGHEST_DATA_RATE(pIE->data));
1859
1860
phtpriv->ldpc_cap_infra_ap = GET_HT_CAP_ELE_LDPC_CAP(pIE->data);
1861
1862
if (GET_HT_CAP_ELE_RX_STBC(pIE->data))
1863
SET_FLAG(cur_stbc_cap_infra_ap, STBC_HT_ENABLE_RX);
1864
if (GET_HT_CAP_ELE_TX_STBC(pIE->data))
1865
SET_FLAG(cur_stbc_cap_infra_ap, STBC_HT_ENABLE_TX);
1866
phtpriv->stbc_cap_infra_ap = cur_stbc_cap_infra_ap;
1867
1868
/*store ap info SGI 20m 40m*/
1869
phtpriv->sgi_20m_infra_ap = GET_HT_CAP_ELE_SHORT_GI20M(pIE->data);
1870
phtpriv->sgi_40m_infra_ap = GET_HT_CAP_ELE_SHORT_GI40M(pIE->data);
1871
1872
/*store ap info for supported channel bandwidth*/
1873
phtpriv->channel_width_infra_ap = GET_HT_CAP_ELE_CHL_WIDTH(pIE->data);
1874
}
1875
#endif /* ROKU_PRIVATE */
1876
1877
void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1878
{
1879
#ifdef CONFIG_80211N_HT
1880
unsigned int i;
1881
u8 max_AMPDU_len, min_MPDU_spacing;
1882
u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0, tx_nss = 0;
1883
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1884
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1885
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1886
struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1887
#ifdef CONFIG_DISABLE_MCS13TO15
1888
struct registry_priv *pregistrypriv = &padapter->registrypriv;
1889
#endif
1890
1891
if (pIE == NULL)
1892
return;
1893
1894
if (phtpriv->ht_option == _FALSE)
1895
return;
1896
1897
pmlmeinfo->HT_caps_enable = 1;
1898
1899
for (i = 0; i < (pIE->Length); i++) {
1900
if (i != 2) {
1901
/* Commented by Albert 2010/07/12 */
1902
/* Got the endian issue here. */
1903
pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]);
1904
} else {
1905
/* AMPDU Parameters field */
1906
1907
/* Get MIN of MAX AMPDU Length Exp */
1908
if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (pIE->data[i] & 0x3))
1909
max_AMPDU_len = (pIE->data[i] & 0x3);
1910
else
1911
max_AMPDU_len = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3);
1912
1913
/* Get MAX of MIN MPDU Start Spacing */
1914
if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) > (pIE->data[i] & 0x1c))
1915
min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c);
1916
else
1917
min_MPDU_spacing = (pIE->data[i] & 0x1c);
1918
1919
pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para = max_AMPDU_len | min_MPDU_spacing;
1920
}
1921
}
1922
1923
/* Commented by Albert 2010/07/12 */
1924
/* Have to handle the endian issue after copying. */
1925
/* HT_ext_caps didn't be used yet. */
1926
pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
1927
pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps = le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps);
1928
1929
/* update the MCS set */
1930
for (i = 0; i < 16; i++)
1931
pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i];
1932
1933
tx_nss = GET_HAL_TX_NSS(padapter);
1934
1935
switch (tx_nss) {
1936
case 1:
1937
set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R);
1938
break;
1939
case 2:
1940
#ifdef CONFIG_DISABLE_MCS13TO15
1941
if (pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1)
1942
set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R_13TO15_OFF);
1943
else
1944
#endif
1945
set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R);
1946
break;
1947
case 3:
1948
set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_3R);
1949
break;
1950
case 4:
1951
set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_4R);
1952
break;
1953
default:
1954
RTW_WARN("rf_type:%d or tx_nss:%u is not expected\n", GET_HAL_RFPATH(padapter), tx_nss);
1955
}
1956
1957
if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1958
/* Config STBC setting */
1959
if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAP_ELE_RX_STBC(pIE->data)) {
1960
SET_FLAG(cur_stbc_cap, STBC_HT_ENABLE_TX);
1961
RTW_INFO("Enable HT Tx STBC !\n");
1962
}
1963
phtpriv->stbc_cap = cur_stbc_cap;
1964
1965
#ifdef CONFIG_BEAMFORMING
1966
/* Config Tx beamforming setting */
1967
if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&
1968
GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pIE->data)) {
1969
SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
1970
/* Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/
1971
SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pIE->data) << 6);
1972
}
1973
1974
if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) &&
1975
GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pIE->data)) {
1976
SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
1977
/* Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/
1978
SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pIE->data) << 4);
1979
}
1980
phtpriv->beamform_cap = cur_beamform_cap;
1981
if (cur_beamform_cap)
1982
RTW_INFO("AP HT Beamforming Cap = 0x%02X\n", cur_beamform_cap);
1983
#endif /*CONFIG_BEAMFORMING*/
1984
} else {
1985
/*WIFI_STATION_STATEorI_ADHOC_STATE or WIFI_ADHOC_MASTER_STATE*/
1986
/* Config LDPC Coding Capability */
1987
if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX) && GET_HT_CAP_ELE_LDPC_CAP(pIE->data)) {
1988
SET_FLAG(cur_ldpc_cap, (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX));
1989
RTW_INFO("Enable HT Tx LDPC!\n");
1990
}
1991
phtpriv->ldpc_cap = cur_ldpc_cap;
1992
1993
/* Config STBC setting */
1994
if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAP_ELE_RX_STBC(pIE->data)) {
1995
SET_FLAG(cur_stbc_cap, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX));
1996
RTW_INFO("Enable HT Tx STBC!\n");
1997
}
1998
phtpriv->stbc_cap = cur_stbc_cap;
1999
2000
#ifdef CONFIG_BEAMFORMING
2001
#ifdef RTW_BEAMFORMING_VERSION_2
2002
/* Config beamforming setting */
2003
if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) &&
2004
GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pIE->data)) {
2005
SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
2006
/* Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/
2007
SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pIE->data) << 6);
2008
}
2009
2010
if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&
2011
GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pIE->data)) {
2012
SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
2013
/* Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/
2014
SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pIE->data) << 4);
2015
}
2016
#else /* !RTW_BEAMFORMING_VERSION_2 */
2017
/* Config Tx beamforming setting */
2018
if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) &&
2019
GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pIE->data)) {
2020
SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
2021
/* Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/
2022
SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pIE->data) << 6);
2023
}
2024
2025
if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&
2026
GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pIE->data)) {
2027
SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
2028
/* Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/
2029
SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pIE->data) << 4);
2030
}
2031
#endif /* !RTW_BEAMFORMING_VERSION_2 */
2032
phtpriv->beamform_cap = cur_beamform_cap;
2033
if (cur_beamform_cap)
2034
RTW_INFO("Client HT Beamforming Cap = 0x%02X\n", cur_beamform_cap);
2035
#endif /*CONFIG_BEAMFORMING*/
2036
}
2037
2038
#endif /* CONFIG_80211N_HT */
2039
}
2040
2041
void HT_info_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
2042
{
2043
#ifdef CONFIG_80211N_HT
2044
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2045
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2046
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2047
struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2048
2049
if (pIE == NULL)
2050
return;
2051
2052
if (phtpriv->ht_option == _FALSE)
2053
return;
2054
2055
2056
if (pIE->Length > sizeof(struct HT_info_element))
2057
return;
2058
2059
pmlmeinfo->HT_info_enable = 1;
2060
_rtw_memcpy(&(pmlmeinfo->HT_info), pIE->data, pIE->Length);
2061
#endif /* CONFIG_80211N_HT */
2062
return;
2063
}
2064
2065
void HTOnAssocRsp(_adapter *padapter)
2066
{
2067
unsigned char max_AMPDU_len;
2068
unsigned char min_MPDU_spacing;
2069
/* struct registry_priv *pregpriv = &padapter->registrypriv; */
2070
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2071
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2072
2073
RTW_INFO("%s\n", __FUNCTION__);
2074
2075
if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
2076
pmlmeinfo->HT_enable = 1;
2077
else {
2078
pmlmeinfo->HT_enable = 0;
2079
/* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
2080
return;
2081
}
2082
2083
/* handle A-MPDU parameter field */
2084
/*
2085
AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
2086
AMPDU_para [4:2]:Min MPDU Start Spacing
2087
*/
2088
max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
2089
2090
min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
2091
2092
rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
2093
#ifdef CONFIG_80211N_HT
2094
rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
2095
#endif /* CONFIG_80211N_HT */
2096
#if 0 /* move to rtw_update_ht_cap() */
2097
if ((pregpriv->bw_mode > 0) &&
2098
(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) &&
2099
(pmlmeinfo->HT_info.infos[0] & BIT(2))) {
2100
/* switch to the 40M Hz mode accoring to the AP */
2101
pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;
2102
switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
2103
case EXTCHNL_OFFSET_UPPER:
2104
pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
2105
break;
2106
2107
case EXTCHNL_OFFSET_LOWER:
2108
pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
2109
break;
2110
2111
default:
2112
pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2113
break;
2114
}
2115
}
2116
#endif
2117
2118
/* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
2119
2120
#if 0 /* move to rtw_update_ht_cap() */
2121
/* */
2122
/* Config SM Power Save setting */
2123
/* */
2124
pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
2125
if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) {
2126
#if 0
2127
u8 i;
2128
/* update the MCS rates */
2129
for (i = 0; i < 16; i++)
2130
pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
2131
#endif
2132
RTW_INFO("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __FUNCTION__);
2133
}
2134
2135
/* */
2136
/* Config current HT Protection mode. */
2137
/* */
2138
pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
2139
#endif
2140
2141
}
2142
2143
void ERP_IE_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
2144
{
2145
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2146
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2147
2148
if (pIE->Length > 1)
2149
return;
2150
2151
pmlmeinfo->ERP_enable = 1;
2152
_rtw_memcpy(&(pmlmeinfo->ERP_IE), pIE->data, pIE->Length);
2153
}
2154
2155
void VCS_update(_adapter *padapter, struct sta_info *psta)
2156
{
2157
struct registry_priv *pregpriv = &padapter->registrypriv;
2158
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2159
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2160
2161
switch (pregpriv->vrtl_carrier_sense) { /* 0:off 1:on 2:auto */
2162
case 0: /* off */
2163
psta->rtsen = 0;
2164
psta->cts2self = 0;
2165
break;
2166
2167
case 1: /* on */
2168
if (pregpriv->vcs_type == 1) { /* 1:RTS/CTS 2:CTS to self */
2169
psta->rtsen = 1;
2170
psta->cts2self = 0;
2171
} else {
2172
psta->rtsen = 0;
2173
psta->cts2self = 1;
2174
}
2175
break;
2176
2177
case 2: /* auto */
2178
default:
2179
if (((pmlmeinfo->ERP_enable) && (pmlmeinfo->ERP_IE & BIT(1)))
2180
/*||(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)*/
2181
) {
2182
if (pregpriv->vcs_type == 1) {
2183
psta->rtsen = 1;
2184
psta->cts2self = 0;
2185
} else {
2186
psta->rtsen = 0;
2187
psta->cts2self = 1;
2188
}
2189
} else {
2190
psta->rtsen = 0;
2191
psta->cts2self = 0;
2192
}
2193
break;
2194
}
2195
}
2196
2197
void update_ldpc_stbc_cap(struct sta_info *psta)
2198
{
2199
#ifdef CONFIG_80211N_HT
2200
2201
#ifdef CONFIG_80211AC_VHT
2202
if (psta->vhtpriv.vht_option) {
2203
if (TEST_FLAG(psta->vhtpriv.ldpc_cap, LDPC_VHT_ENABLE_TX))
2204
psta->cmn.ldpc_en = VHT_LDPC_EN;
2205
else
2206
psta->cmn.ldpc_en = 0;
2207
2208
if (TEST_FLAG(psta->vhtpriv.stbc_cap, STBC_VHT_ENABLE_TX))
2209
psta->cmn.stbc_en = VHT_STBC_EN;
2210
else
2211
psta->cmn.stbc_en = 0;
2212
} else
2213
#endif /* CONFIG_80211AC_VHT */
2214
if (psta->htpriv.ht_option) {
2215
if (TEST_FLAG(psta->htpriv.ldpc_cap, LDPC_HT_ENABLE_TX))
2216
psta->cmn.ldpc_en = HT_LDPC_EN;
2217
else
2218
psta->cmn.ldpc_en = 0;
2219
2220
if (TEST_FLAG(psta->htpriv.stbc_cap, STBC_HT_ENABLE_TX))
2221
psta->cmn.stbc_en = HT_STBC_EN;
2222
else
2223
psta->cmn.stbc_en = 0;
2224
} else {
2225
psta->cmn.ldpc_en = 0;
2226
psta->cmn.stbc_en = 0;
2227
}
2228
2229
#endif /* CONFIG_80211N_HT */
2230
}
2231
2232
int check_ielen(u8 *start, uint len)
2233
{
2234
int left = len;
2235
u8 *pos = start;
2236
u8 id, elen;
2237
2238
while (left >= 2) {
2239
id = *pos++;
2240
elen = *pos++;
2241
left -= 2;
2242
2243
if (elen > left) {
2244
RTW_INFO("IEEE 802.11 element parse failed (id=%d elen=%d left=%lu)\n",
2245
id, elen, (unsigned long) left);
2246
return _FALSE;
2247
}
2248
if ((id == WLAN_EID_VENDOR_SPECIFIC) && (elen < 3))
2249
return _FALSE;
2250
2251
left -= elen;
2252
pos += elen;
2253
}
2254
if (left)
2255
return _FALSE;
2256
2257
return _TRUE;
2258
}
2259
2260
int validate_beacon_len(u8 *pframe, u32 len)
2261
{
2262
u8 ie_offset = _BEACON_IE_OFFSET_ + sizeof(struct rtw_ieee80211_hdr_3addr);
2263
2264
if (len < ie_offset) {
2265
RTW_INFO("%s: incorrect beacon length(%d)\n", __func__, len);
2266
return _FALSE;
2267
}
2268
2269
if (check_ielen(pframe + ie_offset, len - ie_offset) == _FALSE)
2270
return _FALSE;
2271
2272
return _TRUE;
2273
}
2274
2275
2276
u8 support_rate_ranges[] = {
2277
IEEE80211_CCK_RATE_1MB,
2278
IEEE80211_CCK_RATE_2MB,
2279
IEEE80211_CCK_RATE_5MB,
2280
IEEE80211_CCK_RATE_11MB,
2281
IEEE80211_OFDM_RATE_6MB,
2282
IEEE80211_OFDM_RATE_9MB,
2283
IEEE80211_OFDM_RATE_12MB,
2284
IEEE80211_OFDM_RATE_18MB,
2285
IEEE80211_OFDM_RATE_24MB,
2286
IEEE80211_OFDM_RATE_36MB,
2287
IEEE80211_OFDM_RATE_48MB,
2288
IEEE80211_OFDM_RATE_54MB,
2289
};
2290
2291
inline bool match_ranges(u16 EID, u32 value)
2292
{
2293
int i;
2294
int nr_range;
2295
2296
switch (EID) {
2297
case _EXT_SUPPORTEDRATES_IE_:
2298
case _SUPPORTEDRATES_IE_:
2299
nr_range = sizeof(support_rate_ranges)/sizeof(u8);
2300
for (i = 0; i < nr_range; i++) {
2301
/* clear bit7 before searching. */
2302
value &= ~BIT(7);
2303
if (value == support_rate_ranges[i])
2304
return _TRUE;
2305
}
2306
break;
2307
default:
2308
break;
2309
};
2310
return _FALSE;
2311
}
2312
2313
/*
2314
* rtw_validate_value: validate the IE contain.
2315
*
2316
* Input :
2317
* EID : Element ID
2318
* p : IE buffer (without EID & length)
2319
* len : IE length
2320
* return:
2321
* _TRUE : All Values are validated.
2322
* _FALSE : At least one value is NOT validated.
2323
*/
2324
bool rtw_validate_value(u16 EID, u8 *p, u16 len)
2325
{
2326
u8 rate;
2327
u32 i, nr_val;
2328
2329
switch (EID) {
2330
case _EXT_SUPPORTEDRATES_IE_:
2331
case _SUPPORTEDRATES_IE_:
2332
nr_val = len;
2333
for (i=0; i<nr_val; i++) {
2334
rate = *(p+i);
2335
if (match_ranges(EID, rate) == _FALSE)
2336
return _FALSE;
2337
}
2338
break;
2339
default:
2340
break;
2341
};
2342
return _TRUE;
2343
}
2344
2345
inline bool hidden_ssid_ap(WLAN_BSSID_EX *snetwork)
2346
{
2347
return ((snetwork->Ssid.SsidLength == 0) ||
2348
is_all_null(snetwork->Ssid.Ssid, snetwork->Ssid.SsidLength) == _TRUE);
2349
}
2350
2351
/*
2352
Get SSID if this ilegal frame(probe resp) comes from a hidden SSID AP.
2353
Update the SSID to the corresponding pnetwork in scan queue.
2354
*/
2355
void rtw_absorb_ssid_ifneed(_adapter *padapter, WLAN_BSSID_EX *bssid, u8 *pframe)
2356
{
2357
struct wlan_network *scanned = NULL;
2358
WLAN_BSSID_EX *snetwork;
2359
u8 ie_offset, *p=NULL, *next_ie=NULL, *mac = get_addr2_ptr(pframe);
2360
sint ssid_len_ori;
2361
u32 remain_len = 0;
2362
u8 backupIE[MAX_IE_SZ];
2363
u16 subtype = get_frame_sub_type(pframe);
2364
_irqL irqL;
2365
2366
if ((!bssid) || (!pframe))
2367
return;
2368
2369
if (subtype == WIFI_BEACON) {
2370
bssid->Reserved[0] = BSS_TYPE_BCN;
2371
ie_offset = _BEACON_IE_OFFSET_;
2372
} else {
2373
/* FIXME : more type */
2374
if (subtype == WIFI_PROBERSP) {
2375
ie_offset = _PROBERSP_IE_OFFSET_;
2376
bssid->Reserved[0] = BSS_TYPE_PROB_RSP;
2377
} else if (subtype == WIFI_PROBEREQ) {
2378
ie_offset = _PROBEREQ_IE_OFFSET_;
2379
bssid->Reserved[0] = BSS_TYPE_PROB_REQ;
2380
} else {
2381
bssid->Reserved[0] = BSS_TYPE_UNDEF;
2382
ie_offset = _FIXED_IE_LENGTH_;
2383
}
2384
}
2385
2386
_enter_critical_bh(&padapter->mlmepriv.scanned_queue.lock, &irqL);
2387
scanned = _rtw_find_network(&padapter->mlmepriv.scanned_queue, mac);
2388
if (!scanned) {
2389
_exit_critical_bh(&padapter->mlmepriv.scanned_queue.lock, &irqL);
2390
return;
2391
}
2392
2393
snetwork = &(scanned->network);
2394
/* scan queue records as Hidden SSID && Input frame is NOT Hidden SSID */
2395
if (hidden_ssid_ap(snetwork) && !hidden_ssid_ap(bssid)) {
2396
p = rtw_get_ie(snetwork->IEs+ie_offset, _SSID_IE_, &ssid_len_ori, snetwork->IELength-ie_offset);
2397
if (!p) {
2398
_exit_critical_bh(&padapter->mlmepriv.scanned_queue.lock, &irqL);
2399
return;
2400
}
2401
next_ie = p + 2 + ssid_len_ori;
2402
remain_len = snetwork->IELength - (next_ie - snetwork->IEs);
2403
scanned->network.Ssid.SsidLength = bssid->Ssid.SsidLength;
2404
_rtw_memcpy(scanned->network.Ssid.Ssid, bssid->Ssid.Ssid, bssid->Ssid.SsidLength);
2405
2406
//update pnetwork->ssid, pnetwork->ssidlen
2407
_rtw_memcpy(backupIE, next_ie, remain_len);
2408
*(p+1) = bssid->Ssid.SsidLength;
2409
_rtw_memcpy(p+2, bssid->Ssid.Ssid, bssid->Ssid.SsidLength);
2410
_rtw_memcpy(p+2+bssid->Ssid.SsidLength, backupIE, remain_len);
2411
snetwork->IELength += bssid->Ssid.SsidLength;
2412
}
2413
_exit_critical_bh(&padapter->mlmepriv.scanned_queue.lock, &irqL);
2414
}
2415
2416
#ifdef DBG_RX_BCN
2417
void rtw_debug_rx_bcn(_adapter *adapter, u8 *pframe, u32 packet_len)
2418
{
2419
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
2420
struct mlme_ext_info *mlmeinfo = &(pmlmeext->mlmext_info);
2421
u16 sn = ((struct rtw_ieee80211_hdr_3addr *)pframe)->seq_ctl >> 4;
2422
u64 tsf, tsf_offset;
2423
u8 dtim_cnt, dtim_period, tim_bmap, tim_pvbit;
2424
2425
update_TSF(pmlmeext, pframe, packet_len);
2426
tsf = pmlmeext->TSFValue;
2427
tsf_offset = rtw_modular64(pmlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024));
2428
2429
/*get TIM IE*/
2430
/*DTIM Count*/
2431
dtim_cnt = pmlmeext->tim[0];
2432
/*DTIM Period*/
2433
dtim_period = pmlmeext->tim[1];
2434
/*Bitmap*/
2435
tim_bmap = pmlmeext->tim[2];
2436
/*Partial VBitmap AID 0 ~ 7*/
2437
tim_pvbit = pmlmeext->tim[3];
2438
2439
RTW_INFO("[BCN] SN-%d, TSF-%lld(us), offset-%lld, bcn_interval-%d DTIM-%d[%d] bitmap-0x%02x-0x%02x\n",
2440
sn, tsf, tsf_offset, mlmeinfo->bcn_interval, dtim_period, dtim_cnt, tim_bmap, tim_pvbit);
2441
}
2442
#endif
2443
2444
/*
2445
* rtw_get_bcn_keys: get beacon keys from recv frame
2446
*
2447
* TODO:
2448
* WLAN_EID_COUNTRY
2449
* WLAN_EID_ERP_INFO
2450
* WLAN_EID_CHANNEL_SWITCH
2451
* WLAN_EID_PWR_CONSTRAINT
2452
*/
2453
int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len,
2454
struct beacon_keys *recv_beacon)
2455
{
2456
int left;
2457
u16 capability;
2458
unsigned char *pos;
2459
struct rtw_ieee802_11_elems elems;
2460
2461
_rtw_memset(recv_beacon, 0, sizeof(*recv_beacon));
2462
2463
/* checking capabilities */
2464
capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 10));
2465
2466
/* checking IEs */
2467
left = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_;
2468
pos = pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_;
2469
if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed)
2470
return _FALSE;
2471
2472
if (elems.ht_capabilities) {
2473
if (elems.ht_capabilities_len != 26)
2474
return _FALSE;
2475
}
2476
2477
if (elems.ht_operation) {
2478
if (elems.ht_operation_len != 22)
2479
return _FALSE;
2480
}
2481
2482
if (elems.vht_capabilities) {
2483
if (elems.vht_capabilities_len != 12)
2484
return _FALSE;
2485
}
2486
2487
if (elems.vht_operation) {
2488
if (elems.vht_operation_len != 5)
2489
return _FALSE;
2490
}
2491
2492
if (rtw_ies_get_supported_rate(pos, left, recv_beacon->rate_set, &recv_beacon->rate_num) == _FAIL)
2493
return _FALSE;
2494
2495
if (cckratesonly_included(recv_beacon->rate_set, recv_beacon->rate_num) == _TRUE)
2496
recv_beacon->proto_cap |= PROTO_CAP_11B;
2497
else if (cckrates_included(recv_beacon->rate_set, recv_beacon->rate_num) == _TRUE)
2498
recv_beacon->proto_cap |= PROTO_CAP_11B | PROTO_CAP_11G;
2499
else
2500
recv_beacon->proto_cap |= PROTO_CAP_11G;
2501
2502
if (elems.ht_capabilities && elems.ht_operation)
2503
recv_beacon->proto_cap |= PROTO_CAP_11N;
2504
2505
if (elems.vht_capabilities && elems.vht_operation)
2506
recv_beacon->proto_cap |= PROTO_CAP_11AC;
2507
2508
/* check bw and channel offset */
2509
rtw_ies_get_chbw(pos, left, &recv_beacon->ch, &recv_beacon->bw, &recv_beacon->offset, 1, 1);
2510
if (!recv_beacon->ch) {
2511
/* we don't find channel IE, so don't check it */
2512
/* RTW_INFO("Oops: %s we don't find channel IE, so don't check it\n", __func__); */
2513
recv_beacon->ch = Adapter->mlmeextpriv.cur_channel;
2514
}
2515
2516
/* checking SSID */
2517
if (elems.ssid) {
2518
if (elems.ssid_len > sizeof(recv_beacon->ssid))
2519
return _FALSE;
2520
2521
_rtw_memcpy(recv_beacon->ssid, elems.ssid, elems.ssid_len);
2522
recv_beacon->ssid_len = elems.ssid_len;
2523
}
2524
2525
/* checking RSN first */
2526
if (elems.rsn_ie && elems.rsn_ie_len) {
2527
recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA2;
2528
rtw_parse_wpa2_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
2529
&recv_beacon->group_cipher, &recv_beacon->pairwise_cipher,
2530
&recv_beacon->akm, NULL);
2531
}
2532
/* checking WPA secon */
2533
else if (elems.wpa_ie && elems.wpa_ie_len) {
2534
recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA;
2535
rtw_parse_wpa_ie(elems.wpa_ie - 2, elems.wpa_ie_len + 2,
2536
&recv_beacon->group_cipher, &recv_beacon->pairwise_cipher,
2537
&recv_beacon->akm);
2538
} else if (capability & BIT(4))
2539
recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WEP;
2540
2541
if (elems.tim && elems.tim_len) {
2542
struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
2543
2544
#ifdef DBG_RX_BCN
2545
_rtw_memcpy(pmlmeext->tim, elems.tim, 4);
2546
#endif
2547
pmlmeext->dtim = elems.tim[1];
2548
}
2549
2550
return _TRUE;
2551
}
2552
2553
void rtw_dump_bcn_keys(void *sel, struct beacon_keys *recv_beacon)
2554
{
2555
u8 ssid[IW_ESSID_MAX_SIZE + 1];
2556
2557
_rtw_memcpy(ssid, recv_beacon->ssid, recv_beacon->ssid_len);
2558
ssid[recv_beacon->ssid_len] = '\0';
2559
2560
RTW_PRINT_SEL(sel, "ssid = %s (len = %u)\n", ssid, recv_beacon->ssid_len);
2561
RTW_PRINT_SEL(sel, "ch = %u,%u,%u\n"
2562
, recv_beacon->ch, recv_beacon->bw, recv_beacon->offset);
2563
RTW_PRINT_SEL(sel, "proto_cap = 0x%02x\n", recv_beacon->proto_cap);
2564
RTW_MAP_DUMP_SEL(sel, "rate_set = "
2565
, recv_beacon->rate_set, recv_beacon->rate_num);
2566
RTW_PRINT_SEL(sel, "sec = %d, group = 0x%x, pair = 0x%x, akm = 0x%08x\n"
2567
, recv_beacon->encryp_protocol, recv_beacon->group_cipher
2568
, recv_beacon->pairwise_cipher, recv_beacon->akm);
2569
}
2570
2571
int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len)
2572
{
2573
#define BCNKEY_VERIFY_PROTO_CAP 0
2574
#define BCNKEY_VERIFY_WHOLE_RATE_SET 0
2575
2576
u8 *pbssid = GetAddr3Ptr(pframe);
2577
struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
2578
struct wlan_network *cur_network = &(Adapter->mlmepriv.cur_network);
2579
struct beacon_keys *cur_beacon = &pmlmepriv->cur_beacon_keys;
2580
struct beacon_keys recv_beacon;
2581
int ret = 0;
2582
2583
if (is_client_associated_to_ap(Adapter) == _FALSE)
2584
goto exit_success;
2585
2586
if (rtw_get_bcn_keys(Adapter, pframe, packet_len, &recv_beacon) == _FALSE)
2587
goto exit_success; /* parsing failed => broken IE */
2588
2589
#ifdef DBG_RX_BCN
2590
rtw_debug_bcn(Adapter, pframe, packet_len);
2591
#endif
2592
2593
#ifdef CONFIG_BCN_CNT_CONFIRM_HDL
2594
if (_rtw_memcmp(&recv_beacon, cur_beacon, sizeof(recv_beacon)) == _TRUE)
2595
pmlmepriv->new_beacon_cnts = 0;
2596
else if ((pmlmepriv->new_beacon_cnts == 0) ||
2597
_rtw_memcmp(&recv_beacon, &pmlmepriv->new_beacon_keys, sizeof(recv_beacon)) == _FALSE) {
2598
RTW_DBG("%s: start new beacon (seq=%d)\n", __func__, GetSequence(pframe));
2599
2600
if (pmlmepriv->new_beacon_cnts == 0) {
2601
RTW_ERR("%s: cur beacon key\n", __func__);
2602
RTW_DBG_EXPR(rtw_dump_bcn_keys(RTW_DBGDUMP, cur_beacon));
2603
}
2604
2605
RTW_DBG("%s: new beacon key\n", __func__);
2606
RTW_DBG_EXPR(rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon));
2607
2608
_rtw_memcpy(&pmlmepriv->new_beacon_keys, &recv_beacon, sizeof(recv_beacon));
2609
pmlmepriv->new_beacon_cnts = 1;
2610
} else {
2611
RTW_DBG("%s: new beacon again (seq=%d)\n", __func__, GetSequence(pframe));
2612
pmlmepriv->new_beacon_cnts++;
2613
}
2614
2615
/* if counter >= max, it means beacon is changed really */
2616
if (pmlmepriv->new_beacon_cnts >= new_bcn_max)
2617
#else
2618
if (_rtw_memcmp(&recv_beacon, cur_beacon, sizeof(recv_beacon)) == _FALSE)
2619
#endif
2620
{
2621
struct beacon_keys tmp_beacon;
2622
2623
RTW_INFO(FUNC_ADPT_FMT" new beacon occur!!\n", FUNC_ADPT_ARG(Adapter));
2624
RTW_INFO(FUNC_ADPT_FMT" cur beacon key:\n", FUNC_ADPT_ARG(Adapter));
2625
rtw_dump_bcn_keys(RTW_DBGDUMP, cur_beacon);
2626
RTW_INFO(FUNC_ADPT_FMT" new beacon key:\n", FUNC_ADPT_ARG(Adapter));
2627
rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon);
2628
2629
if (!rtw_is_chbw_grouped(cur_beacon->ch, cur_beacon->bw, cur_beacon->offset
2630
, recv_beacon.ch, recv_beacon.bw, recv_beacon.offset))
2631
goto exit;
2632
2633
_rtw_memcpy(&tmp_beacon, cur_beacon, sizeof(tmp_beacon));
2634
2635
/* check fields excluding below */
2636
tmp_beacon.ch = recv_beacon.ch;
2637
tmp_beacon.bw = recv_beacon.bw;
2638
tmp_beacon.offset = recv_beacon.offset;
2639
if (!BCNKEY_VERIFY_PROTO_CAP)
2640
tmp_beacon.proto_cap = recv_beacon.proto_cap;
2641
if (!BCNKEY_VERIFY_WHOLE_RATE_SET) {
2642
tmp_beacon.rate_num = recv_beacon.rate_num;
2643
_rtw_memcpy(tmp_beacon.rate_set, recv_beacon.rate_set, 12);
2644
}
2645
if (_rtw_memcmp(&tmp_beacon, &recv_beacon, sizeof(recv_beacon)) == _FALSE)
2646
goto exit;
2647
2648
_rtw_memcpy(cur_beacon, &recv_beacon, sizeof(recv_beacon));
2649
#ifdef CONFIG_BCN_CNT_CONFIRM_HDL
2650
pmlmepriv->new_beacon_cnts = 0;
2651
#endif
2652
}
2653
2654
exit_success:
2655
ret = 1;
2656
2657
exit:
2658
return ret;
2659
}
2660
2661
void update_beacon_info(_adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta)
2662
{
2663
unsigned int i;
2664
unsigned int len;
2665
PNDIS_802_11_VARIABLE_IEs pIE;
2666
2667
#ifdef CONFIG_TDLS
2668
struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
2669
u8 tdls_prohibited[] = { 0x00, 0x00, 0x00, 0x00, 0x10 }; /* bit(38): TDLS_prohibited */
2670
#endif /* CONFIG_TDLS */
2671
2672
len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN);
2673
2674
for (i = 0; i < len;) {
2675
pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i);
2676
2677
switch (pIE->ElementID) {
2678
case _VENDOR_SPECIFIC_IE_:
2679
/* to update WMM paramter set while receiving beacon */
2680
if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6) && pIE->Length == WLAN_WMM_LEN) /* WMM */
2681
(WMM_param_handler(padapter, pIE)) ? report_wmm_edca_update(padapter) : 0;
2682
2683
break;
2684
2685
case _HT_EXTRA_INFO_IE_: /* HT info */
2686
/* HT_info_handler(padapter, pIE); */
2687
bwmode_update_check(padapter, pIE);
2688
break;
2689
#ifdef CONFIG_80211AC_VHT
2690
case EID_OpModeNotification:
2691
rtw_process_vht_op_mode_notify(padapter, pIE->data, psta);
2692
break;
2693
#endif /* CONFIG_80211AC_VHT */
2694
case _ERPINFO_IE_:
2695
ERP_IE_handler(padapter, pIE);
2696
VCS_update(padapter, psta);
2697
break;
2698
2699
#ifdef CONFIG_TDLS
2700
case _EXT_CAP_IE_:
2701
if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
2702
ptdlsinfo->ap_prohibited = _TRUE;
2703
if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
2704
ptdlsinfo->ch_switch_prohibited = _TRUE;
2705
break;
2706
#endif /* CONFIG_TDLS */
2707
default:
2708
break;
2709
}
2710
2711
i += (pIE->Length + 2);
2712
}
2713
}
2714
2715
#ifdef CONFIG_DFS
2716
void process_csa_ie(_adapter *padapter, u8 *ies, uint ies_len)
2717
{
2718
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
2719
unsigned int i;
2720
PNDIS_802_11_VARIABLE_IEs pIE;
2721
u8 ch = 0;
2722
2723
/* TODO: compare with scheduling CSA */
2724
if (rfctl->csa_ch)
2725
return;
2726
2727
for (i = 0; i + 1 < ies_len;) {
2728
pIE = (PNDIS_802_11_VARIABLE_IEs)(ies + i);
2729
2730
switch (pIE->ElementID) {
2731
case _CH_SWTICH_ANNOUNCE_:
2732
ch = *(pIE->data + 1);
2733
break;
2734
default:
2735
break;
2736
}
2737
2738
i += (pIE->Length + 2);
2739
}
2740
2741
if (ch != 0) {
2742
rfctl->csa_ch = ch;
2743
if (rtw_set_csa_cmd(padapter) != _SUCCESS)
2744
rfctl->csa_ch = 0;
2745
}
2746
}
2747
#endif /* CONFIG_DFS */
2748
2749
void parsing_eapol_packet(_adapter *padapter, u8 *key_payload, struct sta_info *psta, u8 trx_type)
2750
{
2751
struct security_priv *psecuritypriv = &(padapter->securitypriv);
2752
struct ieee802_1x_hdr *hdr;
2753
struct wpa_eapol_key *key;
2754
u16 key_info, key_data_length;
2755
char *trx_msg = trx_type ? "send" : "recv";
2756
2757
hdr = (struct ieee802_1x_hdr *) key_payload;
2758
2759
/* WPS - eapol start packet */
2760
if (hdr->type == 1 && hdr->length == 0) {
2761
RTW_INFO("%s eapol start packet\n", trx_msg);
2762
return;
2763
}
2764
2765
if (hdr->type == 0) { /* WPS - eapol packet */
2766
RTW_INFO("%s eapol packet\n", trx_msg);
2767
return;
2768
}
2769
2770
key = (struct wpa_eapol_key *) (hdr + 1);
2771
key_info = be16_to_cpu(*((u16 *)(key->key_info)));
2772
key_data_length = be16_to_cpu(*((u16 *)(key->key_data_length)));
2773
2774
if (!(key_info & WPA_KEY_INFO_KEY_TYPE)) { /* WPA group key handshake */
2775
if (key_info & WPA_KEY_INFO_ACK) {
2776
RTW_PRINT("%s eapol packet - WPA Group Key 1/2\n", trx_msg);
2777
} else {
2778
RTW_PRINT("%s eapol packet - WPA Group Key 2/2\n", trx_msg);
2779
2780
/* WPA key-handshake has completed */
2781
if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK)
2782
psta->state &= (~WIFI_UNDER_KEY_HANDSHAKE);
2783
}
2784
} else if (key_info & WPA_KEY_INFO_MIC) {
2785
if (key_data_length == 0)
2786
RTW_PRINT("%s eapol packet 4/4\n", trx_msg);
2787
else if (key_info & WPA_KEY_INFO_ACK)
2788
RTW_PRINT("%s eapol packet 3/4\n", trx_msg);
2789
else
2790
RTW_PRINT("%s eapol packet 2/4\n", trx_msg);
2791
} else {
2792
RTW_PRINT("%s eapol packet 1/4\n", trx_msg);
2793
}
2794
2795
}
2796
2797
unsigned int is_ap_in_tkip(_adapter *padapter)
2798
{
2799
u32 i;
2800
PNDIS_802_11_VARIABLE_IEs pIE;
2801
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2802
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2803
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
2804
2805
if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
2806
for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) {
2807
pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
2808
2809
switch (pIE->ElementID) {
2810
case _VENDOR_SPECIFIC_IE_:
2811
if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) && (_rtw_memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4)))
2812
return _TRUE;
2813
break;
2814
2815
case _RSN_IE_2_:
2816
if (_rtw_memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4))
2817
return _TRUE;
2818
2819
default:
2820
break;
2821
}
2822
2823
i += (pIE->Length + 2);
2824
}
2825
2826
return _FALSE;
2827
} else
2828
return _FALSE;
2829
2830
}
2831
2832
unsigned int should_forbid_n_rate(_adapter *padapter)
2833
{
2834
u32 i;
2835
PNDIS_802_11_VARIABLE_IEs pIE;
2836
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2837
WLAN_BSSID_EX *cur_network = &pmlmepriv->cur_network.network;
2838
2839
if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
2840
for (i = sizeof(NDIS_802_11_FIXED_IEs); i < cur_network->IELength;) {
2841
pIE = (PNDIS_802_11_VARIABLE_IEs)(cur_network->IEs + i);
2842
2843
switch (pIE->ElementID) {
2844
case _VENDOR_SPECIFIC_IE_:
2845
if (_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4) &&
2846
((_rtw_memcmp((pIE->data + 12), WPA_CIPHER_SUITE_CCMP, 4)) ||
2847
(_rtw_memcmp((pIE->data + 16), WPA_CIPHER_SUITE_CCMP, 4))))
2848
return _FALSE;
2849
break;
2850
2851
case _RSN_IE_2_:
2852
if ((_rtw_memcmp((pIE->data + 8), RSN_CIPHER_SUITE_CCMP, 4)) ||
2853
(_rtw_memcmp((pIE->data + 12), RSN_CIPHER_SUITE_CCMP, 4)))
2854
return _FALSE;
2855
2856
default:
2857
break;
2858
}
2859
2860
i += (pIE->Length + 2);
2861
}
2862
2863
return _TRUE;
2864
} else
2865
return _FALSE;
2866
2867
}
2868
2869
2870
unsigned int is_ap_in_wep(_adapter *padapter)
2871
{
2872
u32 i;
2873
PNDIS_802_11_VARIABLE_IEs pIE;
2874
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2875
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2876
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
2877
2878
if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
2879
for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) {
2880
pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
2881
2882
switch (pIE->ElementID) {
2883
case _VENDOR_SPECIFIC_IE_:
2884
if (_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4))
2885
return _FALSE;
2886
break;
2887
2888
case _RSN_IE_2_:
2889
return _FALSE;
2890
2891
default:
2892
break;
2893
}
2894
2895
i += (pIE->Length + 2);
2896
}
2897
2898
return _TRUE;
2899
} else
2900
return _FALSE;
2901
2902
}
2903
2904
int wifirate2_ratetbl_inx(unsigned char rate);
2905
int wifirate2_ratetbl_inx(unsigned char rate)
2906
{
2907
int inx = 0;
2908
rate = rate & 0x7f;
2909
2910
switch (rate) {
2911
case 54*2:
2912
inx = 11;
2913
break;
2914
2915
case 48*2:
2916
inx = 10;
2917
break;
2918
2919
case 36*2:
2920
inx = 9;
2921
break;
2922
2923
case 24*2:
2924
inx = 8;
2925
break;
2926
2927
case 18*2:
2928
inx = 7;
2929
break;
2930
2931
case 12*2:
2932
inx = 6;
2933
break;
2934
2935
case 9*2:
2936
inx = 5;
2937
break;
2938
2939
case 6*2:
2940
inx = 4;
2941
break;
2942
2943
case 11*2:
2944
inx = 3;
2945
break;
2946
case 11:
2947
inx = 2;
2948
break;
2949
2950
case 2*2:
2951
inx = 1;
2952
break;
2953
2954
case 1*2:
2955
inx = 0;
2956
break;
2957
2958
}
2959
return inx;
2960
}
2961
2962
unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz)
2963
{
2964
unsigned int i, num_of_rate;
2965
unsigned int mask = 0;
2966
2967
num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz;
2968
2969
for (i = 0; i < num_of_rate; i++) {
2970
if ((*(ptn + i)) & 0x80)
2971
mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
2972
}
2973
return mask;
2974
}
2975
2976
unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz)
2977
{
2978
unsigned int i, num_of_rate;
2979
unsigned int mask = 0;
2980
2981
num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz;
2982
2983
for (i = 0; i < num_of_rate; i++)
2984
mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
2985
2986
return mask;
2987
}
2988
2989
int support_short_GI(_adapter *padapter, struct HT_caps_element *pHT_caps, u8 bwmode)
2990
{
2991
unsigned char bit_offset;
2992
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2993
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2994
2995
if (!(pmlmeinfo->HT_enable))
2996
return _FAIL;
2997
2998
bit_offset = (bwmode & CHANNEL_WIDTH_40) ? 6 : 5;
2999
3000
if (pHT_caps->u.HT_cap_element.HT_caps_info & (0x1 << bit_offset))
3001
return _SUCCESS;
3002
else
3003
return _FAIL;
3004
}
3005
3006
unsigned char get_highest_rate_idx(u64 mask)
3007
{
3008
int i;
3009
unsigned char rate_idx = 0;
3010
3011
for (i = 63; i >= 0; i--) {
3012
if ((mask >> i) & 0x01) {
3013
rate_idx = i;
3014
break;
3015
}
3016
}
3017
3018
return rate_idx;
3019
}
3020
unsigned char get_lowest_rate_idx_ex(u64 mask, int start_bit)
3021
{
3022
int i;
3023
unsigned char rate_idx = 0;
3024
3025
for (i = start_bit; i < 64; i++) {
3026
if ((mask >> i) & 0x01) {
3027
rate_idx = i;
3028
break;
3029
}
3030
}
3031
3032
return rate_idx;
3033
}
3034
3035
void Update_RA_Entry(_adapter *padapter, struct sta_info *psta)
3036
{
3037
rtw_hal_update_ra_mask(psta);
3038
}
3039
3040
void set_sta_rate(_adapter *padapter, struct sta_info *psta)
3041
{
3042
/* rate adaptive */
3043
rtw_hal_update_ra_mask(psta);
3044
}
3045
3046
/* Update RRSR and Rate for USERATE */
3047
void update_tx_basic_rate(_adapter *padapter, u8 wirelessmode)
3048
{
3049
NDIS_802_11_RATES_EX supported_rates;
3050
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3051
#ifdef CONFIG_P2P
3052
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3053
3054
/* Added by Albert 2011/03/22 */
3055
/* In the P2P mode, the driver should not support the b mode. */
3056
/* So, the Tx packet shouldn't use the CCK rate */
3057
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3058
return;
3059
#endif /* CONFIG_P2P */
3060
3061
_rtw_memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
3062
3063
/* clear B mod if current channel is in 5G band, avoid tx cck rate in 5G band. */
3064
if (pmlmeext->cur_channel > 14)
3065
wirelessmode &= ~(WIRELESS_11B);
3066
3067
if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B))
3068
_rtw_memcpy(supported_rates, rtw_basic_rate_cck, 4);
3069
else if (wirelessmode & WIRELESS_11B)
3070
_rtw_memcpy(supported_rates, rtw_basic_rate_mix, 7);
3071
else
3072
_rtw_memcpy(supported_rates, rtw_basic_rate_ofdm, 3);
3073
3074
if (wirelessmode & WIRELESS_11B)
3075
update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
3076
else
3077
update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
3078
3079
rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, supported_rates);
3080
}
3081
3082
unsigned char check_assoc_AP(u8 *pframe, uint len)
3083
{
3084
unsigned int i;
3085
PNDIS_802_11_VARIABLE_IEs pIE;
3086
3087
for (i = sizeof(NDIS_802_11_FIXED_IEs); i < len;) {
3088
pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
3089
3090
switch (pIE->ElementID) {
3091
case _VENDOR_SPECIFIC_IE_:
3092
if ((_rtw_memcmp(pIE->data, ARTHEROS_OUI1, 3)) || (_rtw_memcmp(pIE->data, ARTHEROS_OUI2, 3))) {
3093
RTW_INFO("link to Artheros AP\n");
3094
return HT_IOT_PEER_ATHEROS;
3095
} else if ((_rtw_memcmp(pIE->data, BROADCOM_OUI1, 3))
3096
|| (_rtw_memcmp(pIE->data, BROADCOM_OUI2, 3))
3097
|| (_rtw_memcmp(pIE->data, BROADCOM_OUI3, 3))) {
3098
RTW_INFO("link to Broadcom AP\n");
3099
return HT_IOT_PEER_BROADCOM;
3100
} else if (_rtw_memcmp(pIE->data, MARVELL_OUI, 3)) {
3101
RTW_INFO("link to Marvell AP\n");
3102
return HT_IOT_PEER_MARVELL;
3103
} else if (_rtw_memcmp(pIE->data, RALINK_OUI, 3)) {
3104
RTW_INFO("link to Ralink AP\n");
3105
return HT_IOT_PEER_RALINK;
3106
} else if (_rtw_memcmp(pIE->data, CISCO_OUI, 3)) {
3107
RTW_INFO("link to Cisco AP\n");
3108
return HT_IOT_PEER_CISCO;
3109
} else if (_rtw_memcmp(pIE->data, REALTEK_OUI, 3)) {
3110
u32 Vender = HT_IOT_PEER_REALTEK;
3111
3112
if (pIE->Length >= 5) {
3113
if (pIE->data[4] == 1) {
3114
/* if(pIE->data[5] & RT_HT_CAP_USE_LONG_PREAMBLE) */
3115
/* bssDesc->BssHT.RT2RT_HT_Mode |= RT_HT_CAP_USE_LONG_PREAMBLE; */
3116
3117
if (pIE->data[5] & RT_HT_CAP_USE_92SE) {
3118
/* bssDesc->BssHT.RT2RT_HT_Mode |= RT_HT_CAP_USE_92SE; */
3119
Vender = HT_IOT_PEER_REALTEK_92SE;
3120
}
3121
}
3122
3123
if (pIE->data[5] & RT_HT_CAP_USE_SOFTAP)
3124
Vender = HT_IOT_PEER_REALTEK_SOFTAP;
3125
3126
if (pIE->data[4] == 2) {
3127
if (pIE->data[6] & RT_HT_CAP_USE_JAGUAR_BCUT) {
3128
Vender = HT_IOT_PEER_REALTEK_JAGUAR_BCUTAP;
3129
RTW_INFO("link to Realtek JAGUAR_BCUTAP\n");
3130
}
3131
if (pIE->data[6] & RT_HT_CAP_USE_JAGUAR_CCUT) {
3132
Vender = HT_IOT_PEER_REALTEK_JAGUAR_CCUTAP;
3133
RTW_INFO("link to Realtek JAGUAR_CCUTAP\n");
3134
}
3135
}
3136
}
3137
3138
RTW_INFO("link to Realtek AP\n");
3139
return Vender;
3140
} else if (_rtw_memcmp(pIE->data, AIRGOCAP_OUI, 3)) {
3141
RTW_INFO("link to Airgo Cap\n");
3142
return HT_IOT_PEER_AIRGO;
3143
} else
3144
break;
3145
3146
default:
3147
break;
3148
}
3149
3150
i += (pIE->Length + 2);
3151
}
3152
3153
RTW_INFO("link to new AP\n");
3154
return HT_IOT_PEER_UNKNOWN;
3155
}
3156
3157
void get_assoc_AP_Vendor(char *vendor, u8 assoc_AP_vendor)
3158
{
3159
switch (assoc_AP_vendor) {
3160
3161
case HT_IOT_PEER_UNKNOWN:
3162
sprintf(vendor, "%s", "unknown");
3163
break;
3164
3165
case HT_IOT_PEER_REALTEK:
3166
case HT_IOT_PEER_REALTEK_92SE:
3167
case HT_IOT_PEER_REALTEK_SOFTAP:
3168
case HT_IOT_PEER_REALTEK_JAGUAR_BCUTAP:
3169
case HT_IOT_PEER_REALTEK_JAGUAR_CCUTAP:
3170
3171
sprintf(vendor, "%s", "Realtek");
3172
break;
3173
3174
case HT_IOT_PEER_BROADCOM:
3175
sprintf(vendor, "%s", "Broadcom");
3176
break;
3177
3178
case HT_IOT_PEER_MARVELL:
3179
sprintf(vendor, "%s", "Marvell");
3180
break;
3181
3182
case HT_IOT_PEER_RALINK:
3183
sprintf(vendor, "%s", "Ralink");
3184
break;
3185
3186
case HT_IOT_PEER_CISCO:
3187
sprintf(vendor, "%s", "Cisco");
3188
break;
3189
3190
case HT_IOT_PEER_AIRGO:
3191
sprintf(vendor, "%s", "Airgo");
3192
break;
3193
3194
case HT_IOT_PEER_ATHEROS:
3195
sprintf(vendor, "%s", "Atheros");
3196
break;
3197
3198
default:
3199
sprintf(vendor, "%s", "unkown");
3200
break;
3201
}
3202
3203
}
3204
#ifdef CONFIG_RTS_FULL_BW
3205
void rtw_parse_sta_vendor_ie_8812(_adapter *adapter, struct sta_info *sta, u8 *tlv_ies, u16 tlv_ies_len)
3206
{
3207
unsigned char REALTEK_OUI[] = {0x00,0xe0, 0x4c};
3208
u8 *p;
3209
3210
p = rtw_get_ie_ex(tlv_ies, tlv_ies_len, WLAN_EID_VENDOR_SPECIFIC, REALTEK_OUI, 3, NULL, NULL);
3211
if (!p)
3212
goto exit;
3213
else {
3214
if(*(p+1) > 6 ) {
3215
3216
if(*(p+6) != 2)
3217
goto exit;
3218
3219
if(*(p+8) == RT_HT_CAP_USE_JAGUAR_BCUT)
3220
sta->vendor_8812 = TRUE;
3221
else if (*(p+8) == RT_HT_CAP_USE_JAGUAR_CCUT)
3222
sta->vendor_8812 = TRUE;
3223
}
3224
}
3225
exit:
3226
return;
3227
}
3228
#endif/*CONFIG_RTS_FULL_BW*/
3229
3230
#ifdef CONFIG_80211AC_VHT
3231
unsigned char get_vht_mu_bfer_cap(u8 *pframe, uint len)
3232
{
3233
unsigned int i;
3234
unsigned int mu_bfer=0;
3235
PNDIS_802_11_VARIABLE_IEs pIE;
3236
3237
for (i = sizeof(NDIS_802_11_FIXED_IEs); i < len;) {
3238
pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
3239
3240
switch (pIE->ElementID) {
3241
3242
case EID_VHTCapability:
3243
mu_bfer = GET_VHT_CAPABILITY_ELE_MU_BFER(pIE->data);
3244
break;
3245
default:
3246
break;
3247
}
3248
i += (pIE->Length + 2);
3249
}
3250
return mu_bfer;
3251
}
3252
#endif
3253
3254
void update_capinfo(PADAPTER Adapter, u16 updateCap)
3255
{
3256
struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
3257
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3258
BOOLEAN ShortPreamble;
3259
3260
/* Check preamble mode, 2005.01.06, by rcnjko. */
3261
/* Mark to update preamble value forever, 2008.03.18 by lanhsin */
3262
/* if( pMgntInfo->RegPreambleMode == PREAMBLE_AUTO ) */
3263
{
3264
3265
if (updateCap & cShortPreamble) {
3266
/* Short Preamble */
3267
if (pmlmeinfo->preamble_mode != PREAMBLE_SHORT) { /* PREAMBLE_LONG or PREAMBLE_AUTO */
3268
ShortPreamble = _TRUE;
3269
pmlmeinfo->preamble_mode = PREAMBLE_SHORT;
3270
rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble);
3271
}
3272
} else {
3273
/* Long Preamble */
3274
if (pmlmeinfo->preamble_mode != PREAMBLE_LONG) { /* PREAMBLE_SHORT or PREAMBLE_AUTO */
3275
ShortPreamble = _FALSE;
3276
pmlmeinfo->preamble_mode = PREAMBLE_LONG;
3277
rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble);
3278
}
3279
}
3280
}
3281
3282
if (updateCap & cIBSS) {
3283
/* Filen: See 802.11-2007 p.91 */
3284
pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
3285
} else {
3286
/* Filen: See 802.11-2007 p.90 */
3287
if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N | WIRELESS_11A | WIRELESS_11_5N | WIRELESS_11AC))
3288
pmlmeinfo->slotTime = SHORT_SLOT_TIME;
3289
else if (pmlmeext->cur_wireless_mode & (WIRELESS_11G)) {
3290
if ((updateCap & cShortSlotTime) /* && (!(pMgntInfo->pHTInfo->RT2RT_HT_Mode & RT_HT_CAP_USE_LONG_PREAMBLE)) */) {
3291
/* Short Slot Time */
3292
pmlmeinfo->slotTime = SHORT_SLOT_TIME;
3293
} else {
3294
/* Long Slot Time */
3295
pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
3296
}
3297
} else {
3298
/* B Mode */
3299
pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
3300
}
3301
}
3302
3303
rtw_hal_set_hwreg(Adapter, HW_VAR_SLOT_TIME, &pmlmeinfo->slotTime);
3304
3305
}
3306
3307
/*
3308
* set adapter.mlmeextpriv.mlmext_info.HT_enable
3309
* set adapter.mlmeextpriv.cur_wireless_mode
3310
* set SIFS register
3311
* set mgmt tx rate
3312
*/
3313
void update_wireless_mode(_adapter *padapter)
3314
{
3315
int ratelen, network_type = 0;
3316
u32 SIFS_Timer;
3317
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3318
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3319
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
3320
unsigned char *rate = cur_network->SupportedRates;
3321
#ifdef CONFIG_P2P
3322
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3323
#endif /* CONFIG_P2P */
3324
3325
ratelen = rtw_get_rateset_len(cur_network->SupportedRates);
3326
3327
if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
3328
pmlmeinfo->HT_enable = 1;
3329
3330
if (pmlmeext->cur_channel > 14) {
3331
if (pmlmeinfo->VHT_enable)
3332
network_type = WIRELESS_11AC;
3333
else if (pmlmeinfo->HT_enable)
3334
network_type = WIRELESS_11_5N;
3335
3336
network_type |= WIRELESS_11A;
3337
} else {
3338
if (pmlmeinfo->VHT_enable)
3339
network_type = WIRELESS_11AC;
3340
else if (pmlmeinfo->HT_enable)
3341
network_type = WIRELESS_11_24N;
3342
3343
if ((cckratesonly_included(rate, ratelen)) == _TRUE)
3344
network_type |= WIRELESS_11B;
3345
else if ((cckrates_included(rate, ratelen)) == _TRUE)
3346
network_type |= WIRELESS_11BG;
3347
else
3348
network_type |= WIRELESS_11G;
3349
}
3350
3351
pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode;
3352
/* RTW_INFO("network_type=%02x, padapter->registrypriv.wireless_mode=%02x\n", network_type, padapter->registrypriv.wireless_mode); */
3353
3354
#ifndef RTW_HALMAC
3355
/* HALMAC IC do not set HW_VAR_RESP_SIFS here */
3356
#if 0
3357
if ((pmlmeext->cur_wireless_mode == WIRELESS_11G) ||
3358
(pmlmeext->cur_wireless_mode == WIRELESS_11BG)) /* WIRELESS_MODE_G) */
3359
SIFS_Timer = 0x0a0a;/* CCK */
3360
else
3361
SIFS_Timer = 0x0e0e;/* pHalData->SifsTime; //OFDM */
3362
#endif
3363
3364
SIFS_Timer = 0x0a0a0808; /* 0x0808->for CCK, 0x0a0a->for OFDM
3365
* change this value if having IOT issues. */
3366
3367
rtw_hal_set_hwreg(padapter, HW_VAR_RESP_SIFS, (u8 *)&SIFS_Timer);
3368
#endif
3369
3370
rtw_hal_set_hwreg(padapter, HW_VAR_WIRELESS_MODE, (u8 *)&(pmlmeext->cur_wireless_mode));
3371
3372
if ((pmlmeext->cur_wireless_mode & WIRELESS_11B)
3373
#ifdef CONFIG_P2P
3374
&& (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
3375
#ifdef CONFIG_IOCTL_CFG80211
3376
|| !rtw_cfg80211_iface_has_p2p_group_cap(padapter)
3377
#endif
3378
)
3379
#endif
3380
)
3381
update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
3382
else
3383
update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
3384
}
3385
3386
void fire_write_MAC_cmd(_adapter *padapter, unsigned int addr, unsigned int value);
3387
void fire_write_MAC_cmd(_adapter *padapter, unsigned int addr, unsigned int value)
3388
{
3389
#if 0
3390
struct cmd_obj *ph2c;
3391
struct reg_rw_parm *pwriteMacPara;
3392
struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
3393
3394
ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
3395
if (ph2c == NULL)
3396
return;
3397
3398
pwriteMacPara = (struct reg_rw_parm *)rtw_malloc(sizeof(struct reg_rw_parm));
3399
if (pwriteMacPara == NULL) {
3400
rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
3401
return;
3402
}
3403
3404
pwriteMacPara->rw = 1;
3405
pwriteMacPara->addr = addr;
3406
pwriteMacPara->value = value;
3407
3408
init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteMacPara, GEN_CMD_CODE(_Write_MACREG));
3409
rtw_enqueue_cmd(pcmdpriv, ph2c);
3410
#endif
3411
}
3412
3413
void update_sta_basic_rate(struct sta_info *psta, u8 wireless_mode)
3414
{
3415
if (IsSupportedTxCCK(wireless_mode)) {
3416
/* Only B, B/G, and B/G/N AP could use CCK rate */
3417
_rtw_memcpy(psta->bssrateset, rtw_basic_rate_cck, 4);
3418
psta->bssratelen = 4;
3419
} else {
3420
_rtw_memcpy(psta->bssrateset, rtw_basic_rate_ofdm, 3);
3421
psta->bssratelen = 3;
3422
}
3423
}
3424
3425
int rtw_ies_get_supported_rate(u8 *ies, uint ies_len, u8 *rate_set, u8 *rate_num)
3426
{
3427
u8 *ie, *p;
3428
unsigned int ie_len;
3429
int i, j;
3430
3431
struct support_rate_handler support_rate_tbl[] = {
3432
{IEEE80211_CCK_RATE_1MB, _FALSE, _FALSE},
3433
{IEEE80211_CCK_RATE_2MB, _FALSE, _FALSE},
3434
{IEEE80211_CCK_RATE_5MB, _FALSE, _FALSE},
3435
{IEEE80211_CCK_RATE_11MB, _FALSE, _FALSE},
3436
{IEEE80211_OFDM_RATE_6MB, _FALSE, _FALSE},
3437
{IEEE80211_OFDM_RATE_9MB, _FALSE, _FALSE},
3438
{IEEE80211_OFDM_RATE_12MB, _FALSE, _FALSE},
3439
{IEEE80211_OFDM_RATE_18MB, _FALSE, _FALSE},
3440
{IEEE80211_OFDM_RATE_24MB, _FALSE, _FALSE},
3441
{IEEE80211_OFDM_RATE_36MB, _FALSE, _FALSE},
3442
{IEEE80211_OFDM_RATE_48MB, _FALSE, _FALSE},
3443
{IEEE80211_OFDM_RATE_54MB, _FALSE, _FALSE},
3444
};
3445
3446
if (!rate_set || !rate_num)
3447
return _FALSE;
3448
3449
*rate_num = 0;
3450
ie = rtw_get_ie(ies, _SUPPORTEDRATES_IE_, &ie_len, ies_len);
3451
if (ie == NULL)
3452
goto ext_rate;
3453
3454
/* get valid supported rates */
3455
for (i = 0; i < 12; i++) {
3456
p = ie + 2;
3457
for (j = 0; j < ie_len; j++) {
3458
if ((*p & ~BIT(7)) == support_rate_tbl[i].rate){
3459
support_rate_tbl[i].existence = _TRUE;
3460
if ((*p) & BIT(7))
3461
support_rate_tbl[i].basic = _TRUE;
3462
}
3463
p++;
3464
}
3465
}
3466
3467
ext_rate:
3468
ie = rtw_get_ie(ies, _EXT_SUPPORTEDRATES_IE_, &ie_len, ies_len);
3469
if (ie) {
3470
/* get valid extended supported rates */
3471
for (i = 0; i < 12; i++) {
3472
p = ie + 2;
3473
for (j = 0; j < ie_len; j++) {
3474
if ((*p & ~BIT(7)) == support_rate_tbl[i].rate){
3475
support_rate_tbl[i].existence = _TRUE;
3476
if ((*p) & BIT(7))
3477
support_rate_tbl[i].basic = _TRUE;
3478
}
3479
p++;
3480
}
3481
}
3482
}
3483
3484
for (i = 0; i < 12; i++){
3485
if (support_rate_tbl[i].existence){
3486
if (support_rate_tbl[i].basic)
3487
rate_set[*rate_num] = support_rate_tbl[i].rate | IEEE80211_BASIC_RATE_MASK;
3488
else
3489
rate_set[*rate_num] = support_rate_tbl[i].rate;
3490
*rate_num += 1;
3491
}
3492
}
3493
3494
if (*rate_num == 0)
3495
return _FAIL;
3496
3497
if (0) {
3498
int i;
3499
3500
for (i = 0; i < *rate_num; i++)
3501
RTW_INFO("rate:0x%02x\n", *(rate_set + i));
3502
}
3503
3504
return _SUCCESS;
3505
}
3506
3507
void process_addba_req(_adapter *padapter, u8 *paddba_req, u8 *addr)
3508
{
3509
struct sta_info *psta;
3510
u16 tid, start_seq, param;
3511
struct sta_priv *pstapriv = &padapter->stapriv;
3512
struct ADDBA_request *preq = (struct ADDBA_request *)paddba_req;
3513
u8 size, accept = _FALSE;
3514
3515
psta = rtw_get_stainfo(pstapriv, addr);
3516
if (!psta)
3517
goto exit;
3518
3519
start_seq = le16_to_cpu(preq->BA_starting_seqctrl) >> 4;
3520
3521
param = le16_to_cpu(preq->BA_para_set);
3522
tid = (param >> 2) & 0x0f;
3523
3524
3525
accept = rtw_rx_ampdu_is_accept(padapter);
3526
if (padapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID)
3527
size = padapter->fix_rx_ampdu_size;
3528
else {
3529
size = rtw_rx_ampdu_size(padapter);
3530
size = rtw_min(size, rx_ampdu_size_sta_limit(padapter, psta));
3531
}
3532
3533
if (accept == _TRUE)
3534
rtw_addbarsp_cmd(padapter, addr, tid, 0, size, start_seq);
3535
else
3536
rtw_addbarsp_cmd(padapter, addr, tid, 37, size, start_seq); /* reject ADDBA Req */
3537
3538
exit:
3539
return;
3540
}
3541
3542
void rtw_process_bar_frame(_adapter *padapter, union recv_frame *precv_frame)
3543
{
3544
struct sta_priv *pstapriv = &padapter->stapriv;
3545
u8 *pframe = precv_frame->u.hdr.rx_data;
3546
struct sta_info *psta = NULL;
3547
struct recv_reorder_ctrl *preorder_ctrl = NULL;
3548
u8 tid = 0;
3549
u16 start_seq=0;
3550
3551
psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3552
if (psta == NULL)
3553
goto exit;
3554
3555
tid = ((cpu_to_le16((*(u16 *)(pframe + 16))) & 0xf000) >> 12);
3556
preorder_ctrl = &psta->recvreorder_ctrl[tid];
3557
start_seq = ((cpu_to_le16(*(u16 *)(pframe + 18))) >> 4);
3558
preorder_ctrl->indicate_seq = start_seq;
3559
3560
/* for Debug use */
3561
if (0)
3562
RTW_INFO(FUNC_ADPT_FMT" tid=%d, start_seq=%d\n", FUNC_ADPT_ARG(padapter), tid, start_seq);
3563
3564
exit:
3565
return;
3566
}
3567
3568
void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len)
3569
{
3570
u8 *pIE;
3571
u32 *pbuf;
3572
3573
pIE = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
3574
pbuf = (u32 *)pIE;
3575
3576
pmlmeext->TSFValue = le32_to_cpu(*(pbuf + 1));
3577
3578
pmlmeext->TSFValue = pmlmeext->TSFValue << 32;
3579
3580
pmlmeext->TSFValue |= le32_to_cpu(*pbuf);
3581
}
3582
3583
void correct_TSF(_adapter *padapter, u8 mlme_state)
3584
{
3585
u8 m_state = mlme_state;
3586
3587
rtw_hal_set_hwreg(padapter, HW_VAR_CORRECT_TSF, (u8 *)&m_state);
3588
}
3589
3590
#ifdef CONFIG_BCN_RECV_TIME
3591
/* calculate beacon receiving time
3592
1.RxBCNTime(CCK_1M) = [192us(preamble)] + [length of beacon(byte)*8us] + [10us]
3593
2.RxBCNTime(OFDM_6M) = [8us(S) + 8us(L) + 4us(L-SIG)] + [(length of beacon(byte)/3 + 1] *4us] + [10us]
3594
*/
3595
inline u16 _rx_bcn_time_calculate(uint bcn_len, u8 data_rate)
3596
{
3597
u16 rx_bcn_time = 0;/*us*/
3598
3599
if (data_rate == DESC_RATE1M)
3600
rx_bcn_time = 192 + bcn_len * 8 + 10;
3601
else if(data_rate == DESC_RATE6M)
3602
rx_bcn_time = 8 + 8 + 4 + (bcn_len /3 + 1) * 4 + 10;
3603
/*
3604
else
3605
RTW_ERR("%s invalid data rate(0x%02x)\n", __func__, data_rate);
3606
*/
3607
return rx_bcn_time;
3608
}
3609
void rtw_rx_bcn_time_update(_adapter *adapter, uint bcn_len, u8 data_rate)
3610
{
3611
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3612
3613
pmlmeext->bcn_rx_time = _rx_bcn_time_calculate(bcn_len, data_rate);
3614
}
3615
#endif
3616
3617
void beacon_timing_control(_adapter *padapter)
3618
{
3619
rtw_hal_bcn_related_reg_setting(padapter);
3620
}
3621
3622
void dump_macid_map(void *sel, struct macid_bmp *map, u8 max_num)
3623
{
3624
RTW_PRINT_SEL(sel, "0x%08x\n", map->m0);
3625
#if (MACID_NUM_SW_LIMIT > 32)
3626
if (max_num && max_num > 32)
3627
RTW_PRINT_SEL(sel, "0x%08x\n", map->m1);
3628
#endif
3629
#if (MACID_NUM_SW_LIMIT > 64)
3630
if (max_num && max_num > 64)
3631
RTW_PRINT_SEL(sel, "0x%08x\n", map->m2);
3632
#endif
3633
#if (MACID_NUM_SW_LIMIT > 96)
3634
if (max_num && max_num > 96)
3635
RTW_PRINT_SEL(sel, "0x%08x\n", map->m3);
3636
#endif
3637
}
3638
3639
inline bool rtw_macid_is_set(struct macid_bmp *map, u8 id)
3640
{
3641
if (id < 32)
3642
return map->m0 & BIT(id);
3643
#if (MACID_NUM_SW_LIMIT > 32)
3644
else if (id < 64)
3645
return map->m1 & BIT(id - 32);
3646
#endif
3647
#if (MACID_NUM_SW_LIMIT > 64)
3648
else if (id < 96)
3649
return map->m2 & BIT(id - 64);
3650
#endif
3651
#if (MACID_NUM_SW_LIMIT > 96)
3652
else if (id < 128)
3653
return map->m3 & BIT(id - 96);
3654
#endif
3655
else
3656
rtw_warn_on(1);
3657
3658
return 0;
3659
}
3660
3661
inline void rtw_macid_map_set(struct macid_bmp *map, u8 id)
3662
{
3663
if (id < 32)
3664
map->m0 |= BIT(id);
3665
#if (MACID_NUM_SW_LIMIT > 32)
3666
else if (id < 64)
3667
map->m1 |= BIT(id - 32);
3668
#endif
3669
#if (MACID_NUM_SW_LIMIT > 64)
3670
else if (id < 96)
3671
map->m2 |= BIT(id - 64);
3672
#endif
3673
#if (MACID_NUM_SW_LIMIT > 96)
3674
else if (id < 128)
3675
map->m3 |= BIT(id - 96);
3676
#endif
3677
else
3678
rtw_warn_on(1);
3679
}
3680
3681
inline void rtw_macid_map_clr(struct macid_bmp *map, u8 id)
3682
{
3683
if (id < 32)
3684
map->m0 &= ~BIT(id);
3685
#if (MACID_NUM_SW_LIMIT > 32)
3686
else if (id < 64)
3687
map->m1 &= ~BIT(id - 32);
3688
#endif
3689
#if (MACID_NUM_SW_LIMIT > 64)
3690
else if (id < 96)
3691
map->m2 &= ~BIT(id - 64);
3692
#endif
3693
#if (MACID_NUM_SW_LIMIT > 96)
3694
else if (id < 128)
3695
map->m3 &= ~BIT(id - 96);
3696
#endif
3697
else
3698
rtw_warn_on(1);
3699
}
3700
3701
inline bool rtw_macid_is_used(struct macid_ctl_t *macid_ctl, u8 id)
3702
{
3703
return rtw_macid_is_set(&macid_ctl->used, id);
3704
}
3705
3706
inline bool rtw_macid_is_bmc(struct macid_ctl_t *macid_ctl, u8 id)
3707
{
3708
return rtw_macid_is_set(&macid_ctl->bmc, id);
3709
}
3710
3711
inline u8 rtw_macid_get_iface_bmp(struct macid_ctl_t *macid_ctl, u8 id)
3712
{
3713
int i;
3714
u8 iface_bmp = 0;
3715
3716
for (i = 0; i < CONFIG_IFACE_NUMBER; i++) {
3717
if (rtw_macid_is_set(&macid_ctl->if_g[i], id))
3718
iface_bmp |= BIT(i);
3719
}
3720
return iface_bmp;
3721
}
3722
3723
inline bool rtw_macid_is_iface_shared(struct macid_ctl_t *macid_ctl, u8 id)
3724
{
3725
#if CONFIG_IFACE_NUMBER >= 2
3726
int i;
3727
u8 iface_bmp = 0;
3728
3729
for (i = 0; i < CONFIG_IFACE_NUMBER; i++) {
3730
if (rtw_macid_is_set(&macid_ctl->if_g[i], id)) {
3731
if (iface_bmp)
3732
return 1;
3733
iface_bmp |= BIT(i);
3734
}
3735
}
3736
#endif
3737
return 0;
3738
}
3739
3740
inline bool rtw_macid_is_iface_specific(struct macid_ctl_t *macid_ctl, u8 id, _adapter *adapter)
3741
{
3742
int i;
3743
u8 iface_bmp = 0;
3744
3745
for (i = 0; i < CONFIG_IFACE_NUMBER; i++) {
3746
if (rtw_macid_is_set(&macid_ctl->if_g[i], id)) {
3747
if (iface_bmp || i != adapter->iface_id)
3748
return 0;
3749
iface_bmp |= BIT(i);
3750
}
3751
}
3752
3753
return iface_bmp ? 1 : 0;
3754
}
3755
3756
inline s8 rtw_macid_get_ch_g(struct macid_ctl_t *macid_ctl, u8 id)
3757
{
3758
int i;
3759
3760
for (i = 0; i < 2; i++) {
3761
if (rtw_macid_is_set(&macid_ctl->ch_g[i], id))
3762
return i;
3763
}
3764
return -1;
3765
}
3766
3767
/*Record bc's mac-id and sec-cam-id*/
3768
inline void rtw_iface_bcmc_id_set(_adapter *padapter, u8 mac_id)
3769
{
3770
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3771
struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
3772
3773
macid_ctl->iface_bmc[padapter->iface_id] = mac_id;
3774
}
3775
inline u8 rtw_iface_bcmc_id_get(_adapter *padapter)
3776
{
3777
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3778
struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
3779
3780
return macid_ctl->iface_bmc[padapter->iface_id];
3781
}
3782
#if defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE)
3783
void rtw_iface_bcmc_sec_cam_map_restore(_adapter *adapter)
3784
{
3785
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3786
struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj);
3787
int cam_id = -1;
3788
3789
cam_id = rtw_iface_bcmc_id_get(adapter);
3790
if (cam_id != INVALID_SEC_MAC_CAM_ID)
3791
rtw_sec_cam_map_set(&cam_ctl->used, cam_id);
3792
}
3793
#endif
3794
void rtw_alloc_macid(_adapter *padapter, struct sta_info *psta)
3795
{
3796
int i;
3797
_irqL irqL;
3798
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3799
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3800
struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
3801
struct macid_bmp *used_map = &macid_ctl->used;
3802
/* static u8 last_id = 0; for testing */
3803
u8 last_id = 0;
3804
u8 is_bc_sta = _FALSE;
3805
3806
if (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN)) {
3807
psta->cmn.mac_id = macid_ctl->num;
3808
return;
3809
}
3810
3811
if (_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN)) {
3812
is_bc_sta = _TRUE;
3813
rtw_iface_bcmc_id_set(padapter, INVALID_SEC_MAC_CAM_ID); /*init default value*/
3814
}
3815
3816
if (is_bc_sta
3817
#ifdef CONFIG_CONCURRENT_MODE
3818
&& (MLME_IS_STA(padapter) || MLME_IS_NULL(padapter))
3819
#endif
3820
) {
3821
/* STA mode have no BMC data TX, shared with this macid */
3822
/* When non-concurrent, only one BMC data TX is used, shared with this macid */
3823
/* TODO: When concurrent, non-security BMC data TX may use this, but will not control by specific macid sleep */
3824
i = RTW_DEFAULT_MGMT_MACID;
3825
goto assigned;
3826
}
3827
3828
_enter_critical_bh(&macid_ctl->lock, &irqL);
3829
3830
for (i = last_id; i < macid_ctl->num; i++) {
3831
#ifdef CONFIG_MCC_MODE
3832
/* macid 0/1 reserve for mcc for mgnt queue macid */
3833
if (MCC_EN(padapter)) {
3834
if (i == MCC_ROLE_STA_GC_MGMT_QUEUE_MACID)
3835
continue;
3836
if (i == MCC_ROLE_SOFTAP_GO_MGMT_QUEUE_MACID)
3837
continue;
3838
}
3839
#endif /* CONFIG_MCC_MODE */
3840
3841
#ifdef CONFIG_CONCURRENT_MODE
3842
/* for BMC data TX with force camid */
3843
if (is_bc_sta && rtw_sec_camid_is_used(dvobj_to_sec_camctl(dvobj), i))
3844
continue;
3845
#endif
3846
3847
if (!rtw_macid_is_used(macid_ctl, i))
3848
break;
3849
}
3850
3851
if (i < macid_ctl->num) {
3852
3853
rtw_macid_map_set(used_map, i);
3854
3855
#ifdef CONFIG_CONCURRENT_MODE
3856
/* for BMC data TX with force camid */
3857
if (is_bc_sta) {
3858
struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj);
3859
3860
rtw_macid_map_set(&macid_ctl->bmc, i);
3861
rtw_iface_bcmc_id_set(padapter, i);
3862
rtw_sec_cam_map_set(&cam_ctl->used, i);
3863
}
3864
#endif
3865
3866
rtw_macid_map_set(&macid_ctl->if_g[padapter->iface_id], i);
3867
macid_ctl->sta[i] = psta;
3868
3869
/* TODO ch_g? */
3870
3871
last_id++;
3872
last_id %= macid_ctl->num;
3873
}
3874
3875
_exit_critical_bh(&macid_ctl->lock, &irqL);
3876
3877
if (i >= macid_ctl->num) {
3878
psta->cmn.mac_id = macid_ctl->num;
3879
RTW_ERR(FUNC_ADPT_FMT" if%u, mac_addr:"MAC_FMT" no available macid\n"
3880
, FUNC_ADPT_ARG(padapter), padapter->iface_id + 1, MAC_ARG(psta->cmn.mac_addr));
3881
rtw_warn_on(1);
3882
goto exit;
3883
} else
3884
goto assigned;
3885
3886
assigned:
3887
psta->cmn.mac_id = i;
3888
RTW_INFO(FUNC_ADPT_FMT" if%u, mac_addr:"MAC_FMT" macid:%u\n"
3889
, FUNC_ADPT_ARG(padapter), padapter->iface_id + 1, MAC_ARG(psta->cmn.mac_addr), psta->cmn.mac_id);
3890
3891
exit:
3892
return;
3893
}
3894
3895
void rtw_release_macid(_adapter *padapter, struct sta_info *psta)
3896
{
3897
_irqL irqL;
3898
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3899
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3900
struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
3901
u8 ifbmp;
3902
int i;
3903
3904
if (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN))
3905
goto exit;
3906
3907
if (psta->cmn.mac_id >= macid_ctl->num) {
3908
RTW_WARN(FUNC_ADPT_FMT" if%u, mac_addr:"MAC_FMT" macid:%u not valid\n"
3909
, FUNC_ADPT_ARG(padapter), padapter->iface_id + 1
3910
, MAC_ARG(psta->cmn.mac_addr), psta->cmn.mac_id);
3911
rtw_warn_on(1);
3912
goto exit;
3913
}
3914
3915
if (psta->cmn.mac_id == RTW_DEFAULT_MGMT_MACID)
3916
goto msg;
3917
3918
_enter_critical_bh(&macid_ctl->lock, &irqL);
3919
3920
if (!rtw_macid_is_used(macid_ctl, psta->cmn.mac_id)) {
3921
RTW_WARN(FUNC_ADPT_FMT" if%u, mac_addr:"MAC_FMT" macid:%u not used\n"
3922
, FUNC_ADPT_ARG(padapter), padapter->iface_id + 1
3923
, MAC_ARG(psta->cmn.mac_addr), psta->cmn.mac_id);
3924
_exit_critical_bh(&macid_ctl->lock, &irqL);
3925
rtw_warn_on(1);
3926
goto exit;
3927
}
3928
3929
ifbmp = rtw_macid_get_iface_bmp(macid_ctl, psta->cmn.mac_id);
3930
if (!(ifbmp & BIT(padapter->iface_id))) {
3931
RTW_WARN(FUNC_ADPT_FMT" if%u, mac_addr:"MAC_FMT" macid:%u not used by self\n"
3932
, FUNC_ADPT_ARG(padapter), padapter->iface_id + 1
3933
, MAC_ARG(psta->cmn.mac_addr), psta->cmn.mac_id);
3934
_exit_critical_bh(&macid_ctl->lock, &irqL);
3935
rtw_warn_on(1);
3936
goto exit;
3937
}
3938
3939
if (_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN)) {
3940
struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj);
3941
u8 id = rtw_iface_bcmc_id_get(padapter);
3942
3943
if ((id != INVALID_SEC_MAC_CAM_ID) && (id < cam_ctl->num))
3944
rtw_sec_cam_map_clr(&cam_ctl->used, id);
3945
3946
rtw_iface_bcmc_id_set(padapter, INVALID_SEC_MAC_CAM_ID);
3947
}
3948
3949
rtw_macid_map_clr(&macid_ctl->if_g[padapter->iface_id], psta->cmn.mac_id);
3950
3951
ifbmp &= ~BIT(padapter->iface_id);
3952
if (!ifbmp) { /* only used by self */
3953
rtw_macid_map_clr(&macid_ctl->used, psta->cmn.mac_id);
3954
rtw_macid_map_clr(&macid_ctl->bmc, psta->cmn.mac_id);
3955
for (i = 0; i < 2; i++)
3956
rtw_macid_map_clr(&macid_ctl->ch_g[i], psta->cmn.mac_id);
3957
macid_ctl->sta[psta->cmn.mac_id] = NULL;
3958
}
3959
3960
_exit_critical_bh(&macid_ctl->lock, &irqL);
3961
3962
msg:
3963
RTW_INFO(FUNC_ADPT_FMT" if%u, mac_addr:"MAC_FMT" macid:%u\n"
3964
, FUNC_ADPT_ARG(padapter), padapter->iface_id + 1
3965
, MAC_ARG(psta->cmn.mac_addr), psta->cmn.mac_id
3966
);
3967
3968
exit:
3969
psta->cmn.mac_id = macid_ctl->num;
3970
}
3971
3972
/* For 8188E RA */
3973
u8 rtw_search_max_mac_id(_adapter *padapter)
3974
{
3975
u8 max_mac_id = 0;
3976
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3977
struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
3978
int i;
3979
_irqL irqL;
3980
3981
/* TODO: Only search for connected macid? */
3982
3983
_enter_critical_bh(&macid_ctl->lock, &irqL);
3984
for (i = (macid_ctl->num - 1); i > 0 ; i--) {
3985
if (rtw_macid_is_used(macid_ctl, i))
3986
break;
3987
}
3988
_exit_critical_bh(&macid_ctl->lock, &irqL);
3989
max_mac_id = i;
3990
3991
return max_mac_id;
3992
}
3993
3994
inline u8 rtw_macid_ctl_set_h2c_msr(struct macid_ctl_t *macid_ctl, u8 id, u8 h2c_msr)
3995
{
3996
u8 op_num_change_bmp = 0;
3997
3998
if (id >= macid_ctl->num) {
3999
rtw_warn_on(1);
4000
goto exit;
4001
}
4002
4003
if (GET_H2CCMD_MSRRPT_PARM_OPMODE(&macid_ctl->h2c_msr[id])
4004
&& !GET_H2CCMD_MSRRPT_PARM_OPMODE(&h2c_msr)
4005
) {
4006
u8 role = GET_H2CCMD_MSRRPT_PARM_ROLE(&macid_ctl->h2c_msr[id]);
4007
4008
if (role < H2C_MSR_ROLE_MAX) {
4009
macid_ctl->op_num[role]--;
4010
op_num_change_bmp |= BIT(role);
4011
}
4012
} else if (!GET_H2CCMD_MSRRPT_PARM_OPMODE(&macid_ctl->h2c_msr[id])
4013
&& GET_H2CCMD_MSRRPT_PARM_OPMODE(&h2c_msr)
4014
) {
4015
u8 role = GET_H2CCMD_MSRRPT_PARM_ROLE(&h2c_msr);
4016
4017
if (role < H2C_MSR_ROLE_MAX) {
4018
macid_ctl->op_num[role]++;
4019
op_num_change_bmp |= BIT(role);
4020
}
4021
}
4022
4023
macid_ctl->h2c_msr[id] = h2c_msr;
4024
if (0)
4025
RTW_INFO("macid:%u, h2c_msr:"H2C_MSR_FMT"\n", id, H2C_MSR_ARG(&macid_ctl->h2c_msr[id]));
4026
4027
exit:
4028
return op_num_change_bmp;
4029
}
4030
4031
inline void rtw_macid_ctl_set_bw(struct macid_ctl_t *macid_ctl, u8 id, u8 bw)
4032
{
4033
if (id >= macid_ctl->num) {
4034
rtw_warn_on(1);
4035
return;
4036
}
4037
4038
macid_ctl->bw[id] = bw;
4039
if (0)
4040
RTW_INFO("macid:%u, bw:%s\n", id, ch_width_str(macid_ctl->bw[id]));
4041
}
4042
4043
inline void rtw_macid_ctl_set_vht_en(struct macid_ctl_t *macid_ctl, u8 id, u8 en)
4044
{
4045
if (id >= macid_ctl->num) {
4046
rtw_warn_on(1);
4047
return;
4048
}
4049
4050
macid_ctl->vht_en[id] = en;
4051
if (0)
4052
RTW_INFO("macid:%u, vht_en:%u\n", id, macid_ctl->vht_en[id]);
4053
}
4054
4055
inline void rtw_macid_ctl_set_rate_bmp0(struct macid_ctl_t *macid_ctl, u8 id, u32 bmp)
4056
{
4057
if (id >= macid_ctl->num) {
4058
rtw_warn_on(1);
4059
return;
4060
}
4061
4062
macid_ctl->rate_bmp0[id] = bmp;
4063
if (0)
4064
RTW_INFO("macid:%u, rate_bmp0:0x%08X\n", id, macid_ctl->rate_bmp0[id]);
4065
}
4066
4067
inline void rtw_macid_ctl_set_rate_bmp1(struct macid_ctl_t *macid_ctl, u8 id, u32 bmp)
4068
{
4069
if (id >= macid_ctl->num) {
4070
rtw_warn_on(1);
4071
return;
4072
}
4073
4074
macid_ctl->rate_bmp1[id] = bmp;
4075
if (0)
4076
RTW_INFO("macid:%u, rate_bmp1:0x%08X\n", id, macid_ctl->rate_bmp1[id]);
4077
}
4078
4079
#ifdef CONFIG_PROTSEL_MACSLEEP
4080
inline void rtw_macid_ctl_init_sleep_reg(struct macid_ctl_t *macid_ctl, u16 reg_ctrl, u16 reg_info)
4081
{
4082
macid_ctl->reg_sleep_ctrl = reg_ctrl;
4083
macid_ctl->reg_sleep_info = reg_info;
4084
}
4085
#else
4086
inline void rtw_macid_ctl_init_sleep_reg(struct macid_ctl_t *macid_ctl, u16 m0, u16 m1, u16 m2, u16 m3)
4087
{
4088
macid_ctl->reg_sleep_m0 = m0;
4089
#if (MACID_NUM_SW_LIMIT > 32)
4090
macid_ctl->reg_sleep_m1 = m1;
4091
#endif
4092
#if (MACID_NUM_SW_LIMIT > 64)
4093
macid_ctl->reg_sleep_m2 = m2;
4094
#endif
4095
#if (MACID_NUM_SW_LIMIT > 96)
4096
macid_ctl->reg_sleep_m3 = m3;
4097
#endif
4098
}
4099
#endif
4100
4101
inline void rtw_macid_ctl_init(struct macid_ctl_t *macid_ctl)
4102
{
4103
int i;
4104
u8 id = RTW_DEFAULT_MGMT_MACID;
4105
4106
rtw_macid_map_set(&macid_ctl->used, id);
4107
rtw_macid_map_set(&macid_ctl->bmc, id);
4108
for (i = 0; i < CONFIG_IFACE_NUMBER; i++)
4109
rtw_macid_map_set(&macid_ctl->if_g[i], id);
4110
macid_ctl->sta[id] = NULL;
4111
4112
_rtw_spinlock_init(&macid_ctl->lock);
4113
}
4114
4115
inline void rtw_macid_ctl_deinit(struct macid_ctl_t *macid_ctl)
4116
{
4117
_rtw_spinlock_free(&macid_ctl->lock);
4118
}
4119
4120
inline bool rtw_bmp_is_set(const u8 *bmp, u8 bmp_len, u8 id)
4121
{
4122
if (id / 8 >= bmp_len)
4123
return 0;
4124
4125
return bmp[id / 8] & BIT(id % 8);
4126
}
4127
4128
inline void rtw_bmp_set(u8 *bmp, u8 bmp_len, u8 id)
4129
{
4130
if (id / 8 < bmp_len)
4131
bmp[id / 8] |= BIT(id % 8);
4132
}
4133
4134
inline void rtw_bmp_clear(u8 *bmp, u8 bmp_len, u8 id)
4135
{
4136
if (id / 8 < bmp_len)
4137
bmp[id / 8] &= ~BIT(id % 8);
4138
}
4139
4140
inline bool rtw_bmp_not_empty(const u8 *bmp, u8 bmp_len)
4141
{
4142
int i;
4143
4144
for (i = 0; i < bmp_len; i++) {
4145
if (bmp[i])
4146
return 1;
4147
}
4148
4149
return 0;
4150
}
4151
4152
inline bool rtw_bmp_not_empty_exclude_bit0(const u8 *bmp, u8 bmp_len)
4153
{
4154
int i;
4155
4156
for (i = 0; i < bmp_len; i++) {
4157
if (i == 0) {
4158
if (bmp[i] & 0xFE)
4159
return 1;
4160
} else {
4161
if (bmp[i])
4162
return 1;
4163
}
4164
}
4165
4166
return 0;
4167
}
4168
4169
#ifdef CONFIG_AP_MODE
4170
/* Check the id be set or not in map , if yes , return a none zero value*/
4171
bool rtw_tim_map_is_set(_adapter *padapter, const u8 *map, u8 id)
4172
{
4173
return rtw_bmp_is_set(map, padapter->stapriv.aid_bmp_len, id);
4174
}
4175
4176
/* Set the id into map array*/
4177
void rtw_tim_map_set(_adapter *padapter, u8 *map, u8 id)
4178
{
4179
rtw_bmp_set(map, padapter->stapriv.aid_bmp_len, id);
4180
}
4181
4182
/* Clear the id from map array*/
4183
void rtw_tim_map_clear(_adapter *padapter, u8 *map, u8 id)
4184
{
4185
rtw_bmp_clear(map, padapter->stapriv.aid_bmp_len, id);
4186
}
4187
4188
/* Check have anyone bit be set , if yes return true*/
4189
bool rtw_tim_map_anyone_be_set(_adapter *padapter, const u8 *map)
4190
{
4191
return rtw_bmp_not_empty(map, padapter->stapriv.aid_bmp_len);
4192
}
4193
4194
/* Check have anyone bit be set exclude bit0 , if yes return true*/
4195
bool rtw_tim_map_anyone_be_set_exclude_aid0(_adapter *padapter, const u8 *map)
4196
{
4197
return rtw_bmp_not_empty_exclude_bit0(map, padapter->stapriv.aid_bmp_len);
4198
}
4199
#endif /* CONFIG_AP_MODE */
4200
4201
#if 0
4202
unsigned int setup_beacon_frame(_adapter *padapter, unsigned char *beacon_frame)
4203
{
4204
unsigned short ATIMWindow;
4205
unsigned char *pframe;
4206
struct tx_desc *ptxdesc;
4207
struct rtw_ieee80211_hdr *pwlanhdr;
4208
unsigned short *fctrl;
4209
unsigned int rate_len, len = 0;
4210
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4211
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4212
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4213
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
4214
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4215
4216
_rtw_memset(beacon_frame, 0, 256);
4217
4218
pframe = beacon_frame + TXDESC_SIZE;
4219
4220
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4221
4222
fctrl = &(pwlanhdr->frame_ctl);
4223
*(fctrl) = 0;
4224
4225
_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
4226
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4227
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
4228
4229
set_frame_sub_type(pframe, WIFI_BEACON);
4230
4231
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4232
len = sizeof(struct rtw_ieee80211_hdr_3addr);
4233
4234
/* timestamp will be inserted by hardware */
4235
pframe += 8;
4236
len += 8;
4237
4238
/* beacon interval: 2 bytes */
4239
_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
4240
4241
pframe += 2;
4242
len += 2;
4243
4244
/* capability info: 2 bytes */
4245
_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
4246
4247
pframe += 2;
4248
len += 2;
4249
4250
/* SSID */
4251
pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &len);
4252
4253
/* supported rates... */
4254
rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
4255
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &len);
4256
4257
/* DS parameter set */
4258
pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &len);
4259
4260
/* IBSS Parameter Set... */
4261
/* ATIMWindow = cur->Configuration.ATIMWindow; */
4262
ATIMWindow = 0;
4263
pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &len);
4264
4265
/* todo: ERP IE */
4266
4267
/* EXTERNDED SUPPORTED RATE */
4268
if (rate_len > 8)
4269
pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &len);
4270
4271
if ((len + TXDESC_SIZE) > 256) {
4272
/* RTW_INFO("marc: beacon frame too large\n"); */
4273
return 0;
4274
}
4275
4276
/* fill the tx descriptor */
4277
ptxdesc = (struct tx_desc *)beacon_frame;
4278
4279
/* offset 0 */
4280
ptxdesc->txdw0 |= cpu_to_le32(len & 0x0000ffff);
4281
ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); /* default = 32 bytes for TX Desc */
4282
4283
/* offset 4 */
4284
ptxdesc->txdw1 |= cpu_to_le32((0x10 << QSEL_SHT) & 0x00001f00);
4285
4286
/* offset 8 */
4287
ptxdesc->txdw2 |= cpu_to_le32(BMC);
4288
ptxdesc->txdw2 |= cpu_to_le32(BK);
4289
4290
/* offset 16 */
4291
ptxdesc->txdw4 = 0x80000000;
4292
4293
/* offset 20 */
4294
ptxdesc->txdw5 = 0x00000000; /* 1M */
4295
4296
return len + TXDESC_SIZE;
4297
}
4298
#endif
4299
4300
_adapter *dvobj_get_port0_adapter(struct dvobj_priv *dvobj)
4301
{
4302
_adapter *port0_iface = NULL;
4303
int i;
4304
for (i = 0; i < dvobj->iface_nums; i++) {
4305
if (get_hw_port(dvobj->padapters[i]) == HW_PORT0)
4306
break;
4307
}
4308
4309
if (i < 0 || i >= dvobj->iface_nums)
4310
rtw_warn_on(1);
4311
else
4312
port0_iface = dvobj->padapters[i];
4313
4314
return port0_iface;
4315
}
4316
4317
_adapter *dvobj_get_unregisterd_adapter(struct dvobj_priv *dvobj)
4318
{
4319
_adapter *adapter = NULL;
4320
int i;
4321
4322
for (i = 0; i < dvobj->iface_nums; i++) {
4323
if (dvobj->padapters[i]->registered == 0)
4324
break;
4325
}
4326
4327
if (i < dvobj->iface_nums)
4328
adapter = dvobj->padapters[i];
4329
4330
return adapter;
4331
}
4332
4333
_adapter *dvobj_get_adapter_by_addr(struct dvobj_priv *dvobj, u8 *addr)
4334
{
4335
_adapter *adapter = NULL;
4336
int i;
4337
4338
for (i = 0; i < dvobj->iface_nums; i++) {
4339
if (_rtw_memcmp(dvobj->padapters[i]->mac_addr, addr, ETH_ALEN) == _TRUE)
4340
break;
4341
}
4342
4343
if (i < dvobj->iface_nums)
4344
adapter = dvobj->padapters[i];
4345
4346
return adapter;
4347
}
4348
4349
#ifdef CONFIG_WOWLAN
4350
bool rtw_wowlan_parser_pattern_cmd(u8 *input, char *pattern,
4351
int *pattern_len, char *bit_mask)
4352
{
4353
char *cp = NULL;
4354
size_t len = 0;
4355
int pos = 0, mask_pos = 0, res = 0;
4356
4357
/* To get the pattern string after "=", when we use :
4358
* iwpriv wlanX pattern=XX:XX:..:XX
4359
*/
4360
cp = strchr(input, '=');
4361
if (cp) {
4362
*cp = 0;
4363
cp++;
4364
input = cp;
4365
}
4366
4367
/* To take off the newline character '\n'(0x0a) at the end of pattern string,
4368
* when we use echo xxxx > /proc/xxxx
4369
*/
4370
cp = strchr(input, '\n');
4371
if (cp)
4372
*cp = 0;
4373
4374
while (input) {
4375
cp = strsep((char **)(&input), ":");
4376
4377
if (bit_mask && (strcmp(cp, "-") == 0 ||
4378
strcmp(cp, "xx") == 0 ||
4379
strcmp(cp, "--") == 0)) {
4380
/* skip this byte and leave mask bit unset */
4381
} else {
4382
u8 hex;
4383
4384
if (strlen(cp) != 2) {
4385
RTW_ERR("%s:[ERROR] hex len != 2, input=[%s]\n",
4386
__func__, cp);
4387
goto error;
4388
}
4389
4390
if (hexstr2bin(cp, &hex, 1) < 0) {
4391
RTW_ERR("%s:[ERROR] pattern is invalid, input=[%s]\n",
4392
__func__, cp);
4393
goto error;
4394
}
4395
4396
pattern[pos] = hex;
4397
mask_pos = pos / 8;
4398
if (bit_mask)
4399
bit_mask[mask_pos] |= 1 << (pos % 8);
4400
}
4401
4402
pos++;
4403
}
4404
4405
(*pattern_len) = pos;
4406
4407
return _TRUE;
4408
error:
4409
return _FALSE;
4410
}
4411
4412
void rtw_wow_pattern_sw_reset(_adapter *adapter)
4413
{
4414
int i;
4415
struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(adapter);
4416
4417
if (pwrctrlpriv->default_patterns_en == _TRUE)
4418
pwrctrlpriv->wowlan_pattern_idx = DEFAULT_PATTERN_NUM;
4419
else
4420
pwrctrlpriv->wowlan_pattern_idx = 0;
4421
4422
for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
4423
_rtw_memset(pwrctrlpriv->patterns[i].content, '\0', sizeof(pwrctrlpriv->patterns[i].content));
4424
_rtw_memset(pwrctrlpriv->patterns[i].mask, '\0', sizeof(pwrctrlpriv->patterns[i].mask));
4425
pwrctrlpriv->patterns[i].len = 0;
4426
}
4427
}
4428
4429
u8 rtw_set_default_pattern(_adapter *adapter)
4430
{
4431
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
4432
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4433
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4434
u8 index = 0;
4435
u8 multicast_addr[3] = {0x01, 0x00, 0x5e};
4436
u8 multicast_ip[4] = {0xe0, 0x28, 0x28, 0x2a};
4437
4438
u8 unicast_mask[5] = {0x3f, 0x70, 0x80, 0xc0, 0x03};
4439
u8 icmpv6_mask[7] = {0x00, 0x70, 0x10, 0x00, 0xc0, 0xc0, 0x3f};
4440
u8 multicast_mask[5] = {0x07, 0x70, 0x80, 0xc0, 0x03};
4441
4442
u8 ip_protocol[3] = {0x08, 0x00, 0x45};
4443
u8 ipv6_protocol[3] = {0x86, 0xdd, 0x60};
4444
4445
u8 *target = NULL;
4446
4447
if (pwrpriv->default_patterns_en == _FALSE)
4448
return 0;
4449
4450
for (index = 0 ; index < DEFAULT_PATTERN_NUM ; index++) {
4451
_rtw_memset(pwrpriv->patterns[index].content, 0,
4452
sizeof(pwrpriv->patterns[index].content));
4453
_rtw_memset(pwrpriv->patterns[index].mask, 0,
4454
sizeof(pwrpriv->patterns[index].mask));
4455
pwrpriv->patterns[index].len = 0;
4456
}
4457
4458
/*TCP/ICMP unicast*/
4459
for (index = 0 ; index < DEFAULT_PATTERN_NUM ; index++) {
4460
switch (index) {
4461
case 0:
4462
target = pwrpriv->patterns[index].content;
4463
_rtw_memcpy(target, adapter_mac_addr(adapter),
4464
ETH_ALEN);
4465
4466
target += ETH_TYPE_OFFSET;
4467
_rtw_memcpy(target, &ip_protocol,
4468
sizeof(ip_protocol));
4469
4470
/* TCP */
4471
target += (PROTOCOL_OFFSET - ETH_TYPE_OFFSET);
4472
_rtw_memset(target, 0x06, 1);
4473
4474
target += (IP_OFFSET - PROTOCOL_OFFSET);
4475
4476
_rtw_memcpy(target, pmlmeinfo->ip_addr,
4477
RTW_IP_ADDR_LEN);
4478
4479
_rtw_memcpy(pwrpriv->patterns[index].mask,
4480
&unicast_mask, sizeof(unicast_mask));
4481
4482
pwrpriv->patterns[index].len =
4483
IP_OFFSET + RTW_IP_ADDR_LEN;
4484
break;
4485
case 1:
4486
target = pwrpriv->patterns[index].content;
4487
_rtw_memcpy(target, adapter_mac_addr(adapter),
4488
ETH_ALEN);
4489
4490
target += ETH_TYPE_OFFSET;
4491
_rtw_memcpy(target, &ip_protocol, sizeof(ip_protocol));
4492
4493
/* ICMP */
4494
target += (PROTOCOL_OFFSET - ETH_TYPE_OFFSET);
4495
_rtw_memset(target, 0x01, 1);
4496
4497
target += (IP_OFFSET - PROTOCOL_OFFSET);
4498
_rtw_memcpy(target, pmlmeinfo->ip_addr,
4499
RTW_IP_ADDR_LEN);
4500
4501
_rtw_memcpy(pwrpriv->patterns[index].mask,
4502
&unicast_mask, sizeof(unicast_mask));
4503
pwrpriv->patterns[index].len =
4504
4505
IP_OFFSET + RTW_IP_ADDR_LEN;
4506
break;
4507
#ifdef CONFIG_IPV6
4508
case 2:
4509
if (pwrpriv->wowlan_ns_offload_en == _TRUE) {
4510
target = pwrpriv->patterns[index].content;
4511
target += ETH_TYPE_OFFSET;
4512
4513
_rtw_memcpy(target, &ipv6_protocol,
4514
sizeof(ipv6_protocol));
4515
4516
/* ICMPv6 */
4517
target += (IPv6_PROTOCOL_OFFSET -
4518
ETH_TYPE_OFFSET);
4519
_rtw_memset(target, 0x3a, 1);
4520
4521
target += (IPv6_OFFSET - IPv6_PROTOCOL_OFFSET);
4522
_rtw_memcpy(target, pmlmeinfo->ip6_addr,
4523
RTW_IPv6_ADDR_LEN);
4524
4525
_rtw_memcpy(pwrpriv->patterns[index].mask,
4526
&icmpv6_mask, sizeof(icmpv6_mask));
4527
pwrpriv->patterns[index].len =
4528
IPv6_OFFSET + RTW_IPv6_ADDR_LEN;
4529
}
4530
break;
4531
#endif /*CONFIG_IPV6*/
4532
case 3:
4533
target = pwrpriv->patterns[index].content;
4534
_rtw_memcpy(target, &multicast_addr,
4535
sizeof(multicast_addr));
4536
4537
target += ETH_TYPE_OFFSET;
4538
_rtw_memcpy(target, &ip_protocol, sizeof(ip_protocol));
4539
4540
/* UDP */
4541
target += (PROTOCOL_OFFSET - ETH_TYPE_OFFSET);
4542
_rtw_memset(target, 0x11, 1);
4543
4544
target += (IP_OFFSET - PROTOCOL_OFFSET);
4545
_rtw_memcpy(target, &multicast_ip,
4546
sizeof(multicast_ip));
4547
4548
_rtw_memcpy(pwrpriv->patterns[index].mask,
4549
&multicast_mask, sizeof(multicast_mask));
4550
4551
pwrpriv->patterns[index].len =
4552
IP_OFFSET + sizeof(multicast_ip);
4553
break;
4554
default:
4555
break;
4556
}
4557
}
4558
return index;
4559
}
4560
4561
void rtw_dump_priv_pattern(_adapter *adapter, u8 idx)
4562
{
4563
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4564
char str_1[128];
4565
char *p_str;
4566
u8 val8 = 0;
4567
int i = 0, j = 0, len = 0, max_len = 0;
4568
4569
RTW_INFO("=========[%d]========\n", idx);
4570
4571
RTW_INFO(">>>priv_pattern_content:\n");
4572
p_str = str_1;
4573
max_len = sizeof(str_1);
4574
for (i = 0 ; i < MAX_WKFM_PATTERN_SIZE / 8 ; i++) {
4575
_rtw_memset(p_str, 0, max_len);
4576
len = 0;
4577
for (j = 0 ; j < 8 ; j++) {
4578
val8 = pwrctl->patterns[idx].content[i * 8 + j];
4579
len += snprintf(p_str + len, max_len - len,
4580
"%02x ", val8);
4581
}
4582
RTW_INFO("%s\n", p_str);
4583
}
4584
4585
RTW_INFO(">>>priv_pattern_mask:\n");
4586
for (i = 0 ; i < MAX_WKFM_SIZE / 8 ; i++) {
4587
_rtw_memset(p_str, 0, max_len);
4588
len = 0;
4589
for (j = 0 ; j < 8 ; j++) {
4590
val8 = pwrctl->patterns[idx].mask[i * 8 + j];
4591
len += snprintf(p_str + len, max_len - len,
4592
"%02x ", val8);
4593
}
4594
RTW_INFO("%s\n", p_str);
4595
}
4596
4597
RTW_INFO(">>>priv_pattern_len:\n");
4598
RTW_INFO("%s: len: %d\n", __func__, pwrctl->patterns[idx].len);
4599
}
4600
4601
void rtw_wow_pattern_sw_dump(_adapter *adapter)
4602
{
4603
int i;
4604
4605
RTW_INFO("********[RTK priv-patterns]*********\n");
4606
for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++)
4607
rtw_dump_priv_pattern(adapter, i);
4608
}
4609
4610
void rtw_get_sec_iv(PADAPTER padapter, u8 *pcur_dot11txpn, u8 *StaAddr)
4611
{
4612
struct sta_info *psta;
4613
struct security_priv *psecpriv = &padapter->securitypriv;
4614
4615
_rtw_memset(pcur_dot11txpn, 0, 8);
4616
if (NULL == StaAddr)
4617
return;
4618
psta = rtw_get_stainfo(&padapter->stapriv, StaAddr);
4619
RTW_INFO("%s(): StaAddr: %02x %02x %02x %02x %02x %02x\n",
4620
__func__, StaAddr[0], StaAddr[1], StaAddr[2],
4621
StaAddr[3], StaAddr[4], StaAddr[5]);
4622
4623
if (psta) {
4624
if (psecpriv->dot11PrivacyAlgrthm == _AES_)
4625
AES_IV(pcur_dot11txpn, psta->dot11txpn, 0);
4626
else if (psecpriv->dot11PrivacyAlgrthm == _TKIP_)
4627
TKIP_IV(pcur_dot11txpn, psta->dot11txpn, 0);
4628
4629
RTW_INFO("%s(): CurrentIV: %02x %02x %02x %02x %02x %02x %02x %02x\n"
4630
, __func__, pcur_dot11txpn[0], pcur_dot11txpn[1],
4631
pcur_dot11txpn[2], pcur_dot11txpn[3], pcur_dot11txpn[4],
4632
pcur_dot11txpn[5], pcur_dot11txpn[6], pcur_dot11txpn[7]);
4633
}
4634
}
4635
#endif /* CONFIG_WOWLAN */
4636
4637
#ifdef CONFIG_PNO_SUPPORT
4638
#define CSCAN_TLV_TYPE_SSID_IE 'S'
4639
#define CIPHER_IE "key_mgmt="
4640
#define CIPHER_NONE "NONE"
4641
#define CIPHER_WPA_PSK "WPA-PSK"
4642
#define CIPHER_WPA_EAP "WPA-EAP IEEE8021X"
4643
/*
4644
* SSIDs list parsing from cscan tlv list
4645
*/
4646
int rtw_parse_ssid_list_tlv(char **list_str, pno_ssid_t *ssid,
4647
int max, int *bytes_left)
4648
{
4649
char *str;
4650
4651
int idx = 0;
4652
4653
if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) {
4654
RTW_INFO("%s error paramters\n", __func__);
4655
return -1;
4656
}
4657
4658
str = *list_str;
4659
while (*bytes_left > 0) {
4660
4661
if (str[0] != CSCAN_TLV_TYPE_SSID_IE) {
4662
*list_str = str;
4663
RTW_INFO("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0]);
4664
return idx;
4665
}
4666
4667
/* Get proper CSCAN_TLV_TYPE_SSID_IE */
4668
*bytes_left -= 1;
4669
str += 1;
4670
4671
if (str[0] == 0) {
4672
/* Broadcast SSID */
4673
ssid[idx].SSID_len = 0;
4674
memset((char *)ssid[idx].SSID, 0x0, WLAN_SSID_MAXLEN);
4675
*bytes_left -= 1;
4676
str += 1;
4677
4678
RTW_INFO("BROADCAST SCAN left=%d\n", *bytes_left);
4679
} else if (str[0] <= WLAN_SSID_MAXLEN) {
4680
/* Get proper SSID size */
4681
ssid[idx].SSID_len = str[0];
4682
*bytes_left -= 1;
4683
str += 1;
4684
4685
/* Get SSID */
4686
if (ssid[idx].SSID_len > *bytes_left) {
4687
RTW_INFO("%s out of memory range len=%d but left=%d\n",
4688
__func__, ssid[idx].SSID_len, *bytes_left);
4689
return -1;
4690
}
4691
4692
memcpy((char *)ssid[idx].SSID, str, ssid[idx].SSID_len);
4693
4694
*bytes_left -= ssid[idx].SSID_len;
4695
str += ssid[idx].SSID_len;
4696
4697
RTW_INFO("%s :size=%d left=%d\n",
4698
(char *)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left);
4699
} else {
4700
RTW_INFO("### SSID size more that %d\n", str[0]);
4701
return -1;
4702
}
4703
4704
if (idx++ > max) {
4705
RTW_INFO("%s number of SSIDs more that %d\n", __func__, idx);
4706
return -1;
4707
}
4708
}
4709
4710
*list_str = str;
4711
return idx;
4712
}
4713
4714
int rtw_parse_cipher_list(struct pno_nlo_info *nlo_info, char *list_str)
4715
{
4716
4717
char *pch, *pnext, *pend;
4718
u8 key_len = 0, index = 0;
4719
4720
pch = list_str;
4721
4722
if (nlo_info == NULL || list_str == NULL) {
4723
RTW_INFO("%s error paramters\n", __func__);
4724
return -1;
4725
}
4726
4727
while (strlen(pch) != 0) {
4728
pnext = strstr(pch, "key_mgmt=");
4729
if (pnext != NULL) {
4730
pch = pnext + strlen(CIPHER_IE);
4731
pend = strstr(pch, "}");
4732
if (strncmp(pch, CIPHER_NONE,
4733
strlen(CIPHER_NONE)) == 0)
4734
nlo_info->ssid_cipher_info[index] = 0x00;
4735
else if (strncmp(pch, CIPHER_WPA_PSK,
4736
strlen(CIPHER_WPA_PSK)) == 0)
4737
nlo_info->ssid_cipher_info[index] = 0x66;
4738
else if (strncmp(pch, CIPHER_WPA_EAP,
4739
strlen(CIPHER_WPA_EAP)) == 0)
4740
nlo_info->ssid_cipher_info[index] = 0x01;
4741
index++;
4742
pch = pend + 1;
4743
} else
4744
break;
4745
}
4746
return 0;
4747
}
4748
4749
int rtw_dev_nlo_info_set(struct pno_nlo_info *nlo_info, pno_ssid_t *ssid,
4750
int num, int pno_time, int pno_repeat, int pno_freq_expo_max)
4751
{
4752
4753
int i = 0;
4754
struct file *fp;
4755
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
4756
mm_segment_t fs;
4757
#endif
4758
loff_t pos = 0;
4759
u8 *source = NULL;
4760
long len = 0;
4761
4762
RTW_INFO("+%s+\n", __func__);
4763
4764
nlo_info->fast_scan_period = pno_time;
4765
nlo_info->ssid_num = num & BIT_LEN_MASK_32(8);
4766
nlo_info->hidden_ssid_num = num & BIT_LEN_MASK_32(8);
4767
nlo_info->slow_scan_period = (pno_time * 2);
4768
nlo_info->fast_scan_iterations = 5;
4769
4770
if (nlo_info->hidden_ssid_num > 8)
4771
nlo_info->hidden_ssid_num = 8;
4772
4773
/* TODO: channel list and probe index is all empty. */
4774
for (i = 0 ; i < num ; i++) {
4775
nlo_info->ssid_length[i]
4776
= ssid[i].SSID_len;
4777
}
4778
4779
/* cipher array */
4780
fp = filp_open("/data/misc/wifi/wpa_supplicant.conf", O_RDONLY, 0644);
4781
if (IS_ERR(fp)) {
4782
RTW_INFO("Error, wpa_supplicant.conf doesn't exist.\n");
4783
RTW_INFO("Error, cipher array using default value.\n");
4784
return 0;
4785
}
4786
4787
len = i_size_read(fp->f_path.dentry->d_inode);
4788
if (len < 0 || len > 2048) {
4789
RTW_INFO("Error, file size is bigger than 2048.\n");
4790
RTW_INFO("Error, cipher array using default value.\n");
4791
return 0;
4792
}
4793
4794
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
4795
fs = get_fs();
4796
set_fs(KERNEL_DS);
4797
#endif
4798
4799
source = rtw_zmalloc(2048);
4800
4801
if (source != NULL) {
4802
len = vfs_read(fp, source, len, &pos);
4803
rtw_parse_cipher_list(nlo_info, source);
4804
rtw_mfree(source, 2048);
4805
}
4806
4807
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
4808
set_fs(fs);
4809
#endif
4810
filp_close(fp, NULL);
4811
4812
RTW_INFO("-%s-\n", __func__);
4813
return 0;
4814
}
4815
4816
int rtw_dev_ssid_list_set(struct pno_ssid_list *pno_ssid_list,
4817
pno_ssid_t *ssid, u8 num)
4818
{
4819
4820
int i = 0;
4821
if (num > MAX_PNO_LIST_COUNT)
4822
num = MAX_PNO_LIST_COUNT;
4823
4824
for (i = 0 ; i < num ; i++) {
4825
_rtw_memcpy(&pno_ssid_list->node[i].SSID,
4826
ssid[i].SSID, ssid[i].SSID_len);
4827
pno_ssid_list->node[i].SSID_len = ssid[i].SSID_len;
4828
}
4829
return 0;
4830
}
4831
4832
int rtw_dev_scan_info_set(_adapter *padapter, pno_ssid_t *ssid,
4833
unsigned char ch, unsigned char ch_offset, unsigned short bw_mode)
4834
{
4835
4836
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4837
struct pno_scan_info *scan_info = pwrctl->pscan_info;
4838
int i;
4839
4840
scan_info->channel_num = MAX_SCAN_LIST_COUNT;
4841
scan_info->orig_ch = ch;
4842
scan_info->orig_bw = bw_mode;
4843
scan_info->orig_40_offset = ch_offset;
4844
4845
for (i = 0 ; i < scan_info->channel_num ; i++) {
4846
if (i < 11)
4847
scan_info->ssid_channel_info[i].active = 1;
4848
else
4849
scan_info->ssid_channel_info[i].active = 0;
4850
4851
scan_info->ssid_channel_info[i].timeout = 100;
4852
4853
scan_info->ssid_channel_info[i].tx_power =
4854
phy_get_tx_power_index(padapter, 0, 0x02, bw_mode, i + 1);
4855
4856
scan_info->ssid_channel_info[i].channel = i + 1;
4857
}
4858
4859
RTW_INFO("%s, channel_num: %d, orig_ch: %d, orig_bw: %d orig_40_offset: %d\n",
4860
__func__, scan_info->channel_num, scan_info->orig_ch,
4861
scan_info->orig_bw, scan_info->orig_40_offset);
4862
return 0;
4863
}
4864
4865
int rtw_dev_pno_set(struct net_device *net, pno_ssid_t *ssid, int num,
4866
int pno_time, int pno_repeat, int pno_freq_expo_max)
4867
{
4868
4869
_adapter *padapter = (_adapter *)rtw_netdev_priv(net);
4870
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4871
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4872
4873
int ret = -1;
4874
4875
if (num == 0) {
4876
RTW_INFO("%s, nssid is zero, no need to setup pno ssid list\n", __func__);
4877
return 0;
4878
}
4879
4880
if (pwrctl == NULL) {
4881
RTW_INFO("%s, ERROR: pwrctl is NULL\n", __func__);
4882
return -1;
4883
} else {
4884
pwrctl->pnlo_info =
4885
(pno_nlo_info_t *)rtw_zmalloc(sizeof(pno_nlo_info_t));
4886
pwrctl->pno_ssid_list =
4887
(pno_ssid_list_t *)rtw_zmalloc(sizeof(pno_ssid_list_t));
4888
pwrctl->pscan_info =
4889
(pno_scan_info_t *)rtw_zmalloc(sizeof(pno_scan_info_t));
4890
}
4891
4892
if (pwrctl->pnlo_info == NULL ||
4893
pwrctl->pscan_info == NULL ||
4894
pwrctl->pno_ssid_list == NULL) {
4895
RTW_INFO("%s, ERROR: alloc nlo_info, ssid_list, scan_info fail\n", __func__);
4896
goto failing;
4897
}
4898
4899
pwrctl->wowlan_in_resume = _FALSE;
4900
4901
pwrctl->pno_inited = _TRUE;
4902
/* NLO Info */
4903
ret = rtw_dev_nlo_info_set(pwrctl->pnlo_info, ssid, num,
4904
pno_time, pno_repeat, pno_freq_expo_max);
4905
4906
/* SSID Info */
4907
ret = rtw_dev_ssid_list_set(pwrctl->pno_ssid_list, ssid, num);
4908
4909
/* SCAN Info */
4910
ret = rtw_dev_scan_info_set(padapter, ssid, pmlmeext->cur_channel,
4911
pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4912
4913
RTW_INFO("+%s num: %d, pno_time: %d, pno_repeat:%d, pno_freq_expo_max:%d+\n",
4914
__func__, num, pno_time, pno_repeat, pno_freq_expo_max);
4915
4916
return 0;
4917
4918
failing:
4919
if (pwrctl->pnlo_info) {
4920
rtw_mfree((u8 *)pwrctl->pnlo_info, sizeof(pno_nlo_info_t));
4921
pwrctl->pnlo_info = NULL;
4922
}
4923
if (pwrctl->pno_ssid_list) {
4924
rtw_mfree((u8 *)pwrctl->pno_ssid_list, sizeof(pno_ssid_list_t));
4925
pwrctl->pno_ssid_list = NULL;
4926
}
4927
if (pwrctl->pscan_info) {
4928
rtw_mfree((u8 *)pwrctl->pscan_info, sizeof(pno_scan_info_t));
4929
pwrctl->pscan_info = NULL;
4930
}
4931
4932
return -1;
4933
}
4934
4935
#ifdef CONFIG_PNO_SET_DEBUG
4936
void rtw_dev_pno_debug(struct net_device *net)
4937
{
4938
_adapter *padapter = (_adapter *)rtw_netdev_priv(net);
4939
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4940
int i = 0, j = 0;
4941
4942
RTW_INFO("*******NLO_INFO********\n");
4943
RTW_INFO("ssid_num: %d\n", pwrctl->pnlo_info->ssid_num);
4944
RTW_INFO("fast_scan_iterations: %d\n",
4945
pwrctl->pnlo_info->fast_scan_iterations);
4946
RTW_INFO("fast_scan_period: %d\n", pwrctl->pnlo_info->fast_scan_period);
4947
RTW_INFO("slow_scan_period: %d\n", pwrctl->pnlo_info->slow_scan_period);
4948
4949
4950
4951
for (i = 0 ; i < MAX_PNO_LIST_COUNT ; i++) {
4952
RTW_INFO("%d SSID (%s) length (%d) cipher(%x) channel(%d)\n",
4953
i, pwrctl->pno_ssid_list->node[i].SSID, pwrctl->pnlo_info->ssid_length[i],
4954
pwrctl->pnlo_info->ssid_cipher_info[i], pwrctl->pnlo_info->ssid_channel_info[i]);
4955
}
4956
4957
RTW_INFO("******SCAN_INFO******\n");
4958
RTW_INFO("ch_num: %d\n", pwrctl->pscan_info->channel_num);
4959
RTW_INFO("orig_ch: %d\n", pwrctl->pscan_info->orig_ch);
4960
RTW_INFO("orig bw: %d\n", pwrctl->pscan_info->orig_bw);
4961
RTW_INFO("orig 40 offset: %d\n", pwrctl->pscan_info->orig_40_offset);
4962
for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
4963
RTW_INFO("[%02d] avtive:%d, timeout:%d, tx_power:%d, ch:%02d\n",
4964
i, pwrctl->pscan_info->ssid_channel_info[i].active,
4965
pwrctl->pscan_info->ssid_channel_info[i].timeout,
4966
pwrctl->pscan_info->ssid_channel_info[i].tx_power,
4967
pwrctl->pscan_info->ssid_channel_info[i].channel);
4968
}
4969
RTW_INFO("*****************\n");
4970
}
4971
#endif /* CONFIG_PNO_SET_DEBUG */
4972
#endif /* CONFIG_PNO_SUPPORT */
4973
4974
inline void rtw_collect_bcn_info(_adapter *adapter)
4975
{
4976
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4977
4978
if (!is_client_associated_to_ap(adapter))
4979
return;
4980
4981
pmlmeext->cur_bcn_cnt = pmlmeext->bcn_cnt - pmlmeext->last_bcn_cnt;
4982
pmlmeext->last_bcn_cnt = pmlmeext->bcn_cnt;
4983
/*TODO get offset of bcn's timestamp*/
4984
/*pmlmeext->bcn_timestamp;*/
4985
}
4986
4987