1
2
3
4
5
6
7#define _RTW_AP_C_
8
9#include <linux/ieee80211.h>
10
11#include <osdep_service.h>
12#include <drv_types.h>
13#include <wifi.h>
14#include <ieee80211.h>
15#include <asm/unaligned.h>
16
17#ifdef CONFIG_88EU_AP_MODE
18
19void init_mlme_ap_info(struct adapter *padapter)
20{
21 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
22 struct sta_priv *pstapriv = &padapter->stapriv;
23 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
24
25 spin_lock_init(&pmlmepriv->bcn_update_lock);
26
27
28 _rtw_init_queue(&pacl_list->acl_node_q);
29
30 start_ap_mode(padapter);
31}
32
33void free_mlme_ap_info(struct adapter *padapter)
34{
35 struct sta_info *psta = NULL;
36 struct sta_priv *pstapriv = &padapter->stapriv;
37 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
38 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
39 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
40
41 pmlmepriv->update_bcn = false;
42 pmlmeext->bstart_bss = false;
43
44 rtw_sta_flush(padapter);
45
46 pmlmeinfo->state = _HW_STATE_NOLINK_;
47
48
49 rtw_free_all_stainfo(padapter);
50
51
52 psta = rtw_get_bcmc_stainfo(padapter);
53 spin_lock_bh(&pstapriv->sta_hash_lock);
54 rtw_free_stainfo(padapter, psta);
55 spin_unlock_bh(&pstapriv->sta_hash_lock);
56}
57
58static void update_BCNTIM(struct adapter *padapter)
59{
60 struct sta_priv *pstapriv = &padapter->stapriv;
61 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
62 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
63 struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
64 unsigned char *pie = pnetwork_mlmeext->ies;
65 u8 *p, *dst_ie, *premainder_ie = NULL;
66 u8 *pbackup_remainder_ie = NULL;
67 uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
68
69
70 p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, WLAN_EID_TIM, &tim_ielen,
71 pnetwork_mlmeext->ie_length - _FIXED_IE_LENGTH_);
72 if (p && tim_ielen > 0) {
73 tim_ielen += 2;
74 premainder_ie = p + tim_ielen;
75 tim_ie_offset = (int)(p - pie);
76 remainder_ielen = pnetwork_mlmeext->ie_length -
77 tim_ie_offset - tim_ielen;
78
79 dst_ie = p;
80 } else {
81 tim_ielen = 0;
82
83
84 offset = _FIXED_IE_LENGTH_;
85 offset += pnetwork_mlmeext->ssid.ssid_length + 2;
86
87
88 p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, WLAN_EID_SUPP_RATES,
89 &tmp_len, (pnetwork_mlmeext->ie_length -
90 _BEACON_IE_OFFSET_));
91 if (p)
92 offset += tmp_len + 2;
93
94
95 offset += 3;
96
97 premainder_ie = pie + offset;
98
99 remainder_ielen = pnetwork_mlmeext->ie_length -
100 offset - tim_ielen;
101
102
103 dst_ie = pie + offset;
104 }
105
106 if (remainder_ielen > 0) {
107 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
108 if (pbackup_remainder_ie && premainder_ie)
109 memcpy(pbackup_remainder_ie, premainder_ie,
110 remainder_ielen);
111 }
112 *dst_ie++ = WLAN_EID_TIM;
113
114 if ((pstapriv->tim_bitmap & 0xff00) && (pstapriv->tim_bitmap & 0x00fc))
115 tim_ielen = 5;
116 else
117 tim_ielen = 4;
118
119 *dst_ie++ = tim_ielen;
120
121 *dst_ie++ = 0;
122 *dst_ie++ = 1;
123
124 if (pstapriv->tim_bitmap & BIT(0))
125 *dst_ie++ = BIT(0);
126 else
127 *dst_ie++ = 0;
128
129 if (tim_ielen == 4) {
130 *dst_ie++ = pstapriv->tim_bitmap & 0xff;
131 } else if (tim_ielen == 5) {
132 put_unaligned_le16(pstapriv->tim_bitmap, dst_ie);
133 dst_ie += 2;
134 }
135
136
137 if (pbackup_remainder_ie) {
138 memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
139
140 kfree(pbackup_remainder_ie);
141 }
142 offset = (uint)(dst_ie - pie);
143 pnetwork_mlmeext->ie_length = offset + remainder_ielen;
144
145 set_tx_beacon_cmd(padapter);
146}
147
148static u8 chk_sta_is_alive(struct sta_info *psta)
149{
150 u8 ret = false;
151
152 if ((psta->sta_stats.last_rx_data_pkts +
153 psta->sta_stats.last_rx_ctrl_pkts) ==
154 (psta->sta_stats.rx_data_pkts +
155 psta->sta_stats.rx_ctrl_pkts))
156 ;
157 else
158 ret = true;
159
160 sta_update_last_rx_pkts(psta);
161
162 return ret;
163}
164
165void expire_timeout_chk(struct adapter *padapter)
166{
167 struct list_head *phead;
168 u8 updated = 0;
169 struct sta_info *psta, *temp;
170 struct sta_priv *pstapriv = &padapter->stapriv;
171 u8 chk_alive_num = 0;
172 char chk_alive_list[NUM_STA];
173 int i;
174
175 spin_lock_bh(&pstapriv->auth_list_lock);
176
177 phead = &pstapriv->auth_list;
178
179 list_for_each_entry_safe(psta, temp, phead, auth_list) {
180 if (psta->expire_to > 0) {
181 psta->expire_to--;
182 if (psta->expire_to == 0) {
183 list_del_init(&psta->auth_list);
184 pstapriv->auth_list_cnt--;
185
186 spin_unlock_bh(&pstapriv->auth_list_lock);
187
188 spin_lock_bh(&pstapriv->sta_hash_lock);
189 rtw_free_stainfo(padapter, psta);
190 spin_unlock_bh(&pstapriv->sta_hash_lock);
191
192 spin_lock_bh(&pstapriv->auth_list_lock);
193 }
194 }
195 }
196 spin_unlock_bh(&pstapriv->auth_list_lock);
197
198 psta = NULL;
199
200 spin_lock_bh(&pstapriv->asoc_list_lock);
201
202 phead = &pstapriv->asoc_list;
203
204 list_for_each_entry_safe(psta, temp, phead, asoc_list) {
205 if (chk_sta_is_alive(psta) || !psta->expire_to) {
206 psta->expire_to = pstapriv->expire_to;
207 psta->keep_alive_trycnt = 0;
208 psta->under_exist_checking = 0;
209 } else {
210 psta->expire_to--;
211 }
212
213 if (psta->expire_to <= 0) {
214 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
215
216 if (padapter->registrypriv.wifi_spec == 1) {
217 psta->expire_to = pstapriv->expire_to;
218 continue;
219 }
220
221 if (psta->state & WIFI_SLEEP_STATE) {
222 if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
223
224
225
226 psta->expire_to = pstapriv->expire_to;
227 psta->state |= WIFI_STA_ALIVE_CHK_STATE;
228
229
230
231
232 pstapriv->tim_bitmap |= BIT(psta->aid);
233 update_beacon(padapter, WLAN_EID_TIM, NULL,
234 false);
235
236 if (!pmlmeext->active_keep_alive_check)
237 continue;
238 }
239 }
240 if (pmlmeext->active_keep_alive_check) {
241 int stainfo_offset;
242
243 stainfo_offset =
244 rtw_stainfo_offset(pstapriv, psta);
245 if (stainfo_offset_valid(stainfo_offset))
246 chk_alive_list[chk_alive_num++] =
247 stainfo_offset;
248 continue;
249 }
250
251 list_del_init(&psta->asoc_list);
252 pstapriv->asoc_list_cnt--;
253
254 updated = ap_free_sta(padapter, psta, true,
255 WLAN_REASON_DEAUTH_LEAVING);
256 } else {
257
258 if (psta->sleepq_len > (NR_XMITFRAME / pstapriv->asoc_list_cnt) &&
259 padapter->xmitpriv.free_xmitframe_cnt < (NR_XMITFRAME / pstapriv->asoc_list_cnt / 2))
260 wakeup_sta_to_xmit(padapter, psta);
261 }
262 }
263
264 spin_unlock_bh(&pstapriv->asoc_list_lock);
265
266 if (chk_alive_num) {
267 u8 backup_oper_channel = 0;
268 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
269
270 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
271 backup_oper_channel = rtw_get_oper_ch(padapter);
272 SelectChannel(padapter, pmlmeext->cur_channel);
273 }
274
275
276 for (i = 0; i < chk_alive_num; i++) {
277 int ret = _FAIL;
278
279 psta = rtw_get_stainfo_by_offset(pstapriv,
280 chk_alive_list[i]);
281
282 if (psta->state & WIFI_SLEEP_STATE) {
283 ret = issue_nulldata(padapter, psta->hwaddr,
284 0, 1, 50);
285 } else {
286 ret = issue_nulldata(padapter, psta->hwaddr,
287 0, 3, 50);
288 }
289
290 psta->keep_alive_trycnt++;
291 if (ret == _SUCCESS) {
292 psta->expire_to = pstapriv->expire_to;
293 psta->keep_alive_trycnt = 0;
294 continue;
295 } else if (psta->keep_alive_trycnt <= 3) {
296 psta->expire_to = 1;
297 continue;
298 }
299
300 psta->keep_alive_trycnt = 0;
301
302 spin_lock_bh(&pstapriv->asoc_list_lock);
303 list_del_init(&psta->asoc_list);
304 pstapriv->asoc_list_cnt--;
305 updated = ap_free_sta(padapter, psta, true,
306 WLAN_REASON_DEAUTH_LEAVING);
307 spin_unlock_bh(&pstapriv->asoc_list_lock);
308 }
309
310 if (backup_oper_channel > 0)
311 SelectChannel(padapter, backup_oper_channel);
312 }
313
314 associated_clients_update(padapter, updated);
315}
316
317void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
318{
319 int i;
320 u32 init_rate = 0;
321 unsigned char sta_band = 0, raid, shortGIrate = false;
322 unsigned int tx_ra_bitmap = 0;
323 struct ht_priv *psta_ht = NULL;
324
325 if (psta)
326 psta_ht = &psta->htpriv;
327 else
328 return;
329
330 if (!(psta->state & _FW_LINKED))
331 return;
332
333
334 for (i = 0; i < sizeof(psta->bssrateset); i++) {
335 if (psta->bssrateset[i])
336 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
337 }
338
339 if (psta_ht->ht_option) {
340 for (i = 0; i < 8; i++)
341 if (psta_ht->ht_cap.mcs.rx_mask[0] & BIT(i))
342 tx_ra_bitmap |= BIT(i + 12);
343
344
345 shortGIrate = psta_ht->sgi;
346 }
347
348 if (tx_ra_bitmap & 0xffff000)
349 sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
350 else if (tx_ra_bitmap & 0xff0)
351 sta_band |= WIRELESS_11G | WIRELESS_11B;
352 else
353 sta_band |= WIRELESS_11B;
354
355 psta->wireless_mode = sta_band;
356
357 raid = networktype_to_raid(sta_band);
358 init_rate = get_highest_rate_idx(tx_ra_bitmap & 0x0fffffff) & 0x3f;
359
360 if (psta->aid < NUM_STA) {
361 u8 arg = 0;
362
363 arg = psta->mac_id & 0x1f;
364
365 arg |= BIT(7);
366
367 if (shortGIrate)
368 arg |= BIT(5);
369
370 tx_ra_bitmap |= ((raid << 28) & 0xf0000000);
371
372
373
374
375
376 rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level);
377
378 if (shortGIrate)
379 init_rate |= BIT(6);
380
381
382 psta->raid = raid;
383 psta->init_rate = init_rate;
384
385 }
386}
387
388static void update_bmc_sta(struct adapter *padapter)
389{
390 u32 init_rate = 0;
391 unsigned char network_type, raid;
392 int i, supportRateNum = 0;
393 unsigned int tx_ra_bitmap = 0;
394 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
395 struct wlan_bssid_ex *pcur_network = &pmlmepriv->cur_network.network;
396 struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
397
398 if (psta) {
399 psta->aid = 0;
400 psta->mac_id = psta->aid + 1;
401
402 psta->qos_option = 0;
403 psta->htpriv.ht_option = false;
404
405 psta->ieee8021x_blocked = 0;
406
407 memset(&psta->sta_stats, 0, sizeof(struct stainfo_stats));
408
409
410 supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->SupportedRates);
411 network_type = rtw_check_network_type((u8 *)&pcur_network->SupportedRates);
412
413 memcpy(psta->bssrateset, &pcur_network->SupportedRates,
414 supportRateNum);
415 psta->bssratelen = supportRateNum;
416
417
418 for (i = 0; i < supportRateNum; i++) {
419 if (psta->bssrateset[i])
420 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
421 }
422
423
424 network_type = WIRELESS_11B;
425 tx_ra_bitmap = 0xf;
426
427 raid = networktype_to_raid(network_type);
428 init_rate = get_highest_rate_idx(tx_ra_bitmap & 0x0fffffff) &
429 0x3f;
430
431
432 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
433
434 {
435 u8 arg = 0;
436
437 arg = psta->mac_id & 0x1f;
438 arg |= BIT(7);
439 tx_ra_bitmap |= ((raid << 28) & 0xf0000000);
440
441
442
443
444
445 rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0);
446 }
447
448 psta->raid = raid;
449 psta->init_rate = init_rate;
450
451 rtw_stassoc_hw_rpt(padapter, psta);
452
453 spin_lock_bh(&psta->lock);
454 psta->state = _FW_LINKED;
455 spin_unlock_bh(&psta->lock);
456
457 }
458}
459
460
461
462
463
464
465
466
467void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
468{
469 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
470 struct security_priv *psecuritypriv = &padapter->securitypriv;
471 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
472 struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
473 struct ht_priv *phtpriv_sta = &psta->htpriv;
474
475 psta->mac_id = psta->aid + 1;
476
477
478 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
479
480 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
481 psta->ieee8021x_blocked = true;
482 else
483 psta->ieee8021x_blocked = false;
484
485
486
487
488 VCS_update(padapter, psta);
489
490 if (phtpriv_sta->ht_option) {
491
492 phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
493
494
495 if (le16_to_cpu(phtpriv_sta->ht_cap.cap_info &
496 phtpriv_ap->ht_cap.cap_info) &
497 (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40))
498 phtpriv_sta->sgi = true;
499
500
501 if (le16_to_cpu(phtpriv_sta->ht_cap.cap_info &
502 phtpriv_ap->ht_cap.cap_info) &
503 IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
504 phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
505 phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
506 }
507 psta->qos_option = true;
508 } else {
509 phtpriv_sta->ampdu_enable = false;
510 phtpriv_sta->sgi = false;
511 phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
512 phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
513 }
514
515
516 send_delba(padapter, 0, psta->hwaddr);
517
518
519 send_delba(padapter, 1, psta->hwaddr);
520 phtpriv_sta->agg_enable_bitmap = 0x0;
521 phtpriv_sta->candidate_tid_bitmap = 0x0;
522
523
524
525 memset(&psta->sta_stats, 0, sizeof(struct stainfo_stats));
526
527 spin_lock_bh(&psta->lock);
528 psta->state |= _FW_LINKED;
529 spin_unlock_bh(&psta->lock);
530}
531
532static void update_hw_ht_param(struct adapter *padapter)
533{
534 u8 max_ampdu_len;
535 u8 min_mpdu_spacing;
536 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
537 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
538
539
540
541
542
543 max_ampdu_len = pmlmeinfo->HT_caps.ampdu_params_info & 0x03;
544 min_mpdu_spacing = (pmlmeinfo->HT_caps.ampdu_params_info & 0x1c) >> 2;
545
546 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, &min_mpdu_spacing);
547 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, &max_ampdu_len);
548
549
550 pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & 0x0C) >> 2;
551}
552
553static void start_bss_network(struct adapter *padapter, u8 *pbuf)
554{
555 u8 *p;
556 u8 val8, cur_channel, cur_bwmode, cur_ch_offset;
557 u16 bcn_interval;
558 u32 acparm;
559 uint ie_len;
560 struct registry_priv *pregpriv = &padapter->registrypriv;
561 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
562 struct security_priv *psecuritypriv = &padapter->securitypriv;
563 struct wlan_bssid_ex *pnetwork = &pmlmepriv->cur_network.network;
564 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
565 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
566 struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
567 struct HT_info_element *pht_info = NULL;
568
569 bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
570 cur_channel = pnetwork->Configuration.DSConfig;
571 cur_bwmode = HT_CHANNEL_WIDTH_20;
572 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
573
574
575
576
577
578
579 if (!rtw_get_wps_ie(pnetwork->ies + _FIXED_IE_LENGTH_, pnetwork->ie_length - _FIXED_IE_LENGTH_, NULL, NULL))
580 pmlmeext->bstart_bss = true;
581
582
583 if (pmlmepriv->qospriv.qos_option)
584 pmlmeinfo->WMM_enable = true;
585 if (pmlmepriv->htpriv.ht_option) {
586 pmlmeinfo->WMM_enable = true;
587 pmlmeinfo->HT_enable = true;
588
589 update_hw_ht_param(padapter);
590 }
591
592
593 if (!pmlmepriv->cur_network.join_res) {
594
595
596
597 if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) &&
598 (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_))
599 flush_all_cam_entry(padapter);
600 }
601
602
603 Set_MSR(padapter, _HW_STATE_AP_);
604
605
606 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress);
607
608
609 acparm = 0x002F3217;
610 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
611 acparm = 0x005E4317;
612 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
613 acparm = 0x005ea42b;
614 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
615 acparm = 0x0000A444;
616 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
617
618
619 val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
620 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
621
622
623 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL,
624 (u8 *)(&bcn_interval));
625
626 UpdateBrateTbl(padapter, pnetwork->SupportedRates);
627 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
628
629 if (!pmlmepriv->cur_network.join_res) {
630
631 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
632 }
633
634 p = rtw_get_ie(pnetwork->ies + sizeof(struct ndis_802_11_fixed_ie),
635 WLAN_EID_HT_OPERATION, &ie_len,
636 pnetwork->ie_length -
637 sizeof(struct ndis_802_11_fixed_ie));
638 if (p && ie_len) {
639 pht_info = (struct HT_info_element *)(p + 2);
640
641 if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2))) {
642
643 cur_bwmode = HT_CHANNEL_WIDTH_40;
644 switch (pht_info->infos[0] & 0x3) {
645 case 1:
646 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
647 break;
648 case 3:
649 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
650 break;
651 default:
652 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
653 break;
654 }
655 }
656 }
657
658
659
660 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
661
662
663 pmlmeext->cur_channel = cur_channel;
664 pmlmeext->cur_bwmode = cur_bwmode;
665 pmlmeext->cur_ch_offset = cur_ch_offset;
666 pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;
667
668
669 update_wireless_mode(padapter);
670
671
672 update_capinfo(padapter, rtw_get_capability(pnetwork));
673
674
675 memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
676
677 if (pmlmeext->bstart_bss) {
678 update_beacon(padapter, WLAN_EID_TIM, NULL, false);
679
680
681 send_beacon(padapter);
682 }
683
684
685 update_bmc_sta(padapter);
686}
687
688int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
689{
690 int ret = _SUCCESS;
691 u8 *p;
692 u8 *pHT_caps_ie = NULL;
693 u8 *pHT_info_ie = NULL;
694 struct sta_info *psta = NULL;
695 u16 cap, ht_cap = false;
696 uint ie_len = 0;
697 int group_cipher, pairwise_cipher;
698 u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
699 int supportRateNum = 0;
700 u8 OUI1[] = {0x00, 0x50, 0xf2, 0x01};
701 u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
702 struct registry_priv *pregistrypriv = &padapter->registrypriv;
703 struct security_priv *psecuritypriv = &padapter->securitypriv;
704 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
705 struct wlan_bssid_ex *pbss_network = &pmlmepriv->cur_network.network;
706 u8 *ie = pbss_network->ies;
707
708
709
710
711
712
713
714
715
716
717
718
719 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
720 return _FAIL;
721
722 if (len < 0 || len > MAX_IE_SZ)
723 return _FAIL;
724
725 pbss_network->ie_length = len;
726
727 memset(ie, 0, MAX_IE_SZ);
728
729 memcpy(ie, pbuf, pbss_network->ie_length);
730
731 if (pbss_network->InfrastructureMode != Ndis802_11APMode)
732 return _FAIL;
733
734 pbss_network->Rssi = 0;
735
736 ether_addr_copy(pbss_network->MacAddress, myid(&padapter->eeprompriv));
737
738
739 p = rtw_get_beacon_interval_from_ie(ie);
740 pbss_network->Configuration.BeaconPeriod = get_unaligned_le16(p);
741
742
743 cap = get_unaligned_le16(ie);
744
745
746 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_SSID, &ie_len,
747 pbss_network->ie_length - _BEACON_IE_OFFSET_);
748 if (p && ie_len > 0) {
749 ie_len = min_t(int, ie_len, sizeof(pbss_network->ssid.ssid));
750 memset(&pbss_network->ssid, 0, sizeof(struct ndis_802_11_ssid));
751 memcpy(pbss_network->ssid.ssid, p + 2, ie_len);
752 pbss_network->ssid.ssid_length = ie_len;
753 }
754
755
756 channel = 0;
757 pbss_network->Configuration.Length = 0;
758 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_DS_PARAMS, &ie_len,
759 (pbss_network->ie_length - _BEACON_IE_OFFSET_));
760 if (p && ie_len > 0)
761 channel = *(p + 2);
762
763 pbss_network->Configuration.DSConfig = channel;
764
765 memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
766
767 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_SUPP_RATES, &ie_len,
768 pbss_network->ie_length - _BEACON_IE_OFFSET_);
769 if (p) {
770 ie_len = min_t(int, ie_len, NDIS_802_11_LENGTH_RATES_EX);
771 memcpy(supportRate, p + 2, ie_len);
772 supportRateNum = ie_len;
773 }
774
775
776 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_EXT_SUPP_RATES,
777 &ie_len, pbss_network->ie_length - _BEACON_IE_OFFSET_);
778 if (p) {
779 ie_len = min_t(int, ie_len,
780 NDIS_802_11_LENGTH_RATES_EX - supportRateNum);
781 memcpy(supportRate + supportRateNum, p + 2, ie_len);
782 supportRateNum += ie_len;
783 }
784
785 network_type = rtw_check_network_type(supportRate);
786
787 rtw_set_supported_rate(pbss_network->SupportedRates, network_type);
788
789
790 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_ERP_INFO, &ie_len,
791 pbss_network->ie_length - _BEACON_IE_OFFSET_);
792 if (p && ie_len > 0)
793 ERP_IE_handler(padapter, (struct ndis_802_11_var_ie *)p);
794
795
796 if (cap & BIT(4))
797 pbss_network->Privacy = 1;
798 else
799 pbss_network->Privacy = 0;
800
801 psecuritypriv->wpa_psk = 0;
802
803
804 group_cipher = 0;
805 pairwise_cipher = 0;
806 psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
807 psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
808 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_RSN, &ie_len,
809 pbss_network->ie_length - _BEACON_IE_OFFSET_);
810 if (p && ie_len > 0) {
811 if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
812 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
813
814 psecuritypriv->dot8021xalg = 1;
815 psecuritypriv->wpa_psk |= BIT(1);
816
817 psecuritypriv->wpa2_group_cipher = group_cipher;
818 psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
819 }
820 }
821
822 ie_len = 0;
823 group_cipher = 0;
824 pairwise_cipher = 0;
825 psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
826 psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
827 for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) {
828 p = rtw_get_ie(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
829 pbss_network->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2));
830 if ((p) && (!memcmp(p + 2, OUI1, 4))) {
831 if (rtw_parse_wpa_ie(p, ie_len + 2, &group_cipher,
832 &pairwise_cipher, NULL) == _SUCCESS) {
833 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
834
835 psecuritypriv->dot8021xalg = 1;
836
837 psecuritypriv->wpa_psk |= BIT(0);
838
839 psecuritypriv->wpa_group_cipher = group_cipher;
840 psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
841 }
842 break;
843 }
844 if ((!p) || (ie_len == 0))
845 break;
846 }
847
848
849 ie_len = 0;
850 pmlmepriv->qospriv.qos_option = 0;
851 if (pregistrypriv->wmm_enable) {
852 for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) {
853 p = rtw_get_ie(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
854 pbss_network->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2));
855 if ((p) && !memcmp(p + 2, WMM_PARA_IE, 6)) {
856 pmlmepriv->qospriv.qos_option = 1;
857
858
859 *(p + 8) |= BIT(7);
860
861
862
863
864 *(p + 10) &= ~BIT(4);
865 *(p + 14) &= ~BIT(4);
866 *(p + 18) &= ~BIT(4);
867 *(p + 22) &= ~BIT(4);
868 break;
869 }
870
871 if ((!p) || (ie_len == 0))
872 break;
873 }
874 }
875
876 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_HT_CAPABILITY, &ie_len,
877 pbss_network->ie_length - _BEACON_IE_OFFSET_);
878 if (p && ie_len > 0) {
879 struct ieee80211_ht_cap *pht_cap = (struct ieee80211_ht_cap *)(p + 2);
880
881 pHT_caps_ie = p;
882 ht_cap = true;
883 network_type |= WIRELESS_11_24N;
884
885 if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
886 (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
887 pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & (0x07 << 2));
888 else
889 pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00);
890
891
892 pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_FACTOR & 0x03);
893
894 pht_cap->mcs.rx_mask[0] = 0xff;
895 pht_cap->mcs.rx_mask[1] = 0x0;
896 ie_len = min_t(int, ie_len, sizeof(pmlmepriv->htpriv.ht_cap));
897 memcpy(&pmlmepriv->htpriv.ht_cap, p + 2, ie_len);
898 }
899
900
901 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_HT_OPERATION, &ie_len,
902 pbss_network->ie_length - _BEACON_IE_OFFSET_);
903 if (p && ie_len > 0)
904 pHT_info_ie = p;
905 switch (network_type) {
906 case WIRELESS_11B:
907 pbss_network->NetworkTypeInUse = Ndis802_11DS;
908 break;
909 case WIRELESS_11G:
910 case WIRELESS_11BG:
911 case WIRELESS_11G_24N:
912 case WIRELESS_11BG_24N:
913 pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
914 break;
915 case WIRELESS_11A:
916 pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;
917 break;
918 default:
919 pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
920 break;
921 }
922
923 pmlmepriv->cur_network.network_type = network_type;
924
925 pmlmepriv->htpriv.ht_option = false;
926
927 if ((psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
928 (psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
929
930
931 }
932
933
934 if (pregistrypriv->ht_enable && ht_cap) {
935 pmlmepriv->htpriv.ht_option = true;
936 pmlmepriv->qospriv.qos_option = 1;
937
938 if (pregistrypriv->ampdu_enable == 1)
939 pmlmepriv->htpriv.ampdu_enable = true;
940 HT_caps_handler(padapter, (struct ndis_802_11_var_ie *)pHT_caps_ie);
941
942 HT_info_handler(padapter, (struct ndis_802_11_var_ie *)pHT_info_ie);
943 }
944
945 pbss_network->Length = get_wlan_bssid_ex_sz(pbss_network);
946
947
948 start_bss_network(padapter, (u8 *)pbss_network);
949
950
951 psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
952 if (!psta) {
953 psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
954 if (!psta)
955 return _FAIL;
956 }
957
958
959 psta->state |= WIFI_AP_STATE;
960 rtw_indicate_connect(padapter);
961 pmlmepriv->cur_network.join_res = true;
962 return ret;
963}
964
965void rtw_set_macaddr_acl(struct adapter *padapter, int mode)
966{
967 struct sta_priv *pstapriv = &padapter->stapriv;
968 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
969
970 pacl_list->mode = mode;
971}
972
973int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
974{
975 struct list_head *plist, *phead;
976 u8 added = false;
977 int i, ret = 0;
978 struct rtw_wlan_acl_node *paclnode;
979 struct sta_priv *pstapriv = &padapter->stapriv;
980 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
981 struct __queue *pacl_node_q = &pacl_list->acl_node_q;
982
983 if ((NUM_ACL - 1) < pacl_list->num)
984 return -1;
985
986 spin_lock_bh(&pacl_node_q->lock);
987
988 phead = get_list_head(pacl_node_q);
989 list_for_each(plist, phead) {
990 paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
991
992 if (!memcmp(paclnode->addr, addr, ETH_ALEN)) {
993 if (paclnode->valid) {
994 added = true;
995 break;
996 }
997 }
998 }
999
1000 spin_unlock_bh(&pacl_node_q->lock);
1001
1002 if (added)
1003 return ret;
1004
1005 spin_lock_bh(&pacl_node_q->lock);
1006
1007 for (i = 0; i < NUM_ACL; i++) {
1008 paclnode = &pacl_list->aclnode[i];
1009
1010 if (!paclnode->valid) {
1011 INIT_LIST_HEAD(&paclnode->list);
1012
1013 ether_addr_copy(paclnode->addr, addr);
1014
1015 paclnode->valid = true;
1016
1017 list_add_tail(&paclnode->list, get_list_head(pacl_node_q));
1018
1019 pacl_list->num++;
1020
1021 break;
1022 }
1023 }
1024
1025 spin_unlock_bh(&pacl_node_q->lock);
1026
1027 return ret;
1028}
1029
1030int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
1031{
1032 struct list_head *phead;
1033 struct rtw_wlan_acl_node *paclnode, *temp;
1034 struct sta_priv *pstapriv = &padapter->stapriv;
1035 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1036 struct __queue *pacl_node_q = &pacl_list->acl_node_q;
1037
1038 spin_lock_bh(&pacl_node_q->lock);
1039
1040 phead = get_list_head(pacl_node_q);
1041 list_for_each_entry_safe(paclnode, temp, phead, list) {
1042 if (!memcmp(paclnode->addr, addr, ETH_ALEN)) {
1043 if (paclnode->valid) {
1044 paclnode->valid = false;
1045
1046 list_del_init(&paclnode->list);
1047
1048 pacl_list->num--;
1049 }
1050 }
1051 }
1052
1053 spin_unlock_bh(&pacl_node_q->lock);
1054
1055 return 0;
1056}
1057
1058static void update_bcn_erpinfo_ie(struct adapter *padapter)
1059{
1060 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1061 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1062 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1063 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
1064 unsigned char *p, *ie = pnetwork->ies;
1065 u32 len = 0;
1066
1067 if (!pmlmeinfo->ERP_enable)
1068 return;
1069
1070
1071 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_ERP_INFO, &len,
1072 (pnetwork->ie_length - _BEACON_IE_OFFSET_));
1073 if (p && len > 0) {
1074 struct ndis_802_11_var_ie *pIE = (struct ndis_802_11_var_ie *)p;
1075
1076 if (pmlmepriv->num_sta_non_erp == 1)
1077 pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT |
1078 RTW_ERP_INFO_USE_PROTECTION;
1079 else
1080 pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT |
1081 RTW_ERP_INFO_USE_PROTECTION);
1082
1083 if (pmlmepriv->num_sta_no_short_preamble > 0)
1084 pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
1085 else
1086 pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);
1087
1088 ERP_IE_handler(padapter, pIE);
1089 }
1090}
1091
1092static void update_bcn_wps_ie(struct adapter *padapter)
1093{
1094 u8 *pwps_ie = NULL, *pwps_ie_src;
1095 u8 *premainder_ie, *pbackup_remainder_ie = NULL;
1096 uint wps_ielen = 0, wps_offset, remainder_ielen;
1097 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1098 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1099 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1100 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
1101 unsigned char *ie = pnetwork->ies;
1102 u32 ielen = pnetwork->ie_length;
1103
1104 pwps_ie_src = pmlmepriv->wps_beacon_ie;
1105 if (!pwps_ie_src)
1106 return;
1107
1108 pwps_ie = rtw_get_wps_ie(ie + _FIXED_IE_LENGTH_,
1109 ielen - _FIXED_IE_LENGTH_, NULL, &wps_ielen);
1110
1111 if (!pwps_ie || wps_ielen == 0)
1112 return;
1113
1114 wps_offset = (uint)(pwps_ie - ie);
1115
1116 premainder_ie = pwps_ie + wps_ielen;
1117
1118 remainder_ielen = ielen - wps_offset - wps_ielen;
1119
1120 if (remainder_ielen > 0) {
1121 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
1122 if (pbackup_remainder_ie)
1123 memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
1124 }
1125
1126 wps_ielen = (uint)pwps_ie_src[1];
1127 if (wps_offset + wps_ielen + 2 + remainder_ielen <= MAX_IE_SZ) {
1128 memcpy(pwps_ie, pwps_ie_src, wps_ielen + 2);
1129 pwps_ie += wps_ielen + 2;
1130
1131 if (pbackup_remainder_ie)
1132 memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
1133
1134
1135 pnetwork->ie_length = wps_offset + wps_ielen + 2 + remainder_ielen;
1136 }
1137
1138 kfree(pbackup_remainder_ie);
1139}
1140
1141static void update_bcn_vendor_spec_ie(struct adapter *padapter, u8 *oui)
1142{
1143
1144 if (!memcmp(WPS_OUI, oui, 4))
1145 update_bcn_wps_ie(padapter);
1146}
1147
1148void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
1149{
1150 struct mlme_priv *pmlmepriv;
1151 struct mlme_ext_priv *pmlmeext;
1152
1153 if (!padapter)
1154 return;
1155
1156 pmlmepriv = &padapter->mlmepriv;
1157 pmlmeext = &padapter->mlmeextpriv;
1158
1159 if (!pmlmeext->bstart_bss)
1160 return;
1161
1162 spin_lock_bh(&pmlmepriv->bcn_update_lock);
1163
1164 switch (ie_id) {
1165 case WLAN_EID_TIM:
1166 update_BCNTIM(padapter);
1167 break;
1168 case WLAN_EID_ERP_INFO:
1169 update_bcn_erpinfo_ie(padapter);
1170 break;
1171 case WLAN_EID_VENDOR_SPECIFIC:
1172 update_bcn_vendor_spec_ie(padapter, oui);
1173 break;
1174 default:
1175 break;
1176 }
1177
1178 pmlmepriv->update_bcn = true;
1179
1180 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
1181
1182 if (tx)
1183 set_tx_beacon_cmd(padapter);
1184}
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198static int rtw_ht_operation_update(struct adapter *padapter)
1199{
1200 u16 cur_op_mode, new_op_mode;
1201 int op_mode_changes = 0;
1202 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1203 struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
1204
1205 if (pmlmepriv->htpriv.ht_option)
1206 return 0;
1207
1208 if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
1209 pmlmepriv->num_sta_ht_no_gf) {
1210 pmlmepriv->ht_op_mode |=
1211 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
1212 op_mode_changes++;
1213 } else if ((pmlmepriv->ht_op_mode &
1214 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
1215 pmlmepriv->num_sta_ht_no_gf == 0) {
1216 pmlmepriv->ht_op_mode &=
1217 ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
1218 op_mode_changes++;
1219 }
1220
1221 if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
1222 (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
1223 pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
1224 op_mode_changes++;
1225 } else if ((pmlmepriv->ht_op_mode &
1226 HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
1227 (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
1228 pmlmepriv->ht_op_mode &=
1229 ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
1230 op_mode_changes++;
1231 }
1232
1233
1234
1235
1236
1237 new_op_mode = 0;
1238 if (pmlmepriv->num_sta_no_ht ||
1239 (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
1240 new_op_mode = OP_MODE_MIXED;
1241 else if ((le16_to_cpu(phtpriv_ap->ht_cap.cap_info) &
1242 IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
1243 pmlmepriv->num_sta_ht_20mhz)
1244 new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
1245 else if (pmlmepriv->olbc_ht)
1246 new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
1247 else
1248 new_op_mode = OP_MODE_PURE;
1249
1250 cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
1251 if (cur_op_mode != new_op_mode) {
1252 pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
1253 pmlmepriv->ht_op_mode |= new_op_mode;
1254 op_mode_changes++;
1255 }
1256
1257 return op_mode_changes;
1258}
1259
1260void associated_clients_update(struct adapter *padapter, u8 updated)
1261{
1262
1263 if (updated) {
1264 struct list_head *phead, *plist;
1265 struct sta_info *psta = NULL;
1266 struct sta_priv *pstapriv = &padapter->stapriv;
1267
1268 spin_lock_bh(&pstapriv->asoc_list_lock);
1269
1270 phead = &pstapriv->asoc_list;
1271
1272 list_for_each(plist, phead) {
1273 psta = list_entry(plist, struct sta_info, asoc_list);
1274
1275 VCS_update(padapter, psta);
1276 }
1277 spin_unlock_bh(&pstapriv->asoc_list_lock);
1278 }
1279}
1280
1281
1282void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
1283{
1284 u8 beacon_updated = false;
1285 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1286 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1287
1288 if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) {
1289 if (!psta->no_short_preamble_set) {
1290 psta->no_short_preamble_set = 1;
1291
1292 pmlmepriv->num_sta_no_short_preamble++;
1293
1294 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1295 (pmlmepriv->num_sta_no_short_preamble == 1)) {
1296 beacon_updated = true;
1297 update_beacon(padapter, 0xFF, NULL, true);
1298 }
1299 }
1300 } else {
1301 if (psta->no_short_preamble_set) {
1302 psta->no_short_preamble_set = 0;
1303
1304 pmlmepriv->num_sta_no_short_preamble--;
1305
1306 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1307 (pmlmepriv->num_sta_no_short_preamble == 0)) {
1308 beacon_updated = true;
1309 update_beacon(padapter, 0xFF, NULL, true);
1310 }
1311 }
1312 }
1313
1314 if (psta->flags & WLAN_STA_NONERP) {
1315 if (!psta->nonerp_set) {
1316 psta->nonerp_set = 1;
1317
1318 pmlmepriv->num_sta_non_erp++;
1319
1320 if (pmlmepriv->num_sta_non_erp == 1) {
1321 beacon_updated = true;
1322 update_beacon(padapter, WLAN_EID_ERP_INFO, NULL, true);
1323 }
1324 }
1325 } else {
1326 if (psta->nonerp_set) {
1327 psta->nonerp_set = 0;
1328
1329 pmlmepriv->num_sta_non_erp--;
1330
1331 if (pmlmepriv->num_sta_non_erp == 0) {
1332 beacon_updated = true;
1333 update_beacon(padapter, WLAN_EID_ERP_INFO, NULL, true);
1334 }
1335 }
1336 }
1337
1338 if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)) {
1339 if (!psta->no_short_slot_time_set) {
1340 psta->no_short_slot_time_set = 1;
1341
1342 pmlmepriv->num_sta_no_short_slot_time++;
1343
1344 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1345 (pmlmepriv->num_sta_no_short_slot_time == 1)) {
1346 beacon_updated = true;
1347 update_beacon(padapter, 0xFF, NULL, true);
1348 }
1349 }
1350 } else {
1351 if (psta->no_short_slot_time_set) {
1352 psta->no_short_slot_time_set = 0;
1353
1354 pmlmepriv->num_sta_no_short_slot_time--;
1355
1356 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1357 (pmlmepriv->num_sta_no_short_slot_time == 0)) {
1358 beacon_updated = true;
1359 update_beacon(padapter, 0xFF, NULL, true);
1360 }
1361 }
1362 }
1363
1364 if (psta->flags & WLAN_STA_HT) {
1365 u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
1366
1367 if (psta->no_ht_set) {
1368 psta->no_ht_set = 0;
1369 pmlmepriv->num_sta_no_ht--;
1370 }
1371
1372 if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
1373 if (!psta->no_ht_gf_set) {
1374 psta->no_ht_gf_set = 1;
1375 pmlmepriv->num_sta_ht_no_gf++;
1376 }
1377 }
1378
1379 if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH_20_40) == 0) {
1380 if (!psta->ht_20mhz_set) {
1381 psta->ht_20mhz_set = 1;
1382 pmlmepriv->num_sta_ht_20mhz++;
1383 }
1384 }
1385 } else {
1386 if (!psta->no_ht_set) {
1387 psta->no_ht_set = 1;
1388 pmlmepriv->num_sta_no_ht++;
1389 }
1390 }
1391
1392 if (rtw_ht_operation_update(padapter) > 0) {
1393 update_beacon(padapter, WLAN_EID_HT_CAPABILITY, NULL, false);
1394 update_beacon(padapter, WLAN_EID_HT_OPERATION, NULL, true);
1395 }
1396
1397
1398 associated_clients_update(padapter, beacon_updated);
1399}
1400
1401u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta)
1402{
1403 u8 beacon_updated = false;
1404 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1405 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1406
1407 if (!psta)
1408 return beacon_updated;
1409
1410 if (psta->no_short_preamble_set) {
1411 psta->no_short_preamble_set = 0;
1412 pmlmepriv->num_sta_no_short_preamble--;
1413 if (pmlmeext->cur_wireless_mode > WIRELESS_11B &&
1414 pmlmepriv->num_sta_no_short_preamble == 0) {
1415 beacon_updated = true;
1416 update_beacon(padapter, 0xFF, NULL, true);
1417 }
1418 }
1419
1420 if (psta->nonerp_set) {
1421 psta->nonerp_set = 0;
1422 pmlmepriv->num_sta_non_erp--;
1423 if (pmlmepriv->num_sta_non_erp == 0) {
1424 beacon_updated = true;
1425 update_beacon(padapter, WLAN_EID_ERP_INFO, NULL, true);
1426 }
1427 }
1428
1429 if (psta->no_short_slot_time_set) {
1430 psta->no_short_slot_time_set = 0;
1431 pmlmepriv->num_sta_no_short_slot_time--;
1432 if (pmlmeext->cur_wireless_mode > WIRELESS_11B &&
1433 pmlmepriv->num_sta_no_short_slot_time == 0) {
1434 beacon_updated = true;
1435 update_beacon(padapter, 0xFF, NULL, true);
1436 }
1437 }
1438
1439 if (psta->no_ht_gf_set) {
1440 psta->no_ht_gf_set = 0;
1441 pmlmepriv->num_sta_ht_no_gf--;
1442 }
1443
1444 if (psta->no_ht_set) {
1445 psta->no_ht_set = 0;
1446 pmlmepriv->num_sta_no_ht--;
1447 }
1448
1449 if (psta->ht_20mhz_set) {
1450 psta->ht_20mhz_set = 0;
1451 pmlmepriv->num_sta_ht_20mhz--;
1452 }
1453
1454 if (rtw_ht_operation_update(padapter) > 0) {
1455 update_beacon(padapter, WLAN_EID_HT_CAPABILITY, NULL, false);
1456 update_beacon(padapter, WLAN_EID_HT_OPERATION, NULL, true);
1457 }
1458
1459
1460
1461 return beacon_updated;
1462}
1463
1464u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta,
1465 bool active, u16 reason)
1466{
1467 u8 beacon_updated = false;
1468 struct sta_priv *pstapriv = &padapter->stapriv;
1469
1470 if (!psta)
1471 return beacon_updated;
1472
1473
1474 send_delba(padapter, 0, psta->hwaddr);
1475
1476
1477 send_delba(padapter, 1, psta->hwaddr);
1478 psta->htpriv.agg_enable_bitmap = 0x0;
1479 psta->htpriv.candidate_tid_bitmap = 0x0;
1480
1481 if (active)
1482 issue_deauth(padapter, psta->hwaddr, reason);
1483
1484
1485 rtw_clearstakey_cmd(padapter, (u8 *)psta, (u8)(psta->mac_id + 3), true);
1486
1487 spin_lock_bh(&psta->lock);
1488 psta->state &= ~_FW_LINKED;
1489 spin_unlock_bh(&psta->lock);
1490
1491 rtw_indicate_sta_disassoc_event(padapter, psta);
1492
1493 report_del_sta_event(padapter, psta->hwaddr, reason);
1494
1495 beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
1496
1497 spin_lock_bh(&pstapriv->sta_hash_lock);
1498 rtw_free_stainfo(padapter, psta);
1499 spin_unlock_bh(&pstapriv->sta_hash_lock);
1500
1501 return beacon_updated;
1502}
1503
1504int rtw_sta_flush(struct adapter *padapter)
1505{
1506 struct list_head *phead;
1507 struct sta_info *psta, *temp;
1508 struct sta_priv *pstapriv = &padapter->stapriv;
1509 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1510 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1511 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1512
1513 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
1514 return 0;
1515
1516 spin_lock_bh(&pstapriv->asoc_list_lock);
1517 phead = &pstapriv->asoc_list;
1518
1519 list_for_each_entry_safe(psta, temp, phead, asoc_list) {
1520 list_del_init(&psta->asoc_list);
1521 pstapriv->asoc_list_cnt--;
1522
1523 ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
1524 }
1525 spin_unlock_bh(&pstapriv->asoc_list_lock);
1526
1527 issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
1528
1529 associated_clients_update(padapter, true);
1530
1531 return 0;
1532}
1533
1534
1535void sta_info_update(struct adapter *padapter, struct sta_info *psta)
1536{
1537 int flags = psta->flags;
1538 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1539
1540
1541 if (WLAN_STA_WME & flags)
1542 psta->qos_option = 1;
1543 else
1544 psta->qos_option = 0;
1545
1546 if (pmlmepriv->qospriv.qos_option == 0)
1547 psta->qos_option = 0;
1548
1549
1550 if (WLAN_STA_HT & flags) {
1551 psta->htpriv.ht_option = true;
1552 psta->qos_option = 1;
1553 } else {
1554 psta->htpriv.ht_option = false;
1555 }
1556
1557 if (!pmlmepriv->htpriv.ht_option)
1558 psta->htpriv.ht_option = false;
1559
1560 update_sta_info_apmode(padapter, psta);
1561}
1562
1563
1564void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta)
1565{
1566 if (psta->state & _FW_LINKED) {
1567
1568 add_RATid(padapter, psta, 0);
1569 }
1570}
1571
1572void start_ap_mode(struct adapter *padapter)
1573{
1574 int i;
1575 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1576 struct sta_priv *pstapriv = &padapter->stapriv;
1577 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1578 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1579
1580 pmlmepriv->update_bcn = false;
1581
1582 pmlmeext->bstart_bss = false;
1583
1584 pmlmepriv->num_sta_non_erp = 0;
1585
1586 pmlmepriv->num_sta_no_short_slot_time = 0;
1587
1588 pmlmepriv->num_sta_no_short_preamble = 0;
1589
1590 pmlmepriv->num_sta_ht_no_gf = 0;
1591 pmlmepriv->num_sta_no_ht = 0;
1592 pmlmepriv->num_sta_ht_20mhz = 0;
1593
1594 pmlmepriv->olbc = false;
1595
1596 pmlmepriv->olbc_ht = false;
1597
1598 pmlmepriv->ht_op_mode = 0;
1599
1600 for (i = 0; i < NUM_STA; i++)
1601 pstapriv->sta_aid[i] = NULL;
1602
1603 pmlmepriv->wps_beacon_ie = NULL;
1604 pmlmepriv->wps_probe_resp_ie = NULL;
1605 pmlmepriv->wps_assoc_resp_ie = NULL;
1606
1607
1608 INIT_LIST_HEAD(&pacl_list->acl_node_q.queue);
1609 pacl_list->num = 0;
1610 pacl_list->mode = 0;
1611 for (i = 0; i < NUM_ACL; i++) {
1612 INIT_LIST_HEAD(&pacl_list->aclnode[i].list);
1613 pacl_list->aclnode[i].valid = false;
1614 }
1615}
1616
1617void stop_ap_mode(struct adapter *padapter)
1618{
1619 struct rtw_wlan_acl_node *paclnode, *n;
1620 struct sta_info *psta = NULL;
1621 struct sta_priv *pstapriv = &padapter->stapriv;
1622 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1623 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1624 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1625 struct __queue *pacl_node_q = &pacl_list->acl_node_q;
1626
1627 pmlmepriv->update_bcn = false;
1628 pmlmeext->bstart_bss = false;
1629
1630
1631
1632
1633 memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv));
1634 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1635 padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
1636
1637
1638 spin_lock_bh(&pacl_node_q->lock);
1639 list_for_each_entry_safe(paclnode, n, &pacl_node_q->queue, list) {
1640 if (paclnode->valid) {
1641 paclnode->valid = false;
1642
1643 list_del_init(&paclnode->list);
1644
1645 pacl_list->num--;
1646 }
1647 }
1648 spin_unlock_bh(&pacl_node_q->lock);
1649
1650 rtw_sta_flush(padapter);
1651
1652
1653 rtw_free_all_stainfo(padapter);
1654
1655 psta = rtw_get_bcmc_stainfo(padapter);
1656 spin_lock_bh(&pstapriv->sta_hash_lock);
1657 rtw_free_stainfo(padapter, psta);
1658 spin_unlock_bh(&pstapriv->sta_hash_lock);
1659
1660 rtw_init_bcmc_stainfo(padapter);
1661
1662 rtw_free_mlme_priv_ie_data(pmlmepriv);
1663}
1664
1665#endif
1666