Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/ALFA-W1F1/RTL8814AU/core/rtw_ap.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_AP_C_
16
17
#include <drv_types.h>
18
#include <hal_data.h>
19
20
#ifdef CONFIG_AP_MODE
21
22
extern unsigned char RTW_WPA_OUI[];
23
extern unsigned char WMM_OUI[];
24
extern unsigned char WPS_OUI[];
25
extern unsigned char P2P_OUI[];
26
extern unsigned char WFD_OUI[];
27
28
void init_mlme_ap_info(_adapter *padapter)
29
{
30
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
31
32
_rtw_spinlock_init(&pmlmepriv->bcn_update_lock);
33
/* pmlmeext->bstart_bss = _FALSE; */
34
}
35
36
void free_mlme_ap_info(_adapter *padapter)
37
{
38
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
39
40
stop_ap_mode(padapter);
41
_rtw_spinlock_free(&pmlmepriv->bcn_update_lock);
42
43
}
44
45
/*
46
* Set TIM IE
47
* return length of total TIM IE
48
*/
49
u8 rtw_set_tim_ie(u8 dtim_cnt, u8 dtim_period
50
, const u8 *tim_bmp, u8 tim_bmp_len, u8 *tim_ie)
51
{
52
u8 *p = tim_ie;
53
u8 i, n1, n2;
54
u8 bmp_len;
55
56
if (rtw_bmp_not_empty(tim_bmp, tim_bmp_len)) {
57
/* find the first nonzero octet in tim_bitmap */
58
for (i = 0; i < tim_bmp_len; i++)
59
if (tim_bmp[i])
60
break;
61
n1 = i & 0xFE;
62
63
/* find the last nonzero octet in tim_bitmap, except octet 0 */
64
for (i = tim_bmp_len - 1; i > 0; i--)
65
if (tim_bmp[i])
66
break;
67
n2 = i;
68
bmp_len = n2 - n1 + 1;
69
} else {
70
n1 = n2 = 0;
71
bmp_len = 1;
72
}
73
74
*p++ = WLAN_EID_TIM;
75
*p++ = 2 + 1 + bmp_len;
76
*p++ = dtim_cnt;
77
*p++ = dtim_period;
78
*p++ = (rtw_bmp_is_set(tim_bmp, tim_bmp_len, 0) ? BIT0 : 0) | n1;
79
_rtw_memcpy(p, tim_bmp + n1, bmp_len);
80
81
#if 0
82
RTW_INFO("n1:%u, n2:%u, bmp_offset:%u, bmp_len:%u\n", n1, n2, n1 / 2, bmp_len);
83
RTW_INFO_DUMP("tim_ie: ", tim_ie + 2, 2 + 1 + bmp_len);
84
#endif
85
return 2 + 2 + 1 + bmp_len;
86
}
87
88
static void update_BCNTIM(_adapter *padapter)
89
{
90
struct sta_priv *pstapriv = &padapter->stapriv;
91
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
92
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
93
WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);
94
unsigned char *pie = pnetwork_mlmeext->IEs;
95
96
#if 0
97
98
99
/* update TIM IE */
100
/* if(rtw_tim_map_anyone_be_set(padapter, pstapriv->tim_bitmap)) */
101
#endif
102
if (_TRUE) {
103
u8 *p, *dst_ie, *premainder_ie = NULL, *pbackup_remainder_ie = NULL;
104
uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
105
106
p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);
107
if (p != NULL && tim_ielen > 0) {
108
tim_ielen += 2;
109
110
premainder_ie = p + tim_ielen;
111
112
tim_ie_offset = (sint)(p - pie);
113
114
remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen;
115
116
/*append TIM IE from dst_ie offset*/
117
dst_ie = p;
118
} else {
119
tim_ielen = 0;
120
121
/*calculate head_len*/
122
offset = _FIXED_IE_LENGTH_;
123
124
/* get ssid_ie len */
125
p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SSID_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
126
if (p != NULL)
127
offset += tmp_len + 2;
128
129
/*get supported rates len*/
130
p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
131
if (p != NULL)
132
offset += tmp_len + 2;
133
134
/*DS Parameter Set IE, len=3*/
135
offset += 3;
136
137
premainder_ie = pie + offset;
138
139
remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen;
140
141
/*append TIM IE from offset*/
142
dst_ie = pie + offset;
143
144
}
145
146
if (remainder_ielen > 0) {
147
pbackup_remainder_ie = rtw_malloc(remainder_ielen);
148
if (pbackup_remainder_ie && premainder_ie)
149
_rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
150
}
151
152
/* append TIM IE */
153
dst_ie += rtw_set_tim_ie(0, 1, pstapriv->tim_bitmap, pstapriv->aid_bmp_len, dst_ie);
154
155
/*copy remainder IE*/
156
if (pbackup_remainder_ie) {
157
_rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
158
159
rtw_mfree(pbackup_remainder_ie, remainder_ielen);
160
}
161
162
offset = (uint)(dst_ie - pie);
163
pnetwork_mlmeext->IELength = offset + remainder_ielen;
164
165
}
166
}
167
168
void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len)
169
{
170
PNDIS_802_11_VARIABLE_IEs pIE;
171
u8 bmatch = _FALSE;
172
u8 *pie = pnetwork->IEs;
173
u8 *p = NULL, *dst_ie = NULL, *premainder_ie = NULL, *pbackup_remainder_ie = NULL;
174
u32 i, offset, ielen, ie_offset, remainder_ielen = 0;
175
176
for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;) {
177
pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
178
179
if (pIE->ElementID > index)
180
break;
181
else if (pIE->ElementID == index) { /* already exist the same IE */
182
p = (u8 *)pIE;
183
ielen = pIE->Length;
184
bmatch = _TRUE;
185
break;
186
}
187
188
p = (u8 *)pIE;
189
ielen = pIE->Length;
190
i += (pIE->Length + 2);
191
}
192
193
if (p != NULL && ielen > 0) {
194
ielen += 2;
195
196
premainder_ie = p + ielen;
197
198
ie_offset = (sint)(p - pie);
199
200
remainder_ielen = pnetwork->IELength - ie_offset - ielen;
201
202
if (bmatch)
203
dst_ie = p;
204
else
205
dst_ie = (p + ielen);
206
}
207
208
if (dst_ie == NULL)
209
return;
210
211
if (remainder_ielen > 0) {
212
pbackup_remainder_ie = rtw_malloc(remainder_ielen);
213
if (pbackup_remainder_ie && premainder_ie)
214
_rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
215
}
216
217
*dst_ie++ = index;
218
*dst_ie++ = len;
219
220
_rtw_memcpy(dst_ie, data, len);
221
dst_ie += len;
222
223
/* copy remainder IE */
224
if (pbackup_remainder_ie) {
225
_rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
226
227
rtw_mfree(pbackup_remainder_ie, remainder_ielen);
228
}
229
230
offset = (uint)(dst_ie - pie);
231
pnetwork->IELength = offset + remainder_ielen;
232
}
233
234
void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index)
235
{
236
u8 *p, *dst_ie = NULL, *premainder_ie = NULL, *pbackup_remainder_ie = NULL;
237
uint offset, ielen, ie_offset, remainder_ielen = 0;
238
u8 *pie = pnetwork->IEs;
239
240
p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, index, &ielen, pnetwork->IELength - _FIXED_IE_LENGTH_);
241
if (p != NULL && ielen > 0) {
242
ielen += 2;
243
244
premainder_ie = p + ielen;
245
246
ie_offset = (sint)(p - pie);
247
248
remainder_ielen = pnetwork->IELength - ie_offset - ielen;
249
250
dst_ie = p;
251
} else
252
return;
253
254
if (remainder_ielen > 0) {
255
pbackup_remainder_ie = rtw_malloc(remainder_ielen);
256
if (pbackup_remainder_ie && premainder_ie)
257
_rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
258
}
259
260
/* copy remainder IE */
261
if (pbackup_remainder_ie) {
262
_rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
263
264
rtw_mfree(pbackup_remainder_ie, remainder_ielen);
265
}
266
267
offset = (uint)(dst_ie - pie);
268
pnetwork->IELength = offset + remainder_ielen;
269
}
270
271
272
u8 chk_sta_is_alive(struct sta_info *psta);
273
u8 chk_sta_is_alive(struct sta_info *psta)
274
{
275
u8 ret = _FALSE;
276
#ifdef DBG_EXPIRATION_CHK
277
RTW_INFO("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", expire_to:%u, %s%ssq_len:%u\n"
278
, MAC_ARG(psta->cmn.mac_addr)
279
, psta->cmn.rssi_stat.rssi
280
/* , STA_RX_PKTS_ARG(psta) */
281
, STA_RX_PKTS_DIFF_ARG(psta)
282
, psta->expire_to
283
, psta->state & WIFI_SLEEP_STATE ? "PS, " : ""
284
, psta->state & WIFI_STA_ALIVE_CHK_STATE ? "SAC, " : ""
285
, psta->sleepq_len
286
);
287
#endif
288
289
/* if(sta_last_rx_pkts(psta) == sta_rx_pkts(psta)) */
290
if ((psta->sta_stats.last_rx_data_pkts + psta->sta_stats.last_rx_ctrl_pkts) == (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts)) {
291
#if 0
292
if (psta->state & WIFI_SLEEP_STATE)
293
ret = _TRUE;
294
#endif
295
} else
296
ret = _TRUE;
297
298
#ifdef CONFIG_RTW_MESH
299
if (MLME_IS_MESH(psta->padapter)) {
300
u8 bcn_alive, hwmp_alive;
301
302
hwmp_alive = (psta->sta_stats.rx_hwmp_pkts !=
303
psta->sta_stats.last_rx_hwmp_pkts);
304
bcn_alive = (psta->sta_stats.rx_beacon_pkts !=
305
psta->sta_stats.last_rx_beacon_pkts);
306
/* The reference for nexthop_lookup */
307
psta->alive = ret || hwmp_alive || bcn_alive;
308
/* The reference for expire_timeout_chk */
309
/* Exclude bcn_alive to avoid a misjudge condition
310
that a peer unexpectedly leave and restart quickly*/
311
ret = ret || hwmp_alive;
312
}
313
#endif
314
315
sta_update_last_rx_pkts(psta);
316
317
return ret;
318
}
319
320
/**
321
* issue_aka_chk_frame - issue active keep alive check frame
322
* aka = active keep alive
323
*/
324
#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
325
static int issue_aka_chk_frame(_adapter *adapter, struct sta_info *psta)
326
{
327
int ret = _FAIL;
328
u8 *target_addr = psta->cmn.mac_addr;
329
330
if (MLME_IS_AP(adapter)) {
331
/* issue null data to check sta alive */
332
if (psta->state & WIFI_SLEEP_STATE)
333
ret = issue_nulldata(adapter, target_addr, 0, 1, 50);
334
else
335
ret = issue_nulldata(adapter, target_addr, 0, 3, 50);
336
}
337
338
#ifdef CONFIG_RTW_MESH
339
if (MLME_IS_MESH(adapter)) {
340
struct rtw_mesh_path *mpath;
341
342
rtw_rcu_read_lock();
343
mpath = rtw_mesh_path_lookup(adapter, target_addr);
344
if (!mpath) {
345
mpath = rtw_mesh_path_add(adapter, target_addr);
346
if (IS_ERR(mpath)) {
347
rtw_rcu_read_unlock();
348
RTW_ERR(FUNC_ADPT_FMT" rtw_mesh_path_add for "MAC_FMT" fail.\n",
349
FUNC_ADPT_ARG(adapter), MAC_ARG(target_addr));
350
return _FAIL;
351
}
352
}
353
if (mpath->flags & RTW_MESH_PATH_ACTIVE)
354
ret = _SUCCESS;
355
else {
356
u8 flags = RTW_PREQ_Q_F_START | RTW_PREQ_Q_F_PEER_AKA;
357
/* issue PREQ to check peer alive */
358
rtw_mesh_queue_preq(mpath, flags);
359
ret = _FALSE;
360
}
361
rtw_rcu_read_unlock();
362
}
363
#endif
364
return ret;
365
}
366
#endif
367
368
#ifdef RTW_CONFIG_RFREG18_WA
369
static void rtw_check_restore_rf18(_adapter *padapter)
370
{
371
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
372
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
373
u32 reg;
374
u8 union_ch = 0, union_bw = 0, union_offset = 0, setchbw = _FALSE;
375
376
reg = rtw_hal_read_rfreg(padapter, 0, 0x18, 0x3FF);
377
if ((reg & 0xFF) == 0)
378
setchbw = _TRUE;
379
reg = rtw_hal_read_rfreg(padapter, 1, 0x18, 0x3FF);
380
if ((reg & 0xFF) == 0)
381
setchbw = _TRUE;
382
383
if (setchbw) {
384
if (!rtw_mi_get_ch_setting_union(padapter, &union_ch, &union_bw, &union_offset)) {
385
RTW_INFO("Hit RF(0x18)=0!! restore original channel setting.\n");
386
union_ch = pmlmeext->cur_channel;
387
union_offset = pmlmeext->cur_ch_offset ;
388
union_bw = pmlmeext->cur_bwmode;
389
} else {
390
RTW_INFO("Hit RF(0x18)=0!! set ch(%x) offset(%x) bwmode(%x)\n", union_ch, union_offset, union_bw);
391
}
392
/* Initial the channel_bw setting procedure. */
393
pHalData->current_channel = 0;
394
set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
395
}
396
}
397
#endif
398
399
void expire_timeout_chk(_adapter *padapter)
400
{
401
_irqL irqL;
402
_list *phead, *plist;
403
u8 updated = _FALSE;
404
struct sta_info *psta = NULL;
405
struct sta_priv *pstapriv = &padapter->stapriv;
406
u8 chk_alive_num = 0;
407
char chk_alive_list[NUM_STA];
408
int i;
409
410
#ifdef CONFIG_RTW_MESH
411
if (MLME_IS_MESH(padapter)
412
&& check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)
413
) {
414
struct rtw_mesh_cfg *mcfg = &padapter->mesh_cfg;
415
416
rtw_mesh_path_expire(padapter);
417
418
/* TBD: up layer timeout mechanism */
419
/* if (!mcfg->plink_timeout)
420
return; */
421
#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
422
return;
423
#endif
424
}
425
#endif
426
427
#ifdef CONFIG_MCC_MODE
428
/* then driver may check fail due to not recv client's frame under sitesurvey,
429
* don't expire timeout chk under MCC under sitesurvey */
430
431
if (rtw_hal_mcc_link_status_chk(padapter, __func__) == _FALSE)
432
return;
433
#endif
434
435
_enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
436
437
phead = &pstapriv->auth_list;
438
plist = get_next(phead);
439
440
/* check auth_queue */
441
#ifdef DBG_EXPIRATION_CHK
442
if (rtw_end_of_queue_search(phead, plist) == _FALSE) {
443
RTW_INFO(FUNC_ADPT_FMT" auth_list, cnt:%u\n"
444
, FUNC_ADPT_ARG(padapter), pstapriv->auth_list_cnt);
445
}
446
#endif
447
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
448
psta = LIST_CONTAINOR(plist, struct sta_info, auth_list);
449
450
plist = get_next(plist);
451
452
453
#ifdef CONFIG_ATMEL_RC_PATCH
454
if (_rtw_memcmp((void *)(pstapriv->atmel_rc_pattern), (void *)(psta->cmn.mac_addr), ETH_ALEN) == _TRUE)
455
continue;
456
if (psta->flag_atmel_rc)
457
continue;
458
#endif
459
if (psta->expire_to > 0) {
460
psta->expire_to--;
461
if (psta->expire_to == 0) {
462
rtw_list_delete(&psta->auth_list);
463
pstapriv->auth_list_cnt--;
464
465
RTW_INFO(FUNC_ADPT_FMT" auth expire "MAC_FMT"\n"
466
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
467
468
_exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
469
470
/* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
471
rtw_free_stainfo(padapter, psta);
472
/* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
473
474
_enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
475
}
476
}
477
478
}
479
480
_exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
481
psta = NULL;
482
483
484
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
485
486
phead = &pstapriv->asoc_list;
487
plist = get_next(phead);
488
489
/* check asoc_queue */
490
#ifdef DBG_EXPIRATION_CHK
491
if (rtw_end_of_queue_search(phead, plist) == _FALSE) {
492
RTW_INFO(FUNC_ADPT_FMT" asoc_list, cnt:%u\n"
493
, FUNC_ADPT_ARG(padapter), pstapriv->asoc_list_cnt);
494
}
495
#endif
496
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
497
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
498
plist = get_next(plist);
499
#ifdef CONFIG_ATMEL_RC_PATCH
500
RTW_INFO("%s:%d psta=%p, %02x,%02x||%02x,%02x \n\n", __func__, __LINE__,
501
psta, pstapriv->atmel_rc_pattern[0], pstapriv->atmel_rc_pattern[5], psta->cmn.mac_addr[0], psta->cmn.mac_addr[5]);
502
if (_rtw_memcmp((void *)pstapriv->atmel_rc_pattern, (void *)(psta->cmn.mac_addr), ETH_ALEN) == _TRUE)
503
continue;
504
if (psta->flag_atmel_rc)
505
continue;
506
RTW_INFO("%s: debug line:%d\n", __func__, __LINE__);
507
#endif
508
#ifdef CONFIG_AUTO_AP_MODE
509
if (psta->isrc)
510
continue;
511
#endif
512
if (chk_sta_is_alive(psta) || !psta->expire_to) {
513
psta->expire_to = pstapriv->expire_to;
514
psta->keep_alive_trycnt = 0;
515
#ifdef CONFIG_TX_MCAST2UNI
516
psta->under_exist_checking = 0;
517
#endif /* CONFIG_TX_MCAST2UNI */
518
} else
519
psta->expire_to--;
520
521
#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
522
#ifdef CONFIG_80211N_HT
523
#ifdef CONFIG_TX_MCAST2UNI
524
if ((psta->flags & WLAN_STA_HT) && (psta->htpriv.agg_enable_bitmap || psta->under_exist_checking)) {
525
/* check sta by delba(addba) for 11n STA */
526
/* ToDo: use CCX report to check for all STAs */
527
/* RTW_INFO("asoc check by DELBA/ADDBA! (pstapriv->expire_to=%d s)(psta->expire_to=%d s), [%02x, %d]\n", pstapriv->expire_to*2, psta->expire_to*2, psta->htpriv.agg_enable_bitmap, psta->under_exist_checking); */
528
529
if (psta->expire_to <= (pstapriv->expire_to - 50)) {
530
RTW_INFO("asoc expire by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to - psta->expire_to) * 2);
531
psta->under_exist_checking = 0;
532
psta->expire_to = 0;
533
} else if (psta->expire_to <= (pstapriv->expire_to - 3) && (psta->under_exist_checking == 0)) {
534
RTW_INFO("asoc check by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to - psta->expire_to) * 2);
535
psta->under_exist_checking = 1;
536
/* tear down TX AMPDU */
537
send_delba(padapter, 1, psta->cmn.mac_addr);/* */ /* originator */
538
psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
539
psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
540
}
541
}
542
#endif /* CONFIG_TX_MCAST2UNI */
543
#endif /* CONFIG_80211N_HT */
544
#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
545
546
if (psta->expire_to <= 0) {
547
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
548
549
if (padapter->registrypriv.wifi_spec == 1) {
550
psta->expire_to = pstapriv->expire_to;
551
continue;
552
}
553
554
#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
555
#ifdef CONFIG_80211N_HT
556
557
#define KEEP_ALIVE_TRYCNT (3)
558
559
if (psta->keep_alive_trycnt > 0 && psta->keep_alive_trycnt <= KEEP_ALIVE_TRYCNT) {
560
if (psta->state & WIFI_STA_ALIVE_CHK_STATE)
561
psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
562
else
563
psta->keep_alive_trycnt = 0;
564
565
} else if ((psta->keep_alive_trycnt > KEEP_ALIVE_TRYCNT) && !(psta->state & WIFI_STA_ALIVE_CHK_STATE))
566
psta->keep_alive_trycnt = 0;
567
if ((psta->htpriv.ht_option == _TRUE) && (psta->htpriv.ampdu_enable == _TRUE)) {
568
uint priority = 1; /* test using BK */
569
u8 issued = 0;
570
571
/* issued = (psta->htpriv.agg_enable_bitmap>>priority)&0x1; */
572
issued |= (psta->htpriv.candidate_tid_bitmap >> priority) & 0x1;
573
574
if (0 == issued) {
575
if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
576
psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
577
578
if (psta->state & WIFI_SLEEP_STATE)
579
psta->expire_to = 2; /* 2x2=4 sec */
580
else
581
psta->expire_to = 1; /* 2 sec */
582
583
psta->state |= WIFI_STA_ALIVE_CHK_STATE;
584
585
/* add_ba_hdl(padapter, (u8*)paddbareq_parm); */
586
587
RTW_INFO("issue addba_req to check if sta alive, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt);
588
589
issue_addba_req(padapter, psta->cmn.mac_addr, (u8)priority);
590
591
_set_timer(&psta->addba_retry_timer, ADDBA_TO);
592
593
psta->keep_alive_trycnt++;
594
595
continue;
596
}
597
}
598
}
599
if (psta->keep_alive_trycnt > 0 && psta->state & WIFI_STA_ALIVE_CHK_STATE) {
600
psta->keep_alive_trycnt = 0;
601
psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
602
RTW_INFO("change to another methods to check alive if staion is at ps mode\n");
603
}
604
605
#endif /* CONFIG_80211N_HT */
606
#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
607
if (psta->state & WIFI_SLEEP_STATE) {
608
if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
609
/* to check if alive by another methods if staion is at ps mode. */
610
psta->expire_to = pstapriv->expire_to;
611
psta->state |= WIFI_STA_ALIVE_CHK_STATE;
612
613
/* RTW_INFO("alive chk, sta:" MAC_FMT " is at ps mode!\n", MAC_ARG(psta->cmn.mac_addr)); */
614
615
/* to update bcn with tim_bitmap for this station */
616
rtw_tim_map_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid);
617
update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0);
618
619
if (!pmlmeext->active_keep_alive_check)
620
continue;
621
}
622
}
623
624
{
625
int stainfo_offset;
626
627
stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
628
if (stainfo_offset_valid(stainfo_offset))
629
chk_alive_list[chk_alive_num++] = stainfo_offset;
630
continue;
631
}
632
} else {
633
/* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
634
if (psta->sleepq_len > (NR_XMITFRAME / pstapriv->asoc_list_cnt)
635
&& padapter->xmitpriv.free_xmitframe_cnt < ((NR_XMITFRAME / pstapriv->asoc_list_cnt) / 2)
636
) {
637
RTW_INFO(FUNC_ADPT_FMT" sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n"
638
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
639
, psta->sleepq_len, padapter->xmitpriv.free_xmitframe_cnt, pstapriv->asoc_list_cnt);
640
wakeup_sta_to_xmit(padapter, psta);
641
}
642
}
643
}
644
645
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
646
647
if (chk_alive_num) {
648
#if defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK)
649
u8 backup_ch = 0, backup_bw = 0, backup_offset = 0;
650
u8 union_ch = 0, union_bw = 0, union_offset = 0;
651
u8 switch_channel_by_drv = _TRUE;
652
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
653
#endif
654
char del_asoc_list[NUM_STA];
655
656
_rtw_memset(del_asoc_list, NUM_STA, NUM_STA);
657
658
#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
659
if (pmlmeext->active_keep_alive_check) {
660
#ifdef CONFIG_MCC_MODE
661
if (MCC_EN(padapter)) {
662
/* driver doesn't switch channel under MCC */
663
if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
664
switch_channel_by_drv = _FALSE;
665
}
666
#endif
667
668
if (!rtw_mi_get_ch_setting_union(padapter, &union_ch, &union_bw, &union_offset)
669
|| pmlmeext->cur_channel != union_ch)
670
switch_channel_by_drv = _FALSE;
671
672
/* switch to correct channel of current network before issue keep-alive frames */
673
if (switch_channel_by_drv == _TRUE && rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
674
backup_ch = rtw_get_oper_ch(padapter);
675
backup_bw = rtw_get_oper_bw(padapter);
676
backup_offset = rtw_get_oper_choffset(padapter);
677
set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
678
}
679
}
680
#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
681
682
/* check loop */
683
for (i = 0; i < chk_alive_num; i++) {
684
#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
685
int ret = _FAIL;
686
#endif
687
688
psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
689
690
#ifdef CONFIG_ATMEL_RC_PATCH
691
if (_rtw_memcmp(pstapriv->atmel_rc_pattern, psta->cmn.mac_addr, ETH_ALEN) == _TRUE)
692
continue;
693
if (psta->flag_atmel_rc)
694
continue;
695
#endif
696
697
if (!(psta->state & _FW_LINKED))
698
continue;
699
700
#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
701
if (pmlmeext->active_keep_alive_check) {
702
/* issue active keep alive frame to check */
703
ret = issue_aka_chk_frame(padapter, psta);
704
705
psta->keep_alive_trycnt++;
706
if (ret == _SUCCESS) {
707
RTW_INFO(FUNC_ADPT_FMT" asoc check, "MAC_FMT" is alive\n"
708
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
709
psta->expire_to = pstapriv->expire_to;
710
psta->keep_alive_trycnt = 0;
711
continue;
712
} else if (psta->keep_alive_trycnt <= 3) {
713
RTW_INFO(FUNC_ADPT_FMT" asoc check, "MAC_FMT" keep_alive_trycnt=%d\n"
714
, FUNC_ADPT_ARG(padapter) , MAC_ARG(psta->cmn.mac_addr), psta->keep_alive_trycnt);
715
psta->expire_to = 1;
716
continue;
717
}
718
}
719
#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
720
721
psta->keep_alive_trycnt = 0;
722
del_asoc_list[i] = chk_alive_list[i];
723
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
724
if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
725
rtw_list_delete(&psta->asoc_list);
726
pstapriv->asoc_list_cnt--;
727
STA_SET_MESH_PLINK(psta, NULL);
728
}
729
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
730
}
731
732
/* delete loop */
733
for (i = 0; i < chk_alive_num; i++) {
734
u8 sta_addr[ETH_ALEN];
735
736
if (del_asoc_list[i] >= NUM_STA)
737
continue;
738
739
psta = rtw_get_stainfo_by_offset(pstapriv, del_asoc_list[i]);
740
_rtw_memcpy(sta_addr, psta->cmn.mac_addr, ETH_ALEN);
741
742
RTW_INFO(FUNC_ADPT_FMT" asoc expire "MAC_FMT", state=0x%x\n"
743
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr), psta->state);
744
#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
745
updated |= ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING, _FALSE);
746
#else
747
updated |= ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);
748
#endif
749
#ifdef CONFIG_RTW_MESH
750
if (MLME_IS_MESH(padapter))
751
rtw_mesh_expire_peer(padapter, sta_addr);
752
#endif
753
}
754
755
#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
756
if (pmlmeext->active_keep_alive_check) {
757
/* back to the original operation channel */
758
if (switch_channel_by_drv == _TRUE && backup_ch > 0)
759
set_channel_bwmode(padapter, backup_ch, backup_offset, backup_bw);
760
}
761
#endif
762
}
763
764
#ifdef RTW_CONFIG_RFREG18_WA
765
rtw_check_restore_rf18(padapter);
766
#endif
767
associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
768
}
769
770
void rtw_ap_update_sta_ra_info(_adapter *padapter, struct sta_info *psta)
771
{
772
unsigned char sta_band = 0;
773
u64 tx_ra_bitmap = 0;
774
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
775
WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
776
777
if (!psta)
778
return;
779
780
if (!(psta->state & _FW_LINKED))
781
return;
782
783
rtw_hal_update_sta_ra_info(padapter, psta);
784
tx_ra_bitmap = psta->cmn.ra_info.ramask;
785
786
if (pcur_network->Configuration.DSConfig > 14) {
787
788
if (tx_ra_bitmap & 0xffff000)
789
sta_band |= WIRELESS_11_5N;
790
791
if (tx_ra_bitmap & 0xff0)
792
sta_band |= WIRELESS_11A;
793
794
/* 5G band */
795
#ifdef CONFIG_80211AC_VHT
796
if (psta->vhtpriv.vht_option)
797
sta_band = WIRELESS_11_5AC;
798
#endif
799
} else {
800
if (tx_ra_bitmap & 0xffff000)
801
sta_band |= WIRELESS_11_24N;
802
803
if (tx_ra_bitmap & 0xff0)
804
sta_band |= WIRELESS_11G;
805
806
if (tx_ra_bitmap & 0x0f)
807
sta_band |= WIRELESS_11B;
808
}
809
810
psta->wireless_mode = sta_band;
811
rtw_hal_update_sta_wset(padapter, psta);
812
RTW_INFO("%s=> mac_id:%d , tx_ra_bitmap:0x%016llx, networkType:0x%02x\n",
813
__FUNCTION__, psta->cmn.mac_id, tx_ra_bitmap, psta->wireless_mode);
814
}
815
816
#ifdef CONFIG_BMC_TX_RATE_SELECT
817
u8 rtw_ap_find_mini_tx_rate(_adapter *adapter)
818
{
819
_irqL irqL;
820
_list *phead, *plist;
821
u8 miini_tx_rate = ODM_RATEVHTSS4MCS9, sta_tx_rate;
822
struct sta_info *psta = NULL;
823
struct sta_priv *pstapriv = &adapter->stapriv;
824
825
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
826
phead = &pstapriv->asoc_list;
827
plist = get_next(phead);
828
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
829
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
830
plist = get_next(plist);
831
832
sta_tx_rate = psta->cmn.ra_info.curr_tx_rate & 0x7F;
833
if (sta_tx_rate < miini_tx_rate)
834
miini_tx_rate = sta_tx_rate;
835
}
836
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
837
838
return miini_tx_rate;
839
}
840
841
u8 rtw_ap_find_bmc_rate(_adapter *adapter, u8 tx_rate)
842
{
843
PHAL_DATA_TYPE hal_data = GET_HAL_DATA(adapter);
844
u8 tx_ini_rate = ODM_RATE6M;
845
846
switch (tx_rate) {
847
case ODM_RATEVHTSS3MCS9:
848
case ODM_RATEVHTSS3MCS8:
849
case ODM_RATEVHTSS3MCS7:
850
case ODM_RATEVHTSS3MCS6:
851
case ODM_RATEVHTSS3MCS5:
852
case ODM_RATEVHTSS3MCS4:
853
case ODM_RATEVHTSS3MCS3:
854
case ODM_RATEVHTSS2MCS9:
855
case ODM_RATEVHTSS2MCS8:
856
case ODM_RATEVHTSS2MCS7:
857
case ODM_RATEVHTSS2MCS6:
858
case ODM_RATEVHTSS2MCS5:
859
case ODM_RATEVHTSS2MCS4:
860
case ODM_RATEVHTSS2MCS3:
861
case ODM_RATEVHTSS1MCS9:
862
case ODM_RATEVHTSS1MCS8:
863
case ODM_RATEVHTSS1MCS7:
864
case ODM_RATEVHTSS1MCS6:
865
case ODM_RATEVHTSS1MCS5:
866
case ODM_RATEVHTSS1MCS4:
867
case ODM_RATEVHTSS1MCS3:
868
case ODM_RATEMCS15:
869
case ODM_RATEMCS14:
870
case ODM_RATEMCS13:
871
case ODM_RATEMCS12:
872
case ODM_RATEMCS11:
873
case ODM_RATEMCS7:
874
case ODM_RATEMCS6:
875
case ODM_RATEMCS5:
876
case ODM_RATEMCS4:
877
case ODM_RATEMCS3:
878
case ODM_RATE54M:
879
case ODM_RATE48M:
880
case ODM_RATE36M:
881
case ODM_RATE24M:
882
tx_ini_rate = ODM_RATE24M;
883
break;
884
case ODM_RATEVHTSS3MCS2:
885
case ODM_RATEVHTSS3MCS1:
886
case ODM_RATEVHTSS2MCS2:
887
case ODM_RATEVHTSS2MCS1:
888
case ODM_RATEVHTSS1MCS2:
889
case ODM_RATEVHTSS1MCS1:
890
case ODM_RATEMCS10:
891
case ODM_RATEMCS9:
892
case ODM_RATEMCS2:
893
case ODM_RATEMCS1:
894
case ODM_RATE18M:
895
case ODM_RATE12M:
896
tx_ini_rate = ODM_RATE12M;
897
break;
898
case ODM_RATEVHTSS3MCS0:
899
case ODM_RATEVHTSS2MCS0:
900
case ODM_RATEVHTSS1MCS0:
901
case ODM_RATEMCS8:
902
case ODM_RATEMCS0:
903
case ODM_RATE9M:
904
case ODM_RATE6M:
905
tx_ini_rate = ODM_RATE6M;
906
break;
907
case ODM_RATE11M:
908
case ODM_RATE5_5M:
909
case ODM_RATE2M:
910
case ODM_RATE1M:
911
tx_ini_rate = ODM_RATE1M;
912
break;
913
default:
914
tx_ini_rate = ODM_RATE6M;
915
break;
916
}
917
918
if (hal_data->current_band_type == BAND_ON_5G)
919
if (tx_ini_rate < ODM_RATE6M)
920
tx_ini_rate = ODM_RATE6M;
921
922
return tx_ini_rate;
923
}
924
925
void rtw_update_bmc_sta_tx_rate(_adapter *adapter)
926
{
927
struct sta_info *psta = NULL;
928
u8 tx_rate;
929
930
psta = rtw_get_bcmc_stainfo(adapter);
931
if (psta == NULL) {
932
RTW_ERR(ADPT_FMT "could not get bmc_sta !!\n", ADPT_ARG(adapter));
933
return;
934
}
935
936
if (adapter->bmc_tx_rate != MGN_UNKNOWN) {
937
psta->init_rate = adapter->bmc_tx_rate;
938
goto _exit;
939
}
940
941
if (adapter->stapriv.asoc_sta_count <= 2)
942
goto _exit;
943
944
tx_rate = rtw_ap_find_mini_tx_rate(adapter);
945
#ifdef CONFIG_BMC_TX_LOW_RATE
946
tx_rate = rtw_ap_find_bmc_rate(adapter, tx_rate);
947
#endif
948
949
psta->init_rate = hw_rate_to_m_rate(tx_rate);
950
951
_exit:
952
RTW_INFO(ADPT_FMT" BMC Tx rate - %s\n", ADPT_ARG(adapter), MGN_RATE_STR(psta->init_rate));
953
}
954
#endif
955
956
void rtw_init_bmc_sta_tx_rate(_adapter *padapter, struct sta_info *psta)
957
{
958
#ifdef CONFIG_BMC_TX_LOW_RATE
959
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
960
#endif
961
u8 rate_idx = 0;
962
u8 brate_table[] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M,
963
MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M};
964
965
if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
966
return;
967
968
if (padapter->bmc_tx_rate != MGN_UNKNOWN)
969
psta->init_rate = padapter->bmc_tx_rate;
970
else {
971
#ifdef CONFIG_BMC_TX_LOW_RATE
972
if (IsEnableHWOFDM(pmlmeext->cur_wireless_mode) && (psta->cmn.ra_info.ramask && 0xFF0))
973
rate_idx = get_lowest_rate_idx_ex(psta->cmn.ra_info.ramask, 4); /*from basic rate*/
974
else
975
rate_idx = get_lowest_rate_idx(psta->cmn.ra_info.ramask); /*from basic rate*/
976
#else
977
rate_idx = get_highest_rate_idx(psta->cmn.ra_info.ramask); /*from basic rate*/
978
#endif
979
if (rate_idx < 12)
980
psta->init_rate = brate_table[rate_idx];
981
else
982
psta->init_rate = MGN_1M;
983
}
984
985
RTW_INFO(ADPT_FMT" BMC Init Tx rate - %s\n", ADPT_ARG(padapter), MGN_RATE_STR(psta->init_rate));
986
}
987
988
void update_bmc_sta(_adapter *padapter)
989
{
990
_irqL irqL;
991
unsigned char network_type;
992
int supportRateNum = 0;
993
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
994
WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
995
struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
996
997
if (psta) {
998
psta->cmn.aid = 0;/* default set to 0 */
999
#ifdef CONFIG_RTW_MESH
1000
if (MLME_IS_MESH(padapter))
1001
psta->qos_option = 1;
1002
else
1003
#endif
1004
psta->qos_option = 0;
1005
#ifdef CONFIG_80211N_HT
1006
psta->htpriv.ht_option = _FALSE;
1007
#endif /* CONFIG_80211N_HT */
1008
1009
psta->ieee8021x_blocked = 0;
1010
1011
_rtw_memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
1012
1013
/* psta->dot118021XPrivacy = _NO_PRIVACY_; */ /* !!! remove it, because it has been set before this. */
1014
1015
supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->SupportedRates);
1016
network_type = rtw_check_network_type((u8 *)&pcur_network->SupportedRates, supportRateNum, pcur_network->Configuration.DSConfig);
1017
if (IsSupportedTxCCK(network_type))
1018
network_type = WIRELESS_11B;
1019
else if (network_type == WIRELESS_INVALID) { /* error handling */
1020
if (pcur_network->Configuration.DSConfig > 14)
1021
network_type = WIRELESS_11A;
1022
else
1023
network_type = WIRELESS_11B;
1024
}
1025
update_sta_basic_rate(psta, network_type);
1026
psta->wireless_mode = network_type;
1027
1028
rtw_hal_update_sta_ra_info(padapter, psta);
1029
1030
_enter_critical_bh(&psta->lock, &irqL);
1031
psta->state = _FW_LINKED;
1032
_exit_critical_bh(&psta->lock, &irqL);
1033
1034
rtw_sta_media_status_rpt(padapter, psta, 1);
1035
rtw_init_bmc_sta_tx_rate(padapter, psta);
1036
1037
} else
1038
RTW_INFO("add_RATid_bmc_sta error!\n");
1039
1040
}
1041
1042
#if defined(CONFIG_80211N_HT) && defined(CONFIG_BEAMFORMING)
1043
void update_sta_info_apmode_ht_bf_cap(_adapter *padapter, struct sta_info *psta)
1044
{
1045
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1046
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
1047
struct ht_priv *phtpriv_sta = &psta->htpriv;
1048
1049
u8 cur_beamform_cap = 0;
1050
1051
/*Config Tx beamforming setting*/
1052
if (TEST_FLAG(phtpriv_ap->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) &&
1053
GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP((u8 *)(&phtpriv_sta->ht_cap))) {
1054
SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
1055
/*Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/
1056
SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS((u8 *)(&phtpriv_sta->ht_cap)) << 6);
1057
}
1058
1059
if (TEST_FLAG(phtpriv_ap->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&
1060
GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP((u8 *)(&phtpriv_sta->ht_cap))) {
1061
SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
1062
/*Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/
1063
SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS((u8 *)(&phtpriv_sta->ht_cap)) << 4);
1064
}
1065
if (cur_beamform_cap)
1066
RTW_INFO("Client STA(%d) HT Beamforming Cap = 0x%02X\n", psta->cmn.aid, cur_beamform_cap);
1067
1068
phtpriv_sta->beamform_cap = cur_beamform_cap;
1069
psta->cmn.bf_info.ht_beamform_cap = cur_beamform_cap;
1070
1071
}
1072
#endif /*CONFIG_80211N_HT && CONFIG_BEAMFORMING*/
1073
1074
/* notes:
1075
* AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode */
1076
void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta)
1077
{
1078
_irqL irqL;
1079
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1080
struct security_priv *psecuritypriv = &padapter->securitypriv;
1081
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1082
#ifdef CONFIG_80211N_HT
1083
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
1084
struct ht_priv *phtpriv_sta = &psta->htpriv;
1085
#endif /* CONFIG_80211N_HT */
1086
u8 cur_ldpc_cap = 0, cur_stbc_cap = 0;
1087
/* set intf_tag to if1 */
1088
/* psta->intf_tag = 0; */
1089
1090
RTW_INFO("%s\n", __FUNCTION__);
1091
1092
/*alloc macid when call rtw_alloc_stainfo(),release macid when call rtw_free_stainfo()*/
1093
1094
if (!MLME_IS_MESH(padapter) && psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
1095
psta->ieee8021x_blocked = _TRUE;
1096
else
1097
psta->ieee8021x_blocked = _FALSE;
1098
1099
1100
/* update sta's cap */
1101
1102
/* ERP */
1103
VCS_update(padapter, psta);
1104
#ifdef CONFIG_80211N_HT
1105
/* HT related cap */
1106
if (phtpriv_sta->ht_option) {
1107
/* check if sta supports rx ampdu */
1108
phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
1109
1110
phtpriv_sta->rx_ampdu_min_spacing = (phtpriv_sta->ht_cap.ampdu_params_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
1111
1112
/* bwmode */
1113
if ((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
1114
psta->cmn.bw_mode = CHANNEL_WIDTH_40;
1115
else
1116
psta->cmn.bw_mode = CHANNEL_WIDTH_20;
1117
1118
if (phtpriv_sta->op_present
1119
&& !GET_HT_OP_ELE_STA_CHL_WIDTH(phtpriv_sta->ht_op))
1120
psta->cmn.bw_mode = CHANNEL_WIDTH_20;
1121
1122
if (psta->ht_40mhz_intolerant)
1123
psta->cmn.bw_mode = CHANNEL_WIDTH_20;
1124
1125
if (pmlmeext->cur_bwmode < psta->cmn.bw_mode)
1126
psta->cmn.bw_mode = pmlmeext->cur_bwmode;
1127
1128
phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
1129
1130
1131
/* check if sta support s Short GI 20M */
1132
if ((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))
1133
phtpriv_sta->sgi_20m = _TRUE;
1134
1135
/* check if sta support s Short GI 40M */
1136
if ((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_40)) {
1137
if (psta->cmn.bw_mode == CHANNEL_WIDTH_40) /* according to psta->bw_mode */
1138
phtpriv_sta->sgi_40m = _TRUE;
1139
else
1140
phtpriv_sta->sgi_40m = _FALSE;
1141
}
1142
1143
psta->qos_option = _TRUE;
1144
1145
/* B0 Config LDPC Coding Capability */
1146
if (TEST_FLAG(phtpriv_ap->ldpc_cap, LDPC_HT_ENABLE_TX) &&
1147
GET_HT_CAP_ELE_LDPC_CAP((u8 *)(&phtpriv_sta->ht_cap))) {
1148
SET_FLAG(cur_ldpc_cap, (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX));
1149
RTW_INFO("Enable HT Tx LDPC for STA(%d)\n", psta->cmn.aid);
1150
}
1151
1152
/* B7 B8 B9 Config STBC setting */
1153
if (TEST_FLAG(phtpriv_ap->stbc_cap, STBC_HT_ENABLE_TX) &&
1154
GET_HT_CAP_ELE_RX_STBC((u8 *)(&phtpriv_sta->ht_cap))) {
1155
SET_FLAG(cur_stbc_cap, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX));
1156
RTW_INFO("Enable HT Tx STBC for STA(%d)\n", psta->cmn.aid);
1157
}
1158
1159
#ifdef CONFIG_BEAMFORMING
1160
update_sta_info_apmode_ht_bf_cap(padapter, psta);
1161
#endif
1162
} else {
1163
phtpriv_sta->ampdu_enable = _FALSE;
1164
1165
phtpriv_sta->sgi_20m = _FALSE;
1166
phtpriv_sta->sgi_40m = _FALSE;
1167
psta->cmn.bw_mode = CHANNEL_WIDTH_20;
1168
phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1169
}
1170
1171
phtpriv_sta->ldpc_cap = cur_ldpc_cap;
1172
phtpriv_sta->stbc_cap = cur_stbc_cap;
1173
1174
/* Rx AMPDU */
1175
send_delba(padapter, 0, psta->cmn.mac_addr);/* recipient */
1176
1177
/* TX AMPDU */
1178
send_delba(padapter, 1, psta->cmn.mac_addr);/* */ /* originator */
1179
phtpriv_sta->agg_enable_bitmap = 0x0;/* reset */
1180
phtpriv_sta->candidate_tid_bitmap = 0x0;/* reset */
1181
#endif /* CONFIG_80211N_HT */
1182
1183
#ifdef CONFIG_80211AC_VHT
1184
update_sta_vht_info_apmode(padapter, psta);
1185
#endif
1186
psta->cmn.ra_info.is_support_sgi = query_ra_short_GI(psta, rtw_get_tx_bw_mode(padapter, psta));
1187
update_ldpc_stbc_cap(psta);
1188
1189
/* todo: init other variables */
1190
1191
_rtw_memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
1192
1193
1194
/* add ratid */
1195
/* add_RATid(padapter, psta); */ /* move to ap_sta_info_defer_update() */
1196
1197
/* ap mode */
1198
rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
1199
1200
_enter_critical_bh(&psta->lock, &irqL);
1201
1202
/* Check encryption */
1203
if (!MLME_IS_MESH(padapter) && psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
1204
psta->state |= WIFI_UNDER_KEY_HANDSHAKE;
1205
1206
psta->state |= _FW_LINKED;
1207
1208
_exit_critical_bh(&psta->lock, &irqL);
1209
}
1210
1211
static void update_ap_info(_adapter *padapter, struct sta_info *psta)
1212
{
1213
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1214
WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
1215
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1216
#ifdef CONFIG_80211N_HT
1217
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
1218
#endif /* CONFIG_80211N_HT */
1219
1220
psta->wireless_mode = pmlmeext->cur_wireless_mode;
1221
1222
psta->bssratelen = rtw_get_rateset_len(pnetwork->SupportedRates);
1223
_rtw_memcpy(psta->bssrateset, pnetwork->SupportedRates, psta->bssratelen);
1224
1225
#ifdef CONFIG_80211N_HT
1226
/* HT related cap */
1227
if (phtpriv_ap->ht_option) {
1228
/* check if sta supports rx ampdu */
1229
/* phtpriv_ap->ampdu_enable = phtpriv_ap->ampdu_enable; */
1230
1231
/* check if sta support s Short GI 20M */
1232
if ((phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))
1233
phtpriv_ap->sgi_20m = _TRUE;
1234
/* check if sta support s Short GI 40M */
1235
if ((phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_40))
1236
phtpriv_ap->sgi_40m = _TRUE;
1237
1238
psta->qos_option = _TRUE;
1239
} else {
1240
phtpriv_ap->ampdu_enable = _FALSE;
1241
1242
phtpriv_ap->sgi_20m = _FALSE;
1243
phtpriv_ap->sgi_40m = _FALSE;
1244
}
1245
1246
psta->cmn.bw_mode = pmlmeext->cur_bwmode;
1247
phtpriv_ap->ch_offset = pmlmeext->cur_ch_offset;
1248
1249
phtpriv_ap->agg_enable_bitmap = 0x0;/* reset */
1250
phtpriv_ap->candidate_tid_bitmap = 0x0;/* reset */
1251
1252
_rtw_memcpy(&psta->htpriv, &pmlmepriv->htpriv, sizeof(struct ht_priv));
1253
1254
#ifdef CONFIG_80211AC_VHT
1255
_rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
1256
#endif /* CONFIG_80211AC_VHT */
1257
1258
#endif /* CONFIG_80211N_HT */
1259
1260
psta->state |= WIFI_AP_STATE; /* Aries, add,fix bug of flush_cam_entry at STOP AP mode , 0724 */
1261
}
1262
1263
static void rtw_set_hw_wmm_param(_adapter *padapter)
1264
{
1265
u8 AIFS, ECWMin, ECWMax, aSifsTime;
1266
u8 acm_mask;
1267
u16 TXOP;
1268
u32 acParm, i;
1269
u32 edca[4], inx[4];
1270
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1271
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1272
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1273
struct registry_priv *pregpriv = &padapter->registrypriv;
1274
1275
acm_mask = 0;
1276
#ifdef CONFIG_80211N_HT
1277
if (pregpriv->ht_enable &&
1278
(is_supported_5g(pmlmeext->cur_wireless_mode) ||
1279
(pmlmeext->cur_wireless_mode & WIRELESS_11_24N)))
1280
aSifsTime = 16;
1281
else
1282
#endif /* CONFIG_80211N_HT */
1283
aSifsTime = 10;
1284
1285
if (pmlmeinfo->WMM_enable == 0) {
1286
padapter->mlmepriv.acm_mask = 0;
1287
1288
AIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
1289
1290
if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11A)) {
1291
ECWMin = 4;
1292
ECWMax = 10;
1293
} else if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
1294
ECWMin = 5;
1295
ECWMax = 10;
1296
} else {
1297
ECWMin = 4;
1298
ECWMax = 10;
1299
}
1300
1301
TXOP = 0;
1302
acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1303
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
1304
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
1305
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
1306
1307
ECWMin = 2;
1308
ECWMax = 3;
1309
TXOP = 0x2f;
1310
acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1311
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
1312
1313
} else {
1314
edca[0] = edca[1] = edca[2] = edca[3] = 0;
1315
1316
/*TODO:*/
1317
acm_mask = 0;
1318
padapter->mlmepriv.acm_mask = acm_mask;
1319
1320
#if 0
1321
/* BK */
1322
/* AIFS = AIFSN * slot time + SIFS - r2t phy delay */
1323
#endif
1324
AIFS = (7 * pmlmeinfo->slotTime) + aSifsTime;
1325
ECWMin = 4;
1326
ECWMax = 10;
1327
TXOP = 0;
1328
acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1329
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
1330
edca[XMIT_BK_QUEUE] = acParm;
1331
RTW_INFO("WMM(BK): %x\n", acParm);
1332
1333
/* BE */
1334
AIFS = (3 * pmlmeinfo->slotTime) + aSifsTime;
1335
ECWMin = 4;
1336
ECWMax = 6;
1337
TXOP = 0;
1338
acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1339
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
1340
edca[XMIT_BE_QUEUE] = acParm;
1341
RTW_INFO("WMM(BE): %x\n", acParm);
1342
1343
/* VI */
1344
AIFS = (1 * pmlmeinfo->slotTime) + aSifsTime;
1345
ECWMin = 3;
1346
ECWMax = 4;
1347
TXOP = 94;
1348
acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1349
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
1350
edca[XMIT_VI_QUEUE] = acParm;
1351
RTW_INFO("WMM(VI): %x\n", acParm);
1352
1353
/* VO */
1354
AIFS = (1 * pmlmeinfo->slotTime) + aSifsTime;
1355
ECWMin = 2;
1356
ECWMax = 3;
1357
TXOP = 47;
1358
acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1359
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
1360
edca[XMIT_VO_QUEUE] = acParm;
1361
RTW_INFO("WMM(VO): %x\n", acParm);
1362
1363
1364
if (padapter->registrypriv.acm_method == 1)
1365
rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask));
1366
else
1367
padapter->mlmepriv.acm_mask = acm_mask;
1368
1369
inx[0] = 0;
1370
inx[1] = 1;
1371
inx[2] = 2;
1372
inx[3] = 3;
1373
1374
if (pregpriv->wifi_spec == 1) {
1375
u32 j, tmp, change_inx = _FALSE;
1376
1377
/* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */
1378
for (i = 0 ; i < 4 ; i++) {
1379
for (j = i + 1 ; j < 4 ; j++) {
1380
/* compare CW and AIFS */
1381
if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF))
1382
change_inx = _TRUE;
1383
else if ((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF)) {
1384
/* compare TXOP */
1385
if ((edca[j] >> 16) > (edca[i] >> 16))
1386
change_inx = _TRUE;
1387
}
1388
1389
if (change_inx) {
1390
tmp = edca[i];
1391
edca[i] = edca[j];
1392
edca[j] = tmp;
1393
1394
tmp = inx[i];
1395
inx[i] = inx[j];
1396
inx[j] = tmp;
1397
1398
change_inx = _FALSE;
1399
}
1400
}
1401
}
1402
}
1403
1404
for (i = 0 ; i < 4 ; i++) {
1405
pxmitpriv->wmm_para_seq[i] = inx[i];
1406
RTW_INFO("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]);
1407
}
1408
1409
}
1410
1411
}
1412
#ifdef CONFIG_80211N_HT
1413
static void update_hw_ht_param(_adapter *padapter)
1414
{
1415
unsigned char max_AMPDU_len;
1416
unsigned char min_MPDU_spacing;
1417
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1418
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1419
1420
RTW_INFO("%s\n", __FUNCTION__);
1421
1422
1423
/* handle A-MPDU parameter field */
1424
/*
1425
AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
1426
AMPDU_para [4:2]:Min MPDU Start Spacing
1427
*/
1428
max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
1429
1430
min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
1431
1432
rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
1433
1434
rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
1435
1436
/* */
1437
/* Config SM Power Save setting */
1438
/* */
1439
pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
1440
if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) {
1441
#if 0
1442
u8 i;
1443
/* update the MCS rates */
1444
for (i = 0; i < 16; i++)
1445
pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
1446
#endif
1447
RTW_INFO("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __FUNCTION__);
1448
}
1449
1450
/* */
1451
/* Config current HT Protection mode. */
1452
/* */
1453
/* pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3; */
1454
1455
}
1456
#endif /* CONFIG_80211N_HT */
1457
static void rtw_ap_check_scan(_adapter *padapter)
1458
{
1459
_irqL irqL;
1460
_list *plist, *phead;
1461
u32 delta_time, lifetime;
1462
struct wlan_network *pnetwork = NULL;
1463
WLAN_BSSID_EX *pbss = NULL;
1464
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1465
_queue *queue = &(pmlmepriv->scanned_queue);
1466
u8 do_scan = _FALSE;
1467
u8 reason = RTW_AUTO_SCAN_REASON_UNSPECIFIED;
1468
1469
lifetime = SCANQUEUE_LIFETIME; /* 20 sec */
1470
1471
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1472
phead = get_list_head(queue);
1473
if (rtw_end_of_queue_search(phead, get_next(phead)) == _TRUE)
1474
if (padapter->registrypriv.wifi_spec) {
1475
do_scan = _TRUE;
1476
reason |= RTW_AUTO_SCAN_REASON_2040_BSS;
1477
}
1478
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1479
1480
#ifdef CONFIG_RTW_ACS
1481
if (padapter->registrypriv.acs_auto_scan) {
1482
do_scan = _TRUE;
1483
reason |= RTW_AUTO_SCAN_REASON_ACS;
1484
rtw_acs_start(padapter);
1485
}
1486
#endif/*CONFIG_RTW_ACS*/
1487
1488
if (_TRUE == do_scan) {
1489
RTW_INFO("%s : drv scans by itself and wait_completed\n", __func__);
1490
rtw_drv_scan_by_self(padapter, reason);
1491
rtw_scan_wait_completed(padapter);
1492
}
1493
1494
#ifdef CONFIG_RTW_ACS
1495
if (padapter->registrypriv.acs_auto_scan)
1496
rtw_acs_stop(padapter);
1497
#endif
1498
1499
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1500
1501
phead = get_list_head(queue);
1502
plist = get_next(phead);
1503
1504
while (1) {
1505
1506
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
1507
break;
1508
1509
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1510
1511
if (rtw_chset_search_ch(adapter_to_chset(padapter), pnetwork->network.Configuration.DSConfig) >= 0
1512
&& rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
1513
&& _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))) {
1514
delta_time = (u32) rtw_get_passing_time_ms(pnetwork->last_scanned);
1515
1516
if (delta_time < lifetime) {
1517
1518
uint ie_len = 0;
1519
u8 *pbuf = NULL;
1520
u8 *ie = NULL;
1521
1522
pbss = &pnetwork->network;
1523
ie = pbss->IEs;
1524
1525
/*check if HT CAP INFO IE exists or not*/
1526
pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss->IELength - _BEACON_IE_OFFSET_));
1527
if (pbuf == NULL) {
1528
/* HT CAP INFO IE don't exist, it is b/g mode bss.*/
1529
1530
if (_FALSE == ATOMIC_READ(&pmlmepriv->olbc))
1531
ATOMIC_SET(&pmlmepriv->olbc, _TRUE);
1532
1533
if (_FALSE == ATOMIC_READ(&pmlmepriv->olbc_ht))
1534
ATOMIC_SET(&pmlmepriv->olbc_ht, _TRUE);
1535
1536
if (padapter->registrypriv.wifi_spec)
1537
RTW_INFO("%s: %s is a/b/g ap\n", __func__, pnetwork->network.Ssid.Ssid);
1538
}
1539
}
1540
}
1541
1542
plist = get_next(plist);
1543
1544
}
1545
1546
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1547
#ifdef CONFIG_80211N_HT
1548
pmlmepriv->num_sta_no_ht = 0; /* reset to 0 after ap do scanning*/
1549
#endif
1550
}
1551
1552
void rtw_start_bss_hdl_after_chbw_decided(_adapter *adapter)
1553
{
1554
WLAN_BSSID_EX *pnetwork = &(adapter->mlmepriv.cur_network.network);
1555
struct sta_info *sta = NULL;
1556
1557
/* update cur_wireless_mode */
1558
update_wireless_mode(adapter);
1559
1560
/* update RRSR and RTS_INIT_RATE register after set channel and bandwidth */
1561
UpdateBrateTbl(adapter, pnetwork->SupportedRates);
1562
rtw_hal_set_hwreg(adapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
1563
1564
/* update capability after cur_wireless_mode updated */
1565
update_capinfo(adapter, rtw_get_capability(pnetwork));
1566
1567
/* update bc/mc sta_info */
1568
update_bmc_sta(adapter);
1569
1570
/* update AP's sta info */
1571
sta = rtw_get_stainfo(&adapter->stapriv, pnetwork->MacAddress);
1572
if (!sta) {
1573
RTW_INFO(FUNC_ADPT_FMT" !sta for macaddr="MAC_FMT"\n", FUNC_ADPT_ARG(adapter), MAC_ARG(pnetwork->MacAddress));
1574
rtw_warn_on(1);
1575
return;
1576
}
1577
1578
update_ap_info(adapter, sta);
1579
}
1580
1581
#ifdef CONFIG_FW_HANDLE_TXBCN
1582
bool rtw_ap_nums_check(_adapter *adapter)
1583
{
1584
if (rtw_ap_get_nums(adapter) < CONFIG_LIMITED_AP_NUM)
1585
return _TRUE;
1586
return _FALSE;
1587
}
1588
u8 rtw_ap_allocate_vapid(struct dvobj_priv *dvobj)
1589
{
1590
u8 vap_id;
1591
1592
for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {
1593
if (!(dvobj->vap_map & BIT(vap_id)))
1594
break;
1595
}
1596
1597
if (vap_id < CONFIG_LIMITED_AP_NUM)
1598
dvobj->vap_map |= BIT(vap_id);
1599
1600
return vap_id;
1601
}
1602
u8 rtw_ap_release_vapid(struct dvobj_priv *dvobj, u8 vap_id)
1603
{
1604
if (vap_id >= CONFIG_LIMITED_AP_NUM) {
1605
RTW_ERR("%s - vapid(%d) failed\n", __func__, vap_id);
1606
rtw_warn_on(1);
1607
return _FAIL;
1608
}
1609
dvobj->vap_map &= ~ BIT(vap_id);
1610
return _SUCCESS;
1611
}
1612
#endif
1613
static void _rtw_iface_undersurvey_chk(const char *func, _adapter *adapter)
1614
{
1615
int i;
1616
_adapter *iface;
1617
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1618
struct mlme_priv *pmlmepriv;
1619
1620
for (i = 0; i < dvobj->iface_nums; i++) {
1621
iface = dvobj->padapters[i];
1622
if ((iface) && rtw_is_adapter_up(iface)) {
1623
pmlmepriv = &iface->mlmepriv;
1624
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1625
RTW_ERR("%s ("ADPT_FMT") under survey\n", func, ADPT_ARG(iface));
1626
}
1627
}
1628
}
1629
void start_bss_network(_adapter *padapter, struct createbss_parm *parm)
1630
{
1631
#define DUMP_ADAPTERS_STATUS 0
1632
u8 mlme_act = MLME_ACTION_UNKNOWN;
1633
u8 val8;
1634
u16 bcn_interval;
1635
u32 acparm;
1636
struct registry_priv *pregpriv = &padapter->registrypriv;
1637
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1638
struct security_priv *psecuritypriv = &(padapter->securitypriv);
1639
WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; /* used as input */
1640
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1641
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1642
WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);
1643
struct dvobj_priv *pdvobj = padapter->dvobj;
1644
s16 req_ch = REQ_CH_NONE, req_bw = REQ_BW_NONE, req_offset = REQ_OFFSET_NONE;
1645
u8 ch_to_set = 0, bw_to_set, offset_to_set;
1646
u8 doiqk = _FALSE;
1647
/* use for check ch bw offset can be allowed or not */
1648
u8 chbw_allow = _TRUE;
1649
int i;
1650
u8 ifbmp_ch_changed = 0;
1651
1652
if (parm->req_ch != 0) {
1653
/* bypass other setting, go checking ch, bw, offset */
1654
mlme_act = MLME_OPCH_SWITCH;
1655
req_ch = parm->req_ch;
1656
req_bw = parm->req_bw;
1657
req_offset = parm->req_offset;
1658
goto chbw_decision;
1659
} else {
1660
/* request comes from upper layer */
1661
if (MLME_IS_AP(padapter))
1662
mlme_act = MLME_AP_STARTED;
1663
else if (MLME_IS_MESH(padapter))
1664
mlme_act = MLME_MESH_STARTED;
1665
else
1666
rtw_warn_on(1);
1667
req_ch = 0;
1668
_rtw_memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
1669
}
1670
1671
bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
1672
1673
/* check if there is wps ie, */
1674
/* if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, */
1675
/* and at first time the security ie ( RSN/WPA IE) will not include in beacon. */
1676
if (NULL == rtw_get_wps_ie(pnetwork->IEs + _FIXED_IE_LENGTH_, pnetwork->IELength - _FIXED_IE_LENGTH_, NULL, NULL))
1677
pmlmeext->bstart_bss = _TRUE;
1678
1679
/* todo: update wmm, ht cap */
1680
/* pmlmeinfo->WMM_enable; */
1681
/* pmlmeinfo->HT_enable; */
1682
if (pmlmepriv->qospriv.qos_option)
1683
pmlmeinfo->WMM_enable = _TRUE;
1684
#ifdef CONFIG_80211N_HT
1685
if (pmlmepriv->htpriv.ht_option) {
1686
pmlmeinfo->WMM_enable = _TRUE;
1687
pmlmeinfo->HT_enable = _TRUE;
1688
/* pmlmeinfo->HT_info_enable = _TRUE; */
1689
/* pmlmeinfo->HT_caps_enable = _TRUE; */
1690
1691
update_hw_ht_param(padapter);
1692
}
1693
#endif /* #CONFIG_80211N_HT */
1694
1695
#ifdef CONFIG_80211AC_VHT
1696
if (pmlmepriv->vhtpriv.vht_option) {
1697
pmlmeinfo->VHT_enable = _TRUE;
1698
update_hw_vht_param(padapter);
1699
}
1700
#endif /* CONFIG_80211AC_VHT */
1701
1702
if (pmlmepriv->cur_network.join_res != _TRUE) { /* setting only at first time */
1703
/* WEP Key will be set before this function, do not clear CAM. */
1704
if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
1705
&& !MLME_IS_MESH(padapter) /* mesh group key is set before this function */
1706
)
1707
flush_all_cam_entry(padapter); /* clear CAM */
1708
}
1709
1710
/* set MSR to AP_Mode */
1711
Set_MSR(padapter, _HW_STATE_AP_);
1712
1713
/* Set BSSID REG */
1714
rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress);
1715
1716
/* Set Security */
1717
val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
1718
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
1719
1720
/* Beacon Control related register */
1721
rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));
1722
1723
rtw_hal_rcr_set_chk_bssid(padapter, mlme_act);
1724
1725
chbw_decision:
1726
ifbmp_ch_changed = rtw_ap_chbw_decision(padapter, parm->ifbmp, parm->excl_ifbmp
1727
, req_ch, req_bw, req_offset
1728
, &ch_to_set, &bw_to_set, &offset_to_set, &chbw_allow);
1729
1730
for (i = 0; i < pdvobj->iface_nums; i++) {
1731
if (!(parm->ifbmp & BIT(i)) || !pdvobj->padapters[i])
1732
continue;
1733
1734
/* let pnetwork_mlme == pnetwork_mlmeext */
1735
_rtw_memcpy(&(pdvobj->padapters[i]->mlmepriv.cur_network.network)
1736
, &(pdvobj->padapters[i]->mlmeextpriv.mlmext_info.network)
1737
, pdvobj->padapters[i]->mlmeextpriv.mlmext_info.network.Length);
1738
1739
rtw_start_bss_hdl_after_chbw_decided(pdvobj->padapters[i]);
1740
1741
/* Set EDCA param reg after update cur_wireless_mode & update_capinfo */
1742
if (pregpriv->wifi_spec == 1)
1743
rtw_set_hw_wmm_param(pdvobj->padapters[i]);
1744
}
1745
1746
#if defined(CONFIG_DFS_MASTER)
1747
rtw_dfs_rd_en_decision(padapter, mlme_act, parm->excl_ifbmp);
1748
#endif
1749
1750
#ifdef CONFIG_MCC_MODE
1751
if (MCC_EN(padapter)) {
1752
/*
1753
* due to check under rtw_ap_chbw_decision
1754
* if under MCC mode, means req channel setting is the same as current channel setting
1755
* if not under MCC mode, mean req channel setting is not the same as current channel setting
1756
*/
1757
if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC)) {
1758
RTW_INFO(FUNC_ADPT_FMT": req channel setting is the same as current channel setting, go to update BCN\n"
1759
, FUNC_ADPT_ARG(padapter));
1760
1761
goto update_beacon;
1762
1763
}
1764
}
1765
1766
/* issue null data to AP for all interface connecting to AP before switch channel setting for softap */
1767
rtw_hal_mcc_issue_null_data(padapter, chbw_allow, 1);
1768
#endif /* CONFIG_MCC_MODE */
1769
1770
if (!IS_CH_WAITING(adapter_to_rfctl(padapter))) {
1771
doiqk = _TRUE;
1772
rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
1773
}
1774
1775
if (ch_to_set != 0) {
1776
set_channel_bwmode(padapter, ch_to_set, offset_to_set, bw_to_set);
1777
rtw_mi_update_union_chan_inf(padapter, ch_to_set, offset_to_set, bw_to_set);
1778
}
1779
1780
doiqk = _FALSE;
1781
rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
1782
1783
#ifdef CONFIG_MCC_MODE
1784
/* after set_channel_bwmode for backup IQK */
1785
rtw_hal_set_mcc_setting_start_bss_network(padapter, chbw_allow);
1786
#endif
1787
1788
#if defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
1789
for (i = 0; i < pdvobj->iface_nums; i++) {
1790
if (!(ifbmp_ch_changed & BIT(i)) || !pdvobj->padapters[i])
1791
continue;
1792
1793
{
1794
u8 ht_option = 0;
1795
1796
#ifdef CONFIG_80211N_HT
1797
ht_option = pdvobj->padapters[i]->mlmepriv.htpriv.ht_option;
1798
#endif
1799
1800
rtw_cfg80211_ch_switch_notify(pdvobj->padapters[i]
1801
, pdvobj->padapters[i]->mlmeextpriv.cur_channel
1802
, pdvobj->padapters[i]->mlmeextpriv.cur_bwmode
1803
, pdvobj->padapters[i]->mlmeextpriv.cur_ch_offset
1804
, ht_option
1805
, 0);
1806
}
1807
}
1808
#endif /* defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) */
1809
1810
if (DUMP_ADAPTERS_STATUS) {
1811
RTW_INFO(FUNC_ADPT_FMT" done\n", FUNC_ADPT_ARG(padapter));
1812
dump_adapters_status(RTW_DBGDUMP , adapter_to_dvobj(padapter));
1813
}
1814
1815
#ifdef CONFIG_MCC_MODE
1816
update_beacon:
1817
#endif
1818
1819
for (i = 0; i < pdvobj->iface_nums; i++) {
1820
struct mlme_priv *mlme;
1821
1822
if (!(parm->ifbmp & BIT(i)) || !pdvobj->padapters[i])
1823
continue;
1824
1825
/* update beacon content only if bstart_bss is _TRUE */
1826
if (pdvobj->padapters[i]->mlmeextpriv.bstart_bss != _TRUE)
1827
continue;
1828
1829
mlme = &(pdvobj->padapters[i]->mlmepriv);
1830
1831
#ifdef CONFIG_80211N_HT
1832
if ((ATOMIC_READ(&mlme->olbc) == _TRUE) || (ATOMIC_READ(&mlme->olbc_ht) == _TRUE)) {
1833
/* AP is not starting a 40 MHz BSS in presence of an 802.11g BSS. */
1834
mlme->ht_op_mode &= (~HT_INFO_OPERATION_MODE_OP_MODE_MASK);
1835
mlme->ht_op_mode |= OP_MODE_MAY_BE_LEGACY_STAS;
1836
update_beacon(pdvobj->padapters[i], _HT_ADD_INFO_IE_, NULL, _FALSE, 0);
1837
}
1838
#endif
1839
1840
update_beacon(pdvobj->padapters[i], _TIM_IE_, NULL, _FALSE, 0);
1841
}
1842
1843
if (mlme_act != MLME_OPCH_SWITCH
1844
&& pmlmeext->bstart_bss == _TRUE
1845
) {
1846
#ifdef CONFIG_SUPPORT_MULTI_BCN
1847
_irqL irqL;
1848
1849
_enter_critical_bh(&pdvobj->ap_if_q.lock, &irqL);
1850
if (rtw_is_list_empty(&padapter->list)) {
1851
#ifdef CONFIG_FW_HANDLE_TXBCN
1852
padapter->vap_id = rtw_ap_allocate_vapid(pdvobj);
1853
#endif
1854
rtw_list_insert_tail(&padapter->list, get_list_head(&pdvobj->ap_if_q));
1855
pdvobj->nr_ap_if++;
1856
pdvobj->inter_bcn_space = DEFAULT_BCN_INTERVAL / pdvobj->nr_ap_if;
1857
}
1858
_exit_critical_bh(&pdvobj->ap_if_q.lock, &irqL);
1859
1860
#ifdef CONFIG_SWTIMER_BASED_TXBCN
1861
rtw_ap_set_mbid_num(padapter, pdvobj->nr_ap_if);
1862
rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pdvobj->inter_bcn_space));
1863
#endif /*CONFIG_SWTIMER_BASED_TXBCN*/
1864
1865
#endif /*CONFIG_SUPPORT_MULTI_BCN*/
1866
1867
#ifdef CONFIG_HW_P0_TSF_SYNC
1868
correct_TSF(padapter, mlme_act);
1869
#endif
1870
}
1871
1872
rtw_scan_wait_completed(padapter);
1873
1874
_rtw_iface_undersurvey_chk(__func__, padapter);
1875
/* send beacon */
1876
ResumeTxBeacon(padapter);
1877
{
1878
#if !defined(CONFIG_INTERRUPT_BASED_TXBCN)
1879
#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) || defined(CONFIG_PCI_BCN_POLLING)
1880
#ifdef CONFIG_SWTIMER_BASED_TXBCN
1881
if (pdvobj->nr_ap_if == 1
1882
&& mlme_act != MLME_OPCH_SWITCH
1883
) {
1884
RTW_INFO("start SW BCN TIMER!\n");
1885
_set_timer(&pdvobj->txbcn_timer, bcn_interval);
1886
}
1887
#else
1888
for (i = 0; i < pdvobj->iface_nums; i++) {
1889
if (!(parm->ifbmp & BIT(i)) || !pdvobj->padapters[i])
1890
continue;
1891
1892
if (send_beacon(pdvobj->padapters[i]) == _FAIL)
1893
RTW_INFO(ADPT_FMT" issue_beacon, fail!\n", ADPT_ARG(pdvobj->padapters[i]));
1894
}
1895
#endif
1896
#endif
1897
#endif /* !defined(CONFIG_INTERRUPT_BASED_TXBCN) */
1898
1899
#ifdef CONFIG_FW_HANDLE_TXBCN
1900
if (mlme_act != MLME_OPCH_SWITCH)
1901
rtw_ap_mbid_bcn_en(padapter, padapter->vap_id);
1902
#endif
1903
}
1904
}
1905
1906
int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len)
1907
{
1908
int ret = _SUCCESS;
1909
u8 *p;
1910
u8 *pHT_caps_ie = NULL;
1911
u8 *pHT_info_ie = NULL;
1912
u16 cap, ht_cap = _FALSE;
1913
uint ie_len = 0;
1914
int group_cipher, pairwise_cipher;
1915
u32 akm;
1916
u8 mfp_opt = MFP_NO;
1917
u8 channel, network_type;
1918
u8 OUI1[] = {0x00, 0x50, 0xf2, 0x01};
1919
u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
1920
HT_CAP_AMPDU_DENSITY best_ampdu_density;
1921
struct registry_priv *pregistrypriv = &padapter->registrypriv;
1922
struct security_priv *psecuritypriv = &padapter->securitypriv;
1923
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1924
WLAN_BSSID_EX *pbss_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
1925
u8 *ie = pbss_network->IEs;
1926
u8 vht_cap = _FALSE;
1927
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1928
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1929
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
1930
u8 rf_num = 0;
1931
int ret_rm;
1932
/* SSID */
1933
/* Supported rates */
1934
/* DS Params */
1935
/* WLAN_EID_COUNTRY */
1936
/* ERP Information element */
1937
/* Extended supported rates */
1938
/* WPA/WPA2 */
1939
/* Wi-Fi Wireless Multimedia Extensions */
1940
/* ht_capab, ht_oper */
1941
/* WPS IE */
1942
1943
RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
1944
1945
if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
1946
return _FAIL;
1947
1948
1949
if (len > MAX_IE_SZ)
1950
return _FAIL;
1951
1952
pbss_network->IELength = len;
1953
1954
_rtw_memset(ie, 0, MAX_IE_SZ);
1955
1956
_rtw_memcpy(ie, pbuf, pbss_network->IELength);
1957
1958
1959
if (pbss_network->InfrastructureMode != Ndis802_11APMode
1960
&& pbss_network->InfrastructureMode != Ndis802_11_mesh
1961
) {
1962
rtw_warn_on(1);
1963
return _FAIL;
1964
}
1965
1966
1967
rtw_ap_check_scan(padapter);
1968
1969
1970
pbss_network->Rssi = 0;
1971
1972
_rtw_memcpy(pbss_network->MacAddress, adapter_mac_addr(padapter), ETH_ALEN);
1973
1974
/* beacon interval */
1975
p = rtw_get_beacon_interval_from_ie(ie);/* ie + 8; */ /* 8: TimeStamp, 2: Beacon Interval 2:Capability */
1976
/* pbss_network->Configuration.BeaconPeriod = le16_to_cpu(*(unsigned short*)p); */
1977
pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p);
1978
1979
/* capability */
1980
/* cap = *(unsigned short *)rtw_get_capability_from_ie(ie); */
1981
/* cap = le16_to_cpu(cap); */
1982
cap = RTW_GET_LE16(ie);
1983
1984
/* SSID */
1985
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
1986
if (p && ie_len > 0) {
1987
_rtw_memset(&pbss_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
1988
_rtw_memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);
1989
pbss_network->Ssid.SsidLength = ie_len;
1990
#ifdef CONFIG_P2P
1991
_rtw_memcpy(padapter->wdinfo.p2p_group_ssid, pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
1992
padapter->wdinfo.p2p_group_ssid_len = pbss_network->Ssid.SsidLength;
1993
#endif
1994
}
1995
1996
#ifdef CONFIG_RTW_MESH
1997
/* Mesh ID */
1998
if (MLME_IS_MESH(padapter)) {
1999
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_MESH_ID, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
2000
if (p && ie_len > 0) {
2001
_rtw_memset(&pbss_network->mesh_id, 0, sizeof(NDIS_802_11_SSID));
2002
_rtw_memcpy(pbss_network->mesh_id.Ssid, (p + 2), ie_len);
2003
pbss_network->mesh_id.SsidLength = ie_len;
2004
}
2005
}
2006
#endif
2007
2008
/* chnnel */
2009
channel = 0;
2010
pbss_network->Configuration.Length = 0;
2011
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
2012
if (p && ie_len > 0)
2013
channel = *(p + 2);
2014
2015
pbss_network->Configuration.DSConfig = channel;
2016
2017
/* support rate ie & ext support ie & IElen & SupportedRates */
2018
network_type = rtw_update_rate_bymode(pbss_network, pregistrypriv->wireless_mode);
2019
2020
/* parsing ERP_IE */
2021
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
2022
if (p && ie_len > 0) {
2023
if(padapter->registrypriv.wireless_mode == WIRELESS_11B ) {
2024
2025
pbss_network->IELength = pbss_network->IELength - *(p+1) - 2;
2026
ret_rm = rtw_ies_remove_ie(ie , &len, _BEACON_IE_OFFSET_, _ERPINFO_IE_,NULL,0);
2027
RTW_DBG("%s, remove_ie of ERP_IE=%d\n", __FUNCTION__, ret_rm);
2028
} else
2029
ERP_IE_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)p);
2030
2031
}
2032
2033
/* update privacy/security */
2034
if (cap & BIT(4))
2035
pbss_network->Privacy = 1;
2036
else
2037
pbss_network->Privacy = 0;
2038
2039
psecuritypriv->wpa_psk = 0;
2040
2041
/* wpa2 */
2042
akm = 0;
2043
group_cipher = 0;
2044
pairwise_cipher = 0;
2045
psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
2046
psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
2047
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
2048
if (p && ie_len > 0) {
2049
if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, &akm, &mfp_opt) == _SUCCESS) {
2050
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2051
psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2052
psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */
2053
psecuritypriv->wpa_psk |= BIT(1);
2054
2055
psecuritypriv->wpa2_group_cipher = group_cipher;
2056
psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
2057
2058
/*
2059
Kernel < v5.1, the auth_type set as NL80211_AUTHTYPE_AUTOMATIC
2060
in cfg80211_rtw_start_ap().
2061
if the AKM SAE in the RSN IE, we have to update the auth_type for SAE
2062
in rtw_check_beacon_data().
2063
*/
2064
if (CHECK_BIT(WLAN_AKM_TYPE_SAE, akm))
2065
psecuritypriv->auth_type = NL80211_AUTHTYPE_SAE;
2066
#if 0
2067
switch (group_cipher) {
2068
case WPA_CIPHER_NONE:
2069
psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
2070
break;
2071
case WPA_CIPHER_WEP40:
2072
psecuritypriv->wpa2_group_cipher = _WEP40_;
2073
break;
2074
case WPA_CIPHER_TKIP:
2075
psecuritypriv->wpa2_group_cipher = _TKIP_;
2076
break;
2077
case WPA_CIPHER_CCMP:
2078
psecuritypriv->wpa2_group_cipher = _AES_;
2079
break;
2080
case WPA_CIPHER_WEP104:
2081
psecuritypriv->wpa2_group_cipher = _WEP104_;
2082
break;
2083
}
2084
2085
switch (pairwise_cipher) {
2086
case WPA_CIPHER_NONE:
2087
psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
2088
break;
2089
case WPA_CIPHER_WEP40:
2090
psecuritypriv->wpa2_pairwise_cipher = _WEP40_;
2091
break;
2092
case WPA_CIPHER_TKIP:
2093
psecuritypriv->wpa2_pairwise_cipher = _TKIP_;
2094
break;
2095
case WPA_CIPHER_CCMP:
2096
psecuritypriv->wpa2_pairwise_cipher = _AES_;
2097
break;
2098
case WPA_CIPHER_WEP104:
2099
psecuritypriv->wpa2_pairwise_cipher = _WEP104_;
2100
break;
2101
}
2102
#endif
2103
}
2104
2105
}
2106
2107
/* wpa */
2108
ie_len = 0;
2109
group_cipher = 0;
2110
pairwise_cipher = 0;
2111
psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
2112
psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
2113
for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
2114
p = rtw_get_ie(p, _SSN_IE_1_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
2115
if ((p) && (_rtw_memcmp(p + 2, OUI1, 4))) {
2116
if (rtw_parse_wpa_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
2117
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2118
psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
2119
psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */
2120
2121
psecuritypriv->wpa_psk |= BIT(0);
2122
2123
psecuritypriv->wpa_group_cipher = group_cipher;
2124
psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
2125
2126
#if 0
2127
switch (group_cipher) {
2128
case WPA_CIPHER_NONE:
2129
psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
2130
break;
2131
case WPA_CIPHER_WEP40:
2132
psecuritypriv->wpa_group_cipher = _WEP40_;
2133
break;
2134
case WPA_CIPHER_TKIP:
2135
psecuritypriv->wpa_group_cipher = _TKIP_;
2136
break;
2137
case WPA_CIPHER_CCMP:
2138
psecuritypriv->wpa_group_cipher = _AES_;
2139
break;
2140
case WPA_CIPHER_WEP104:
2141
psecuritypriv->wpa_group_cipher = _WEP104_;
2142
break;
2143
}
2144
2145
switch (pairwise_cipher) {
2146
case WPA_CIPHER_NONE:
2147
psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
2148
break;
2149
case WPA_CIPHER_WEP40:
2150
psecuritypriv->wpa_pairwise_cipher = _WEP40_;
2151
break;
2152
case WPA_CIPHER_TKIP:
2153
psecuritypriv->wpa_pairwise_cipher = _TKIP_;
2154
break;
2155
case WPA_CIPHER_CCMP:
2156
psecuritypriv->wpa_pairwise_cipher = _AES_;
2157
break;
2158
case WPA_CIPHER_WEP104:
2159
psecuritypriv->wpa_pairwise_cipher = _WEP104_;
2160
break;
2161
}
2162
#endif
2163
}
2164
2165
break;
2166
2167
}
2168
2169
if ((p == NULL) || (ie_len == 0))
2170
break;
2171
2172
}
2173
2174
#ifdef CONFIG_RTW_MESH
2175
if (MLME_IS_MESH(padapter)) {
2176
/* MFP is mandatory for secure mesh */
2177
if (padapter->mesh_info.mesh_auth_id)
2178
mfp_opt = MFP_REQUIRED;
2179
} else
2180
#endif
2181
if (mfp_opt == MFP_INVALID) {
2182
RTW_INFO(FUNC_ADPT_FMT" invalid MFP setting\n", FUNC_ADPT_ARG(padapter));
2183
return _FAIL;
2184
}
2185
psecuritypriv->mfp_opt = mfp_opt;
2186
2187
/* wmm */
2188
ie_len = 0;
2189
pmlmepriv->qospriv.qos_option = 0;
2190
#ifdef CONFIG_RTW_MESH
2191
if (MLME_IS_MESH(padapter))
2192
pmlmepriv->qospriv.qos_option = 1;
2193
#endif
2194
if (pregistrypriv->wmm_enable) {
2195
for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
2196
p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
2197
if ((p) && _rtw_memcmp(p + 2, WMM_PARA_IE, 6)) {
2198
pmlmepriv->qospriv.qos_option = 1;
2199
2200
*(p + 8) |= BIT(7); /* QoS Info, support U-APSD */
2201
2202
/* disable all ACM bits since the WMM admission control is not supported */
2203
*(p + 10) &= ~BIT(4); /* BE */
2204
*(p + 14) &= ~BIT(4); /* BK */
2205
*(p + 18) &= ~BIT(4); /* VI */
2206
*(p + 22) &= ~BIT(4); /* VO */
2207
2208
WMM_param_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)p);
2209
2210
break;
2211
}
2212
2213
if ((p == NULL) || (ie_len == 0))
2214
break;
2215
}
2216
}
2217
#ifdef CONFIG_80211N_HT
2218
if(padapter->registrypriv.ht_enable &&
2219
is_supported_ht(padapter->registrypriv.wireless_mode)) {
2220
/* parsing HT_CAP_IE */
2221
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
2222
if (p && ie_len > 0) {
2223
HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor = MAX_AMPDU_FACTOR_64K;
2224
struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2);
2225
2226
if (0) {
2227
RTW_INFO(FUNC_ADPT_FMT" HT_CAP_IE from upper layer:\n", FUNC_ADPT_ARG(padapter));
2228
dump_ht_cap_ie_content(RTW_DBGDUMP, p + 2, ie_len);
2229
}
2230
2231
pHT_caps_ie = p;
2232
2233
ht_cap = _TRUE;
2234
network_type |= WIRELESS_11_24N;
2235
2236
rtw_ht_use_default_setting(padapter);
2237
2238
/* Update HT Capabilities Info field */
2239
if (pmlmepriv->htpriv.sgi_20m == _FALSE)
2240
pht_cap->cap_info &= ~(IEEE80211_HT_CAP_SGI_20);
2241
2242
if (pmlmepriv->htpriv.sgi_40m == _FALSE)
2243
pht_cap->cap_info &= ~(IEEE80211_HT_CAP_SGI_40);
2244
2245
if (!TEST_FLAG(pmlmepriv->htpriv.ldpc_cap, LDPC_HT_ENABLE_RX))
2246
pht_cap->cap_info &= ~(IEEE80211_HT_CAP_LDPC_CODING);
2247
2248
if (!TEST_FLAG(pmlmepriv->htpriv.stbc_cap, STBC_HT_ENABLE_TX))
2249
pht_cap->cap_info &= ~(IEEE80211_HT_CAP_TX_STBC);
2250
2251
if (!TEST_FLAG(pmlmepriv->htpriv.stbc_cap, STBC_HT_ENABLE_RX))
2252
pht_cap->cap_info &= ~(IEEE80211_HT_CAP_RX_STBC_3R);
2253
2254
/* Update A-MPDU Parameters field */
2255
pht_cap->ampdu_params_info &= ~(IEEE80211_HT_CAP_AMPDU_FACTOR | IEEE80211_HT_CAP_AMPDU_DENSITY);
2256
2257
if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
2258
(psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP)) {
2259
rtw_hal_get_def_var(padapter, HW_VAR_BEST_AMPDU_DENSITY, &best_ampdu_density);
2260
pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (best_ampdu_density << 2));
2261
} else
2262
pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00);
2263
2264
rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
2265
pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & max_rx_ampdu_factor); /* set Max Rx AMPDU size to 64K */
2266
2267
_rtw_memcpy(&(pmlmeinfo->HT_caps), pht_cap, sizeof(struct HT_caps_element));
2268
2269
/* Update Supported MCS Set field */
2270
{
2271
u8 rx_nss = 0;
2272
int i;
2273
2274
rx_nss = GET_HAL_RX_NSS(padapter);
2275
2276
/* RX MCS Bitmask */
2277
switch (rx_nss) {
2278
case 1:
2279
set_mcs_rate_by_mask(HT_CAP_ELE_RX_MCS_MAP(pht_cap), MCS_RATE_1R);
2280
break;
2281
case 2:
2282
set_mcs_rate_by_mask(HT_CAP_ELE_RX_MCS_MAP(pht_cap), MCS_RATE_2R);
2283
break;
2284
case 3:
2285
set_mcs_rate_by_mask(HT_CAP_ELE_RX_MCS_MAP(pht_cap), MCS_RATE_3R);
2286
break;
2287
case 4:
2288
set_mcs_rate_by_mask(HT_CAP_ELE_RX_MCS_MAP(pht_cap), MCS_RATE_4R);
2289
break;
2290
default:
2291
RTW_WARN("rf_type:%d or rx_nss:%u is not expected\n", GET_HAL_RFPATH(padapter), rx_nss);
2292
}
2293
for (i = 0; i < 10; i++)
2294
*(HT_CAP_ELE_RX_MCS_MAP(pht_cap) + i) &= padapter->mlmeextpriv.default_supported_mcs_set[i];
2295
}
2296
2297
#ifdef CONFIG_BEAMFORMING
2298
/* Use registry value to enable HT Beamforming. */
2299
/* ToDo: use configure file to set these capability. */
2300
pht_cap->tx_BF_cap_info = 0;
2301
2302
/* HT Beamformer */
2303
if (TEST_FLAG(pmlmepriv->htpriv.beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) {
2304
/* Transmit NDP Capable */
2305
SET_HT_CAP_TXBF_TRANSMIT_NDP_CAP(pht_cap, 1);
2306
/* Explicit Compressed Steering Capable */
2307
SET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pht_cap, 1);
2308
/* Compressed Steering Number Antennas */
2309
SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pht_cap, 1);
2310
rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMER_CAP, (u8 *)&rf_num);
2311
SET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pht_cap, rf_num);
2312
}
2313
2314
/* HT Beamformee */
2315
if (TEST_FLAG(pmlmepriv->htpriv.beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) {
2316
/* Receive NDP Capable */
2317
SET_HT_CAP_TXBF_RECEIVE_NDP_CAP(pht_cap, 1);
2318
/* Explicit Compressed Beamforming Feedback Capable */
2319
SET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pht_cap, 2);
2320
rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMEE_CAP, (u8 *)&rf_num);
2321
SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pht_cap, rf_num);
2322
}
2323
#endif /* CONFIG_BEAMFORMING */
2324
2325
_rtw_memcpy(&pmlmepriv->htpriv.ht_cap, p + 2, ie_len);
2326
2327
if (0) {
2328
RTW_INFO(FUNC_ADPT_FMT" HT_CAP_IE driver masked:\n", FUNC_ADPT_ARG(padapter));
2329
dump_ht_cap_ie_content(RTW_DBGDUMP, p + 2, ie_len);
2330
}
2331
}
2332
2333
/* parsing HT_INFO_IE */
2334
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
2335
if (p && ie_len > 0) {
2336
pHT_info_ie = p;
2337
if (channel == 0)
2338
pbss_network->Configuration.DSConfig = GET_HT_OP_ELE_PRI_CHL(pHT_info_ie + 2);
2339
else if (channel != GET_HT_OP_ELE_PRI_CHL(pHT_info_ie + 2)) {
2340
RTW_INFO(FUNC_ADPT_FMT" ch inconsistent, DSSS:%u, HT primary:%u\n"
2341
, FUNC_ADPT_ARG(padapter), channel, GET_HT_OP_ELE_PRI_CHL(pHT_info_ie + 2));
2342
}
2343
}
2344
}
2345
#endif /* CONFIG_80211N_HT */
2346
pmlmepriv->cur_network.network_type = network_type;
2347
2348
#ifdef CONFIG_80211N_HT
2349
pmlmepriv->htpriv.ht_option = _FALSE;
2350
2351
if ((psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
2352
(psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
2353
/* todo: */
2354
/* ht_cap = _FALSE; */
2355
}
2356
2357
/* ht_cap */
2358
if (padapter->registrypriv.ht_enable &&
2359
is_supported_ht(padapter->registrypriv.wireless_mode) && ht_cap == _TRUE) {
2360
2361
pmlmepriv->htpriv.ht_option = _TRUE;
2362
pmlmepriv->qospriv.qos_option = 1;
2363
2364
pmlmepriv->htpriv.ampdu_enable = pregistrypriv->ampdu_enable ? _TRUE : _FALSE;
2365
2366
HT_caps_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_caps_ie);
2367
2368
HT_info_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_info_ie);
2369
}
2370
#endif
2371
2372
#ifdef CONFIG_80211AC_VHT
2373
pmlmepriv->ori_vht_en = 0;
2374
pmlmepriv->vhtpriv.vht_option = _FALSE;
2375
2376
if (pmlmepriv->htpriv.ht_option == _TRUE
2377
&& pbss_network->Configuration.DSConfig > 14
2378
&& REGSTY_IS_11AC_ENABLE(pregistrypriv)
2379
&& is_supported_vht(pregistrypriv->wireless_mode)
2380
&& (!rfctl->country_ent || COUNTRY_CHPLAN_EN_11AC(rfctl->country_ent))
2381
) {
2382
/* Parsing VHT CAP IE */
2383
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
2384
if (p && ie_len > 0)
2385
vht_cap = _TRUE;
2386
2387
/* Parsing VHT OPERATION IE */
2388
2389
if (vht_cap == _TRUE
2390
&& MLME_IS_MESH(padapter) /* allow only mesh temporarily before VHT IE checking is ready */
2391
) {
2392
rtw_check_for_vht20(padapter, ie + _BEACON_IE_OFFSET_, pbss_network->IELength - _BEACON_IE_OFFSET_);
2393
pmlmepriv->ori_vht_en = 1;
2394
pmlmepriv->vhtpriv.vht_option = _TRUE;
2395
} else if (REGSTY_IS_11AC_AUTO(pregistrypriv)) {
2396
rtw_vht_ies_detach(padapter, pbss_network);
2397
rtw_vht_ies_attach(padapter, pbss_network);
2398
}
2399
}
2400
2401
if (pmlmepriv->vhtpriv.vht_option == _FALSE)
2402
rtw_vht_ies_detach(padapter, pbss_network);
2403
#endif /* CONFIG_80211AC_VHT */
2404
2405
#ifdef CONFIG_80211N_HT
2406
if(padapter->registrypriv.ht_enable &&
2407
is_supported_ht(padapter->registrypriv.wireless_mode) &&
2408
pbss_network->Configuration.DSConfig <= 14 && padapter->registrypriv.wifi_spec == 1 &&
2409
pbss_network->IELength + 10 <= MAX_IE_SZ) {
2410
uint len = 0;
2411
2412
SET_EXT_CAPABILITY_ELE_BSS_COEXIST(pmlmepriv->ext_capab_ie_data, 1);
2413
pmlmepriv->ext_capab_ie_len = 10;
2414
rtw_set_ie(pbss_network->IEs + pbss_network->IELength, EID_EXTCapability, 8, pmlmepriv->ext_capab_ie_data, &len);
2415
pbss_network->IELength += pmlmepriv->ext_capab_ie_len;
2416
}
2417
#endif /* CONFIG_80211N_HT */
2418
2419
pbss_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pbss_network);
2420
2421
rtw_ies_get_chbw(pbss_network->IEs + _BEACON_IE_OFFSET_, pbss_network->IELength - _BEACON_IE_OFFSET_
2422
, &pmlmepriv->ori_ch, &pmlmepriv->ori_bw, &pmlmepriv->ori_offset, 1, 1);
2423
rtw_warn_on(pmlmepriv->ori_ch == 0);
2424
2425
{
2426
/* alloc sta_info for ap itself */
2427
2428
struct sta_info *sta;
2429
2430
sta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
2431
if (!sta) {
2432
sta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
2433
if (sta == NULL)
2434
return _FAIL;
2435
}
2436
}
2437
2438
rtw_startbss_cmd(padapter, RTW_CMDF_WAIT_ACK);
2439
{
2440
int sk_band = RTW_GET_SCAN_BAND_SKIP(padapter);
2441
2442
if (sk_band)
2443
RTW_CLR_SCAN_BAND_SKIP(padapter, sk_band);
2444
}
2445
2446
rtw_indicate_connect(padapter);
2447
2448
pmlmepriv->cur_network.join_res = _TRUE;/* for check if already set beacon */
2449
2450
/* update bc/mc sta_info */
2451
/* update_bmc_sta(padapter); */
2452
2453
return ret;
2454
2455
}
2456
2457
#if CONFIG_RTW_MACADDR_ACL
2458
void rtw_macaddr_acl_init(_adapter *adapter, u8 period)
2459
{
2460
struct sta_priv *stapriv = &adapter->stapriv;
2461
struct wlan_acl_pool *acl;
2462
_queue *acl_node_q;
2463
int i;
2464
_irqL irqL;
2465
2466
if (period >= RTW_ACL_PERIOD_NUM) {
2467
rtw_warn_on(1);
2468
return;
2469
}
2470
2471
acl = &stapriv->acl_list[period];
2472
acl_node_q = &acl->acl_node_q;
2473
2474
_rtw_spinlock_init(&(acl_node_q->lock));
2475
2476
_enter_critical_bh(&(acl_node_q->lock), &irqL);
2477
_rtw_init_listhead(&(acl_node_q->queue));
2478
acl->num = 0;
2479
acl->mode = RTW_ACL_MODE_DISABLED;
2480
for (i = 0; i < NUM_ACL; i++) {
2481
_rtw_init_listhead(&acl->aclnode[i].list);
2482
acl->aclnode[i].valid = _FALSE;
2483
}
2484
_exit_critical_bh(&(acl_node_q->lock), &irqL);
2485
}
2486
2487
static void _rtw_macaddr_acl_deinit(_adapter *adapter, u8 period, bool clear_only)
2488
{
2489
struct sta_priv *stapriv = &adapter->stapriv;
2490
struct wlan_acl_pool *acl;
2491
_queue *acl_node_q;
2492
_irqL irqL;
2493
_list *head, *list;
2494
struct rtw_wlan_acl_node *acl_node;
2495
2496
if (period >= RTW_ACL_PERIOD_NUM) {
2497
rtw_warn_on(1);
2498
return;
2499
}
2500
2501
acl = &stapriv->acl_list[period];
2502
acl_node_q = &acl->acl_node_q;
2503
2504
_enter_critical_bh(&(acl_node_q->lock), &irqL);
2505
head = get_list_head(acl_node_q);
2506
list = get_next(head);
2507
while (rtw_end_of_queue_search(head, list) == _FALSE) {
2508
acl_node = LIST_CONTAINOR(list, struct rtw_wlan_acl_node, list);
2509
list = get_next(list);
2510
2511
if (acl_node->valid == _TRUE) {
2512
acl_node->valid = _FALSE;
2513
rtw_list_delete(&acl_node->list);
2514
acl->num--;
2515
}
2516
}
2517
_exit_critical_bh(&(acl_node_q->lock), &irqL);
2518
2519
if (!clear_only)
2520
_rtw_spinlock_free(&(acl_node_q->lock));
2521
2522
rtw_warn_on(acl->num);
2523
acl->mode = RTW_ACL_MODE_DISABLED;
2524
}
2525
2526
void rtw_macaddr_acl_deinit(_adapter *adapter, u8 period)
2527
{
2528
_rtw_macaddr_acl_deinit(adapter, period, 0);
2529
}
2530
2531
void rtw_macaddr_acl_clear(_adapter *adapter, u8 period)
2532
{
2533
_rtw_macaddr_acl_deinit(adapter, period, 1);
2534
}
2535
2536
void rtw_set_macaddr_acl(_adapter *adapter, u8 period, int mode)
2537
{
2538
struct sta_priv *stapriv = &adapter->stapriv;
2539
struct wlan_acl_pool *acl;
2540
2541
if (period >= RTW_ACL_PERIOD_NUM) {
2542
rtw_warn_on(1);
2543
return;
2544
}
2545
2546
acl = &stapriv->acl_list[period];
2547
2548
RTW_INFO(FUNC_ADPT_FMT" p=%u, mode=%d\n"
2549
, FUNC_ADPT_ARG(adapter), period, mode);
2550
2551
acl->mode = mode;
2552
}
2553
2554
int rtw_acl_add_sta(_adapter *adapter, u8 period, const u8 *addr)
2555
{
2556
_irqL irqL;
2557
_list *list, *head;
2558
u8 existed = 0;
2559
int i = -1, ret = 0;
2560
struct rtw_wlan_acl_node *acl_node;
2561
struct sta_priv *stapriv = &adapter->stapriv;
2562
struct wlan_acl_pool *acl;
2563
_queue *acl_node_q;
2564
2565
if (period >= RTW_ACL_PERIOD_NUM) {
2566
rtw_warn_on(1);
2567
ret = -1;
2568
goto exit;
2569
}
2570
2571
acl = &stapriv->acl_list[period];
2572
acl_node_q = &acl->acl_node_q;
2573
2574
_enter_critical_bh(&(acl_node_q->lock), &irqL);
2575
2576
head = get_list_head(acl_node_q);
2577
list = get_next(head);
2578
2579
/* search for existed entry */
2580
while (rtw_end_of_queue_search(head, list) == _FALSE) {
2581
acl_node = LIST_CONTAINOR(list, struct rtw_wlan_acl_node, list);
2582
list = get_next(list);
2583
2584
if (_rtw_memcmp(acl_node->addr, addr, ETH_ALEN)) {
2585
if (acl_node->valid == _TRUE) {
2586
existed = 1;
2587
break;
2588
}
2589
}
2590
}
2591
if (existed)
2592
goto release_lock;
2593
2594
if (acl->num >= NUM_ACL)
2595
goto release_lock;
2596
2597
/* find empty one and use */
2598
for (i = 0; i < NUM_ACL; i++) {
2599
2600
acl_node = &acl->aclnode[i];
2601
if (acl_node->valid == _FALSE) {
2602
2603
_rtw_init_listhead(&acl_node->list);
2604
_rtw_memcpy(acl_node->addr, addr, ETH_ALEN);
2605
acl_node->valid = _TRUE;
2606
2607
rtw_list_insert_tail(&acl_node->list, get_list_head(acl_node_q));
2608
acl->num++;
2609
break;
2610
}
2611
}
2612
2613
release_lock:
2614
_exit_critical_bh(&(acl_node_q->lock), &irqL);
2615
2616
if (!existed && (i < 0 || i >= NUM_ACL))
2617
ret = -1;
2618
2619
RTW_INFO(FUNC_ADPT_FMT" p=%u "MAC_FMT" %s (acl_num=%d)\n"
2620
, FUNC_ADPT_ARG(adapter), period, MAC_ARG(addr)
2621
, (existed ? "existed" : ((i < 0 || i >= NUM_ACL) ? "no room" : "added"))
2622
, acl->num);
2623
exit:
2624
return ret;
2625
}
2626
2627
int rtw_acl_remove_sta(_adapter *adapter, u8 period, const u8 *addr)
2628
{
2629
_irqL irqL;
2630
_list *list, *head;
2631
int ret = 0;
2632
struct rtw_wlan_acl_node *acl_node;
2633
struct sta_priv *stapriv = &adapter->stapriv;
2634
struct wlan_acl_pool *acl;
2635
_queue *acl_node_q;
2636
u8 is_baddr = is_broadcast_mac_addr(addr);
2637
u8 match = 0;
2638
2639
if (period >= RTW_ACL_PERIOD_NUM) {
2640
rtw_warn_on(1);
2641
goto exit;
2642
}
2643
2644
acl = &stapriv->acl_list[period];
2645
acl_node_q = &acl->acl_node_q;
2646
2647
_enter_critical_bh(&(acl_node_q->lock), &irqL);
2648
2649
head = get_list_head(acl_node_q);
2650
list = get_next(head);
2651
2652
while (rtw_end_of_queue_search(head, list) == _FALSE) {
2653
acl_node = LIST_CONTAINOR(list, struct rtw_wlan_acl_node, list);
2654
list = get_next(list);
2655
2656
if (is_baddr || _rtw_memcmp(acl_node->addr, addr, ETH_ALEN)) {
2657
if (acl_node->valid == _TRUE) {
2658
acl_node->valid = _FALSE;
2659
rtw_list_delete(&acl_node->list);
2660
acl->num--;
2661
match = 1;
2662
}
2663
}
2664
}
2665
2666
_exit_critical_bh(&(acl_node_q->lock), &irqL);
2667
2668
RTW_INFO(FUNC_ADPT_FMT" p=%u "MAC_FMT" %s (acl_num=%d)\n"
2669
, FUNC_ADPT_ARG(adapter), period, MAC_ARG(addr)
2670
, is_baddr ? "clear all" : (match ? "match" : "no found")
2671
, acl->num);
2672
2673
exit:
2674
return ret;
2675
}
2676
#endif /* CONFIG_RTW_MACADDR_ACL */
2677
2678
u8 rtw_ap_set_sta_key(_adapter *adapter, const u8 *addr, u8 alg, const u8 *key, u8 keyid, u8 gk)
2679
{
2680
struct cmd_priv *cmdpriv = &adapter->cmdpriv;
2681
struct cmd_obj *cmd;
2682
struct set_stakey_parm *param;
2683
u8 res = _SUCCESS;
2684
2685
cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
2686
if (cmd == NULL) {
2687
res = _FAIL;
2688
goto exit;
2689
}
2690
2691
param = (struct set_stakey_parm *)rtw_zmalloc(sizeof(struct set_stakey_parm));
2692
if (param == NULL) {
2693
rtw_mfree((u8 *) cmd, sizeof(struct cmd_obj));
2694
res = _FAIL;
2695
goto exit;
2696
}
2697
2698
init_h2fwcmd_w_parm_no_rsp(cmd, param, _SetStaKey_CMD_);
2699
2700
_rtw_memcpy(param->addr, addr, ETH_ALEN);
2701
param->algorithm = alg;
2702
param->keyid = keyid;
2703
_rtw_memcpy(param->key, key, 16);
2704
param->gk = gk;
2705
2706
res = rtw_enqueue_cmd(cmdpriv, cmd);
2707
2708
exit:
2709
return res;
2710
}
2711
2712
u8 rtw_ap_set_pairwise_key(_adapter *padapter, struct sta_info *psta)
2713
{
2714
return rtw_ap_set_sta_key(padapter
2715
, psta->cmn.mac_addr
2716
, psta->dot118021XPrivacy
2717
, psta->dot118021x_UncstKey.skey
2718
, 0
2719
, 0
2720
);
2721
}
2722
2723
static int rtw_ap_set_key(_adapter *padapter, u8 *key, u8 alg, int keyid, u8 set_tx)
2724
{
2725
u8 keylen;
2726
struct cmd_obj *pcmd;
2727
struct setkey_parm *psetkeyparm;
2728
struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
2729
int res = _SUCCESS;
2730
2731
/* RTW_INFO("%s\n", __FUNCTION__); */
2732
2733
pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
2734
if (pcmd == NULL) {
2735
res = _FAIL;
2736
goto exit;
2737
}
2738
psetkeyparm = (struct setkey_parm *)rtw_zmalloc(sizeof(struct setkey_parm));
2739
if (psetkeyparm == NULL) {
2740
rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj));
2741
res = _FAIL;
2742
goto exit;
2743
}
2744
2745
_rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
2746
2747
psetkeyparm->keyid = (u8)keyid;
2748
if (is_wep_enc(alg))
2749
padapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);
2750
2751
psetkeyparm->algorithm = alg;
2752
2753
psetkeyparm->set_tx = set_tx;
2754
2755
switch (alg) {
2756
case _WEP40_:
2757
keylen = 5;
2758
break;
2759
case _WEP104_:
2760
keylen = 13;
2761
break;
2762
case _TKIP_:
2763
case _TKIP_WTMIC_:
2764
case _AES_:
2765
default:
2766
keylen = 16;
2767
}
2768
2769
_rtw_memcpy(&(psetkeyparm->key[0]), key, keylen);
2770
2771
pcmd->cmdcode = _SetKey_CMD_;
2772
pcmd->parmbuf = (u8 *)psetkeyparm;
2773
pcmd->cmdsz = (sizeof(struct setkey_parm));
2774
pcmd->rsp = NULL;
2775
pcmd->rspsz = 0;
2776
2777
2778
_rtw_init_listhead(&pcmd->list);
2779
2780
res = rtw_enqueue_cmd(pcmdpriv, pcmd);
2781
2782
exit:
2783
2784
return res;
2785
}
2786
2787
int rtw_ap_set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid)
2788
{
2789
RTW_INFO("%s\n", __FUNCTION__);
2790
2791
return rtw_ap_set_key(padapter, key, alg, keyid, 1);
2792
}
2793
2794
int rtw_ap_set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid, u8 set_tx)
2795
{
2796
u8 alg;
2797
2798
switch (keylen) {
2799
case 5:
2800
alg = _WEP40_;
2801
break;
2802
case 13:
2803
alg = _WEP104_;
2804
break;
2805
default:
2806
alg = _NO_PRIVACY_;
2807
}
2808
2809
RTW_INFO("%s\n", __FUNCTION__);
2810
2811
return rtw_ap_set_key(padapter, key, alg, keyid, set_tx);
2812
}
2813
2814
u8 rtw_ap_bmc_frames_hdl(_adapter *padapter)
2815
{
2816
#define HIQ_XMIT_COUNTS (6)
2817
_irqL irqL;
2818
struct sta_info *psta_bmc;
2819
_list *xmitframe_plist, *xmitframe_phead;
2820
struct xmit_frame *pxmitframe = NULL;
2821
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2822
struct sta_priv *pstapriv = &padapter->stapriv;
2823
bool update_tim = _FALSE;
2824
2825
2826
if (padapter->registrypriv.wifi_spec != 1)
2827
return H2C_SUCCESS;
2828
2829
2830
psta_bmc = rtw_get_bcmc_stainfo(padapter);
2831
if (!psta_bmc)
2832
return H2C_SUCCESS;
2833
2834
2835
_enter_critical_bh(&pxmitpriv->lock, &irqL);
2836
2837
if ((rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, 0)) && (psta_bmc->sleepq_len > 0)) {
2838
int tx_counts = 0;
2839
2840
_update_beacon(padapter, _TIM_IE_, NULL, _FALSE, 0, "update TIM with TIB=1");
2841
2842
RTW_INFO("sleepq_len of bmc_sta = %d\n", psta_bmc->sleepq_len);
2843
2844
xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
2845
xmitframe_plist = get_next(xmitframe_phead);
2846
2847
while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
2848
pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
2849
2850
xmitframe_plist = get_next(xmitframe_plist);
2851
2852
rtw_list_delete(&pxmitframe->list);
2853
2854
psta_bmc->sleepq_len--;
2855
tx_counts++;
2856
2857
if (psta_bmc->sleepq_len > 0)
2858
pxmitframe->attrib.mdata = 1;
2859
else
2860
pxmitframe->attrib.mdata = 0;
2861
2862
if (tx_counts == HIQ_XMIT_COUNTS)
2863
pxmitframe->attrib.mdata = 0;
2864
2865
pxmitframe->attrib.triggered = 1;
2866
2867
if (xmitframe_hiq_filter(pxmitframe) == _TRUE)
2868
pxmitframe->attrib.qsel = QSLT_HIGH;/*HIQ*/
2869
2870
rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
2871
2872
if (tx_counts == HIQ_XMIT_COUNTS)
2873
break;
2874
2875
}
2876
2877
} else {
2878
if (psta_bmc->sleepq_len == 0) {
2879
2880
/*RTW_INFO("sleepq_len of bmc_sta = %d\n", psta_bmc->sleepq_len);*/
2881
2882
if (rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, 0))
2883
update_tim = _TRUE;
2884
2885
rtw_tim_map_clear(padapter, pstapriv->tim_bitmap, 0);
2886
rtw_tim_map_clear(padapter, pstapriv->sta_dz_bitmap, 0);
2887
2888
if (update_tim == _TRUE) {
2889
RTW_INFO("clear TIB\n");
2890
_update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0, "bmc sleepq and HIQ empty");
2891
}
2892
}
2893
}
2894
2895
_exit_critical_bh(&pxmitpriv->lock, &irqL);
2896
2897
#if 0
2898
/* HIQ Check */
2899
rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty);
2900
2901
while (_FALSE == empty && rtw_get_passing_time_ms(start) < 3000) {
2902
rtw_msleep_os(100);
2903
rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty);
2904
}
2905
2906
2907
printk("check if hiq empty=%d\n", empty);
2908
#endif
2909
2910
return H2C_SUCCESS;
2911
}
2912
2913
#ifdef CONFIG_NATIVEAP_MLME
2914
2915
static void associated_stainfo_update(_adapter *padapter, struct sta_info *psta, u32 sta_info_type)
2916
{
2917
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2918
2919
RTW_INFO("%s: "MAC_FMT", updated_type=0x%x\n", __func__, MAC_ARG(psta->cmn.mac_addr), sta_info_type);
2920
#ifdef CONFIG_80211N_HT
2921
if (sta_info_type & STA_INFO_UPDATE_BW) {
2922
2923
if ((psta->flags & WLAN_STA_HT) && !psta->ht_20mhz_set) {
2924
if (pmlmepriv->sw_to_20mhz) {
2925
psta->cmn.bw_mode = CHANNEL_WIDTH_20;
2926
/*psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;*/
2927
psta->htpriv.sgi_40m = _FALSE;
2928
} else {
2929
/*TODO: Switch back to 40MHZ?80MHZ*/
2930
}
2931
}
2932
}
2933
#endif /* CONFIG_80211N_HT */
2934
/*
2935
if (sta_info_type & STA_INFO_UPDATE_RATE) {
2936
2937
}
2938
*/
2939
2940
if (sta_info_type & STA_INFO_UPDATE_PROTECTION_MODE)
2941
VCS_update(padapter, psta);
2942
2943
/*
2944
if (sta_info_type & STA_INFO_UPDATE_CAP) {
2945
2946
}
2947
2948
if (sta_info_type & STA_INFO_UPDATE_HT_CAP) {
2949
2950
}
2951
2952
if (sta_info_type & STA_INFO_UPDATE_VHT_CAP) {
2953
2954
}
2955
*/
2956
2957
}
2958
2959
static void update_bcn_ext_capab_ie(_adapter *padapter)
2960
{
2961
sint ie_len = 0;
2962
unsigned char *pbuf;
2963
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2964
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2965
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2966
WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
2967
u8 *ie = pnetwork->IEs;
2968
u8 null_extcap_data[8] = {0};
2969
2970
pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_CAP_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
2971
if (pbuf && ie_len > 0)
2972
rtw_remove_bcn_ie(padapter, pnetwork, _EXT_CAP_IE_);
2973
2974
if ((pmlmepriv->ext_capab_ie_len > 0) &&
2975
(_rtw_memcmp(pmlmepriv->ext_capab_ie_data, null_extcap_data, sizeof(null_extcap_data)) == _FALSE))
2976
rtw_add_bcn_ie(padapter, pnetwork, _EXT_CAP_IE_, pmlmepriv->ext_capab_ie_data, pmlmepriv->ext_capab_ie_len);
2977
2978
}
2979
2980
static void update_bcn_erpinfo_ie(_adapter *padapter)
2981
{
2982
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2983
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2984
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2985
WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
2986
unsigned char *p, *ie = pnetwork->IEs;
2987
u32 len = 0;
2988
2989
RTW_INFO("%s, ERP_enable=%d\n", __FUNCTION__, pmlmeinfo->ERP_enable);
2990
2991
if (!pmlmeinfo->ERP_enable)
2992
return;
2993
2994
/* parsing ERP_IE */
2995
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
2996
if (p && len > 0) {
2997
PNDIS_802_11_VARIABLE_IEs pIE = (PNDIS_802_11_VARIABLE_IEs)p;
2998
2999
if (pmlmepriv->num_sta_non_erp == 1)
3000
pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION;
3001
else
3002
pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION);
3003
3004
if (pmlmepriv->num_sta_no_short_preamble > 0)
3005
pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
3006
else
3007
pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);
3008
3009
ERP_IE_handler(padapter, pIE);
3010
}
3011
3012
}
3013
3014
static void update_bcn_htcap_ie(_adapter *padapter)
3015
{
3016
RTW_INFO("%s\n", __FUNCTION__);
3017
3018
}
3019
3020
static void update_bcn_htinfo_ie(_adapter *padapter)
3021
{
3022
#ifdef CONFIG_80211N_HT
3023
/*
3024
u8 beacon_updated = _FALSE;
3025
u32 sta_info_update_type = STA_INFO_UPDATE_NONE;
3026
*/
3027
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3028
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3029
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3030
WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
3031
unsigned char *p, *ie = pnetwork->IEs;
3032
u32 len = 0;
3033
3034
if (pmlmepriv->htpriv.ht_option == _FALSE)
3035
return;
3036
3037
if (pmlmeinfo->HT_info_enable != 1)
3038
return;
3039
3040
3041
RTW_INFO("%s current operation mode=0x%X\n",
3042
__FUNCTION__, pmlmepriv->ht_op_mode);
3043
3044
RTW_INFO("num_sta_40mhz_intolerant(%d), 20mhz_width_req(%d), intolerant_ch_rpt(%d), olbc(%d)\n",
3045
pmlmepriv->num_sta_40mhz_intolerant, pmlmepriv->ht_20mhz_width_req, pmlmepriv->ht_intolerant_ch_reported, ATOMIC_READ(&pmlmepriv->olbc));
3046
3047
/*parsing HT_INFO_IE, currently only update ht_op_mode - pht_info->infos[1] & pht_info->infos[2] for wifi logo test*/
3048
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
3049
if (p && len > 0) {
3050
struct HT_info_element *pht_info = NULL;
3051
3052
pht_info = (struct HT_info_element *)(p + 2);
3053
3054
/* for STA Channel Width/Secondary Channel Offset*/
3055
if ((pmlmepriv->sw_to_20mhz == 0) && (pmlmeext->cur_channel <= 14)) {
3056
if ((pmlmepriv->num_sta_40mhz_intolerant > 0) || (pmlmepriv->ht_20mhz_width_req == _TRUE)
3057
|| (pmlmepriv->ht_intolerant_ch_reported == _TRUE) || (ATOMIC_READ(&pmlmepriv->olbc) == _TRUE)) {
3058
SET_HT_OP_ELE_2ND_CHL_OFFSET(pht_info, 0);
3059
SET_HT_OP_ELE_STA_CHL_WIDTH(pht_info, 0);
3060
3061
pmlmepriv->sw_to_20mhz = 1;
3062
/*
3063
sta_info_update_type |= STA_INFO_UPDATE_BW;
3064
beacon_updated = _TRUE;
3065
*/
3066
3067
RTW_INFO("%s:switching to 20Mhz\n", __FUNCTION__);
3068
3069
/*TODO : cur_bwmode/cur_ch_offset switches to 20Mhz*/
3070
}
3071
} else {
3072
3073
if ((pmlmepriv->num_sta_40mhz_intolerant == 0) && (pmlmepriv->ht_20mhz_width_req == _FALSE)
3074
&& (pmlmepriv->ht_intolerant_ch_reported == _FALSE) && (ATOMIC_READ(&pmlmepriv->olbc) == _FALSE)) {
3075
3076
if (pmlmeext->cur_bwmode >= CHANNEL_WIDTH_40) {
3077
3078
SET_HT_OP_ELE_STA_CHL_WIDTH(pht_info, 1);
3079
3080
SET_HT_OP_ELE_2ND_CHL_OFFSET(pht_info,
3081
(pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) ?
3082
HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE : HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW);
3083
3084
pmlmepriv->sw_to_20mhz = 0;
3085
/*
3086
sta_info_update_type |= STA_INFO_UPDATE_BW;
3087
beacon_updated = _TRUE;
3088
*/
3089
3090
RTW_INFO("%s:switching back to 40Mhz\n", __FUNCTION__);
3091
}
3092
}
3093
}
3094
3095
/* to update ht_op_mode*/
3096
*(u16 *)(pht_info->infos + 1) = cpu_to_le16(pmlmepriv->ht_op_mode);
3097
3098
}
3099
3100
/*associated_clients_update(padapter, beacon_updated, sta_info_update_type);*/
3101
#endif /* CONFIG_80211N_HT */
3102
}
3103
3104
static void update_bcn_rsn_ie(_adapter *padapter)
3105
{
3106
RTW_INFO("%s\n", __FUNCTION__);
3107
3108
}
3109
3110
static void update_bcn_wpa_ie(_adapter *padapter)
3111
{
3112
RTW_INFO("%s\n", __FUNCTION__);
3113
3114
}
3115
3116
static void update_bcn_wmm_ie(_adapter *padapter)
3117
{
3118
RTW_INFO("%s\n", __FUNCTION__);
3119
3120
}
3121
3122
static void update_bcn_wps_ie(_adapter *padapter)
3123
{
3124
u8 *pwps_ie = NULL, *pwps_ie_src, *premainder_ie, *pbackup_remainder_ie = NULL;
3125
uint wps_ielen = 0, wps_offset, remainder_ielen;
3126
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3127
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3128
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3129
WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
3130
unsigned char *ie = pnetwork->IEs;
3131
u32 ielen = pnetwork->IELength;
3132
3133
3134
RTW_INFO("%s\n", __FUNCTION__);
3135
3136
pwps_ie = rtw_get_wps_ie(ie + _FIXED_IE_LENGTH_, ielen - _FIXED_IE_LENGTH_, NULL, &wps_ielen);
3137
3138
if (pwps_ie == NULL || wps_ielen == 0)
3139
return;
3140
3141
pwps_ie_src = pmlmepriv->wps_beacon_ie;
3142
if (pwps_ie_src == NULL)
3143
return;
3144
3145
wps_offset = (uint)(pwps_ie - ie);
3146
3147
premainder_ie = pwps_ie + wps_ielen;
3148
3149
remainder_ielen = ielen - wps_offset - wps_ielen;
3150
3151
if (remainder_ielen > 0) {
3152
pbackup_remainder_ie = rtw_malloc(remainder_ielen);
3153
if (pbackup_remainder_ie)
3154
_rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
3155
}
3156
3157
wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */
3158
if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) {
3159
_rtw_memcpy(pwps_ie, pwps_ie_src, wps_ielen + 2);
3160
pwps_ie += (wps_ielen + 2);
3161
3162
if (pbackup_remainder_ie)
3163
_rtw_memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
3164
3165
/* update IELength */
3166
pnetwork->IELength = wps_offset + (wps_ielen + 2) + remainder_ielen;
3167
}
3168
3169
if (pbackup_remainder_ie)
3170
rtw_mfree(pbackup_remainder_ie, remainder_ielen);
3171
3172
/* deal with the case without set_tx_beacon_cmd() in update_beacon() */
3173
#if defined(CONFIG_INTERRUPT_BASED_TXBCN) || defined(CONFIG_PCI_HCI)
3174
if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3175
u8 sr = 0;
3176
rtw_get_wps_attr_content(pwps_ie_src, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
3177
3178
if (sr) {
3179
set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
3180
RTW_INFO("%s, set WIFI_UNDER_WPS\n", __func__);
3181
} else {
3182
clr_fwstate(pmlmepriv, WIFI_UNDER_WPS);
3183
RTW_INFO("%s, clr WIFI_UNDER_WPS\n", __func__);
3184
}
3185
}
3186
#endif
3187
}
3188
3189
static void update_bcn_p2p_ie(_adapter *padapter)
3190
{
3191
3192
}
3193
3194
static void update_bcn_vendor_spec_ie(_adapter *padapter, u8 *oui)
3195
{
3196
RTW_INFO("%s\n", __FUNCTION__);
3197
3198
if (_rtw_memcmp(RTW_WPA_OUI, oui, 4))
3199
update_bcn_wpa_ie(padapter);
3200
else if (_rtw_memcmp(WMM_OUI, oui, 4))
3201
update_bcn_wmm_ie(padapter);
3202
else if (_rtw_memcmp(WPS_OUI, oui, 4))
3203
update_bcn_wps_ie(padapter);
3204
else if (_rtw_memcmp(P2P_OUI, oui, 4))
3205
update_bcn_p2p_ie(padapter);
3206
else
3207
RTW_INFO("unknown OUI type!\n");
3208
3209
3210
}
3211
3212
void _update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx, u8 flags, const char *tag)
3213
{
3214
_irqL irqL;
3215
struct mlme_priv *pmlmepriv;
3216
struct mlme_ext_priv *pmlmeext;
3217
bool updated = 1; /* treat as upadated by default */
3218
3219
if (!padapter)
3220
return;
3221
3222
pmlmepriv = &(padapter->mlmepriv);
3223
pmlmeext = &(padapter->mlmeextpriv);
3224
3225
if (pmlmeext->bstart_bss == _FALSE)
3226
return;
3227
3228
_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
3229
3230
switch (ie_id) {
3231
case _TIM_IE_:
3232
update_BCNTIM(padapter);
3233
break;
3234
3235
case _ERPINFO_IE_:
3236
update_bcn_erpinfo_ie(padapter);
3237
break;
3238
3239
case _HT_CAPABILITY_IE_:
3240
update_bcn_htcap_ie(padapter);
3241
break;
3242
3243
case _RSN_IE_2_:
3244
update_bcn_rsn_ie(padapter);
3245
break;
3246
3247
case _HT_ADD_INFO_IE_:
3248
update_bcn_htinfo_ie(padapter);
3249
break;
3250
3251
case _EXT_CAP_IE_:
3252
update_bcn_ext_capab_ie(padapter);
3253
break;
3254
3255
#ifdef CONFIG_RTW_MESH
3256
case WLAN_EID_MESH_CONFIG:
3257
updated = rtw_mesh_update_bss_peering_status(padapter, &(pmlmeext->mlmext_info.network));
3258
updated |= rtw_mesh_update_bss_formation_info(padapter, &(pmlmeext->mlmext_info.network));
3259
updated |= rtw_mesh_update_bss_forwarding_state(padapter, &(pmlmeext->mlmext_info.network));
3260
break;
3261
#endif
3262
3263
case _VENDOR_SPECIFIC_IE_:
3264
update_bcn_vendor_spec_ie(padapter, oui);
3265
break;
3266
3267
case 0xFF:
3268
default:
3269
break;
3270
}
3271
3272
if (updated)
3273
pmlmepriv->update_bcn = _TRUE;
3274
3275
_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
3276
3277
#ifndef CONFIG_INTERRUPT_BASED_TXBCN
3278
#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) || defined(CONFIG_PCI_BCN_POLLING)
3279
if (tx && updated) {
3280
/* send_beacon(padapter); */ /* send_beacon must execute on TSR level */
3281
if (0)
3282
RTW_INFO(FUNC_ADPT_FMT" ie_id:%u - %s\n", FUNC_ADPT_ARG(padapter), ie_id, tag);
3283
if(flags == RTW_CMDF_WAIT_ACK)
3284
set_tx_beacon_cmd(padapter, RTW_CMDF_WAIT_ACK);
3285
else
3286
set_tx_beacon_cmd(padapter, 0);
3287
}
3288
#else
3289
{
3290
/* PCI will issue beacon when BCN interrupt occurs. */
3291
}
3292
#endif
3293
#endif /* !CONFIG_INTERRUPT_BASED_TXBCN */
3294
}
3295
3296
#ifdef CONFIG_80211N_HT
3297
3298
void rtw_process_public_act_bsscoex(_adapter *padapter, u8 *pframe, uint frame_len)
3299
{
3300
struct sta_info *psta;
3301
struct sta_priv *pstapriv = &padapter->stapriv;
3302
u8 beacon_updated = _FALSE;
3303
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3304
u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
3305
uint frame_body_len = frame_len - sizeof(struct rtw_ieee80211_hdr_3addr);
3306
u8 category, action;
3307
3308
psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3309
if (psta == NULL)
3310
return;
3311
3312
3313
category = frame_body[0];
3314
action = frame_body[1];
3315
3316
if (frame_body_len > 0) {
3317
if ((frame_body[2] == EID_BSSCoexistence) && (frame_body[3] > 0)) {
3318
u8 ie_data = frame_body[4];
3319
3320
if (ie_data & RTW_WLAN_20_40_BSS_COEX_40MHZ_INTOL) {
3321
if (psta->ht_40mhz_intolerant == 0) {
3322
psta->ht_40mhz_intolerant = 1;
3323
pmlmepriv->num_sta_40mhz_intolerant++;
3324
beacon_updated = _TRUE;
3325
}
3326
} else if (ie_data & RTW_WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ) {
3327
if (pmlmepriv->ht_20mhz_width_req == _FALSE) {
3328
pmlmepriv->ht_20mhz_width_req = _TRUE;
3329
beacon_updated = _TRUE;
3330
}
3331
} else
3332
beacon_updated = _FALSE;
3333
}
3334
}
3335
3336
if (frame_body_len > 8) {
3337
/* if EID_BSSIntolerantChlReport ie exists */
3338
if ((frame_body[5] == EID_BSSIntolerantChlReport) && (frame_body[6] > 0)) {
3339
/*todo:*/
3340
if (pmlmepriv->ht_intolerant_ch_reported == _FALSE) {
3341
pmlmepriv->ht_intolerant_ch_reported = _TRUE;
3342
beacon_updated = _TRUE;
3343
}
3344
}
3345
}
3346
3347
if (beacon_updated) {
3348
3349
update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE, 0);
3350
3351
associated_stainfo_update(padapter, psta, STA_INFO_UPDATE_BW);
3352
}
3353
3354
3355
3356
}
3357
3358
void rtw_process_ht_action_smps(_adapter *padapter, u8 *ta, u8 ctrl_field)
3359
{
3360
u8 e_field, m_field;
3361
struct sta_info *psta;
3362
struct sta_priv *pstapriv = &padapter->stapriv;
3363
3364
psta = rtw_get_stainfo(pstapriv, ta);
3365
if (psta == NULL)
3366
return;
3367
3368
e_field = (ctrl_field & BIT(0)) ? 1 : 0; /*SM Power Save Enabled*/
3369
m_field = (ctrl_field & BIT(1)) ? 1 : 0; /*SM Mode, 0:static SMPS, 1:dynamic SMPS*/
3370
3371
if (e_field) {
3372
if (m_field) { /*mode*/
3373
psta->htpriv.smps_cap = WLAN_HT_CAP_SM_PS_DYNAMIC;
3374
RTW_ERR("Don't support dynamic SMPS\n");
3375
}
3376
else
3377
psta->htpriv.smps_cap = WLAN_HT_CAP_SM_PS_STATIC;
3378
} else {
3379
/*disable*/
3380
psta->htpriv.smps_cap = WLAN_HT_CAP_SM_PS_DISABLED;
3381
}
3382
3383
if (psta->htpriv.smps_cap != WLAN_HT_CAP_SM_PS_DYNAMIC)
3384
rtw_ssmps_wk_cmd(padapter, psta, e_field, 1);
3385
}
3386
3387
/*
3388
op_mode
3389
Set to 0 (HT pure) under the followign conditions
3390
- all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
3391
- all STAs in the BSS are 20 MHz HT in 20 MHz BSS
3392
Set to 1 (HT non-member protection) if there may be non-HT STAs
3393
in both the primary and the secondary channel
3394
Set to 2 if only HT STAs are associated in BSS,
3395
however and at least one 20 MHz HT STA is associated
3396
Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
3397
(currently non-GF HT station is considered as non-HT STA also)
3398
*/
3399
int rtw_ht_operation_update(_adapter *padapter)
3400
{
3401
u16 cur_op_mode, new_op_mode;
3402
int op_mode_changes = 0;
3403
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3404
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
3405
3406
if (pmlmepriv->htpriv.ht_option == _FALSE)
3407
return 0;
3408
3409
/*if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)
3410
return 0;*/
3411
3412
RTW_INFO("%s current operation mode=0x%X\n",
3413
__FUNCTION__, pmlmepriv->ht_op_mode);
3414
3415
if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)
3416
&& pmlmepriv->num_sta_ht_no_gf) {
3417
pmlmepriv->ht_op_mode |=
3418
HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
3419
op_mode_changes++;
3420
} else if ((pmlmepriv->ht_op_mode &
3421
HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
3422
pmlmepriv->num_sta_ht_no_gf == 0) {
3423
pmlmepriv->ht_op_mode &=
3424
~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
3425
op_mode_changes++;
3426
}
3427
3428
if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
3429
(pmlmepriv->num_sta_no_ht || ATOMIC_READ(&pmlmepriv->olbc_ht))) {
3430
pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
3431
op_mode_changes++;
3432
} else if ((pmlmepriv->ht_op_mode &
3433
HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
3434
(pmlmepriv->num_sta_no_ht == 0 && !ATOMIC_READ(&pmlmepriv->olbc_ht))) {
3435
pmlmepriv->ht_op_mode &=
3436
~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
3437
op_mode_changes++;
3438
}
3439
3440
/* Note: currently we switch to the MIXED op mode if HT non-greenfield
3441
* station is associated. Probably it's a theoretical case, since
3442
* it looks like all known HT STAs support greenfield.
3443
*/
3444
new_op_mode = 0;
3445
if (pmlmepriv->num_sta_no_ht /*||
3446
(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)*/)
3447
new_op_mode = OP_MODE_MIXED;
3448
else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH)
3449
&& pmlmepriv->num_sta_ht_20mhz)
3450
new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
3451
else if (ATOMIC_READ(&pmlmepriv->olbc_ht))
3452
new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
3453
else
3454
new_op_mode = OP_MODE_PURE;
3455
3456
cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
3457
if (cur_op_mode != new_op_mode) {
3458
pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
3459
pmlmepriv->ht_op_mode |= new_op_mode;
3460
op_mode_changes++;
3461
}
3462
3463
RTW_INFO("%s new operation mode=0x%X changes=%d\n",
3464
__FUNCTION__, pmlmepriv->ht_op_mode, op_mode_changes);
3465
3466
return op_mode_changes;
3467
3468
}
3469
3470
#endif /* CONFIG_80211N_HT */
3471
3472
void associated_clients_update(_adapter *padapter, u8 updated, u32 sta_info_type)
3473
{
3474
/* update associcated stations cap. */
3475
if (updated == _TRUE) {
3476
_irqL irqL;
3477
_list *phead, *plist;
3478
struct sta_info *psta = NULL;
3479
struct sta_priv *pstapriv = &padapter->stapriv;
3480
3481
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3482
3483
phead = &pstapriv->asoc_list;
3484
plist = get_next(phead);
3485
3486
/* check asoc_queue */
3487
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
3488
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3489
3490
plist = get_next(plist);
3491
3492
associated_stainfo_update(padapter, psta, sta_info_type);
3493
}
3494
3495
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3496
3497
}
3498
3499
}
3500
3501
/* called > TSR LEVEL for USB or SDIO Interface*/
3502
void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta)
3503
{
3504
u8 beacon_updated = _FALSE;
3505
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3506
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3507
3508
3509
#if 0
3510
if (!(psta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
3511
!psta->no_short_preamble_set) {
3512
psta->no_short_preamble_set = 1;
3513
pmlmepriv->num_sta_no_short_preamble++;
3514
if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
3515
(pmlmepriv->num_sta_no_short_preamble == 1))
3516
ieee802_11_set_beacons(hapd->iface);
3517
}
3518
#endif
3519
3520
3521
if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) {
3522
if (!psta->no_short_preamble_set) {
3523
psta->no_short_preamble_set = 1;
3524
3525
pmlmepriv->num_sta_no_short_preamble++;
3526
3527
if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
3528
(pmlmepriv->num_sta_no_short_preamble == 1))
3529
beacon_updated = _TRUE;
3530
}
3531
} else {
3532
if (psta->no_short_preamble_set) {
3533
psta->no_short_preamble_set = 0;
3534
3535
pmlmepriv->num_sta_no_short_preamble--;
3536
3537
if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
3538
(pmlmepriv->num_sta_no_short_preamble == 0))
3539
beacon_updated = _TRUE;
3540
}
3541
}
3542
3543
#if 0
3544
if (psta->flags & WLAN_STA_NONERP && !psta->nonerp_set) {
3545
psta->nonerp_set = 1;
3546
pmlmepriv->num_sta_non_erp++;
3547
if (pmlmepriv->num_sta_non_erp == 1)
3548
ieee802_11_set_beacons(hapd->iface);
3549
}
3550
#endif
3551
3552
if (psta->flags & WLAN_STA_NONERP) {
3553
if (!psta->nonerp_set) {
3554
psta->nonerp_set = 1;
3555
3556
pmlmepriv->num_sta_non_erp++;
3557
3558
if (pmlmepriv->num_sta_non_erp == 1) {
3559
beacon_updated = _TRUE;
3560
update_beacon(padapter, _ERPINFO_IE_, NULL, _FALSE, 0);
3561
}
3562
}
3563
3564
} else {
3565
if (psta->nonerp_set) {
3566
psta->nonerp_set = 0;
3567
3568
pmlmepriv->num_sta_non_erp--;
3569
3570
if (pmlmepriv->num_sta_non_erp == 0) {
3571
beacon_updated = _TRUE;
3572
update_beacon(padapter, _ERPINFO_IE_, NULL, _FALSE, 0);
3573
}
3574
}
3575
3576
}
3577
3578
3579
#if 0
3580
if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT) &&
3581
!psta->no_short_slot_time_set) {
3582
psta->no_short_slot_time_set = 1;
3583
pmlmepriv->num_sta_no_short_slot_time++;
3584
if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
3585
(pmlmepriv->num_sta_no_short_slot_time == 1))
3586
ieee802_11_set_beacons(hapd->iface);
3587
}
3588
#endif
3589
3590
if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT)) {
3591
if (!psta->no_short_slot_time_set) {
3592
psta->no_short_slot_time_set = 1;
3593
3594
pmlmepriv->num_sta_no_short_slot_time++;
3595
3596
if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
3597
(pmlmepriv->num_sta_no_short_slot_time == 1))
3598
beacon_updated = _TRUE;
3599
}
3600
} else {
3601
if (psta->no_short_slot_time_set) {
3602
psta->no_short_slot_time_set = 0;
3603
3604
pmlmepriv->num_sta_no_short_slot_time--;
3605
3606
if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
3607
(pmlmepriv->num_sta_no_short_slot_time == 0))
3608
beacon_updated = _TRUE;
3609
}
3610
}
3611
3612
#ifdef CONFIG_80211N_HT
3613
if(padapter->registrypriv.ht_enable &&
3614
is_supported_ht(padapter->registrypriv.wireless_mode)) {
3615
if (psta->flags & WLAN_STA_HT) {
3616
u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
3617
3618
RTW_INFO("HT: STA " MAC_FMT " HT Capabilities Info: 0x%04x\n",
3619
MAC_ARG(psta->cmn.mac_addr), ht_capab);
3620
3621
if (psta->no_ht_set) {
3622
psta->no_ht_set = 0;
3623
pmlmepriv->num_sta_no_ht--;
3624
}
3625
3626
if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
3627
if (!psta->no_ht_gf_set) {
3628
psta->no_ht_gf_set = 1;
3629
pmlmepriv->num_sta_ht_no_gf++;
3630
}
3631
RTW_INFO("%s STA " MAC_FMT " - no "
3632
"greenfield, num of non-gf stations %d\n",
3633
__FUNCTION__, MAC_ARG(psta->cmn.mac_addr),
3634
pmlmepriv->num_sta_ht_no_gf);
3635
}
3636
3637
if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) {
3638
if (!psta->ht_20mhz_set) {
3639
psta->ht_20mhz_set = 1;
3640
pmlmepriv->num_sta_ht_20mhz++;
3641
}
3642
RTW_INFO("%s STA " MAC_FMT " - 20 MHz HT, "
3643
"num of 20MHz HT STAs %d\n",
3644
__FUNCTION__, MAC_ARG(psta->cmn.mac_addr),
3645
pmlmepriv->num_sta_ht_20mhz);
3646
}
3647
3648
if (((ht_capab & RTW_IEEE80211_HT_CAP_40MHZ_INTOLERANT) != 0) &&
3649
(psta->ht_40mhz_intolerant == 0)) {
3650
psta->ht_40mhz_intolerant = 1;
3651
pmlmepriv->num_sta_40mhz_intolerant++;
3652
RTW_INFO("%s STA " MAC_FMT " - 40MHZ_INTOLERANT, ",
3653
__FUNCTION__, MAC_ARG(psta->cmn.mac_addr));
3654
}
3655
3656
} else {
3657
if (!psta->no_ht_set) {
3658
psta->no_ht_set = 1;
3659
pmlmepriv->num_sta_no_ht++;
3660
}
3661
if (pmlmepriv->htpriv.ht_option == _TRUE) {
3662
RTW_INFO("%s STA " MAC_FMT
3663
" - no HT, num of non-HT stations %d\n",
3664
__FUNCTION__, MAC_ARG(psta->cmn.mac_addr),
3665
pmlmepriv->num_sta_no_ht);
3666
}
3667
}
3668
3669
if (rtw_ht_operation_update(padapter) > 0) {
3670
update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE, 0);
3671
update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _FALSE, 0);
3672
beacon_updated = _TRUE;
3673
}
3674
}
3675
#endif /* CONFIG_80211N_HT */
3676
3677
#ifdef CONFIG_RTW_MESH
3678
if (MLME_IS_MESH(padapter)) {
3679
struct sta_priv *pstapriv = &padapter->stapriv;
3680
3681
update_beacon(padapter, WLAN_EID_MESH_CONFIG, NULL, _FALSE, 0);
3682
if (pstapriv->asoc_list_cnt == 1)
3683
_set_timer(&padapter->mesh_atlm_param_req_timer, 0);
3684
beacon_updated = _TRUE;
3685
}
3686
#endif
3687
3688
if (beacon_updated)
3689
update_beacon(padapter, 0xFF, NULL, _TRUE, 0);
3690
3691
/* update associcated stations cap. */
3692
associated_clients_update(padapter, beacon_updated, STA_INFO_UPDATE_ALL);
3693
3694
RTW_INFO("%s, updated=%d\n", __func__, beacon_updated);
3695
3696
}
3697
3698
u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta)
3699
{
3700
u8 beacon_updated = _FALSE;
3701
struct sta_priv *pstapriv = &padapter->stapriv;
3702
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3703
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3704
3705
if (!psta)
3706
return beacon_updated;
3707
3708
if (rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid)) {
3709
rtw_tim_map_clear(padapter, pstapriv->tim_bitmap, psta->cmn.aid);
3710
beacon_updated = _TRUE;
3711
update_beacon(padapter, _TIM_IE_, NULL, _FALSE, 0);
3712
}
3713
3714
if (psta->no_short_preamble_set) {
3715
psta->no_short_preamble_set = 0;
3716
pmlmepriv->num_sta_no_short_preamble--;
3717
if (pmlmeext->cur_wireless_mode > WIRELESS_11B
3718
&& pmlmepriv->num_sta_no_short_preamble == 0)
3719
beacon_updated = _TRUE;
3720
}
3721
3722
if (psta->nonerp_set) {
3723
psta->nonerp_set = 0;
3724
pmlmepriv->num_sta_non_erp--;
3725
if (pmlmepriv->num_sta_non_erp == 0) {
3726
beacon_updated = _TRUE;
3727
update_beacon(padapter, _ERPINFO_IE_, NULL, _FALSE, 0);
3728
}
3729
}
3730
3731
if (psta->no_short_slot_time_set) {
3732
psta->no_short_slot_time_set = 0;
3733
pmlmepriv->num_sta_no_short_slot_time--;
3734
if (pmlmeext->cur_wireless_mode > WIRELESS_11B
3735
&& pmlmepriv->num_sta_no_short_slot_time == 0)
3736
beacon_updated = _TRUE;
3737
}
3738
3739
#ifdef CONFIG_80211N_HT
3740
if (psta->no_ht_gf_set) {
3741
psta->no_ht_gf_set = 0;
3742
pmlmepriv->num_sta_ht_no_gf--;
3743
}
3744
3745
if (psta->no_ht_set) {
3746
psta->no_ht_set = 0;
3747
pmlmepriv->num_sta_no_ht--;
3748
}
3749
3750
if (psta->ht_20mhz_set) {
3751
psta->ht_20mhz_set = 0;
3752
pmlmepriv->num_sta_ht_20mhz--;
3753
}
3754
3755
if (psta->ht_40mhz_intolerant) {
3756
psta->ht_40mhz_intolerant = 0;
3757
if (pmlmepriv->num_sta_40mhz_intolerant > 0)
3758
pmlmepriv->num_sta_40mhz_intolerant--;
3759
else
3760
rtw_warn_on(1);
3761
}
3762
3763
if (rtw_ht_operation_update(padapter) > 0) {
3764
update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE, 0);
3765
update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _FALSE, 0);
3766
}
3767
#endif /* CONFIG_80211N_HT */
3768
3769
#ifdef CONFIG_RTW_MESH
3770
if (MLME_IS_MESH(padapter)) {
3771
update_beacon(padapter, WLAN_EID_MESH_CONFIG, NULL, _FALSE, 0);
3772
if (pstapriv->asoc_list_cnt == 0)
3773
_cancel_timer_ex(&padapter->mesh_atlm_param_req_timer);
3774
beacon_updated = _TRUE;
3775
}
3776
#endif
3777
3778
if (beacon_updated == _TRUE)
3779
update_beacon(padapter, 0xFF, NULL, _TRUE, 0);
3780
3781
#if 0
3782
/* update associated stations cap. */
3783
associated_clients_update(padapter, beacon_updated, STA_INFO_UPDATE_ALL); /* move it to avoid deadlock */
3784
#endif
3785
3786
RTW_INFO("%s, updated=%d\n", __func__, beacon_updated);
3787
3788
return beacon_updated;
3789
3790
}
3791
3792
u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason, bool enqueue)
3793
{
3794
_irqL irqL;
3795
u8 beacon_updated = _FALSE;
3796
3797
if (!psta)
3798
return beacon_updated;
3799
3800
if (active == _TRUE) {
3801
#ifdef CONFIG_80211N_HT
3802
/* tear down Rx AMPDU */
3803
send_delba(padapter, 0, psta->cmn.mac_addr);/* recipient */
3804
3805
/* tear down TX AMPDU */
3806
send_delba(padapter, 1, psta->cmn.mac_addr);/* */ /* originator */
3807
3808
#endif /* CONFIG_80211N_HT */
3809
3810
if (!MLME_IS_MESH(padapter))
3811
issue_deauth(padapter, psta->cmn.mac_addr, reason);
3812
}
3813
3814
#ifdef CONFIG_RTW_MESH
3815
if (MLME_IS_MESH(padapter))
3816
rtw_mesh_path_flush_by_nexthop(psta);
3817
#endif
3818
3819
#ifdef CONFIG_BEAMFORMING
3820
beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_LEAVE, psta->cmn.mac_addr, ETH_ALEN, 1);
3821
#endif
3822
3823
#ifdef CONFIG_80211N_HT
3824
psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
3825
psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
3826
#endif
3827
3828
/* clear cam entry / key */
3829
rtw_clearstakey_cmd(padapter, psta, enqueue);
3830
3831
3832
_enter_critical_bh(&psta->lock, &irqL);
3833
psta->state &= ~(_FW_LINKED | WIFI_UNDER_KEY_HANDSHAKE);
3834
3835
if ((psta->auth_len != 0) && (psta->pauth_frame != NULL)) {
3836
rtw_mfree(psta->pauth_frame, psta->auth_len);
3837
psta->pauth_frame = NULL;
3838
psta->auth_len = 0;
3839
}
3840
_exit_critical_bh(&psta->lock, &irqL);
3841
3842
if (!MLME_IS_MESH(padapter)) {
3843
#ifdef CONFIG_IOCTL_CFG80211
3844
#ifdef COMPAT_KERNEL_RELEASE
3845
rtw_cfg80211_indicate_sta_disassoc(padapter, psta->cmn.mac_addr, reason);
3846
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3847
rtw_cfg80211_indicate_sta_disassoc(padapter, psta->cmn.mac_addr, reason);
3848
#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */
3849
/* will call rtw_cfg80211_indicate_sta_disassoc() in cmd_thread for old API context */
3850
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */
3851
#else
3852
rtw_indicate_sta_disassoc_event(padapter, psta);
3853
#endif
3854
}
3855
3856
beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
3857
3858
report_del_sta_event(padapter, psta->cmn.mac_addr, reason, enqueue, _FALSE);
3859
3860
return beacon_updated;
3861
3862
}
3863
3864
int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset)
3865
{
3866
_irqL irqL;
3867
_list *phead, *plist;
3868
int ret = 0;
3869
struct sta_info *psta = NULL;
3870
struct sta_priv *pstapriv = &padapter->stapriv;
3871
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3872
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3873
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3874
3875
if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
3876
return ret;
3877
3878
RTW_INFO(FUNC_NDEV_FMT" with ch:%u, offset:%u\n",
3879
FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset);
3880
3881
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3882
phead = &pstapriv->asoc_list;
3883
plist = get_next(phead);
3884
3885
/* for each sta in asoc_queue */
3886
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
3887
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3888
plist = get_next(plist);
3889
3890
issue_action_spct_ch_switch(padapter, psta->cmn.mac_addr, new_ch, ch_offset);
3891
psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2);
3892
}
3893
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3894
3895
issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset);
3896
3897
return ret;
3898
}
3899
3900
int rtw_sta_flush(_adapter *padapter, bool enqueue)
3901
{
3902
_irqL irqL;
3903
_list *phead, *plist;
3904
int ret = 0;
3905
struct sta_info *psta = NULL;
3906
struct sta_priv *pstapriv = &padapter->stapriv;
3907
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3908
u8 flush_num = 0;
3909
char flush_list[NUM_STA];
3910
int i;
3911
3912
if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
3913
return ret;
3914
3915
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
3916
3917
/* pick sta from sta asoc_queue */
3918
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3919
phead = &pstapriv->asoc_list;
3920
plist = get_next(phead);
3921
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
3922
int stainfo_offset;
3923
3924
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3925
plist = get_next(plist);
3926
3927
rtw_list_delete(&psta->asoc_list);
3928
pstapriv->asoc_list_cnt--;
3929
STA_SET_MESH_PLINK(psta, NULL);
3930
3931
stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
3932
if (stainfo_offset_valid(stainfo_offset))
3933
flush_list[flush_num++] = stainfo_offset;
3934
else
3935
rtw_warn_on(1);
3936
}
3937
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3938
3939
/* call ap_free_sta() for each sta picked */
3940
for (i = 0; i < flush_num; i++) {
3941
u8 sta_addr[ETH_ALEN];
3942
3943
psta = rtw_get_stainfo_by_offset(pstapriv, flush_list[i]);
3944
_rtw_memcpy(sta_addr, psta->cmn.mac_addr, ETH_ALEN);
3945
3946
ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, enqueue);
3947
#ifdef CONFIG_RTW_MESH
3948
if (MLME_IS_MESH(padapter))
3949
rtw_mesh_expire_peer(padapter, sta_addr);
3950
#endif
3951
}
3952
3953
if (!MLME_IS_MESH(padapter))
3954
issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
3955
3956
associated_clients_update(padapter, _TRUE, STA_INFO_UPDATE_ALL);
3957
3958
return ret;
3959
}
3960
3961
/* called > TSR LEVEL for USB or SDIO Interface*/
3962
void sta_info_update(_adapter *padapter, struct sta_info *psta)
3963
{
3964
int flags = psta->flags;
3965
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3966
3967
3968
/* update wmm cap. */
3969
if (WLAN_STA_WME & flags)
3970
psta->qos_option = 1;
3971
else
3972
psta->qos_option = 0;
3973
3974
if (pmlmepriv->qospriv.qos_option == 0)
3975
psta->qos_option = 0;
3976
3977
3978
#ifdef CONFIG_80211N_HT
3979
/* update 802.11n ht cap. */
3980
if (WLAN_STA_HT & flags) {
3981
psta->htpriv.ht_option = _TRUE;
3982
psta->qos_option = 1;
3983
3984
psta->htpriv.smps_cap = (psta->htpriv.ht_cap.cap_info & IEEE80211_HT_CAP_SM_PS) >> 2;
3985
} else
3986
psta->htpriv.ht_option = _FALSE;
3987
3988
if (pmlmepriv->htpriv.ht_option == _FALSE)
3989
psta->htpriv.ht_option = _FALSE;
3990
#endif
3991
3992
#ifdef CONFIG_80211AC_VHT
3993
/* update 802.11AC vht cap. */
3994
if (WLAN_STA_VHT & flags)
3995
psta->vhtpriv.vht_option = _TRUE;
3996
else
3997
psta->vhtpriv.vht_option = _FALSE;
3998
3999
if (pmlmepriv->vhtpriv.vht_option == _FALSE)
4000
psta->vhtpriv.vht_option = _FALSE;
4001
#endif
4002
4003
update_sta_info_apmode(padapter, psta);
4004
}
4005
4006
/* called >= TSR LEVEL for USB or SDIO Interface*/
4007
void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta)
4008
{
4009
if (psta->state & _FW_LINKED)
4010
rtw_hal_update_ra_mask(psta); /* DM_RATR_STA_INIT */
4011
}
4012
/* restore hw setting from sw data structures */
4013
void rtw_ap_restore_network(_adapter *padapter)
4014
{
4015
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4016
struct sta_priv *pstapriv = &padapter->stapriv;
4017
struct sta_info *psta;
4018
struct security_priv *psecuritypriv = &(padapter->securitypriv);
4019
_irqL irqL;
4020
_list *phead, *plist;
4021
u8 chk_alive_num = 0;
4022
char chk_alive_list[NUM_STA];
4023
int i;
4024
4025
rtw_setopmode_cmd(padapter
4026
, MLME_IS_AP(padapter) ? Ndis802_11APMode : Ndis802_11_mesh
4027
, RTW_CMDF_DIRECTLY
4028
);
4029
4030
set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4031
4032
rtw_startbss_cmd(padapter, RTW_CMDF_DIRECTLY);
4033
4034
if ((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
4035
(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
4036
/* restore group key, WEP keys is restored in ips_leave() */
4037
rtw_set_key(padapter, psecuritypriv, psecuritypriv->dot118021XGrpKeyid, 0, _FALSE);
4038
}
4039
4040
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
4041
4042
phead = &pstapriv->asoc_list;
4043
plist = get_next(phead);
4044
4045
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
4046
int stainfo_offset;
4047
4048
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
4049
plist = get_next(plist);
4050
4051
stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
4052
if (stainfo_offset_valid(stainfo_offset))
4053
chk_alive_list[chk_alive_num++] = stainfo_offset;
4054
}
4055
4056
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
4057
4058
for (i = 0; i < chk_alive_num; i++) {
4059
psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
4060
4061
if (psta == NULL)
4062
RTW_INFO(FUNC_ADPT_FMT" sta_info is null\n", FUNC_ADPT_ARG(padapter));
4063
else if (psta->state & _FW_LINKED) {
4064
rtw_sta_media_status_rpt(padapter, psta, 1);
4065
Update_RA_Entry(padapter, psta);
4066
/* pairwise key */
4067
/* per sta pairwise key and settings */
4068
if ((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
4069
(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))
4070
rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _FALSE);
4071
}
4072
}
4073
4074
}
4075
4076
void start_ap_mode(_adapter *padapter)
4077
{
4078
int i;
4079
struct sta_info *psta = NULL;
4080
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4081
struct sta_priv *pstapriv = &padapter->stapriv;
4082
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4083
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4084
#ifdef CONFIG_CONCURRENT_MODE
4085
struct security_priv *psecuritypriv = &padapter->securitypriv;
4086
#endif
4087
4088
pmlmepriv->update_bcn = _FALSE;
4089
4090
/*init_mlme_ap_info(padapter);*/
4091
4092
pmlmeext->bstart_bss = _FALSE;
4093
4094
pmlmepriv->num_sta_non_erp = 0;
4095
4096
pmlmepriv->num_sta_no_short_slot_time = 0;
4097
4098
pmlmepriv->num_sta_no_short_preamble = 0;
4099
4100
pmlmepriv->num_sta_ht_no_gf = 0;
4101
#ifdef CONFIG_80211N_HT
4102
pmlmepriv->num_sta_no_ht = 0;
4103
#endif /* CONFIG_80211N_HT */
4104
pmlmeinfo->HT_info_enable = 0;
4105
pmlmeinfo->HT_caps_enable = 0;
4106
pmlmeinfo->HT_enable = 0;
4107
4108
pmlmepriv->num_sta_ht_20mhz = 0;
4109
pmlmepriv->num_sta_40mhz_intolerant = 0;
4110
ATOMIC_SET(&pmlmepriv->olbc, _FALSE);
4111
ATOMIC_SET(&pmlmepriv->olbc_ht, _FALSE);
4112
4113
#ifdef CONFIG_80211N_HT
4114
pmlmepriv->ht_20mhz_width_req = _FALSE;
4115
pmlmepriv->ht_intolerant_ch_reported = _FALSE;
4116
pmlmepriv->ht_op_mode = 0;
4117
pmlmepriv->sw_to_20mhz = 0;
4118
#endif
4119
4120
_rtw_memset(pmlmepriv->ext_capab_ie_data, 0, sizeof(pmlmepriv->ext_capab_ie_data));
4121
pmlmepriv->ext_capab_ie_len = 0;
4122
4123
#ifdef CONFIG_CONCURRENT_MODE
4124
psecuritypriv->dot118021x_bmc_cam_id = INVALID_SEC_MAC_CAM_ID;
4125
#endif
4126
4127
for (i = 0 ; i < pstapriv->max_aid; i++)
4128
pstapriv->sta_aid[i] = NULL;
4129
4130
psta = rtw_get_bcmc_stainfo(padapter);
4131
/*_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);*/
4132
if (psta)
4133
rtw_free_stainfo(padapter, psta);
4134
/*_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);*/
4135
4136
rtw_init_bcmc_stainfo(padapter);
4137
4138
if (rtw_mi_get_ap_num(padapter))
4139
RTW_SET_SCAN_BAND_SKIP(padapter, BAND_5G);
4140
4141
}
4142
4143
void rtw_ap_bcmc_sta_flush(_adapter *padapter)
4144
{
4145
#ifdef CONFIG_CONCURRENT_MODE
4146
int cam_id = -1;
4147
u8 *addr = adapter_mac_addr(padapter);
4148
4149
cam_id = rtw_iface_bcmc_id_get(padapter);
4150
if (cam_id != INVALID_SEC_MAC_CAM_ID) {
4151
RTW_PRINT("clear group key for "ADPT_FMT" addr:"MAC_FMT", camid:%d\n",
4152
ADPT_ARG(padapter), MAC_ARG(addr), cam_id);
4153
clear_cam_entry(padapter, cam_id);
4154
rtw_camid_free(padapter, cam_id);
4155
rtw_iface_bcmc_id_set(padapter, INVALID_SEC_MAC_CAM_ID); /*init default value*/
4156
}
4157
#else
4158
invalidate_cam_all(padapter);
4159
#endif
4160
}
4161
4162
void stop_ap_mode(_adapter *padapter)
4163
{
4164
u8 self_action = MLME_ACTION_UNKNOWN;
4165
struct sta_info *psta = NULL;
4166
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4167
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4168
#ifdef CONFIG_SUPPORT_MULTI_BCN
4169
struct dvobj_priv *pdvobj = padapter->dvobj;
4170
_irqL irqL;
4171
#endif
4172
4173
RTW_INFO("%s -"ADPT_FMT"\n", __func__, ADPT_ARG(padapter));
4174
4175
if (MLME_IS_AP(padapter))
4176
self_action = MLME_AP_STOPPED;
4177
else if (MLME_IS_MESH(padapter))
4178
self_action = MLME_MESH_STOPPED;
4179
else
4180
rtw_warn_on(1);
4181
4182
pmlmepriv->update_bcn = _FALSE;
4183
/*pmlmeext->bstart_bss = _FALSE;*/
4184
padapter->netif_up = _FALSE;
4185
/* _rtw_spinlock_free(&pmlmepriv->bcn_update_lock); */
4186
4187
/* reset and init security priv , this can refine with rtw_reset_securitypriv */
4188
_rtw_memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv));
4189
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
4190
padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
4191
4192
#ifdef CONFIG_DFS_MASTER
4193
rtw_dfs_rd_en_decision(padapter, self_action, 0);
4194
#endif
4195
4196
/* free scan queue */
4197
rtw_free_network_queue(padapter, _TRUE);
4198
4199
#if CONFIG_RTW_MACADDR_ACL
4200
rtw_macaddr_acl_clear(padapter, RTW_ACL_PERIOD_BSS);
4201
#endif
4202
4203
rtw_sta_flush(padapter, _TRUE);
4204
rtw_ap_bcmc_sta_flush(padapter);
4205
4206
/* free_assoc_sta_resources */
4207
rtw_free_all_stainfo(padapter);
4208
4209
psta = rtw_get_bcmc_stainfo(padapter);
4210
if (psta) {
4211
rtw_sta_mstatus_disc_rpt(padapter, psta->cmn.mac_id);
4212
/* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
4213
rtw_free_stainfo(padapter, psta);
4214
/*_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);*/
4215
}
4216
4217
rtw_free_mlme_priv_ie_data(pmlmepriv);
4218
4219
#ifdef CONFIG_SUPPORT_MULTI_BCN
4220
if (pmlmeext->bstart_bss == _TRUE) {
4221
#ifdef CONFIG_FW_HANDLE_TXBCN
4222
u8 free_apid = CONFIG_LIMITED_AP_NUM;
4223
#endif
4224
4225
_enter_critical_bh(&pdvobj->ap_if_q.lock, &irqL);
4226
pdvobj->nr_ap_if--;
4227
if (pdvobj->nr_ap_if > 0)
4228
pdvobj->inter_bcn_space = DEFAULT_BCN_INTERVAL / pdvobj->nr_ap_if;
4229
else
4230
pdvobj->inter_bcn_space = DEFAULT_BCN_INTERVAL;
4231
#ifdef CONFIG_FW_HANDLE_TXBCN
4232
rtw_ap_release_vapid(pdvobj, padapter->vap_id);
4233
free_apid = padapter->vap_id;
4234
padapter->vap_id = CONFIG_LIMITED_AP_NUM;
4235
#endif
4236
rtw_list_delete(&padapter->list);
4237
_exit_critical_bh(&pdvobj->ap_if_q.lock, &irqL);
4238
#ifdef CONFIG_FW_HANDLE_TXBCN
4239
rtw_ap_mbid_bcn_dis(padapter, free_apid);
4240
#endif
4241
4242
#ifdef CONFIG_SWTIMER_BASED_TXBCN
4243
rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pdvobj->inter_bcn_space));
4244
4245
if (pdvobj->nr_ap_if == 0)
4246
_cancel_timer_ex(&pdvobj->txbcn_timer);
4247
#endif
4248
}
4249
#endif
4250
4251
pmlmeext->bstart_bss = _FALSE;
4252
4253
rtw_hal_rcr_set_chk_bssid(padapter, self_action);
4254
4255
#ifdef CONFIG_HW_P0_TSF_SYNC
4256
correct_TSF(padapter, self_action);
4257
#endif
4258
4259
#ifdef CONFIG_BT_COEXIST
4260
rtw_btcoex_MediaStatusNotify(padapter, 0); /* disconnect */
4261
#endif
4262
4263
}
4264
4265
#endif /* CONFIG_NATIVEAP_MLME */
4266
4267
void rtw_ap_update_bss_chbw(_adapter *adapter, WLAN_BSSID_EX *bss, u8 ch, u8 bw, u8 offset)
4268
{
4269
#define UPDATE_VHT_CAP 1
4270
#define UPDATE_HT_CAP 1
4271
#ifdef CONFIG_80211AC_VHT
4272
struct vht_priv *vhtpriv = &adapter->mlmepriv.vhtpriv;
4273
#endif
4274
{
4275
u8 *p;
4276
int ie_len;
4277
u8 old_ch = bss->Configuration.DSConfig;
4278
bool change_band = _FALSE;
4279
4280
if ((ch <= 14 && old_ch >= 36) || (ch >= 36 && old_ch <= 14))
4281
change_band = _TRUE;
4282
4283
/* update channel in IE */
4284
p = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
4285
if (p && ie_len > 0)
4286
*(p + 2) = ch;
4287
4288
bss->Configuration.DSConfig = ch;
4289
4290
/* band is changed, update ERP, support rate, ext support rate IE */
4291
if (change_band == _TRUE)
4292
change_band_update_ie(adapter, bss, ch);
4293
}
4294
4295
#ifdef CONFIG_80211AC_VHT
4296
if (vhtpriv->vht_option == _TRUE) {
4297
u8 *vht_cap_ie, *vht_op_ie;
4298
int vht_cap_ielen, vht_op_ielen;
4299
u8 center_freq;
4300
4301
vht_cap_ie = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTCapability, &vht_cap_ielen, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
4302
vht_op_ie = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTOperation, &vht_op_ielen, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
4303
center_freq = rtw_get_center_ch(ch, bw, offset);
4304
4305
/* update vht cap ie */
4306
if (vht_cap_ie && vht_cap_ielen) {
4307
#if UPDATE_VHT_CAP
4308
/* if ((bw == CHANNEL_WIDTH_160 || bw == CHANNEL_WIDTH_80_80) && pvhtpriv->sgi_160m)
4309
SET_VHT_CAPABILITY_ELE_SHORT_GI160M(pvht_cap_ie + 2, 1);
4310
else */
4311
SET_VHT_CAPABILITY_ELE_SHORT_GI160M(vht_cap_ie + 2, 0);
4312
4313
if (bw >= CHANNEL_WIDTH_80 && vhtpriv->sgi_80m)
4314
SET_VHT_CAPABILITY_ELE_SHORT_GI80M(vht_cap_ie + 2, 1);
4315
else
4316
SET_VHT_CAPABILITY_ELE_SHORT_GI80M(vht_cap_ie + 2, 0);
4317
#endif
4318
}
4319
4320
/* update vht op ie */
4321
if (vht_op_ie && vht_op_ielen) {
4322
if (bw < CHANNEL_WIDTH_80) {
4323
SET_VHT_OPERATION_ELE_CHL_WIDTH(vht_op_ie + 2, 0);
4324
SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(vht_op_ie + 2, 0);
4325
SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(vht_op_ie + 2, 0);
4326
} else if (bw == CHANNEL_WIDTH_80) {
4327
SET_VHT_OPERATION_ELE_CHL_WIDTH(vht_op_ie + 2, 1);
4328
SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(vht_op_ie + 2, center_freq);
4329
SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(vht_op_ie + 2, 0);
4330
} else {
4331
RTW_ERR(FUNC_ADPT_FMT" unsupported BW:%u\n", FUNC_ADPT_ARG(adapter), bw);
4332
rtw_warn_on(1);
4333
}
4334
}
4335
}
4336
#endif /* CONFIG_80211AC_VHT */
4337
#ifdef CONFIG_80211N_HT
4338
{
4339
struct ht_priv *htpriv = &adapter->mlmepriv.htpriv;
4340
u8 *ht_cap_ie, *ht_op_ie;
4341
int ht_cap_ielen, ht_op_ielen;
4342
4343
ht_cap_ie = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_HTCapability, &ht_cap_ielen, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
4344
ht_op_ie = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_HTInfo, &ht_op_ielen, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
4345
4346
/* update ht cap ie */
4347
if (ht_cap_ie && ht_cap_ielen) {
4348
#if UPDATE_HT_CAP
4349
if (bw >= CHANNEL_WIDTH_40)
4350
SET_HT_CAP_ELE_CHL_WIDTH(ht_cap_ie + 2, 1);
4351
else
4352
SET_HT_CAP_ELE_CHL_WIDTH(ht_cap_ie + 2, 0);
4353
4354
if (bw >= CHANNEL_WIDTH_40 && htpriv->sgi_40m)
4355
SET_HT_CAP_ELE_SHORT_GI40M(ht_cap_ie + 2, 1);
4356
else
4357
SET_HT_CAP_ELE_SHORT_GI40M(ht_cap_ie + 2, 0);
4358
4359
if (htpriv->sgi_20m)
4360
SET_HT_CAP_ELE_SHORT_GI20M(ht_cap_ie + 2, 1);
4361
else
4362
SET_HT_CAP_ELE_SHORT_GI20M(ht_cap_ie + 2, 0);
4363
#endif
4364
}
4365
4366
/* update ht op ie */
4367
if (ht_op_ie && ht_op_ielen) {
4368
SET_HT_OP_ELE_PRI_CHL(ht_op_ie + 2, ch);
4369
switch (offset) {
4370
case HAL_PRIME_CHNL_OFFSET_LOWER:
4371
SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op_ie + 2, SCA);
4372
break;
4373
case HAL_PRIME_CHNL_OFFSET_UPPER:
4374
SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op_ie + 2, SCB);
4375
break;
4376
case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
4377
default:
4378
SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op_ie + 2, SCN);
4379
break;
4380
}
4381
4382
if (bw >= CHANNEL_WIDTH_40)
4383
SET_HT_OP_ELE_STA_CHL_WIDTH(ht_op_ie + 2, 1);
4384
else
4385
SET_HT_OP_ELE_STA_CHL_WIDTH(ht_op_ie + 2, 0);
4386
}
4387
}
4388
#endif /* CONFIG_80211N_HT */
4389
}
4390
4391
static u8 rtw_ap_update_chbw_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp
4392
, u8 cur_ie_ch[], u8 cur_ie_bw[], u8 cur_ie_offset[]
4393
, u8 dec_ch[], u8 dec_bw[], u8 dec_offset[]
4394
, const char *caller)
4395
{
4396
_adapter *iface;
4397
struct mlme_ext_priv *mlmeext;
4398
WLAN_BSSID_EX *network;
4399
u8 ifbmp_ch_changed = 0;
4400
int i;
4401
4402
for (i = 0; i < dvobj->iface_nums; i++) {
4403
if (!(ifbmp & BIT(i)) || !dvobj->padapters)
4404
continue;
4405
4406
iface = dvobj->padapters[i];
4407
mlmeext = &(iface->mlmeextpriv);
4408
4409
if (MLME_IS_ASOC(iface)) {
4410
RTW_INFO(FUNC_ADPT_FMT" %u,%u,%u => %u,%u,%u%s\n", caller, ADPT_ARG(iface)
4411
, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset
4412
, dec_ch[i], dec_bw[i], dec_offset[i]
4413
, MLME_IS_OPCH_SW(iface) ? " OPCH_SW" : "");
4414
} else {
4415
RTW_INFO(FUNC_ADPT_FMT" %u,%u,%u => %u,%u,%u%s\n", caller, ADPT_ARG(iface)
4416
, cur_ie_ch[i], cur_ie_bw[i], cur_ie_offset[i]
4417
, dec_ch[i], dec_bw[i], dec_offset[i]
4418
, MLME_IS_OPCH_SW(iface) ? " OPCH_SW" : "");
4419
}
4420
}
4421
4422
for (i = 0; i < dvobj->iface_nums; i++) {
4423
if (!(ifbmp & BIT(i)) || !dvobj->padapters)
4424
continue;
4425
4426
iface = dvobj->padapters[i];
4427
mlmeext = &(iface->mlmeextpriv);
4428
network = &(mlmeext->mlmext_info.network);
4429
4430
/* ch setting differs from mlmeext.network IE */
4431
if (cur_ie_ch[i] != dec_ch[i]
4432
|| cur_ie_bw[i] != dec_bw[i]
4433
|| cur_ie_offset[i] != dec_offset[i])
4434
ifbmp_ch_changed |= BIT(i);
4435
4436
/* ch setting differs from existing one */
4437
if (MLME_IS_ASOC(iface)
4438
&& (mlmeext->cur_channel != dec_ch[i]
4439
|| mlmeext->cur_bwmode != dec_bw[i]
4440
|| mlmeext->cur_ch_offset != dec_offset[i])
4441
) {
4442
if (rtw_linked_check(iface) == _TRUE) {
4443
#ifdef CONFIG_SPCT_CH_SWITCH
4444
if (1)
4445
rtw_ap_inform_ch_switch(iface, dec_ch[i], dec_offset[i]);
4446
else
4447
#endif
4448
rtw_sta_flush(iface, _FALSE);
4449
}
4450
}
4451
4452
mlmeext->cur_channel = dec_ch[i];
4453
mlmeext->cur_bwmode = dec_bw[i];
4454
mlmeext->cur_ch_offset = dec_offset[i];
4455
4456
rtw_ap_update_bss_chbw(iface, network, dec_ch[i], dec_bw[i], dec_offset[i]);
4457
}
4458
4459
return ifbmp_ch_changed;
4460
}
4461
4462
static u8 rtw_ap_ch_specific_chk(_adapter *adapter, u8 ch, u8 *bw, u8 *offset, const char *caller)
4463
{
4464
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4465
RT_CHANNEL_INFO *chset = adapter_to_chset(adapter);
4466
u8 ret = _SUCCESS;
4467
4468
if (rtw_chset_search_ch(chset, ch) < 0) {
4469
RTW_WARN("%s ch:%u doesn't fit in chplan\n", caller, ch);
4470
ret = _FAIL;
4471
goto exit;
4472
}
4473
4474
rtw_adjust_chbw(adapter, ch, bw, offset);
4475
4476
if (!rtw_get_offset_by_chbw(ch, *bw, offset)) {
4477
RTW_WARN("%s %u,%u has no valid offset\n", caller, ch, *bw);
4478
ret = _FAIL;
4479
goto exit;
4480
}
4481
4482
while (!rtw_chset_is_chbw_valid(chset, ch, *bw, *offset)
4483
|| (rtw_odm_dfs_domain_unknown(dvobj) && rtw_is_dfs_chbw(ch, *bw, *offset))
4484
) {
4485
if (*bw > CHANNEL_WIDTH_20)
4486
(*bw)--;
4487
if (*bw == CHANNEL_WIDTH_20) {
4488
*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4489
break;
4490
}
4491
}
4492
4493
if (rtw_odm_dfs_domain_unknown(dvobj) && rtw_is_dfs_chbw(ch, *bw, *offset)) {
4494
RTW_WARN("%s DFS channel %u can't be used\n", caller, ch);
4495
ret = _FAIL;
4496
goto exit;
4497
}
4498
4499
exit:
4500
return ret;
4501
}
4502
4503
static bool rtw_ap_choose_chbw(_adapter *adapter, u8 sel_ch, u8 max_bw, u8 cur_ch
4504
, u8 *ch, u8 *bw, u8 *offset, u8 mesh_only, const char *caller)
4505
{
4506
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4507
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
4508
bool ch_avail = _FALSE;
4509
4510
#if defined(CONFIG_DFS_MASTER)
4511
if (!rtw_odm_dfs_domain_unknown(dvobj)) {
4512
if (rfctl->radar_detected
4513
&& rfctl->dbg_dfs_choose_dfs_ch_first
4514
) {
4515
ch_avail = rtw_choose_shortest_waiting_ch(rfctl, sel_ch, max_bw
4516
, ch, bw, offset
4517
, RTW_CHF_2G | RTW_CHF_NON_DFS
4518
, cur_ch
4519
, rfctl->ch_sel_same_band_prefer, mesh_only);
4520
if (ch_avail == _TRUE) {
4521
RTW_INFO("%s choose 5G DFS channel for debug\n", caller);
4522
goto exit;
4523
}
4524
}
4525
4526
if (rfctl->radar_detected
4527
&& rfctl->dfs_ch_sel_d_flags
4528
) {
4529
ch_avail = rtw_choose_shortest_waiting_ch(rfctl, sel_ch, max_bw
4530
, ch, bw, offset
4531
, rfctl->dfs_ch_sel_d_flags
4532
, cur_ch
4533
, rfctl->ch_sel_same_band_prefer, mesh_only);
4534
if (ch_avail == _TRUE) {
4535
RTW_INFO("%s choose with dfs_ch_sel_d_flags:0x%02x for debug\n"
4536
, caller, rfctl->dfs_ch_sel_d_flags);
4537
goto exit;
4538
}
4539
}
4540
4541
ch_avail = rtw_choose_shortest_waiting_ch(rfctl, sel_ch, max_bw
4542
, ch, bw, offset
4543
, 0
4544
, cur_ch
4545
, rfctl->ch_sel_same_band_prefer, mesh_only);
4546
} else
4547
#endif /* defined(CONFIG_DFS_MASTER) */
4548
{
4549
ch_avail = rtw_choose_shortest_waiting_ch(rfctl, sel_ch, max_bw
4550
, ch, bw, offset
4551
, RTW_CHF_DFS
4552
, cur_ch
4553
, rfctl->ch_sel_same_band_prefer, mesh_only);
4554
}
4555
#if defined(CONFIG_DFS_MASTER)
4556
exit:
4557
#endif
4558
if (ch_avail == _FALSE)
4559
RTW_WARN("%s no available channel\n", caller);
4560
4561
return ch_avail;
4562
}
4563
4564
u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp
4565
, s16 req_ch, s8 req_bw, s8 req_offset
4566
, u8 *ch, u8 *bw, u8 *offset, u8 *chbw_allow)
4567
{
4568
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4569
RT_CHANNEL_INFO *chset = adapter_to_chset(adapter);
4570
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
4571
bool ch_avail = _FALSE;
4572
u8 cur_ie_ch[CONFIG_IFACE_NUMBER] = {0};
4573
u8 cur_ie_bw[CONFIG_IFACE_NUMBER] = {0};
4574
u8 cur_ie_offset[CONFIG_IFACE_NUMBER] = {0};
4575
u8 dec_ch[CONFIG_IFACE_NUMBER] = {0};
4576
u8 dec_bw[CONFIG_IFACE_NUMBER] = {0};
4577
u8 dec_offset[CONFIG_IFACE_NUMBER] = {0};
4578
u8 u_ch = 0, u_bw = 0, u_offset = 0;
4579
struct mlme_ext_priv *mlmeext;
4580
WLAN_BSSID_EX *network;
4581
struct mi_state mstate;
4582
struct mi_state mstate_others;
4583
bool set_u_ch = _FALSE;
4584
u8 ifbmp_others = 0xFF & ~ifbmp & ~excl_ifbmp;
4585
u8 ifbmp_ch_changed = 0;
4586
bool ifbmp_all_mesh = 0;
4587
_adapter *iface;
4588
int i;
4589
4590
#ifdef CONFIG_RTW_MESH
4591
for (i = 0; i < dvobj->iface_nums; i++)
4592
if ((ifbmp & BIT(i)) && dvobj->padapters)
4593
if (!MLME_IS_MESH(dvobj->padapters[i]))
4594
break;
4595
ifbmp_all_mesh = i >= dvobj->iface_nums ? 1 : 0;
4596
#endif
4597
4598
RTW_INFO("%s ifbmp:0x%02x excl_ifbmp:0x%02x req:%d,%d,%d\n", __func__
4599
, ifbmp, excl_ifbmp, req_ch, req_bw, req_offset);
4600
rtw_mi_status_by_ifbmp(dvobj, ifbmp, &mstate);
4601
rtw_mi_status_by_ifbmp(dvobj, ifbmp_others, &mstate_others);
4602
RTW_INFO("%s others ld_sta_num:%u, lg_sta_num:%u, ap_num:%u, mesh_num:%u\n"
4603
, __func__, MSTATE_STA_LD_NUM(&mstate_others), MSTATE_STA_LG_NUM(&mstate_others)
4604
, MSTATE_AP_NUM(&mstate_others), MSTATE_MESH_NUM(&mstate_others));
4605
4606
for (i = 0; i < dvobj->iface_nums; i++) {
4607
if (!(ifbmp & BIT(i)) || !dvobj->padapters[i])
4608
continue;
4609
iface = dvobj->padapters[i];
4610
mlmeext = &(iface->mlmeextpriv);
4611
network = &(mlmeext->mlmext_info.network);
4612
4613
/* get current IE channel settings */
4614
rtw_ies_get_chbw(BSS_EX_TLV_IES(network), BSS_EX_TLV_IES_LEN(network)
4615
, &cur_ie_ch[i], &cur_ie_bw[i], &cur_ie_offset[i], 1, 1);
4616
4617
/* prepare temporary channel setting decision */
4618
if (req_ch == 0) {
4619
/* request comes from upper layer, use cur_ie values */
4620
dec_ch[i] = cur_ie_ch[i];
4621
dec_bw[i] = cur_ie_bw[i];
4622
dec_offset[i] = cur_ie_offset[i];
4623
} else {
4624
/* use chbw of cur_ie updated with specifying req as temporary decision */
4625
dec_ch[i] = (req_ch <= REQ_CH_NONE) ? cur_ie_ch[i] : req_ch;
4626
if (req_bw <= REQ_BW_NONE) {
4627
if (req_bw == REQ_BW_ORI)
4628
dec_bw[i] = iface->mlmepriv.ori_bw;
4629
else
4630
dec_bw[i] = cur_ie_bw[i];
4631
} else
4632
dec_bw[i] = req_bw;
4633
dec_offset[i] = (req_offset <= REQ_OFFSET_NONE) ? cur_ie_offset[i] : req_offset;
4634
}
4635
}
4636
4637
if (MSTATE_STA_LD_NUM(&mstate_others) || MSTATE_STA_LG_NUM(&mstate_others)
4638
|| MSTATE_AP_NUM(&mstate_others) || MSTATE_MESH_NUM(&mstate_others)
4639
) {
4640
/* has linked/linking STA or has AP/Mesh mode */
4641
rtw_warn_on(!rtw_mi_get_ch_setting_union_by_ifbmp(dvobj, ifbmp_others, &u_ch, &u_bw, &u_offset));
4642
RTW_INFO("%s others union:%u,%u,%u\n", __func__, u_ch, u_bw, u_offset);
4643
}
4644
4645
#ifdef CONFIG_MCC_MODE
4646
if (MCC_EN(adapter) && req_ch == 0) {
4647
if (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC)) {
4648
u8 if_id = adapter->iface_id;
4649
4650
mlmeext = &(adapter->mlmeextpriv);
4651
4652
/* check channel settings are the same */
4653
if (cur_ie_ch[if_id] == mlmeext->cur_channel
4654
&& cur_ie_bw[if_id] == mlmeext->cur_bwmode
4655
&& cur_ie_offset[if_id] == mlmeext->cur_ch_offset) {
4656
4657
RTW_INFO(FUNC_ADPT_FMT"req ch settings are the same as current ch setting, go to exit\n"
4658
, FUNC_ADPT_ARG(adapter));
4659
4660
*chbw_allow = _FALSE;
4661
goto exit;
4662
} else {
4663
RTW_INFO(FUNC_ADPT_FMT"request channel settings are not the same as current channel setting(%d,%d,%d,%d,%d,%d), restart MCC\n"
4664
, FUNC_ADPT_ARG(adapter)
4665
, cur_ie_ch[if_id], cur_ie_bw[if_id], cur_ie_offset[if_id]
4666
, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
4667
4668
rtw_hal_set_mcc_setting_disconnect(adapter);
4669
}
4670
}
4671
}
4672
#endif /* CONFIG_MCC_MODE */
4673
4674
if (MSTATE_STA_LG_NUM(&mstate_others) && !MSTATE_STA_LD_NUM(&mstate_others)) {
4675
/* has linking STA but no linked STA */
4676
4677
for (i = 0; i < dvobj->iface_nums; i++) {
4678
if (!(ifbmp & BIT(i)) || !dvobj->padapters[i])
4679
continue;
4680
iface = dvobj->padapters[i];
4681
4682
rtw_adjust_chbw(iface, dec_ch[i], &dec_bw[i], &dec_offset[i]);
4683
#ifdef CONFIG_RTW_MESH
4684
if (MLME_IS_MESH(iface))
4685
rtw_mesh_adjust_chbw(dec_ch[i], &dec_bw[i], &dec_offset[i]);
4686
#endif
4687
4688
if (rtw_is_chbw_grouped(u_ch, u_bw, u_offset, dec_ch[i], dec_bw[i], dec_offset[i])) {
4689
rtw_chset_sync_chbw(chset
4690
, &dec_ch[i], &dec_bw[i], &dec_offset[i]
4691
, &u_ch, &u_bw, &u_offset);
4692
set_u_ch = _TRUE;
4693
4694
/* channel bw offset can be allowed, not need MCC */
4695
*chbw_allow = _TRUE;
4696
} else {
4697
#ifdef CONFIG_MCC_MODE
4698
if (MCC_EN(iface)) {
4699
mlmeext = &(iface->mlmeextpriv);
4700
mlmeext->cur_channel = *ch = dec_ch[i];
4701
mlmeext->cur_bwmode = *bw = dec_bw[i];
4702
mlmeext->cur_ch_offset = *offset = dec_offset[i];
4703
4704
/* channel bw offset can not be allowed, need MCC */
4705
*chbw_allow = _FALSE;
4706
RTW_INFO(FUNC_ADPT_FMT" enable mcc: %u,%u,%u\n", FUNC_ADPT_ARG(iface)
4707
, *ch, *bw, *offset);
4708
goto exit;
4709
}
4710
#endif /* CONFIG_MCC_MODE */
4711
4712
/* set this for possible ch change when join down*/
4713
set_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING);
4714
}
4715
}
4716
4717
} else if (MSTATE_STA_LD_NUM(&mstate_others)
4718
|| MSTATE_AP_NUM(&mstate_others) || MSTATE_MESH_NUM(&mstate_others)
4719
) {
4720
/* has linked STA mode or AP/Mesh mode */
4721
4722
for (i = 0; i < dvobj->iface_nums; i++) {
4723
if (!(ifbmp & BIT(i)) || !dvobj->padapters[i])
4724
continue;
4725
iface = dvobj->padapters[i];
4726
4727
rtw_adjust_chbw(iface, u_ch, &dec_bw[i], &dec_offset[i]);
4728
#ifdef CONFIG_RTW_MESH
4729
if (MLME_IS_MESH(iface))
4730
rtw_mesh_adjust_chbw(u_ch, &dec_bw[i], &dec_offset[i]);
4731
#endif
4732
4733
#ifdef CONFIG_MCC_MODE
4734
if (MCC_EN(iface)) {
4735
if (!rtw_is_chbw_grouped(u_ch, u_bw, u_offset, dec_ch[i], dec_bw[i], dec_offset[i])) {
4736
mlmeext = &(iface->mlmeextpriv);
4737
mlmeext->cur_channel = *ch = dec_ch[i] = cur_ie_ch[i];
4738
mlmeext->cur_bwmode = *bw = dec_bw[i] = cur_ie_bw[i];
4739
mlmeext->cur_ch_offset = *offset = dec_offset[i] = cur_ie_offset[i];
4740
/* channel bw offset can not be allowed, need MCC */
4741
*chbw_allow = _FALSE;
4742
RTW_INFO(FUNC_ADPT_FMT" enable mcc: %u,%u,%u\n", FUNC_ADPT_ARG(iface)
4743
, *ch, *bw, *offset);
4744
goto exit;
4745
} else
4746
/* channel bw offset can be allowed, not need MCC */
4747
*chbw_allow = _TRUE;
4748
}
4749
#endif /* CONFIG_MCC_MODE */
4750
4751
if (req_ch == 0 && dec_bw[i] > u_bw
4752
&& rtw_is_dfs_chbw(u_ch, u_bw, u_offset)
4753
) {
4754
/* request comes from upper layer, prevent from additional channel waiting */
4755
dec_bw[i] = u_bw;
4756
if (dec_bw[i] == CHANNEL_WIDTH_20)
4757
dec_offset[i] = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4758
}
4759
4760
/* follow */
4761
rtw_chset_sync_chbw(chset
4762
, &dec_ch[i], &dec_bw[i], &dec_offset[i]
4763
, &u_ch, &u_bw, &u_offset);
4764
}
4765
4766
set_u_ch = _TRUE;
4767
4768
} else {
4769
/* autonomous decision */
4770
u8 ori_ch = 0;
4771
u8 max_bw;
4772
4773
/* autonomous decision, not need MCC */
4774
*chbw_allow = _TRUE;
4775
4776
if (req_ch <= REQ_CH_NONE) /* channel is not specified */
4777
goto choose_chbw;
4778
4779
/* get tmp dec union of ifbmp */
4780
for (i = 0; i < dvobj->iface_nums; i++) {
4781
if (!(ifbmp & BIT(i)) || !dvobj->padapters[i])
4782
continue;
4783
if (u_ch == 0) {
4784
u_ch = dec_ch[i];
4785
u_bw = dec_bw[i];
4786
u_offset = dec_offset[i];
4787
rtw_adjust_chbw(adapter, u_ch, &u_bw, &u_offset);
4788
rtw_get_offset_by_chbw(u_ch, u_bw, &u_offset);
4789
} else {
4790
u8 tmp_ch = dec_ch[i];
4791
u8 tmp_bw = dec_bw[i];
4792
u8 tmp_offset = dec_offset[i];
4793
4794
rtw_adjust_chbw(adapter, tmp_ch, &tmp_bw, &tmp_offset);
4795
rtw_get_offset_by_chbw(tmp_ch, tmp_bw, &tmp_offset);
4796
4797
rtw_warn_on(!rtw_is_chbw_grouped(u_ch, u_bw, u_offset, tmp_ch, tmp_bw, tmp_offset));
4798
rtw_sync_chbw(&tmp_ch, &tmp_bw, &tmp_offset, &u_ch, &u_bw, &u_offset);
4799
}
4800
}
4801
4802
#ifdef CONFIG_RTW_MESH
4803
/* if ifbmp are all mesh, apply bw restriction */
4804
if (ifbmp_all_mesh)
4805
rtw_mesh_adjust_chbw(u_ch, &u_bw, &u_offset);
4806
#endif
4807
4808
RTW_INFO("%s ifbmp:0x%02x tmp union:%u,%u,%u\n", __func__, ifbmp, u_ch, u_bw, u_offset);
4809
4810
/* check if tmp dec union is usable */
4811
if (rtw_ap_ch_specific_chk(adapter, u_ch, &u_bw, &u_offset, __func__) == _FAIL) {
4812
/* channel can't be used */
4813
if (req_ch > 0) {
4814
/* specific channel and not from IE => don't change channel setting */
4815
goto exit;
4816
}
4817
goto choose_chbw;
4818
} else if (rtw_chset_is_chbw_non_ocp(chset, u_ch, u_bw, u_offset)) {
4819
RTW_WARN("%s DFS channel %u,%u under non ocp\n", __func__, u_ch, u_bw);
4820
if (req_ch > 0 && req_bw > REQ_BW_NONE) {
4821
/* change_chbw with specific channel and specific bw, goto update_bss_chbw directly */
4822
goto update_bss_chbw;
4823
}
4824
} else
4825
goto update_bss_chbw;
4826
4827
choose_chbw:
4828
req_ch = req_ch > 0 ? req_ch : 0;
4829
max_bw = req_bw > REQ_BW_NONE ? req_bw : CHANNEL_WIDTH_20;
4830
for (i = 0; i < dvobj->iface_nums; i++) {
4831
if (!(ifbmp & BIT(i)) || !dvobj->padapters[i])
4832
continue;
4833
iface = dvobj->padapters[i];
4834
mlmeext = &(iface->mlmeextpriv);
4835
4836
if (req_bw <= REQ_BW_NONE) {
4837
if (req_bw == REQ_BW_ORI) {
4838
if (max_bw < iface->mlmepriv.ori_bw)
4839
max_bw = iface->mlmepriv.ori_bw;
4840
} else {
4841
if (max_bw < cur_ie_bw[i])
4842
max_bw = cur_ie_bw[i];
4843
}
4844
}
4845
4846
if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate)) {
4847
if (ori_ch == 0)
4848
ori_ch = mlmeext->cur_channel;
4849
else if (ori_ch != mlmeext->cur_channel)
4850
rtw_warn_on(1);
4851
} else {
4852
if (ori_ch == 0)
4853
ori_ch = cur_ie_ch[i];
4854
else if (ori_ch != cur_ie_ch[i])
4855
rtw_warn_on(1);
4856
}
4857
}
4858
4859
ch_avail = rtw_ap_choose_chbw(adapter, req_ch, max_bw
4860
, ori_ch, &u_ch, &u_bw, &u_offset, ifbmp_all_mesh, __func__);
4861
if (ch_avail == _FALSE)
4862
goto exit;
4863
4864
update_bss_chbw:
4865
for (i = 0; i < dvobj->iface_nums; i++) {
4866
if (!(ifbmp & BIT(i)) || !dvobj->padapters[i])
4867
continue;
4868
iface = dvobj->padapters[i];
4869
4870
dec_ch[i] = u_ch;
4871
if (dec_bw[i] > u_bw)
4872
dec_bw[i] = u_bw;
4873
if (dec_bw[i] == CHANNEL_WIDTH_20)
4874
dec_offset[i] = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4875
else
4876
dec_offset[i] = u_offset;
4877
4878
#ifdef CONFIG_RTW_MESH
4879
if (MLME_IS_MESH(iface))
4880
rtw_mesh_adjust_chbw(dec_ch[i], &dec_bw[i], &dec_offset[i]);
4881
#endif
4882
}
4883
4884
set_u_ch = _TRUE;
4885
}
4886
4887
ifbmp_ch_changed = rtw_ap_update_chbw_by_ifbmp(dvobj, ifbmp
4888
, cur_ie_ch, cur_ie_bw, cur_ie_offset
4889
, dec_ch, dec_bw, dec_offset
4890
, __func__);
4891
4892
if (u_ch != 0)
4893
RTW_INFO("%s union:%u,%u,%u\n", __func__, u_ch, u_bw, u_offset);
4894
4895
if (rtw_mi_check_fwstate(adapter, _FW_UNDER_SURVEY)) {
4896
/* scanning, leave ch setting to scan state machine */
4897
set_u_ch = _FALSE;
4898
}
4899
4900
if (set_u_ch == _TRUE) {
4901
*ch = u_ch;
4902
*bw = u_bw;
4903
*offset = u_offset;
4904
}
4905
exit:
4906
return ifbmp_ch_changed;
4907
}
4908
4909
u8 rtw_ap_sta_states_check(_adapter *adapter)
4910
{
4911
struct sta_info *psta;
4912
struct sta_priv *pstapriv = &adapter->stapriv;
4913
_list *plist, *phead;
4914
_irqL irqL;
4915
u8 rst = _FALSE;
4916
4917
if (!MLME_IS_AP(adapter) && !MLME_IS_MESH(adapter))
4918
return _FALSE;
4919
4920
if (pstapriv->auth_list_cnt !=0)
4921
return _TRUE;
4922
4923
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
4924
phead = &pstapriv->asoc_list;
4925
plist = get_next(phead);
4926
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
4927
4928
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
4929
plist = get_next(plist);
4930
4931
if (!(psta->state & _FW_LINKED)) {
4932
RTW_INFO(ADPT_FMT"- SoftAP/Mesh - sta under linking, its state = 0x%x\n", ADPT_ARG(adapter), psta->state);
4933
rst = _TRUE;
4934
break;
4935
} else if (psta->state & WIFI_UNDER_KEY_HANDSHAKE) {
4936
RTW_INFO(ADPT_FMT"- SoftAP/Mesh - sta under key handshaking, its state = 0x%x\n", ADPT_ARG(adapter), psta->state);
4937
rst = _TRUE;
4938
break;
4939
}
4940
}
4941
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
4942
return rst;
4943
}
4944
4945
/*#define DBG_SWTIMER_BASED_TXBCN*/
4946
#ifdef CONFIG_SWTIMER_BASED_TXBCN
4947
void tx_beacon_handlder(struct dvobj_priv *pdvobj)
4948
{
4949
#define BEACON_EARLY_TIME 20 /* unit:TU*/
4950
_irqL irqL;
4951
_list *plist, *phead;
4952
u32 timestamp[2];
4953
u32 bcn_interval_us; /* unit : usec */
4954
u64 time;
4955
u32 cur_tick, time_offset; /* unit : usec */
4956
u32 inter_bcn_space_us; /* unit : usec */
4957
u32 txbcn_timer_ms; /* unit : ms */
4958
int nr_vap, idx, bcn_idx;
4959
int i;
4960
u8 val8, late = 0;
4961
_adapter *padapter = NULL;
4962
4963
i = 0;
4964
4965
/* get first ap mode interface */
4966
_enter_critical_bh(&pdvobj->ap_if_q.lock, &irqL);
4967
if (rtw_is_list_empty(&pdvobj->ap_if_q.queue) || (pdvobj->nr_ap_if == 0)) {
4968
RTW_INFO("[%s] ERROR: ap_if_q is empty!or nr_ap = %d\n", __func__, pdvobj->nr_ap_if);
4969
_exit_critical_bh(&pdvobj->ap_if_q.lock, &irqL);
4970
return;
4971
} else
4972
padapter = LIST_CONTAINOR(get_next(&(pdvobj->ap_if_q.queue)), struct _ADAPTER, list);
4973
_exit_critical_bh(&pdvobj->ap_if_q.lock, &irqL);
4974
4975
if (NULL == padapter) {
4976
RTW_INFO("[%s] ERROR: no any ap interface!\n", __func__);
4977
return;
4978
}
4979
4980
4981
bcn_interval_us = DEFAULT_BCN_INTERVAL * NET80211_TU_TO_US;
4982
if (0 == bcn_interval_us) {
4983
RTW_INFO("[%s] ERROR: beacon interval = 0\n", __func__);
4984
return;
4985
}
4986
4987
/* read TSF */
4988
timestamp[1] = rtw_read32(padapter, 0x560 + 4);
4989
timestamp[0] = rtw_read32(padapter, 0x560);
4990
while (timestamp[1]) {
4991
time = (0xFFFFFFFF % bcn_interval_us + 1) * timestamp[1] + timestamp[0];
4992
timestamp[0] = (u32)time;
4993
timestamp[1] = (u32)(time >> 32);
4994
}
4995
cur_tick = timestamp[0] % bcn_interval_us;
4996
4997
4998
_enter_critical_bh(&pdvobj->ap_if_q.lock, &irqL);
4999
5000
nr_vap = (pdvobj->nr_ap_if - 1);
5001
if (nr_vap > 0) {
5002
inter_bcn_space_us = pdvobj->inter_bcn_space * NET80211_TU_TO_US; /* beacon_interval / (nr_vap+1); */
5003
idx = cur_tick / inter_bcn_space_us;
5004
if (idx < nr_vap) /* if (idx < (nr_vap+1))*/
5005
bcn_idx = idx + 1; /* bcn_idx = (idx + 1) % (nr_vap+1);*/
5006
else
5007
bcn_idx = 0;
5008
5009
/* to get padapter based on bcn_idx */
5010
padapter = NULL;
5011
phead = get_list_head(&pdvobj->ap_if_q);
5012
plist = get_next(phead);
5013
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
5014
padapter = LIST_CONTAINOR(plist, struct _ADAPTER, list);
5015
5016
plist = get_next(plist);
5017
5018
if (i == bcn_idx)
5019
break;
5020
5021
i++;
5022
}
5023
if ((NULL == padapter) || (i > pdvobj->nr_ap_if)) {
5024
RTW_INFO("[%s] ERROR: nr_ap_if = %d, padapter=%p, bcn_idx=%d, index=%d\n",
5025
__func__, pdvobj->nr_ap_if, padapter, bcn_idx, i);
5026
_exit_critical_bh(&pdvobj->ap_if_q.lock, &irqL);
5027
return;
5028
}
5029
#ifdef DBG_SWTIMER_BASED_TXBCN
5030
RTW_INFO("BCN_IDX=%d, cur_tick=%d, padapter=%p\n", bcn_idx, cur_tick, padapter);
5031
#endif
5032
if (((idx + 2 == nr_vap + 1) && (idx < nr_vap + 1)) || (0 == bcn_idx)) {
5033
time_offset = bcn_interval_us - cur_tick - BEACON_EARLY_TIME * NET80211_TU_TO_US;
5034
if ((s32)time_offset < 0)
5035
time_offset += inter_bcn_space_us;
5036
5037
} else {
5038
time_offset = (idx + 2) * inter_bcn_space_us - cur_tick - BEACON_EARLY_TIME * NET80211_TU_TO_US;
5039
if (time_offset > (inter_bcn_space_us + (inter_bcn_space_us >> 1))) {
5040
time_offset -= inter_bcn_space_us;
5041
late = 1;
5042
}
5043
}
5044
} else
5045
/*#endif*/ { /* MBSSID */
5046
time_offset = 2 * bcn_interval_us - cur_tick - BEACON_EARLY_TIME * NET80211_TU_TO_US;
5047
if (time_offset > (bcn_interval_us + (bcn_interval_us >> 1))) {
5048
time_offset -= bcn_interval_us;
5049
late = 1;
5050
}
5051
}
5052
_exit_critical_bh(&pdvobj->ap_if_q.lock, &irqL);
5053
5054
#ifdef DBG_SWTIMER_BASED_TXBCN
5055
RTW_INFO("set sw bcn timer %d us\n", time_offset);
5056
#endif
5057
txbcn_timer_ms = time_offset / NET80211_TU_TO_US;
5058
_set_timer(&pdvobj->txbcn_timer, txbcn_timer_ms);
5059
5060
if (padapter) {
5061
#ifdef CONFIG_BCN_RECOVERY
5062
rtw_ap_bcn_recovery(padapter);
5063
#endif /*CONFIG_BCN_RECOVERY*/
5064
5065
#ifdef CONFIG_BCN_XMIT_PROTECT
5066
rtw_ap_bcn_queue_empty_check(padapter, txbcn_timer_ms);
5067
#endif /*CONFIG_BCN_XMIT_PROTECT*/
5068
5069
#ifdef DBG_SWTIMER_BASED_TXBCN
5070
RTW_INFO("padapter=%p, PORT=%d\n", padapter, padapter->hw_port);
5071
#endif
5072
/* bypass TX BCN queue if op ch is switching/waiting */
5073
if (!check_fwstate(&padapter->mlmepriv, WIFI_OP_CH_SWITCHING)
5074
&& !IS_CH_WAITING(adapter_to_rfctl(padapter))
5075
) {
5076
/*update_beacon(padapter, _TIM_IE_, NULL, _FALSE, 0);*/
5077
/*issue_beacon(padapter, 0);*/
5078
send_beacon(padapter);
5079
}
5080
}
5081
5082
#if 0
5083
/* handle any buffered BC/MC frames*/
5084
/* Don't dynamically change DIS_ATIM due to HW will auto send ACQ after HIQ empty.*/
5085
val8 = *((unsigned char *)priv->beaconbuf + priv->timoffset + 4);
5086
if (val8 & 0x01) {
5087
process_mcast_dzqueue(priv);
5088
priv->pkt_in_dtimQ = 0;
5089
}
5090
#endif
5091
5092
}
5093
5094
void tx_beacon_timer_handlder(void *ctx)
5095
{
5096
struct dvobj_priv *pdvobj = (struct dvobj_priv *)ctx;
5097
_adapter *padapter = pdvobj->padapters[0];
5098
5099
if (padapter)
5100
set_tx_beacon_cmd(padapter, 0);
5101
}
5102
#endif
5103
5104
void rtw_ap_parse_sta_capability(_adapter *adapter, struct sta_info *sta, u8 *cap)
5105
{
5106
sta->capability = RTW_GET_LE16(cap);
5107
if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
5108
sta->flags |= WLAN_STA_SHORT_PREAMBLE;
5109
else
5110
sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
5111
}
5112
5113
u16 rtw_ap_parse_sta_supported_rates(_adapter *adapter, struct sta_info *sta, u8 *tlv_ies, u16 tlv_ies_len)
5114
{
5115
u8 rate_set[12];
5116
u8 rate_num;
5117
int i;
5118
u16 status = _STATS_SUCCESSFUL_;
5119
5120
rtw_ies_get_supported_rate(tlv_ies, tlv_ies_len, rate_set, &rate_num);
5121
if (rate_num == 0) {
5122
RTW_INFO(FUNC_ADPT_FMT" sta "MAC_FMT" with no supported rate\n"
5123
, FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr));
5124
status = _STATS_FAILURE_;
5125
goto exit;
5126
}
5127
5128
_rtw_memcpy(sta->bssrateset, rate_set, rate_num);
5129
sta->bssratelen = rate_num;
5130
5131
if (MLME_IS_AP(adapter)) {
5132
/* this function force only CCK rates to be bassic rate... */
5133
UpdateBrateTblForSoftAP(sta->bssrateset, sta->bssratelen);
5134
}
5135
5136
/* if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) */ /* ? */
5137
sta->flags |= WLAN_STA_NONERP;
5138
for (i = 0; i < sta->bssratelen; i++) {
5139
if ((sta->bssrateset[i] & 0x7f) > 22) {
5140
sta->flags &= ~WLAN_STA_NONERP;
5141
break;
5142
}
5143
}
5144
5145
exit:
5146
return status;
5147
}
5148
5149
u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct rtw_ieee802_11_elems *elems)
5150
{
5151
struct security_priv *sec = &adapter->securitypriv;
5152
u8 *wpa_ie;
5153
int wpa_ie_len;
5154
int group_cipher = 0, pairwise_cipher = 0;
5155
u32 akm = 0;
5156
u8 mfp_opt = MFP_NO;
5157
u16 status = _STATS_SUCCESSFUL_;
5158
5159
sta->dot8021xalg = 0;
5160
sta->wpa_psk = 0;
5161
sta->wpa_group_cipher = 0;
5162
sta->wpa2_group_cipher = 0;
5163
sta->wpa_pairwise_cipher = 0;
5164
sta->wpa2_pairwise_cipher = 0;
5165
_rtw_memset(sta->wpa_ie, 0, sizeof(sta->wpa_ie));
5166
5167
if ((sec->wpa_psk & BIT(1)) && elems->rsn_ie) {
5168
wpa_ie = elems->rsn_ie;
5169
wpa_ie_len = elems->rsn_ie_len;
5170
5171
if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, &akm, &mfp_opt) == _SUCCESS) {
5172
sta->dot8021xalg = 1;/* psk, todo:802.1x */
5173
sta->wpa_psk |= BIT(1);
5174
5175
sta->wpa2_group_cipher = group_cipher & sec->wpa2_group_cipher;
5176
sta->wpa2_pairwise_cipher = pairwise_cipher & sec->wpa2_pairwise_cipher;
5177
5178
sta->akm_suite_type = akm;
5179
if ((CHECK_BIT(WLAN_AKM_TYPE_SAE, akm)) && (MFP_NO == mfp_opt))
5180
status = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
5181
5182
if (!sta->wpa2_group_cipher)
5183
status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
5184
5185
if (!sta->wpa2_pairwise_cipher)
5186
status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
5187
} else
5188
status = WLAN_STATUS_INVALID_IE;
5189
5190
}
5191
else if ((sec->wpa_psk & BIT(0)) && elems->wpa_ie) {
5192
wpa_ie = elems->wpa_ie;
5193
wpa_ie_len = elems->wpa_ie_len;
5194
5195
if (rtw_parse_wpa_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
5196
sta->dot8021xalg = 1;/* psk, todo:802.1x */
5197
sta->wpa_psk |= BIT(0);
5198
5199
sta->wpa_group_cipher = group_cipher & sec->wpa_group_cipher;
5200
sta->wpa_pairwise_cipher = pairwise_cipher & sec->wpa_pairwise_cipher;
5201
5202
if (!sta->wpa_group_cipher)
5203
status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
5204
5205
if (!sta->wpa_pairwise_cipher)
5206
status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
5207
} else
5208
status = WLAN_STATUS_INVALID_IE;
5209
5210
} else {
5211
wpa_ie = NULL;
5212
wpa_ie_len = 0;
5213
}
5214
5215
#ifdef CONFIG_RTW_MESH
5216
if (MLME_IS_MESH(adapter)) {
5217
/* MFP is mandatory for secure mesh */
5218
if (adapter->mesh_info.mesh_auth_id)
5219
sta->flags |= WLAN_STA_MFP;
5220
} else
5221
#endif
5222
if ((sec->mfp_opt == MFP_REQUIRED && mfp_opt == MFP_NO) || mfp_opt == MFP_INVALID)
5223
status = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
5224
else if (sec->mfp_opt >= MFP_OPTIONAL && mfp_opt >= MFP_OPTIONAL)
5225
sta->flags |= WLAN_STA_MFP;
5226
5227
if ((sec->auth_type == NL80211_AUTHTYPE_SAE) &&
5228
(CHECK_BIT(WLAN_AKM_TYPE_SAE, sta->akm_suite_type)) &&
5229
(WLAN_AUTH_OPEN == sta->authalg)) {
5230
/* WPA3-SAE, PMK caching */
5231
if (rtw_cached_pmkid(adapter, sta->cmn.mac_addr) == -1) {
5232
RTW_INFO("SAE: No PMKSA cache entry found\n");
5233
status = WLAN_STATUS_INVALID_PMKID;
5234
} else {
5235
RTW_INFO("SAE: PMKSA cache entry found\n");
5236
}
5237
}
5238
5239
if (status != _STATS_SUCCESSFUL_)
5240
goto exit;
5241
5242
if (!MLME_IS_AP(adapter))
5243
goto exit;
5244
5245
sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
5246
/* if (hapd->conf->wps_state && wpa_ie == NULL) { */ /* todo: to check ap if supporting WPS */
5247
if (wpa_ie == NULL) {
5248
if (elems->wps_ie) {
5249
RTW_INFO("STA included WPS IE in "
5250
"(Re)Association Request - assume WPS is "
5251
"used\n");
5252
sta->flags |= WLAN_STA_WPS;
5253
/* wpabuf_free(sta->wps_ie); */
5254
/* sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, */
5255
/* elems.wps_ie_len - 4); */
5256
} else {
5257
RTW_INFO("STA did not include WPA/RSN IE "
5258
"in (Re)Association Request - possible WPS "
5259
"use\n");
5260
sta->flags |= WLAN_STA_MAYBE_WPS;
5261
}
5262
5263
/* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */
5264
/* that the selected registrar of AP is _FLASE */
5265
if ((sec->wpa_psk > 0)
5266
&& (sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))
5267
) {
5268
struct mlme_priv *mlme = &adapter->mlmepriv;
5269
5270
if (mlme->wps_beacon_ie) {
5271
u8 selected_registrar = 0;
5272
5273
rtw_get_wps_attr_content(mlme->wps_beacon_ie, mlme->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL);
5274
5275
if (!selected_registrar) {
5276
RTW_INFO("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
5277
status = _STATS_UNABLE_HANDLE_STA_;
5278
goto exit;
5279
}
5280
}
5281
}
5282
5283
} else {
5284
int copy_len;
5285
5286
if (sec->wpa_psk == 0) {
5287
RTW_INFO("STA " MAC_FMT
5288
": WPA/RSN IE in association request, but AP don't support WPA/RSN\n",
5289
MAC_ARG(sta->cmn.mac_addr));
5290
status = WLAN_STATUS_INVALID_IE;
5291
goto exit;
5292
}
5293
5294
if (elems->wps_ie) {
5295
RTW_INFO("STA included WPS IE in "
5296
"(Re)Association Request - WPS is "
5297
"used\n");
5298
sta->flags |= WLAN_STA_WPS;
5299
copy_len = 0;
5300
} else
5301
copy_len = ((wpa_ie_len + 2) > sizeof(sta->wpa_ie)) ? (sizeof(sta->wpa_ie)) : (wpa_ie_len + 2);
5302
5303
if (copy_len > 0)
5304
_rtw_memcpy(sta->wpa_ie, wpa_ie - 2, copy_len);
5305
}
5306
5307
exit:
5308
return status;
5309
}
5310
5311
void rtw_ap_parse_sta_wmm_ie(_adapter *adapter, struct sta_info *sta, u8 *tlv_ies, u16 tlv_ies_len)
5312
{
5313
struct mlme_priv *mlme = &adapter->mlmepriv;
5314
unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
5315
u8 *p;
5316
5317
sta->flags &= ~WLAN_STA_WME;
5318
sta->qos_option = 0;
5319
sta->qos_info = 0;
5320
sta->has_legacy_ac = _TRUE;
5321
sta->uapsd_vo = 0;
5322
sta->uapsd_vi = 0;
5323
sta->uapsd_be = 0;
5324
sta->uapsd_bk = 0;
5325
5326
if (!mlme->qospriv.qos_option)
5327
goto exit;
5328
5329
#ifdef CONFIG_RTW_MESH
5330
if (MLME_IS_MESH(adapter)) {
5331
/* QoS is mandatory in mesh */
5332
sta->flags |= WLAN_STA_WME;
5333
}
5334
#endif
5335
5336
p = rtw_get_ie_ex(tlv_ies, tlv_ies_len, WLAN_EID_VENDOR_SPECIFIC, WMM_IE, 6, NULL, NULL);
5337
if (!p)
5338
goto exit;
5339
5340
sta->flags |= WLAN_STA_WME;
5341
sta->qos_option = 1;
5342
sta->qos_info = *(p + 8);
5343
sta->max_sp_len = (sta->qos_info >> 5) & 0x3;
5344
5345
if ((sta->qos_info & 0xf) != 0xf)
5346
sta->has_legacy_ac = _TRUE;
5347
else
5348
sta->has_legacy_ac = _FALSE;
5349
5350
if (sta->qos_info & 0xf) {
5351
if (sta->qos_info & BIT(0))
5352
sta->uapsd_vo = BIT(0) | BIT(1);
5353
else
5354
sta->uapsd_vo = 0;
5355
5356
if (sta->qos_info & BIT(1))
5357
sta->uapsd_vi = BIT(0) | BIT(1);
5358
else
5359
sta->uapsd_vi = 0;
5360
5361
if (sta->qos_info & BIT(2))
5362
sta->uapsd_bk = BIT(0) | BIT(1);
5363
else
5364
sta->uapsd_bk = 0;
5365
5366
if (sta->qos_info & BIT(3))
5367
sta->uapsd_be = BIT(0) | BIT(1);
5368
else
5369
sta->uapsd_be = 0;
5370
}
5371
5372
exit:
5373
return;
5374
}
5375
5376
void rtw_ap_parse_sta_ht_ie(_adapter *adapter, struct sta_info *sta, struct rtw_ieee802_11_elems *elems)
5377
{
5378
struct mlme_priv *mlme = &adapter->mlmepriv;
5379
5380
sta->flags &= ~WLAN_STA_HT;
5381
5382
#ifdef CONFIG_80211N_HT
5383
if (mlme->htpriv.ht_option == _FALSE)
5384
goto exit;
5385
5386
/* save HT capabilities in the sta object */
5387
_rtw_memset(&sta->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
5388
if (elems->ht_capabilities && elems->ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap)) {
5389
sta->flags |= WLAN_STA_HT;
5390
sta->flags |= WLAN_STA_WME;
5391
_rtw_memcpy(&sta->htpriv.ht_cap, elems->ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
5392
5393
if (elems->ht_operation && elems->ht_operation_len == HT_OP_IE_LEN) {
5394
_rtw_memcpy(sta->htpriv.ht_op, elems->ht_operation, HT_OP_IE_LEN);
5395
sta->htpriv.op_present = 1;
5396
}
5397
}
5398
exit:
5399
#endif
5400
5401
return;
5402
}
5403
5404
void rtw_ap_parse_sta_vht_ie(_adapter *adapter, struct sta_info *sta, struct rtw_ieee802_11_elems *elems)
5405
{
5406
struct mlme_priv *mlme = &adapter->mlmepriv;
5407
5408
sta->flags &= ~WLAN_STA_VHT;
5409
5410
#ifdef CONFIG_80211AC_VHT
5411
if (mlme->vhtpriv.vht_option == _FALSE)
5412
goto exit;
5413
5414
_rtw_memset(&sta->vhtpriv, 0, sizeof(struct vht_priv));
5415
if (elems->vht_capabilities && elems->vht_capabilities_len == VHT_CAP_IE_LEN) {
5416
sta->flags |= WLAN_STA_VHT;
5417
_rtw_memcpy(sta->vhtpriv.vht_cap, elems->vht_capabilities, VHT_CAP_IE_LEN);
5418
5419
if (elems->vht_operation && elems->vht_operation_len== VHT_OP_IE_LEN) {
5420
_rtw_memcpy(sta->vhtpriv.vht_op, elems->vht_operation, VHT_OP_IE_LEN);
5421
sta->vhtpriv.op_present = 1;
5422
}
5423
5424
if (elems->vht_op_mode_notify && elems->vht_op_mode_notify_len == 1) {
5425
_rtw_memcpy(&sta->vhtpriv.vht_op_mode_notify, elems->vht_op_mode_notify, 1);
5426
sta->vhtpriv.notify_present = 1;
5427
}
5428
}
5429
exit:
5430
#endif
5431
5432
return;
5433
}
5434
#endif /* CONFIG_AP_MODE */
5435
5436
5437