1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#define _RTW_AP_C_
16
17#include <drv_types.h>
18#include <rtw_debug.h>
19
20extern unsigned char RTW_WPA_OUI[];
21extern unsigned char WMM_OUI[];
22extern unsigned char WPS_OUI[];
23extern unsigned char P2P_OUI[];
24extern unsigned char WFD_OUI[];
25
26void init_mlme_ap_info(struct adapter *padapter)
27{
28 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
29 struct sta_priv *pstapriv = &padapter->stapriv;
30 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
31
32
33 spin_lock_init(&pmlmepriv->bcn_update_lock);
34
35
36 _rtw_init_queue(&pacl_list->acl_node_q);
37
38
39
40 start_ap_mode(padapter);
41}
42
43void free_mlme_ap_info(struct adapter *padapter)
44{
45 struct sta_info *psta = NULL;
46 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
47 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
48 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
49
50
51
52 pmlmepriv->update_bcn = false;
53 pmlmeext->bstart_bss = false;
54
55 rtw_sta_flush(padapter);
56
57 pmlmeinfo->state = _HW_STATE_NOLINK_;
58
59
60 rtw_free_all_stainfo(padapter);
61
62
63 psta = rtw_get_bcmc_stainfo(padapter);
64 rtw_free_stainfo(padapter, psta);
65}
66
67static void update_BCNTIM(struct adapter *padapter)
68{
69 struct sta_priv *pstapriv = &padapter->stapriv;
70 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
71 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
72 struct wlan_bssid_ex *pnetwork_mlmeext = &(pmlmeinfo->network);
73 unsigned char *pie = pnetwork_mlmeext->IEs;
74
75
76
77
78
79 if (true) {
80
81 u8 *p, *dst_ie, *premainder_ie = NULL, *pbackup_remainder_ie = NULL;
82 __le16 tim_bitmap_le;
83 uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
84
85 tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);
86
87 p = rtw_get_ie(
88 pie + _FIXED_IE_LENGTH_,
89 _TIM_IE_,
90 &tim_ielen,
91 pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_
92 );
93 if (p != NULL && tim_ielen > 0) {
94
95 tim_ielen += 2;
96
97 premainder_ie = p+tim_ielen;
98
99 tim_ie_offset = (sint)(p - pie);
100
101 remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen;
102
103
104 dst_ie = p;
105 } else{
106
107
108 tim_ielen = 0;
109
110
111 offset = _FIXED_IE_LENGTH_;
112
113
114 p = rtw_get_ie(
115 pie + _BEACON_IE_OFFSET_,
116 _SSID_IE_,
117 &tmp_len,
118 (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_)
119 );
120 if (p != NULL)
121 offset += tmp_len+2;
122
123
124 p = rtw_get_ie(
125 pie + _BEACON_IE_OFFSET_,
126 _SUPPORTEDRATES_IE_, &tmp_len,
127 (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_)
128 );
129 if (p != NULL)
130 offset += tmp_len+2;
131
132
133
134 offset += 3;
135
136 premainder_ie = pie + offset;
137
138 remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen;
139
140
141 dst_ie = pie + offset;
142
143 }
144
145
146 if (remainder_ielen > 0) {
147
148 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
149 if (pbackup_remainder_ie && premainder_ie)
150 memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
151 }
152
153 *dst_ie++ = _TIM_IE_;
154
155 if ((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fe))
156 tim_ielen = 5;
157 else
158 tim_ielen = 4;
159
160 *dst_ie++ = tim_ielen;
161
162 *dst_ie++ = 0;
163 *dst_ie++ = 1;
164
165 if (pstapriv->tim_bitmap&BIT(0))
166 *dst_ie++ = BIT(0);
167 else
168 *dst_ie++ = 0;
169
170 if (tim_ielen == 4) {
171
172 __le16 pvb;
173
174 if (pstapriv->tim_bitmap&0xff00)
175 pvb = cpu_to_le16(pstapriv->tim_bitmap >> 8);
176 else
177 pvb = tim_bitmap_le;
178
179 *dst_ie++ = le16_to_cpu(pvb);
180
181 } else if (tim_ielen == 5) {
182
183
184 memcpy(dst_ie, &tim_bitmap_le, 2);
185 dst_ie += 2;
186 }
187
188
189 if (pbackup_remainder_ie) {
190
191 memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
192
193 kfree(pbackup_remainder_ie);
194 }
195
196 offset = (uint)(dst_ie - pie);
197 pnetwork_mlmeext->IELength = offset + remainder_ielen;
198
199 }
200}
201
202u8 chk_sta_is_alive(struct sta_info *psta);
203u8 chk_sta_is_alive(struct sta_info *psta)
204{
205 #ifdef DBG_EXPIRATION_CHK
206 DBG_871X(
207 "sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", expire_to:%u, %s%ssq_len:%u\n"
208 , MAC_ARG(psta->hwaddr)
209 , psta->rssi_stat.UndecoratedSmoothedPWDB
210
211 , STA_RX_PKTS_DIFF_ARG(psta)
212 , psta->expire_to
213 , psta->state&WIFI_SLEEP_STATE?"PS, ":""
214 , psta->state&WIFI_STA_ALIVE_CHK_STATE?"SAC, ":""
215 , psta->sleepq_len
216 );
217 #endif
218
219 sta_update_last_rx_pkts(psta);
220
221 return true;
222}
223
224void expire_timeout_chk(struct adapter *padapter)
225{
226 struct list_head *phead, *plist;
227 u8 updated = false;
228 struct sta_info *psta = NULL;
229 struct sta_priv *pstapriv = &padapter->stapriv;
230 u8 chk_alive_num = 0;
231 char chk_alive_list[NUM_STA];
232 int i;
233
234
235 spin_lock_bh(&pstapriv->auth_list_lock);
236
237 phead = &pstapriv->auth_list;
238 plist = get_next(phead);
239
240
241 #ifdef DBG_EXPIRATION_CHK
242 if (phead != plist) {
243 DBG_871X(FUNC_NDEV_FMT" auth_list, cnt:%u\n"
244 , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->auth_list_cnt);
245 }
246 #endif
247 while (phead != plist) {
248
249 psta = LIST_CONTAINOR(plist, struct sta_info, auth_list);
250
251 plist = get_next(plist);
252
253 if (psta->expire_to > 0) {
254
255 psta->expire_to--;
256 if (psta->expire_to == 0) {
257
258 list_del_init(&psta->auth_list);
259 pstapriv->auth_list_cnt--;
260
261 DBG_871X(
262 "auth expire %02X%02X%02X%02X%02X%02X\n",
263 psta->hwaddr[0],
264 psta->hwaddr[1],
265 psta->hwaddr[2],
266 psta->hwaddr[3],
267 psta->hwaddr[4],
268 psta->hwaddr[5]
269 );
270
271 spin_unlock_bh(&pstapriv->auth_list_lock);
272
273 rtw_free_stainfo(padapter, psta);
274
275 spin_lock_bh(&pstapriv->auth_list_lock);
276 }
277 }
278
279 }
280
281 spin_unlock_bh(&pstapriv->auth_list_lock);
282 psta = NULL;
283
284
285 spin_lock_bh(&pstapriv->asoc_list_lock);
286
287 phead = &pstapriv->asoc_list;
288 plist = get_next(phead);
289
290
291 #ifdef DBG_EXPIRATION_CHK
292 if (phead != plist) {
293 DBG_871X(FUNC_NDEV_FMT" asoc_list, cnt:%u\n"
294 , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->asoc_list_cnt);
295 }
296 #endif
297 while (phead != plist) {
298
299 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
300 plist = get_next(plist);
301#ifdef CONFIG_AUTO_AP_MODE
302 if (psta->isrc)
303 continue;
304#endif
305 if (chk_sta_is_alive(psta) || !psta->expire_to) {
306 psta->expire_to = pstapriv->expire_to;
307 psta->keep_alive_trycnt = 0;
308 psta->under_exist_checking = 0;
309 } else {
310 if (psta->expire_to > 0)
311 psta->expire_to--;
312 }
313
314 if (psta->expire_to == 0) {
315
316 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
317
318 if (padapter->registrypriv.wifi_spec == 1) {
319
320 psta->expire_to = pstapriv->expire_to;
321 continue;
322 }
323
324 if (psta->state & WIFI_SLEEP_STATE) {
325 if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
326
327 psta->expire_to = pstapriv->expire_to;
328 psta->state |= WIFI_STA_ALIVE_CHK_STATE;
329
330
331
332
333 pstapriv->tim_bitmap |= BIT(psta->aid);
334 update_beacon(padapter, _TIM_IE_, NULL, true);
335
336 if (!pmlmeext->active_keep_alive_check)
337 continue;
338 }
339 }
340 if (pmlmeext->active_keep_alive_check) {
341 int stainfo_offset;
342
343 stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
344 if (stainfo_offset_valid(stainfo_offset))
345 chk_alive_list[chk_alive_num++] = stainfo_offset;
346
347
348 continue;
349 }
350 list_del_init(&psta->asoc_list);
351 pstapriv->asoc_list_cnt--;
352 DBG_871X(
353 "asoc expire "MAC_FMT", state = 0x%x\n",
354 MAC_ARG(psta->hwaddr),
355 psta->state
356 );
357 updated = ap_free_sta(padapter, psta, false, WLAN_REASON_DEAUTH_LEAVING);
358 } else{
359
360
361
362 if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt)
363 && padapter->xmitpriv.free_xmitframe_cnt < ((
364 NR_XMITFRAME/pstapriv->asoc_list_cnt
365 )/2)
366 ) {
367 DBG_871X(
368 "%s sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n",
369 __func__,
370 MAC_ARG(psta->hwaddr),
371 psta->sleepq_len,
372 padapter->xmitpriv.free_xmitframe_cnt,
373 pstapriv->asoc_list_cnt
374 );
375 wakeup_sta_to_xmit(padapter, psta);
376 }
377 }
378 }
379
380 spin_unlock_bh(&pstapriv->asoc_list_lock);
381
382 if (chk_alive_num) {
383 u8 backup_oper_channel = 0;
384 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
385
386
387 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
388 backup_oper_channel = rtw_get_oper_ch(padapter);
389 SelectChannel(padapter, pmlmeext->cur_channel);
390 }
391
392
393 for (i = 0; i < chk_alive_num; i++) {
394 int ret = _FAIL;
395
396 psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
397 if (!(psta->state & _FW_LINKED))
398 continue;
399
400 if (psta->state & WIFI_SLEEP_STATE)
401 ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50);
402 else
403 ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50);
404
405 psta->keep_alive_trycnt++;
406 if (ret == _SUCCESS) {
407 DBG_871X(
408 "asoc check, sta(" MAC_FMT ") is alive\n",
409 MAC_ARG(psta->hwaddr)
410 );
411 psta->expire_to = pstapriv->expire_to;
412 psta->keep_alive_trycnt = 0;
413 continue;
414 } else if (psta->keep_alive_trycnt <= 3) {
415
416 DBG_871X(
417 "ack check for asoc expire, keep_alive_trycnt =%d\n",
418 psta->keep_alive_trycnt);
419 psta->expire_to = 1;
420 continue;
421 }
422
423 psta->keep_alive_trycnt = 0;
424 DBG_871X(
425 "asoc expire "MAC_FMT", state = 0x%x\n",
426 MAC_ARG(psta->hwaddr),
427 psta->state);
428 spin_lock_bh(&pstapriv->asoc_list_lock);
429 if (list_empty(&psta->asoc_list) == false) {
430 list_del_init(&psta->asoc_list);
431 pstapriv->asoc_list_cnt--;
432 updated = ap_free_sta(padapter, psta, false, WLAN_REASON_DEAUTH_LEAVING);
433 }
434 spin_unlock_bh(&pstapriv->asoc_list_lock);
435 }
436
437 if (backup_oper_channel > 0)
438 SelectChannel(padapter, backup_oper_channel);
439 }
440
441 associated_clients_update(padapter, updated);
442}
443
444void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
445{
446 unsigned char sta_band = 0, shortGIrate = false;
447 unsigned int tx_ra_bitmap = 0;
448 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
449 struct wlan_bssid_ex
450 *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
451
452 if (!psta)
453 return;
454
455 if (!(psta->state & _FW_LINKED))
456 return;
457
458 rtw_hal_update_sta_rate_mask(padapter, psta);
459 tx_ra_bitmap = psta->ra_mask;
460
461 shortGIrate = query_ra_short_GI(psta);
462
463 if (pcur_network->Configuration.DSConfig > 14) {
464
465 if (tx_ra_bitmap & 0xffff000)
466 sta_band |= WIRELESS_11_5N;
467
468 if (tx_ra_bitmap & 0xff0)
469 sta_band |= WIRELESS_11A;
470 } else {
471 if (tx_ra_bitmap & 0xffff000)
472 sta_band |= WIRELESS_11_24N;
473
474 if (tx_ra_bitmap & 0xff0)
475 sta_band |= WIRELESS_11G;
476
477 if (tx_ra_bitmap & 0x0f)
478 sta_band |= WIRELESS_11B;
479 }
480
481 psta->wireless_mode = sta_band;
482 psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
483
484 if (psta->aid < NUM_STA) {
485
486 u8 arg[4] = {0};
487
488 arg[0] = psta->mac_id;
489 arg[1] = psta->raid;
490 arg[2] = shortGIrate;
491 arg[3] = psta->init_rate;
492
493 DBG_871X("%s => mac_id:%d , raid:%d , shortGIrate =%d, bitmap = 0x%x\n",
494 __func__, psta->mac_id, psta->raid, shortGIrate, tx_ra_bitmap);
495
496 rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level);
497 } else{
498
499
500 DBG_871X("station aid %d exceed the max number\n", psta->aid);
501 }
502
503}
504
505void update_bmc_sta(struct adapter *padapter)
506{
507 unsigned char network_type;
508 int supportRateNum = 0;
509 unsigned int tx_ra_bitmap = 0;
510 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
511 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
512 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
513 struct wlan_bssid_ex
514 *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
515 struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
516
517 if (psta) {
518
519 psta->aid = 0;
520
521 psta->mac_id = psta->aid + 1;
522
523 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
524
525 psta->qos_option = 0;
526 psta->htpriv.ht_option = false;
527
528 psta->ieee8021x_blocked = 0;
529
530 memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
531
532
533
534
535 supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->SupportedRates);
536 network_type = rtw_check_network_type(
537 (u8 *)&pcur_network->SupportedRates,
538 supportRateNum,
539 pcur_network->Configuration.DSConfig
540 );
541 if (IsSupportedTxCCK(network_type)) {
542 network_type = WIRELESS_11B;
543 } else if (network_type == WIRELESS_INVALID) {
544
545 if (pcur_network->Configuration.DSConfig > 14)
546 network_type = WIRELESS_11A;
547 else
548 network_type = WIRELESS_11B;
549 }
550 update_sta_basic_rate(psta, network_type);
551 psta->wireless_mode = network_type;
552
553 rtw_hal_update_sta_rate_mask(padapter, psta);
554 tx_ra_bitmap = psta->ra_mask;
555
556 psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
557
558
559 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
560
561
562 {
563 u8 arg[4] = {0};
564
565 arg[0] = psta->mac_id;
566 arg[1] = psta->raid;
567 arg[2] = 0;
568 arg[3] = psta->init_rate;
569
570 DBG_871X("%s => mac_id:%d , raid:%d , bitmap = 0x%x\n",
571 __func__, psta->mac_id, psta->raid, tx_ra_bitmap);
572
573 rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0);
574 }
575
576 rtw_sta_media_status_rpt(padapter, psta, 1);
577
578 spin_lock_bh(&psta->lock);
579 psta->state = _FW_LINKED;
580 spin_unlock_bh(&psta->lock);
581
582 } else{
583
584
585 DBG_871X("add_RATid_bmc_sta error!\n");
586 }
587
588}
589
590
591
592
593
594
595
596
597void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
598{
599 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
600 struct security_priv *psecuritypriv = &padapter->securitypriv;
601 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
602 struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
603 struct ht_priv *phtpriv_sta = &psta->htpriv;
604 u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0;
605
606
607
608 DBG_871X("%s\n", __func__);
609
610
611
612
613
614
615 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
616
617 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
618 psta->ieee8021x_blocked = true;
619 else
620 psta->ieee8021x_blocked = false;
621
622
623
624
625
626 VCS_update(padapter, psta);
627
628
629 if (phtpriv_sta->ht_option) {
630
631
632 phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
633
634 phtpriv_sta->rx_ampdu_min_spacing = (
635 phtpriv_sta->ht_cap.ampdu_params_info&IEEE80211_HT_CAP_AMPDU_DENSITY
636 )>>2;
637
638
639 if ((
640 phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info
641 ) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
642 psta->bw_mode = CHANNEL_WIDTH_40;
643 else
644 psta->bw_mode = CHANNEL_WIDTH_20;
645
646 if (pmlmeext->cur_bwmode < psta->bw_mode)
647 psta->bw_mode = pmlmeext->cur_bwmode;
648
649 phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
650
651
652
653 if ((
654 phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info
655 ) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))
656 phtpriv_sta->sgi_20m = true;
657
658
659 if ((
660 phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info
661 ) & cpu_to_le16(IEEE80211_HT_CAP_SGI_40)) {
662
663 if (psta->bw_mode == CHANNEL_WIDTH_40)
664 phtpriv_sta->sgi_40m = true;
665 else
666 phtpriv_sta->sgi_40m = false;
667 }
668
669 psta->qos_option = true;
670
671
672 if (TEST_FLAG(phtpriv_ap->ldpc_cap, LDPC_HT_ENABLE_TX) &&
673 GET_HT_CAPABILITY_ELE_LDPC_CAP((u8 *)(&phtpriv_sta->ht_cap))) {
674
675 SET_FLAG(cur_ldpc_cap, (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX));
676 DBG_871X("Enable HT Tx LDPC for STA(%d)\n", psta->aid);
677 }
678
679
680 if (TEST_FLAG(phtpriv_ap->stbc_cap, STBC_HT_ENABLE_TX) &&
681 GET_HT_CAPABILITY_ELE_RX_STBC((u8 *)(&phtpriv_sta->ht_cap))) {
682
683 SET_FLAG(cur_stbc_cap, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX));
684 DBG_871X("Enable HT Tx STBC for STA(%d)\n", psta->aid);
685 }
686 } else{
687
688
689 phtpriv_sta->ampdu_enable = false;
690
691 phtpriv_sta->sgi_20m = false;
692 phtpriv_sta->sgi_40m = false;
693 psta->bw_mode = CHANNEL_WIDTH_20;
694 phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
695 }
696
697 phtpriv_sta->ldpc_cap = cur_ldpc_cap;
698 phtpriv_sta->stbc_cap = cur_stbc_cap;
699 phtpriv_sta->beamform_cap = cur_beamform_cap;
700
701
702 send_delba(padapter, 0, psta->hwaddr);
703
704
705 send_delba(padapter, 1, psta->hwaddr);
706 phtpriv_sta->agg_enable_bitmap = 0x0;
707 phtpriv_sta->candidate_tid_bitmap = 0x0;
708
709 update_ldpc_stbc_cap(psta);
710
711
712
713 memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
714
715
716
717
718
719
720 spin_lock_bh(&psta->lock);
721 psta->state |= _FW_LINKED;
722 spin_unlock_bh(&psta->lock);
723
724
725}
726
727static void update_ap_info(struct adapter *padapter, struct sta_info *psta)
728{
729 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
730 struct wlan_bssid_ex
731 *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
732 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
733 struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
734
735 psta->wireless_mode = pmlmeext->cur_wireless_mode;
736
737 psta->bssratelen = rtw_get_rateset_len(pnetwork->SupportedRates);
738 memcpy(psta->bssrateset, pnetwork->SupportedRates, psta->bssratelen);
739
740
741 if (phtpriv_ap->ht_option) {
742
743
744
745
746
747 if ((phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))
748 phtpriv_ap->sgi_20m = true;
749
750
751 if ((phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_40))
752 phtpriv_ap->sgi_40m = true;
753
754
755 psta->qos_option = true;
756 } else{
757
758
759 phtpriv_ap->ampdu_enable = false;
760
761 phtpriv_ap->sgi_20m = false;
762 phtpriv_ap->sgi_40m = false;
763 }
764
765 psta->bw_mode = pmlmeext->cur_bwmode;
766 phtpriv_ap->ch_offset = pmlmeext->cur_ch_offset;
767
768 phtpriv_ap->agg_enable_bitmap = 0x0;
769 phtpriv_ap->candidate_tid_bitmap = 0x0;
770
771 memcpy(&psta->htpriv, &pmlmepriv->htpriv, sizeof(struct ht_priv));
772}
773
774static void update_hw_ht_param(struct adapter *padapter)
775{
776 unsigned char max_AMPDU_len;
777 unsigned char min_MPDU_spacing;
778 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
779 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
780
781 DBG_871X("%s\n", __func__);
782
783
784
785
786
787
788
789 max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
790
791 min_MPDU_spacing = (
792 pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c
793 ) >> 2;
794
795 rtw_hal_set_hwreg(
796 padapter,
797 HW_VAR_AMPDU_MIN_SPACE,
798 (u8 *)(&min_MPDU_spacing)
799 );
800
801 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
802
803
804
805
806 pmlmeinfo->SM_PS = (le16_to_cpu(
807 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info
808 ) & 0x0C) >> 2;
809 if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
810 DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
811
812
813
814
815
816
817}
818
819void start_bss_network(struct adapter *padapter, u8 *pbuf)
820{
821 u8 *p;
822 u8 val8, cur_channel, cur_bwmode, cur_ch_offset;
823 u16 bcn_interval;
824 u32 acparm;
825 int ie_len;
826 struct registry_priv *pregpriv = &padapter->registrypriv;
827 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
828 struct security_priv *psecuritypriv = &(padapter->securitypriv);
829 struct wlan_bssid_ex
830 *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
831 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
832 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
833 struct wlan_bssid_ex *pnetwork_mlmeext = &(pmlmeinfo->network);
834 struct HT_info_element *pht_info = NULL;
835 u8 cbw40_enable = 0;
836
837
838
839 bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
840 cur_channel = pnetwork->Configuration.DSConfig;
841 cur_bwmode = CHANNEL_WIDTH_20;
842 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
843
844
845
846
847
848 if (NULL == rtw_get_wps_ie(
849 pnetwork->IEs+_FIXED_IE_LENGTH_,
850 pnetwork->IELength-_FIXED_IE_LENGTH_,
851 NULL,
852 NULL
853 ))
854 pmlmeext->bstart_bss = true;
855
856
857
858
859
860 if (pmlmepriv->qospriv.qos_option)
861 pmlmeinfo->WMM_enable = true;
862 if (pmlmepriv->htpriv.ht_option) {
863
864 pmlmeinfo->WMM_enable = true;
865 pmlmeinfo->HT_enable = true;
866
867
868
869 update_hw_ht_param(padapter);
870 }
871
872 if (pmlmepriv->cur_network.join_res != true) {
873
874
875 if (
876 (psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) &&
877 (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
878 )
879 flush_all_cam_entry(padapter);
880 }
881
882
883 Set_MSR(padapter, _HW_STATE_AP_);
884
885
886 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress);
887
888
889 acparm = 0x002F3217;
890 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
891 acparm = 0x005E4317;
892 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
893
894 acparm = 0x005ea42b;
895 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
896 acparm = 0x0000A444;
897 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
898
899
900 val8 = (
901 psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X
902 ) ? 0xcc : 0xcf;
903 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
904
905
906 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));
907
908 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
909
910 if (pmlmepriv->cur_network.join_res != true) {
911
912
913
914
915
916
917
918
919
920
921
922 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
923
924
925
926 }
927
928
929 p = rtw_get_ie(
930 (pnetwork->IEs + sizeof(struct ndis_802_11_fix_ie)),
931 _HT_ADD_INFO_IE_,
932 &ie_len,
933 (pnetwork->IELength - sizeof(struct ndis_802_11_fix_ie))
934 );
935 if (p && ie_len) {
936
937 pht_info = (struct HT_info_element *)(p+2);
938
939 if (cur_channel > 14) {
940 if ((pregpriv->bw_mode & 0xf0) > 0)
941 cbw40_enable = 1;
942 } else {
943 if ((pregpriv->bw_mode & 0x0f) > 0)
944 cbw40_enable = 1;
945 }
946
947 if ((cbw40_enable) && (pht_info->infos[0] & BIT(2))) {
948
949
950
951 cur_bwmode = CHANNEL_WIDTH_40;
952 switch (pht_info->infos[0] & 0x3) {
953
954 case 1:
955
956 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
957 break;
958
959 case 3:
960
961 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
962 break;
963
964 default:
965
966 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
967 break;
968 }
969
970 }
971
972 }
973
974 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
975 DBG_871X(
976 "CH =%d, BW =%d, offset =%d\n",
977 cur_channel,
978 cur_bwmode,
979 cur_ch_offset
980 );
981 pmlmeext->cur_channel = cur_channel;
982 pmlmeext->cur_bwmode = cur_bwmode;
983 pmlmeext->cur_ch_offset = cur_ch_offset;
984 pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;
985
986
987 memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
988
989
990 update_wireless_mode(padapter);
991
992
993 UpdateBrateTbl(padapter, pnetwork->SupportedRates);
994 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
995
996
997 update_capinfo(
998 padapter,
999 rtw_get_capability((struct wlan_bssid_ex *)pnetwork)
1000 );
1001
1002
1003 if (true == pmlmeext->bstart_bss) {
1004
1005 update_beacon(padapter, _TIM_IE_, NULL, true);
1006
1007#ifndef CONFIG_INTERRUPT_BASED_TXBCN
1008
1009 if (send_beacon(padapter) == _FAIL)
1010 DBG_871X("issue_beacon, fail!\n");
1011
1012#endif
1013
1014 }
1015
1016
1017
1018 update_bmc_sta(padapter);
1019
1020
1021
1022}
1023
1024int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
1025{
1026 int ret = _SUCCESS;
1027 u8 *p;
1028 u8 *pHT_caps_ie = NULL;
1029 u8 *pHT_info_ie = NULL;
1030 struct sta_info *psta = NULL;
1031 u16 cap, ht_cap = false;
1032 uint ie_len = 0;
1033 int group_cipher, pairwise_cipher;
1034 u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
1035 int supportRateNum = 0;
1036 u8 OUI1[] = {0x00, 0x50, 0xf2, 0x01};
1037 u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
1038 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1039 struct security_priv *psecuritypriv = &padapter->securitypriv;
1040 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1041 struct wlan_bssid_ex
1042 *pbss_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
1043 u8 *ie = pbss_network->IEs;
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056 DBG_871X("%s, len =%d\n", __func__, len);
1057
1058 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
1059 return _FAIL;
1060
1061
1062 if (len > MAX_IE_SZ)
1063 return _FAIL;
1064
1065 pbss_network->IELength = len;
1066
1067 memset(ie, 0, MAX_IE_SZ);
1068
1069 memcpy(ie, pbuf, pbss_network->IELength);
1070
1071
1072 if (pbss_network->InfrastructureMode != Ndis802_11APMode)
1073 return _FAIL;
1074
1075 pbss_network->Rssi = 0;
1076
1077 memcpy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)), ETH_ALEN);
1078
1079
1080 p = rtw_get_beacon_interval_from_ie(ie);
1081
1082 pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p);
1083
1084
1085
1086
1087 cap = RTW_GET_LE16(ie);
1088
1089
1090 p = rtw_get_ie(
1091 ie + _BEACON_IE_OFFSET_,
1092 _SSID_IE_,
1093 &ie_len,
1094 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1095 );
1096 if (p && ie_len > 0) {
1097
1098 memset(&pbss_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
1099 memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);
1100 pbss_network->Ssid.SsidLength = ie_len;
1101 }
1102
1103
1104 channel = 0;
1105 pbss_network->Configuration.Length = 0;
1106 p = rtw_get_ie(
1107 ie + _BEACON_IE_OFFSET_,
1108 _DSSET_IE_, &ie_len,
1109 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1110 );
1111 if (p && ie_len > 0)
1112 channel = *(p + 2);
1113
1114 pbss_network->Configuration.DSConfig = channel;
1115
1116
1117 memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
1118
1119 p = rtw_get_ie(
1120 ie + _BEACON_IE_OFFSET_,
1121 _SUPPORTEDRATES_IE_,
1122 &ie_len,
1123 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1124 );
1125 if (p != NULL) {
1126
1127 memcpy(supportRate, p+2, ie_len);
1128 supportRateNum = ie_len;
1129 }
1130
1131
1132 p = rtw_get_ie(
1133 ie + _BEACON_IE_OFFSET_,
1134 _EXT_SUPPORTEDRATES_IE_,
1135 &ie_len,
1136 pbss_network->IELength - _BEACON_IE_OFFSET_
1137 );
1138 if (p != NULL) {
1139
1140 memcpy(supportRate+supportRateNum, p+2, ie_len);
1141 supportRateNum += ie_len;
1142
1143 }
1144
1145 network_type = rtw_check_network_type(supportRate, supportRateNum, channel);
1146
1147 rtw_set_supported_rate(pbss_network->SupportedRates, network_type);
1148
1149
1150
1151 p = rtw_get_ie(
1152 ie + _BEACON_IE_OFFSET_,
1153 _ERPINFO_IE_,
1154 &ie_len,
1155 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1156 );
1157 if (p && ie_len > 0)
1158 ERP_IE_handler(padapter, (struct ndis_80211_var_ie *)p);
1159
1160
1161 if (cap & BIT(4))
1162 pbss_network->Privacy = 1;
1163 else
1164 pbss_network->Privacy = 0;
1165
1166 psecuritypriv->wpa_psk = 0;
1167
1168
1169 group_cipher = 0; pairwise_cipher = 0;
1170 psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
1171 psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
1172 p = rtw_get_ie(
1173 ie + _BEACON_IE_OFFSET_,
1174 _RSN_IE_2_,
1175 &ie_len,
1176 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1177 );
1178 if (p && ie_len > 0) {
1179
1180 if (rtw_parse_wpa2_ie(
1181 p,
1182 ie_len+2,
1183 &group_cipher,
1184 &pairwise_cipher,
1185 NULL
1186 ) == _SUCCESS) {
1187
1188 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1189
1190 psecuritypriv->dot8021xalg = 1;
1191 psecuritypriv->wpa_psk |= BIT(1);
1192
1193 psecuritypriv->wpa2_group_cipher = group_cipher;
1194 psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
1195 }
1196
1197 }
1198
1199
1200 ie_len = 0;
1201 group_cipher = 0; pairwise_cipher = 0;
1202 psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
1203 psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
1204 for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
1205
1206 p = rtw_get_ie(
1207 p,
1208 _SSN_IE_1_,
1209 &ie_len,
1210 (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))
1211 );
1212 if ((p) && (!memcmp(p+2, OUI1, 4))) {
1213
1214 if (rtw_parse_wpa_ie(
1215 p,
1216 ie_len+2,
1217 &group_cipher,
1218 &pairwise_cipher,
1219 NULL
1220 ) == _SUCCESS) {
1221
1222 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1223
1224 psecuritypriv->dot8021xalg = 1;
1225
1226 psecuritypriv->wpa_psk |= BIT(0);
1227
1228 psecuritypriv->wpa_group_cipher = group_cipher;
1229 psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
1230 }
1231
1232 break;
1233
1234 }
1235
1236 if ((p == NULL) || (ie_len == 0))
1237 break;
1238
1239
1240 }
1241
1242
1243 ie_len = 0;
1244 pmlmepriv->qospriv.qos_option = 0;
1245 if (pregistrypriv->wmm_enable) {
1246
1247 for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
1248
1249 p = rtw_get_ie(
1250 p,
1251 _VENDOR_SPECIFIC_IE_,
1252 &ie_len,
1253 (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))
1254 );
1255 if ((p) && !memcmp(p+2, WMM_PARA_IE, 6)) {
1256
1257 pmlmepriv->qospriv.qos_option = 1;
1258
1259 *(p+8) |= BIT(7);
1260
1261
1262 *(p + 10) &= ~BIT(4);
1263 *(p + 14) &= ~BIT(4);
1264 *(p + 18) &= ~BIT(4);
1265 *(p + 22) &= ~BIT(4);
1266
1267 break;
1268 }
1269
1270 if ((p == NULL) || (ie_len == 0))
1271 break;
1272
1273 }
1274 }
1275
1276
1277 p = rtw_get_ie(
1278 ie + _BEACON_IE_OFFSET_,
1279 _HT_CAPABILITY_IE_,
1280 &ie_len,
1281 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1282 );
1283 if (p && ie_len > 0) {
1284
1285 u8 rf_type = 0;
1286 u8 max_rx_ampdu_factor = 0;
1287 struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2);
1288
1289 pHT_caps_ie = p;
1290
1291 ht_cap = true;
1292 network_type |= WIRELESS_11_24N;
1293
1294 rtw_ht_use_default_setting(padapter);
1295
1296 if (pmlmepriv->htpriv.sgi_20m == false)
1297 pht_cap->cap_info &= cpu_to_le16(~(IEEE80211_HT_CAP_SGI_20));
1298
1299 if (pmlmepriv->htpriv.sgi_40m == false)
1300 pht_cap->cap_info &= cpu_to_le16(~(IEEE80211_HT_CAP_SGI_40));
1301
1302 if (!TEST_FLAG(pmlmepriv->htpriv.ldpc_cap, LDPC_HT_ENABLE_RX))
1303 pht_cap->cap_info &= cpu_to_le16(~(IEEE80211_HT_CAP_LDPC_CODING));
1304
1305
1306 if (!TEST_FLAG(pmlmepriv->htpriv.stbc_cap, STBC_HT_ENABLE_TX))
1307 pht_cap->cap_info &= cpu_to_le16(~(IEEE80211_HT_CAP_TX_STBC));
1308
1309
1310 if (!TEST_FLAG(pmlmepriv->htpriv.stbc_cap, STBC_HT_ENABLE_RX))
1311 pht_cap->cap_info &= cpu_to_le16(~(IEEE80211_HT_CAP_RX_STBC_3R));
1312
1313
1314 pht_cap->ampdu_params_info &= ~(
1315 IEEE80211_HT_CAP_AMPDU_FACTOR|IEEE80211_HT_CAP_AMPDU_DENSITY
1316 );
1317
1318 if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
1319 (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP)) {
1320
1321 pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
1322 } else{
1323
1324
1325 pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
1326 }
1327
1328 rtw_hal_get_def_var(
1329 padapter,
1330 HW_VAR_MAX_RX_AMPDU_FACTOR,
1331 &max_rx_ampdu_factor
1332 );
1333 pht_cap->ampdu_params_info |= (
1334 IEEE80211_HT_CAP_AMPDU_FACTOR & max_rx_ampdu_factor
1335 );
1336
1337 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1338 if (rf_type == RF_1T1R) {
1339
1340 pht_cap->supp_mcs_set[0] = 0xff;
1341 pht_cap->supp_mcs_set[1] = 0x0;
1342 }
1343
1344 memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len);
1345
1346 }
1347
1348
1349 p = rtw_get_ie(
1350 ie + _BEACON_IE_OFFSET_,
1351 _HT_ADD_INFO_IE_,
1352 &ie_len,
1353 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1354 );
1355 if (p && ie_len > 0)
1356 pHT_info_ie = p;
1357
1358
1359 switch (network_type) {
1360
1361 case WIRELESS_11B:
1362 pbss_network->NetworkTypeInUse = Ndis802_11DS;
1363 break;
1364 case WIRELESS_11G:
1365 case WIRELESS_11BG:
1366 case WIRELESS_11G_24N:
1367 case WIRELESS_11BG_24N:
1368 pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
1369 break;
1370 case WIRELESS_11A:
1371 pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;
1372 break;
1373 default:
1374 pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
1375 break;
1376 }
1377
1378 pmlmepriv->cur_network.network_type = network_type;
1379
1380 pmlmepriv->htpriv.ht_option = false;
1381
1382 if ((psecuritypriv->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
1383 (psecuritypriv->wpa_pairwise_cipher&WPA_CIPHER_TKIP)) {
1384
1385
1386
1387 }
1388
1389
1390 if (pregistrypriv->ht_enable && ht_cap == true) {
1391
1392 pmlmepriv->htpriv.ht_option = true;
1393 pmlmepriv->qospriv.qos_option = 1;
1394
1395 if (pregistrypriv->ampdu_enable == 1)
1396 pmlmepriv->htpriv.ampdu_enable = true;
1397
1398
1399 HT_caps_handler(padapter, (struct ndis_80211_var_ie *)pHT_caps_ie);
1400
1401 HT_info_handler(padapter, (struct ndis_80211_var_ie *)pHT_info_ie);
1402 }
1403
1404 pbss_network->Length = get_wlan_bssid_ex_sz(
1405 (struct wlan_bssid_ex *)pbss_network
1406 );
1407
1408
1409
1410 rtw_startbss_cmd(padapter, RTW_CMDF_WAIT_ACK);
1411
1412
1413
1414 psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
1415 if (!psta) {
1416
1417 psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
1418 if (psta == NULL)
1419 return _FAIL;
1420
1421 }
1422
1423
1424 update_ap_info(padapter, psta);
1425
1426 psta->state |= WIFI_AP_STATE;
1427 rtw_indicate_connect(padapter);
1428
1429 pmlmepriv->cur_network.join_res = true;
1430
1431
1432
1433
1434 return ret;
1435
1436}
1437
1438void rtw_set_macaddr_acl(struct adapter *padapter, int mode)
1439{
1440 struct sta_priv *pstapriv = &padapter->stapriv;
1441 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1442
1443 DBG_871X("%s, mode =%d\n", __func__, mode);
1444
1445 pacl_list->mode = mode;
1446}
1447
1448int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
1449{
1450 struct list_head *plist, *phead;
1451 u8 added = false;
1452 int i, ret = 0;
1453 struct rtw_wlan_acl_node *paclnode;
1454 struct sta_priv *pstapriv = &padapter->stapriv;
1455 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1456 struct __queue *pacl_node_q = &pacl_list->acl_node_q;
1457
1458 DBG_871X(
1459 "%s(acl_num =%d) =" MAC_FMT "\n",
1460 __func__,
1461 pacl_list->num,
1462 MAC_ARG(addr)
1463 );
1464
1465 if ((NUM_ACL-1) < pacl_list->num)
1466 return (-1);
1467
1468
1469 spin_lock_bh(&(pacl_node_q->lock));
1470
1471 phead = get_list_head(pacl_node_q);
1472 plist = get_next(phead);
1473
1474 while (phead != plist) {
1475
1476 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
1477 plist = get_next(plist);
1478
1479 if (!memcmp(paclnode->addr, addr, ETH_ALEN)) {
1480
1481 if (paclnode->valid == true) {
1482
1483 added = true;
1484 DBG_871X("%s, sta has been added\n", __func__);
1485 break;
1486 }
1487 }
1488 }
1489
1490 spin_unlock_bh(&(pacl_node_q->lock));
1491
1492
1493 if (added == true)
1494 return ret;
1495
1496
1497 spin_lock_bh(&(pacl_node_q->lock));
1498
1499 for (i = 0; i < NUM_ACL; i++) {
1500
1501 paclnode = &pacl_list->aclnode[i];
1502
1503 if (paclnode->valid == false) {
1504
1505 INIT_LIST_HEAD(&paclnode->list);
1506
1507 memcpy(paclnode->addr, addr, ETH_ALEN);
1508
1509 paclnode->valid = true;
1510
1511 list_add_tail(&paclnode->list, get_list_head(pacl_node_q));
1512
1513 pacl_list->num++;
1514
1515 break;
1516 }
1517 }
1518
1519 DBG_871X("%s, acl_num =%d\n", __func__, pacl_list->num);
1520
1521 spin_unlock_bh(&(pacl_node_q->lock));
1522
1523 return ret;
1524}
1525
1526int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
1527{
1528 struct list_head *plist, *phead;
1529 int ret = 0;
1530 struct rtw_wlan_acl_node *paclnode;
1531 struct sta_priv *pstapriv = &padapter->stapriv;
1532 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1533 struct __queue *pacl_node_q = &pacl_list->acl_node_q;
1534 u8 baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1535
1536 DBG_871X(
1537 "%s(acl_num =%d) =" MAC_FMT "\n",
1538 __func__,
1539 pacl_list->num,
1540 MAC_ARG(addr)
1541 );
1542
1543 spin_lock_bh(&(pacl_node_q->lock));
1544
1545 phead = get_list_head(pacl_node_q);
1546 plist = get_next(phead);
1547
1548 while (phead != plist) {
1549
1550 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
1551 plist = get_next(plist);
1552
1553 if (
1554 !memcmp(paclnode->addr, addr, ETH_ALEN) ||
1555 !memcmp(baddr, addr, ETH_ALEN)
1556 ) {
1557
1558 if (paclnode->valid == true) {
1559
1560 paclnode->valid = false;
1561
1562 list_del_init(&paclnode->list);
1563
1564 pacl_list->num--;
1565 }
1566 }
1567 }
1568
1569 spin_unlock_bh(&(pacl_node_q->lock));
1570
1571 DBG_871X("%s, acl_num =%d\n", __func__, pacl_list->num);
1572
1573 return ret;
1574
1575}
1576
1577u8 rtw_ap_set_pairwise_key(struct adapter *padapter, struct sta_info *psta)
1578{
1579 struct cmd_obj *ph2c;
1580 struct set_stakey_parm *psetstakey_para;
1581 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1582 u8 res = _SUCCESS;
1583
1584 ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1585 if (ph2c == NULL) {
1586 res = _FAIL;
1587 goto exit;
1588 }
1589
1590 psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
1591 if (psetstakey_para == NULL) {
1592 kfree((u8 *) ph2c);
1593 res = _FAIL;
1594 goto exit;
1595 }
1596
1597 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
1598
1599
1600 psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy;
1601
1602 memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);
1603
1604 memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
1605
1606
1607 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1608
1609exit:
1610
1611 return res;
1612
1613}
1614
1615static int rtw_ap_set_key(
1616 struct adapter *padapter,
1617 u8 *key,
1618 u8 alg,
1619 int keyid,
1620 u8 set_tx
1621)
1622{
1623 u8 keylen;
1624 struct cmd_obj *pcmd;
1625 struct setkey_parm *psetkeyparm;
1626 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
1627 int res = _SUCCESS;
1628
1629
1630
1631 pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
1632 if (pcmd == NULL) {
1633 res = _FAIL;
1634 goto exit;
1635 }
1636 psetkeyparm = rtw_zmalloc(sizeof(struct setkey_parm));
1637 if (psetkeyparm == NULL) {
1638 kfree((unsigned char *)pcmd);
1639 res = _FAIL;
1640 goto exit;
1641 }
1642
1643 memset(psetkeyparm, 0, sizeof(struct setkey_parm));
1644
1645 psetkeyparm->keyid = (u8)keyid;
1646 if (is_wep_enc(alg))
1647 padapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);
1648
1649 psetkeyparm->algorithm = alg;
1650
1651 psetkeyparm->set_tx = set_tx;
1652
1653 switch (alg) {
1654
1655 case _WEP40_:
1656 keylen = 5;
1657 break;
1658 case _WEP104_:
1659 keylen = 13;
1660 break;
1661 case _TKIP_:
1662 case _TKIP_WTMIC_:
1663 case _AES_:
1664 default:
1665 keylen = 16;
1666 }
1667
1668 memcpy(&(psetkeyparm->key[0]), key, keylen);
1669
1670 pcmd->cmdcode = _SetKey_CMD_;
1671 pcmd->parmbuf = (u8 *)psetkeyparm;
1672 pcmd->cmdsz = (sizeof(struct setkey_parm));
1673 pcmd->rsp = NULL;
1674 pcmd->rspsz = 0;
1675
1676
1677 INIT_LIST_HEAD(&pcmd->list);
1678
1679 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1680
1681exit:
1682
1683 return res;
1684}
1685
1686int rtw_ap_set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
1687{
1688 DBG_871X("%s\n", __func__);
1689
1690 return rtw_ap_set_key(padapter, key, alg, keyid, 1);
1691}
1692
1693int rtw_ap_set_wep_key(
1694 struct adapter *padapter,
1695 u8 *key,
1696 u8 keylen,
1697 int keyid,
1698 u8 set_tx
1699)
1700{
1701 u8 alg;
1702
1703 switch (keylen) {
1704
1705 case 5:
1706 alg = _WEP40_;
1707 break;
1708 case 13:
1709 alg = _WEP104_;
1710 break;
1711 default:
1712 alg = _NO_PRIVACY_;
1713 }
1714
1715 DBG_871X("%s\n", __func__);
1716
1717 return rtw_ap_set_key(padapter, key, alg, keyid, set_tx);
1718}
1719
1720static void update_bcn_fixed_ie(struct adapter *padapter)
1721{
1722 DBG_871X("%s\n", __func__);
1723
1724}
1725
1726static void update_bcn_erpinfo_ie(struct adapter *padapter)
1727{
1728 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1729 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1730 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1731 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1732 unsigned char *p, *ie = pnetwork->IEs;
1733 u32 len = 0;
1734
1735 DBG_871X("%s, ERP_enable =%d\n", __func__, pmlmeinfo->ERP_enable);
1736
1737 if (!pmlmeinfo->ERP_enable)
1738 return;
1739
1740
1741 p = rtw_get_ie(
1742 ie + _BEACON_IE_OFFSET_,
1743 _ERPINFO_IE_,
1744 &len,
1745 (pnetwork->IELength - _BEACON_IE_OFFSET_)
1746 );
1747 if (p && len > 0) {
1748
1749 struct ndis_80211_var_ie *pIE = (struct ndis_80211_var_ie *)p;
1750
1751 if (pmlmepriv->num_sta_non_erp == 1)
1752 pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION;
1753 else
1754 pIE->data[0] &= ~(
1755 RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION
1756 );
1757
1758 if (pmlmepriv->num_sta_no_short_preamble > 0)
1759 pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
1760 else
1761 pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);
1762
1763 ERP_IE_handler(padapter, pIE);
1764 }
1765
1766}
1767
1768static void update_bcn_htcap_ie(struct adapter *padapter)
1769{
1770 DBG_871X("%s\n", __func__);
1771
1772}
1773
1774static void update_bcn_htinfo_ie(struct adapter *padapter)
1775{
1776 DBG_871X("%s\n", __func__);
1777
1778}
1779
1780static void update_bcn_rsn_ie(struct adapter *padapter)
1781{
1782 DBG_871X("%s\n", __func__);
1783
1784}
1785
1786static void update_bcn_wpa_ie(struct adapter *padapter)
1787{
1788 DBG_871X("%s\n", __func__);
1789
1790}
1791
1792static void update_bcn_wmm_ie(struct adapter *padapter)
1793{
1794 DBG_871X("%s\n", __func__);
1795
1796}
1797
1798static void update_bcn_wps_ie(struct adapter *padapter)
1799{
1800 u8 *pwps_ie = NULL;
1801 u8 *pwps_ie_src;
1802 u8 *premainder_ie;
1803 u8 *pbackup_remainder_ie = NULL;
1804
1805 uint wps_ielen = 0, wps_offset, remainder_ielen;
1806 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1807 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1808 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1809 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1810 unsigned char *ie = pnetwork->IEs;
1811 u32 ielen = pnetwork->IELength;
1812
1813
1814 DBG_871X("%s\n", __func__);
1815
1816 pwps_ie = rtw_get_wps_ie(
1817 ie+_FIXED_IE_LENGTH_,
1818 ielen-_FIXED_IE_LENGTH_,
1819 NULL,
1820 &wps_ielen
1821 );
1822
1823 if (pwps_ie == NULL || wps_ielen == 0)
1824 return;
1825
1826 pwps_ie_src = pmlmepriv->wps_beacon_ie;
1827 if (pwps_ie_src == NULL)
1828 return;
1829
1830 wps_offset = (uint)(pwps_ie-ie);
1831
1832 premainder_ie = pwps_ie + wps_ielen;
1833
1834 remainder_ielen = ielen - wps_offset - wps_ielen;
1835
1836 if (remainder_ielen > 0) {
1837
1838 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
1839 if (pbackup_remainder_ie)
1840 memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
1841 }
1842
1843 wps_ielen = (uint)pwps_ie_src[1];
1844 if ((wps_offset+wps_ielen+2+remainder_ielen) <= MAX_IE_SZ) {
1845
1846 memcpy(pwps_ie, pwps_ie_src, wps_ielen+2);
1847 pwps_ie += (wps_ielen+2);
1848
1849 if (pbackup_remainder_ie)
1850 memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
1851
1852
1853 pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen;
1854 }
1855
1856 kfree(pbackup_remainder_ie);
1857
1858
1859#if defined(CONFIG_INTERRUPT_BASED_TXBCN)
1860 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
1861
1862 u8 sr = 0;
1863
1864 rtw_get_wps_attr_content(
1865 pwps_ie_src,
1866 wps_ielen,
1867 WPS_ATTR_SELECTED_REGISTRAR,
1868 (u8 *)(&sr),
1869 NULL
1870 );
1871
1872 if (sr) {
1873 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
1874 DBG_871X("%s, set WIFI_UNDER_WPS\n", __func__);
1875 }
1876 }
1877#endif
1878}
1879
1880static void update_bcn_p2p_ie(struct adapter *padapter)
1881{
1882
1883}
1884
1885static void update_bcn_vendor_spec_ie(struct adapter *padapter, u8 *oui)
1886{
1887 DBG_871X("%s\n", __func__);
1888
1889 if (!memcmp(RTW_WPA_OUI, oui, 4))
1890 update_bcn_wpa_ie(padapter);
1891
1892 else if (!memcmp(WMM_OUI, oui, 4))
1893 update_bcn_wmm_ie(padapter);
1894
1895 else if (!memcmp(WPS_OUI, oui, 4))
1896 update_bcn_wps_ie(padapter);
1897
1898 else if (!memcmp(P2P_OUI, oui, 4))
1899 update_bcn_p2p_ie(padapter);
1900
1901 else
1902 DBG_871X("unknown OUI type!\n");
1903
1904
1905
1906}
1907
1908void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
1909{
1910 struct mlme_priv *pmlmepriv;
1911 struct mlme_ext_priv *pmlmeext;
1912
1913
1914
1915
1916 if (!padapter)
1917 return;
1918
1919 pmlmepriv = &(padapter->mlmepriv);
1920 pmlmeext = &(padapter->mlmeextpriv);
1921
1922
1923 if (false == pmlmeext->bstart_bss)
1924 return;
1925
1926 spin_lock_bh(&pmlmepriv->bcn_update_lock);
1927
1928 switch (ie_id) {
1929
1930 case 0xFF:
1931
1932 update_bcn_fixed_ie(padapter);
1933
1934 break;
1935
1936 case _TIM_IE_:
1937
1938 update_BCNTIM(padapter);
1939
1940 break;
1941
1942 case _ERPINFO_IE_:
1943
1944 update_bcn_erpinfo_ie(padapter);
1945
1946 break;
1947
1948 case _HT_CAPABILITY_IE_:
1949
1950 update_bcn_htcap_ie(padapter);
1951
1952 break;
1953
1954 case _RSN_IE_2_:
1955
1956 update_bcn_rsn_ie(padapter);
1957
1958 break;
1959
1960 case _HT_ADD_INFO_IE_:
1961
1962 update_bcn_htinfo_ie(padapter);
1963
1964 break;
1965
1966 case _VENDOR_SPECIFIC_IE_:
1967
1968 update_bcn_vendor_spec_ie(padapter, oui);
1969
1970 break;
1971
1972 default:
1973 break;
1974 }
1975
1976 pmlmepriv->update_bcn = true;
1977
1978 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
1979
1980#ifndef CONFIG_INTERRUPT_BASED_TXBCN
1981 if (tx) {
1982
1983
1984 set_tx_beacon_cmd(padapter);
1985 }
1986#endif
1987
1988}
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002static int rtw_ht_operation_update(struct adapter *padapter)
2003{
2004 u16 cur_op_mode, new_op_mode;
2005 int op_mode_changes = 0;
2006 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2007 struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
2008
2009 if (pmlmepriv->htpriv.ht_option == true)
2010 return 0;
2011
2012
2013
2014
2015 DBG_871X("%s current operation mode = 0x%X\n",
2016 __func__, pmlmepriv->ht_op_mode);
2017
2018 if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)
2019 && pmlmepriv->num_sta_ht_no_gf) {
2020 pmlmepriv->ht_op_mode |=
2021 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
2022 op_mode_changes++;
2023 } else if ((pmlmepriv->ht_op_mode &
2024 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
2025 pmlmepriv->num_sta_ht_no_gf == 0) {
2026 pmlmepriv->ht_op_mode &=
2027 ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
2028 op_mode_changes++;
2029 }
2030
2031 if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
2032 (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
2033 pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
2034 op_mode_changes++;
2035 } else if ((pmlmepriv->ht_op_mode &
2036 HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
2037 (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
2038 pmlmepriv->ht_op_mode &=
2039 ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
2040 op_mode_changes++;
2041 }
2042
2043
2044
2045
2046
2047 new_op_mode = 0;
2048 if (pmlmepriv->num_sta_no_ht ||
2049 (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
2050 new_op_mode = OP_MODE_MIXED;
2051 else if (
2052 (le16_to_cpu(phtpriv_ap->ht_cap.cap_info) & IEEE80211_HT_CAP_SUP_WIDTH)
2053 && pmlmepriv->num_sta_ht_20mhz)
2054 new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
2055 else if (pmlmepriv->olbc_ht)
2056 new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
2057 else
2058 new_op_mode = OP_MODE_PURE;
2059
2060 cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
2061 if (cur_op_mode != new_op_mode) {
2062 pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
2063 pmlmepriv->ht_op_mode |= new_op_mode;
2064 op_mode_changes++;
2065 }
2066
2067 DBG_871X("%s new operation mode = 0x%X changes =%d\n",
2068 __func__, pmlmepriv->ht_op_mode, op_mode_changes);
2069
2070 return op_mode_changes;
2071
2072}
2073
2074void associated_clients_update(struct adapter *padapter, u8 updated)
2075{
2076
2077 if (updated == true) {
2078
2079 struct list_head *phead, *plist;
2080 struct sta_info *psta = NULL;
2081 struct sta_priv *pstapriv = &padapter->stapriv;
2082
2083 spin_lock_bh(&pstapriv->asoc_list_lock);
2084
2085 phead = &pstapriv->asoc_list;
2086 plist = get_next(phead);
2087
2088
2089 while (phead != plist) {
2090
2091 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
2092
2093 plist = get_next(plist);
2094
2095 VCS_update(padapter, psta);
2096 }
2097
2098 spin_unlock_bh(&pstapriv->asoc_list_lock);
2099
2100 }
2101
2102}
2103
2104
2105void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
2106{
2107 u8 beacon_updated = false;
2108 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2109 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2110
2111 if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) {
2112
2113 if (!psta->no_short_preamble_set) {
2114
2115 psta->no_short_preamble_set = 1;
2116
2117 pmlmepriv->num_sta_no_short_preamble++;
2118
2119 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
2120 (pmlmepriv->num_sta_no_short_preamble == 1)) {
2121
2122 beacon_updated = true;
2123 update_beacon(padapter, 0xFF, NULL, true);
2124 }
2125
2126 }
2127 } else{
2128
2129
2130 if (psta->no_short_preamble_set) {
2131
2132 psta->no_short_preamble_set = 0;
2133
2134 pmlmepriv->num_sta_no_short_preamble--;
2135
2136 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
2137 (pmlmepriv->num_sta_no_short_preamble == 0)) {
2138
2139 beacon_updated = true;
2140 update_beacon(padapter, 0xFF, NULL, true);
2141 }
2142
2143 }
2144 }
2145
2146 if (psta->flags & WLAN_STA_NONERP) {
2147
2148 if (!psta->nonerp_set) {
2149
2150 psta->nonerp_set = 1;
2151
2152 pmlmepriv->num_sta_non_erp++;
2153
2154 if (pmlmepriv->num_sta_non_erp == 1) {
2155
2156 beacon_updated = true;
2157 update_beacon(padapter, _ERPINFO_IE_, NULL, true);
2158 }
2159 }
2160
2161 } else{
2162
2163
2164 if (psta->nonerp_set) {
2165
2166 psta->nonerp_set = 0;
2167
2168 pmlmepriv->num_sta_non_erp--;
2169
2170 if (pmlmepriv->num_sta_non_erp == 0) {
2171
2172 beacon_updated = true;
2173 update_beacon(padapter, _ERPINFO_IE_, NULL, true);
2174 }
2175 }
2176
2177 }
2178
2179
2180 if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT)) {
2181
2182 if (!psta->no_short_slot_time_set) {
2183
2184 psta->no_short_slot_time_set = 1;
2185
2186 pmlmepriv->num_sta_no_short_slot_time++;
2187
2188 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
2189 (pmlmepriv->num_sta_no_short_slot_time == 1)) {
2190
2191 beacon_updated = true;
2192 update_beacon(padapter, 0xFF, NULL, true);
2193 }
2194
2195 }
2196 } else{
2197
2198
2199 if (psta->no_short_slot_time_set) {
2200
2201 psta->no_short_slot_time_set = 0;
2202
2203 pmlmepriv->num_sta_no_short_slot_time--;
2204
2205 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
2206 (pmlmepriv->num_sta_no_short_slot_time == 0)) {
2207
2208 beacon_updated = true;
2209 update_beacon(padapter, 0xFF, NULL, true);
2210 }
2211 }
2212 }
2213
2214 if (psta->flags & WLAN_STA_HT) {
2215
2216 u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
2217
2218 DBG_871X("HT: STA " MAC_FMT " HT Capabilities "
2219 "Info: 0x%04x\n", MAC_ARG(psta->hwaddr), ht_capab);
2220
2221 if (psta->no_ht_set) {
2222 psta->no_ht_set = 0;
2223 pmlmepriv->num_sta_no_ht--;
2224 }
2225
2226 if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
2227 if (!psta->no_ht_gf_set) {
2228 psta->no_ht_gf_set = 1;
2229 pmlmepriv->num_sta_ht_no_gf++;
2230 }
2231 DBG_871X("%s STA " MAC_FMT " - no "
2232 "greenfield, num of non-gf stations %d\n",
2233 __func__, MAC_ARG(psta->hwaddr),
2234 pmlmepriv->num_sta_ht_no_gf);
2235 }
2236
2237 if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) {
2238 if (!psta->ht_20mhz_set) {
2239 psta->ht_20mhz_set = 1;
2240 pmlmepriv->num_sta_ht_20mhz++;
2241 }
2242 DBG_871X("%s STA " MAC_FMT " - 20 MHz HT, "
2243 "num of 20MHz HT STAs %d\n",
2244 __func__, MAC_ARG(psta->hwaddr),
2245 pmlmepriv->num_sta_ht_20mhz);
2246 }
2247
2248 } else{
2249
2250
2251 if (!psta->no_ht_set) {
2252 psta->no_ht_set = 1;
2253 pmlmepriv->num_sta_no_ht++;
2254 }
2255 if (pmlmepriv->htpriv.ht_option == true) {
2256 DBG_871X("%s STA " MAC_FMT
2257 " - no HT, num of non-HT stations %d\n",
2258 __func__, MAC_ARG(psta->hwaddr),
2259 pmlmepriv->num_sta_no_ht);
2260 }
2261 }
2262
2263 if (rtw_ht_operation_update(padapter) > 0) {
2264
2265 update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false);
2266 update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true);
2267 }
2268
2269
2270 associated_clients_update(padapter, beacon_updated);
2271
2272 DBG_871X("%s, updated =%d\n", __func__, beacon_updated);
2273
2274}
2275
2276u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta)
2277{
2278 u8 beacon_updated = false;
2279 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2280 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2281
2282 if (!psta)
2283 return beacon_updated;
2284
2285 if (psta->no_short_preamble_set) {
2286 psta->no_short_preamble_set = 0;
2287 pmlmepriv->num_sta_no_short_preamble--;
2288 if (pmlmeext->cur_wireless_mode > WIRELESS_11B
2289 && pmlmepriv->num_sta_no_short_preamble == 0){
2290
2291 beacon_updated = true;
2292 update_beacon(padapter, 0xFF, NULL, true);
2293 }
2294 }
2295
2296 if (psta->nonerp_set) {
2297 psta->nonerp_set = 0;
2298 pmlmepriv->num_sta_non_erp--;
2299 if (pmlmepriv->num_sta_non_erp == 0) {
2300
2301 beacon_updated = true;
2302 update_beacon(padapter, _ERPINFO_IE_, NULL, true);
2303 }
2304 }
2305
2306 if (psta->no_short_slot_time_set) {
2307 psta->no_short_slot_time_set = 0;
2308 pmlmepriv->num_sta_no_short_slot_time--;
2309 if (pmlmeext->cur_wireless_mode > WIRELESS_11B
2310 && pmlmepriv->num_sta_no_short_slot_time == 0){
2311
2312 beacon_updated = true;
2313 update_beacon(padapter, 0xFF, NULL, true);
2314 }
2315 }
2316
2317 if (psta->no_ht_gf_set) {
2318 psta->no_ht_gf_set = 0;
2319 pmlmepriv->num_sta_ht_no_gf--;
2320 }
2321
2322 if (psta->no_ht_set) {
2323 psta->no_ht_set = 0;
2324 pmlmepriv->num_sta_no_ht--;
2325 }
2326
2327 if (psta->ht_20mhz_set) {
2328 psta->ht_20mhz_set = 0;
2329 pmlmepriv->num_sta_ht_20mhz--;
2330 }
2331
2332 if (rtw_ht_operation_update(padapter) > 0) {
2333
2334 update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false);
2335 update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true);
2336 }
2337
2338
2339
2340
2341 DBG_871X("%s, updated =%d\n", __func__, beacon_updated);
2342
2343 return beacon_updated;
2344
2345}
2346
2347u8 ap_free_sta(
2348 struct adapter *padapter,
2349 struct sta_info *psta,
2350 bool active,
2351 u16 reason
2352)
2353{
2354 u8 beacon_updated = false;
2355
2356 if (!psta)
2357 return beacon_updated;
2358
2359 if (active == true) {
2360
2361
2362 send_delba(padapter, 0, psta->hwaddr);
2363
2364
2365 send_delba(padapter, 1, psta->hwaddr);
2366
2367 issue_deauth(padapter, psta->hwaddr, reason);
2368 }
2369
2370 psta->htpriv.agg_enable_bitmap = 0x0;
2371 psta->htpriv.candidate_tid_bitmap = 0x0;
2372
2373
2374
2375
2376
2377 rtw_clearstakey_cmd(padapter, psta, true);
2378
2379
2380 spin_lock_bh(&psta->lock);
2381 psta->state &= ~_FW_LINKED;
2382 spin_unlock_bh(&psta->lock);
2383
2384 rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
2385
2386 report_del_sta_event(padapter, psta->hwaddr, reason);
2387
2388 beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
2389
2390 rtw_free_stainfo(padapter, psta);
2391
2392
2393 return beacon_updated;
2394
2395}
2396
2397int rtw_sta_flush(struct adapter *padapter)
2398{
2399 struct list_head *phead, *plist;
2400 int ret = 0;
2401 struct sta_info *psta = NULL;
2402 struct sta_priv *pstapriv = &padapter->stapriv;
2403 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2404 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2405 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2406
2407 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
2408
2409 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2410 return ret;
2411
2412
2413 spin_lock_bh(&pstapriv->asoc_list_lock);
2414 phead = &pstapriv->asoc_list;
2415 plist = get_next(phead);
2416
2417
2418 while (phead != plist) {
2419
2420 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
2421
2422 plist = get_next(plist);
2423
2424 list_del_init(&psta->asoc_list);
2425 pstapriv->asoc_list_cnt--;
2426
2427
2428 ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
2429
2430 }
2431 spin_unlock_bh(&pstapriv->asoc_list_lock);
2432
2433
2434 issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
2435
2436 associated_clients_update(padapter, true);
2437
2438 return ret;
2439
2440}
2441
2442
2443void sta_info_update(struct adapter *padapter, struct sta_info *psta)
2444{
2445 int flags = psta->flags;
2446 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2447
2448
2449
2450 if (WLAN_STA_WME&flags)
2451 psta->qos_option = 1;
2452 else
2453 psta->qos_option = 0;
2454
2455 if (pmlmepriv->qospriv.qos_option == 0)
2456 psta->qos_option = 0;
2457
2458
2459 if (WLAN_STA_HT&flags) {
2460
2461 psta->htpriv.ht_option = true;
2462 psta->qos_option = 1;
2463 } else{
2464
2465
2466 psta->htpriv.ht_option = false;
2467 }
2468
2469 if (pmlmepriv->htpriv.ht_option == false)
2470 psta->htpriv.ht_option = false;
2471
2472 update_sta_info_apmode(padapter, psta);
2473
2474
2475}
2476
2477
2478void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta)
2479{
2480 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2481 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2482
2483 if (psta->state & _FW_LINKED) {
2484
2485 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
2486
2487
2488 add_RATid(padapter, psta, 0);
2489 }
2490}
2491
2492void rtw_ap_restore_network(struct adapter *padapter)
2493{
2494 struct mlme_priv *mlmepriv = &padapter->mlmepriv;
2495 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2496 struct sta_priv *pstapriv = &padapter->stapriv;
2497 struct sta_info *psta;
2498 struct security_priv *psecuritypriv = &(padapter->securitypriv);
2499 struct list_head *phead, *plist;
2500 u8 chk_alive_num = 0;
2501 char chk_alive_list[NUM_STA];
2502 int i;
2503
2504 rtw_setopmode_cmd(padapter, Ndis802_11APMode, false);
2505
2506 set_channel_bwmode(
2507 padapter,
2508 pmlmeext->cur_channel,
2509 pmlmeext->cur_ch_offset,
2510 pmlmeext->cur_bwmode
2511 );
2512
2513 start_bss_network(padapter, (u8 *)&mlmepriv->cur_network.network);
2514
2515 if ((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
2516 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
2517
2518
2519 rtw_set_key(
2520 padapter,
2521 psecuritypriv,
2522 psecuritypriv->dot118021XGrpKeyid,
2523 0,
2524 false
2525 );
2526 }
2527
2528 spin_lock_bh(&pstapriv->asoc_list_lock);
2529
2530 phead = &pstapriv->asoc_list;
2531 plist = get_next(phead);
2532
2533 while (phead != plist) {
2534 int stainfo_offset;
2535
2536 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
2537 plist = get_next(plist);
2538
2539 stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
2540 if (stainfo_offset_valid(stainfo_offset))
2541 chk_alive_list[chk_alive_num++] = stainfo_offset;
2542
2543 }
2544
2545 spin_unlock_bh(&pstapriv->asoc_list_lock);
2546
2547 for (i = 0; i < chk_alive_num; i++) {
2548 psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
2549
2550 if (psta == NULL) {
2551 DBG_871X(FUNC_ADPT_FMT" sta_info is null\n", FUNC_ADPT_ARG(padapter));
2552 } else if (psta->state & _FW_LINKED) {
2553 rtw_sta_media_status_rpt(padapter, psta, 1);
2554 Update_RA_Entry(padapter, psta);
2555
2556
2557 if ((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
2558 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
2559
2560 rtw_setstakey_cmd(padapter, psta, true, false);
2561 }
2562 }
2563 }
2564
2565}
2566
2567void start_ap_mode(struct adapter *padapter)
2568{
2569 int i;
2570 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2571 struct sta_priv *pstapriv = &padapter->stapriv;
2572 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2573 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
2574
2575 pmlmepriv->update_bcn = false;
2576
2577
2578 pmlmeext->bstart_bss = false;
2579
2580 pmlmepriv->num_sta_non_erp = 0;
2581
2582 pmlmepriv->num_sta_no_short_slot_time = 0;
2583
2584 pmlmepriv->num_sta_no_short_preamble = 0;
2585
2586 pmlmepriv->num_sta_ht_no_gf = 0;
2587 pmlmepriv->num_sta_no_ht = 0;
2588 pmlmepriv->num_sta_ht_20mhz = 0;
2589
2590 pmlmepriv->olbc = false;
2591
2592 pmlmepriv->olbc_ht = false;
2593
2594 pmlmepriv->ht_op_mode = 0;
2595
2596 for (i = 0; i < NUM_STA; i++)
2597 pstapriv->sta_aid[i] = NULL;
2598
2599 pmlmepriv->wps_beacon_ie = NULL;
2600 pmlmepriv->wps_probe_resp_ie = NULL;
2601 pmlmepriv->wps_assoc_resp_ie = NULL;
2602
2603 pmlmepriv->p2p_beacon_ie = NULL;
2604 pmlmepriv->p2p_probe_resp_ie = NULL;
2605
2606
2607
2608 INIT_LIST_HEAD(&(pacl_list->acl_node_q.queue));
2609 pacl_list->num = 0;
2610 pacl_list->mode = 0;
2611 for (i = 0; i < NUM_ACL; i++) {
2612 INIT_LIST_HEAD(&pacl_list->aclnode[i].list);
2613 pacl_list->aclnode[i].valid = false;
2614 }
2615
2616}
2617
2618void stop_ap_mode(struct adapter *padapter)
2619{
2620 struct list_head *phead, *plist;
2621 struct rtw_wlan_acl_node *paclnode;
2622 struct sta_info *psta = NULL;
2623 struct sta_priv *pstapriv = &padapter->stapriv;
2624 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2625 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2626 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
2627 struct __queue *pacl_node_q = &pacl_list->acl_node_q;
2628
2629 pmlmepriv->update_bcn = false;
2630 pmlmeext->bstart_bss = false;
2631
2632
2633 memset(
2634 (unsigned char *)&padapter->securitypriv,
2635 0,
2636 sizeof(struct security_priv)
2637 );
2638 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
2639 padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
2640
2641
2642 spin_lock_bh(&(pacl_node_q->lock));
2643 phead = get_list_head(pacl_node_q);
2644 plist = get_next(phead);
2645 while (phead != plist) {
2646
2647 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
2648 plist = get_next(plist);
2649
2650 if (paclnode->valid == true) {
2651
2652 paclnode->valid = false;
2653
2654 list_del_init(&paclnode->list);
2655
2656 pacl_list->num--;
2657 }
2658 }
2659 spin_unlock_bh(&(pacl_node_q->lock));
2660
2661 DBG_871X("%s, free acl_node_queue, num =%d\n", __func__, pacl_list->num);
2662
2663 rtw_sta_flush(padapter);
2664
2665
2666 rtw_free_all_stainfo(padapter);
2667
2668 psta = rtw_get_bcmc_stainfo(padapter);
2669 rtw_free_stainfo(padapter, psta);
2670
2671 rtw_init_bcmc_stainfo(padapter);
2672
2673 rtw_free_mlme_priv_ie_data(pmlmepriv);
2674
2675 rtw_btcoex_MediaStatusNotify(padapter, 0);
2676}
2677