1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
22 #include <linux/ieee80211.h>
24 #include <osdep_service.h>
25 #include <drv_types.h>
27 #include <ieee80211.h>
28 #include <asm/unaligned.h>
30 #ifdef CONFIG_88EU_AP_MODE
32 void init_mlme_ap_info(struct adapter
*padapter
)
34 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
35 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
36 struct wlan_acl_pool
*pacl_list
= &pstapriv
->acl_list
;
39 spin_lock_init(&pmlmepriv
->bcn_update_lock
);
42 _rtw_init_queue(&pacl_list
->acl_node_q
);
44 start_ap_mode(padapter
);
47 void free_mlme_ap_info(struct adapter
*padapter
)
49 struct sta_info
*psta
= NULL
;
50 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
51 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
52 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
53 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
55 pmlmepriv
->update_bcn
= false;
56 pmlmeext
->bstart_bss
= false;
58 rtw_sta_flush(padapter
);
60 pmlmeinfo
->state
= _HW_STATE_NOLINK_
;
62 /* free_assoc_sta_resources */
63 rtw_free_all_stainfo(padapter
);
65 /* free bc/mc sta_info */
66 psta
= rtw_get_bcmc_stainfo(padapter
);
67 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
68 rtw_free_stainfo(padapter
, psta
);
69 spin_unlock_bh(&(pstapriv
->sta_hash_lock
));
72 static void update_BCNTIM(struct adapter
*padapter
)
74 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
75 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
76 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
77 struct wlan_bssid_ex
*pnetwork_mlmeext
= &(pmlmeinfo
->network
);
78 unsigned char *pie
= pnetwork_mlmeext
->IEs
;
82 u8
*p
, *dst_ie
, *premainder_ie
= NULL
;
83 u8
*pbackup_remainder_ie
= NULL
;
84 uint offset
, tmp_len
, tim_ielen
, tim_ie_offset
, remainder_ielen
;
86 p
= rtw_get_ie(pie
+ _FIXED_IE_LENGTH_
, _TIM_IE_
, &tim_ielen
,
87 pnetwork_mlmeext
->IELength
- _FIXED_IE_LENGTH_
);
88 if (p
!= NULL
&& tim_ielen
> 0) {
90 premainder_ie
= p
+tim_ielen
;
91 tim_ie_offset
= (int)(p
- pie
);
92 remainder_ielen
= pnetwork_mlmeext
->IELength
-
93 tim_ie_offset
- tim_ielen
;
94 /* append TIM IE from dst_ie offset */
99 /* calculate head_len */
100 offset
= _FIXED_IE_LENGTH_
;
101 offset
+= pnetwork_mlmeext
->Ssid
.SsidLength
+ 2;
103 /* get supported rates len */
104 p
= rtw_get_ie(pie
+ _BEACON_IE_OFFSET_
,
105 _SUPPORTEDRATES_IE_
, &tmp_len
,
106 (pnetwork_mlmeext
->IELength
-
107 _BEACON_IE_OFFSET_
));
111 /* DS Parameter Set IE, len = 3 */
114 premainder_ie
= pie
+ offset
;
116 remainder_ielen
= pnetwork_mlmeext
->IELength
-
119 /* append TIM IE from offset */
120 dst_ie
= pie
+ offset
;
123 if (remainder_ielen
> 0) {
124 pbackup_remainder_ie
= rtw_malloc(remainder_ielen
);
125 if (pbackup_remainder_ie
&& premainder_ie
)
126 memcpy(pbackup_remainder_ie
,
127 premainder_ie
, remainder_ielen
);
129 *dst_ie
++ = _TIM_IE_
;
131 if ((pstapriv
->tim_bitmap
&0xff00) &&
132 (pstapriv
->tim_bitmap
&0x00fc))
137 *dst_ie
++ = tim_ielen
;
139 *dst_ie
++ = 0;/* DTIM count */
140 *dst_ie
++ = 1;/* DTIM period */
142 if (pstapriv
->tim_bitmap
&BIT(0))/* for bc/mc frames */
143 *dst_ie
++ = BIT(0);/* bitmap ctrl */
147 if (tim_ielen
== 4) {
148 *dst_ie
++ = pstapriv
->tim_bitmap
& 0xff;
149 } else if (tim_ielen
== 5) {
150 put_unaligned_le16(pstapriv
->tim_bitmap
, dst_ie
);
154 /* copy remainder IE */
155 if (pbackup_remainder_ie
) {
156 memcpy(dst_ie
, pbackup_remainder_ie
, remainder_ielen
);
158 kfree(pbackup_remainder_ie
);
160 offset
= (uint
)(dst_ie
- pie
);
161 pnetwork_mlmeext
->IELength
= offset
+ remainder_ielen
;
164 set_tx_beacon_cmd(padapter
);
167 void rtw_add_bcn_ie(struct adapter
*padapter
, struct wlan_bssid_ex
*pnetwork
,
168 u8 index
, u8
*data
, u8 len
)
170 struct ndis_802_11_var_ie
*pIE
;
172 u8
*pie
= pnetwork
->IEs
;
173 u8
*p
= NULL
, *dst_ie
= NULL
, *premainder_ie
= NULL
;
174 u8
*pbackup_remainder_ie
= NULL
;
175 u32 i
, offset
, ielen
= 0, ie_offset
, remainder_ielen
= 0;
177 for (i
= sizeof(struct ndis_802_11_fixed_ie
); i
< pnetwork
->IELength
;) {
178 pIE
= (struct ndis_802_11_var_ie
*)(pnetwork
->IEs
+ i
);
180 if (pIE
->ElementID
> index
) {
182 /* already exist the same IE */
183 } else if (pIE
->ElementID
== index
) {
191 i
+= (pIE
->Length
+ 2);
194 if (p
!= NULL
&& ielen
> 0) {
197 premainder_ie
= p
+ielen
;
199 ie_offset
= (int)(p
- pie
);
201 remainder_ielen
= pnetwork
->IELength
- ie_offset
- ielen
;
209 if (remainder_ielen
> 0) {
210 pbackup_remainder_ie
= rtw_malloc(remainder_ielen
);
211 if (pbackup_remainder_ie
&& premainder_ie
)
212 memcpy(pbackup_remainder_ie
,
213 premainder_ie
, remainder_ielen
);
219 memcpy(dst_ie
, data
, len
);
222 /* copy remainder IE */
223 if (pbackup_remainder_ie
) {
224 memcpy(dst_ie
, pbackup_remainder_ie
, remainder_ielen
);
226 kfree(pbackup_remainder_ie
);
229 offset
= (uint
)(dst_ie
- pie
);
230 pnetwork
->IELength
= offset
+ remainder_ielen
;
233 void rtw_remove_bcn_ie(struct adapter
*padapter
, struct wlan_bssid_ex
*pnetwork
,
236 u8
*p
, *dst_ie
= NULL
, *premainder_ie
= NULL
;
237 u8
*pbackup_remainder_ie
= NULL
;
238 uint offset
, ielen
, ie_offset
, remainder_ielen
= 0;
239 u8
*pie
= pnetwork
->IEs
;
241 p
= rtw_get_ie(pie
+ _FIXED_IE_LENGTH_
, index
, &ielen
,
242 pnetwork
->IELength
- _FIXED_IE_LENGTH_
);
243 if (p
!= NULL
&& ielen
> 0) {
246 premainder_ie
= p
+ielen
;
248 ie_offset
= (int)(p
- pie
);
250 remainder_ielen
= pnetwork
->IELength
- ie_offset
- ielen
;
255 if (remainder_ielen
> 0) {
256 pbackup_remainder_ie
= rtw_malloc(remainder_ielen
);
257 if (pbackup_remainder_ie
&& premainder_ie
)
258 memcpy(pbackup_remainder_ie
,
259 premainder_ie
, remainder_ielen
);
262 /* copy remainder IE */
263 if (pbackup_remainder_ie
) {
264 memcpy(dst_ie
, pbackup_remainder_ie
, remainder_ielen
);
266 kfree(pbackup_remainder_ie
);
269 offset
= (uint
)(dst_ie
- pie
);
270 pnetwork
->IELength
= offset
+ remainder_ielen
;
273 static u8
chk_sta_is_alive(struct sta_info
*psta
)
277 if ((psta
->sta_stats
.last_rx_data_pkts
+
278 psta
->sta_stats
.last_rx_ctrl_pkts
) ==
279 (psta
->sta_stats
.rx_data_pkts
+
280 psta
->sta_stats
.rx_ctrl_pkts
))
285 sta_update_last_rx_pkts(psta
);
290 void expire_timeout_chk(struct adapter
*padapter
)
292 struct list_head
*phead
, *plist
;
294 struct sta_info
*psta
= NULL
;
295 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
296 u8 chk_alive_num
= 0;
297 char chk_alive_list
[NUM_STA
];
300 spin_lock_bh(&pstapriv
->auth_list_lock
);
302 phead
= &pstapriv
->auth_list
;
305 /* check auth_queue */
306 while (phead
!= plist
) {
307 psta
= container_of(plist
, struct sta_info
, auth_list
);
310 if (psta
->expire_to
> 0) {
312 if (psta
->expire_to
== 0) {
313 list_del_init(&psta
->auth_list
);
314 pstapriv
->auth_list_cnt
--;
316 DBG_88E("auth expire %6ph\n",
319 spin_unlock_bh(&pstapriv
->auth_list_lock
);
321 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
322 rtw_free_stainfo(padapter
, psta
);
323 spin_unlock_bh(&(pstapriv
->sta_hash_lock
));
325 spin_lock_bh(&pstapriv
->auth_list_lock
);
330 spin_unlock_bh(&pstapriv
->auth_list_lock
);
334 spin_lock_bh(&pstapriv
->asoc_list_lock
);
336 phead
= &pstapriv
->asoc_list
;
339 /* check asoc_queue */
340 while (phead
!= plist
) {
341 psta
= container_of(plist
, struct sta_info
, asoc_list
);
344 if (chk_sta_is_alive(psta
) || !psta
->expire_to
) {
345 psta
->expire_to
= pstapriv
->expire_to
;
346 psta
->keep_alive_trycnt
= 0;
347 psta
->under_exist_checking
= 0;
352 if (psta
->expire_to
<= 0) {
353 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
355 if (padapter
->registrypriv
.wifi_spec
== 1) {
356 psta
->expire_to
= pstapriv
->expire_to
;
360 if (psta
->state
& WIFI_SLEEP_STATE
) {
361 if (!(psta
->state
& WIFI_STA_ALIVE_CHK_STATE
)) {
362 /* to check if alive by another methods
363 * if station is at ps mode.
365 psta
->expire_to
= pstapriv
->expire_to
;
366 psta
->state
|= WIFI_STA_ALIVE_CHK_STATE
;
368 /* to update bcn with tim_bitmap
371 pstapriv
->tim_bitmap
|= BIT(psta
->aid
);
372 update_beacon(padapter
, _TIM_IE_
,
375 if (!pmlmeext
->active_keep_alive_check
)
379 if (pmlmeext
->active_keep_alive_check
) {
383 rtw_stainfo_offset(pstapriv
, psta
);
384 if (stainfo_offset_valid(stainfo_offset
))
385 chk_alive_list
[chk_alive_num
++] = stainfo_offset
;
389 list_del_init(&psta
->asoc_list
);
390 pstapriv
->asoc_list_cnt
--;
392 DBG_88E("asoc expire %pM, state = 0x%x\n", (psta
->hwaddr
), psta
->state
);
393 updated
= ap_free_sta(padapter
, psta
, true, WLAN_REASON_DEAUTH_LEAVING
);
395 /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
396 if (psta
->sleepq_len
> (NR_XMITFRAME
/pstapriv
->asoc_list_cnt
) &&
397 padapter
->xmitpriv
.free_xmitframe_cnt
< (NR_XMITFRAME
/pstapriv
->asoc_list_cnt
/2)) {
398 DBG_88E("%s sta:%pM, sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__
,
399 (psta
->hwaddr
), psta
->sleepq_len
,
400 padapter
->xmitpriv
.free_xmitframe_cnt
,
401 pstapriv
->asoc_list_cnt
);
402 wakeup_sta_to_xmit(padapter
, psta
);
407 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
410 u8 backup_oper_channel
= 0;
411 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
412 /* switch to correct channel of current network before issue keep-alive frames */
413 if (rtw_get_oper_ch(padapter
) != pmlmeext
->cur_channel
) {
414 backup_oper_channel
= rtw_get_oper_ch(padapter
);
415 SelectChannel(padapter
, pmlmeext
->cur_channel
);
418 /* issue null data to check sta alive*/
419 for (i
= 0; i
< chk_alive_num
; i
++) {
422 psta
= rtw_get_stainfo_by_offset(pstapriv
, chk_alive_list
[i
]);
424 if (psta
->state
& WIFI_SLEEP_STATE
)
425 ret
= issue_nulldata(padapter
, psta
->hwaddr
, 0, 1, 50);
427 ret
= issue_nulldata(padapter
, psta
->hwaddr
, 0, 3, 50);
429 psta
->keep_alive_trycnt
++;
430 if (ret
== _SUCCESS
) {
431 DBG_88E("asoc check, sta(%pM) is alive\n", (psta
->hwaddr
));
432 psta
->expire_to
= pstapriv
->expire_to
;
433 psta
->keep_alive_trycnt
= 0;
435 } else if (psta
->keep_alive_trycnt
<= 3) {
436 DBG_88E("ack check for asoc expire, keep_alive_trycnt =%d\n", psta
->keep_alive_trycnt
);
441 psta
->keep_alive_trycnt
= 0;
443 DBG_88E("asoc expire %pM, state = 0x%x\n", (psta
->hwaddr
), psta
->state
);
444 spin_lock_bh(&pstapriv
->asoc_list_lock
);
445 list_del_init(&psta
->asoc_list
);
446 pstapriv
->asoc_list_cnt
--;
447 updated
= ap_free_sta(padapter
, psta
, true, WLAN_REASON_DEAUTH_LEAVING
);
448 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
451 if (backup_oper_channel
> 0) /* back to the original operation channel */
452 SelectChannel(padapter
, backup_oper_channel
);
455 associated_clients_update(padapter
, updated
);
458 void add_RATid(struct adapter
*padapter
, struct sta_info
*psta
, u8 rssi_level
)
463 unsigned char sta_band
= 0, raid
, shortGIrate
= false;
465 unsigned int tx_ra_bitmap
= 0;
466 struct ht_priv
*psta_ht
= NULL
;
467 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
468 struct wlan_bssid_ex
*pcur_network
= (struct wlan_bssid_ex
*)&pmlmepriv
->cur_network
.network
;
471 psta_ht
= &psta
->htpriv
;
475 if (!(psta
->state
& _FW_LINKED
))
478 /* b/g mode ra_bitmap */
479 for (i
= 0; i
< sizeof(psta
->bssrateset
); i
++) {
480 if (psta
->bssrateset
[i
])
481 tx_ra_bitmap
|= rtw_get_bit_value_from_ieee_value(psta
->bssrateset
[i
]&0x7f);
483 /* n mode ra_bitmap */
484 if (psta_ht
->ht_option
) {
485 rtw_hal_get_hwreg(padapter
, HW_VAR_RF_TYPE
, (u8
*)(&rf_type
));
486 if (rf_type
== RF_2T2R
)
491 for (i
= 0; i
< limit
; i
++) {
492 if (psta_ht
->ht_cap
.supp_mcs_set
[i
/8] & BIT(i
%8))
493 tx_ra_bitmap
|= BIT(i
+12);
496 /* max short GI rate */
497 shortGIrate
= psta_ht
->sgi
;
500 if (pcur_network
->Configuration
.DSConfig
> 14) {
502 if (tx_ra_bitmap
& 0xffff000)
503 sta_band
|= WIRELESS_11_5N
| WIRELESS_11A
;
505 sta_band
|= WIRELESS_11A
;
507 if (tx_ra_bitmap
& 0xffff000)
508 sta_band
|= WIRELESS_11_24N
| WIRELESS_11G
| WIRELESS_11B
;
509 else if (tx_ra_bitmap
& 0xff0)
510 sta_band
|= WIRELESS_11G
| WIRELESS_11B
;
512 sta_band
|= WIRELESS_11B
;
515 psta
->wireless_mode
= sta_band
;
517 raid
= networktype_to_raid(sta_band
);
518 init_rate
= get_highest_rate_idx(tx_ra_bitmap
&0x0fffffff)&0x3f;
520 if (psta
->aid
< NUM_STA
) {
523 arg
= psta
->mac_id
&0x1f;
525 arg
|= BIT(7);/* support entry 2~31 */
530 tx_ra_bitmap
|= ((raid
<<28)&0xf0000000);
532 DBG_88E("%s => mac_id:%d , raid:%d , bitmap = 0x%x, arg = 0x%x\n",
533 __func__
, psta
->mac_id
, raid
, tx_ra_bitmap
, arg
);
535 /* bitmap[0:27] = tx_rate_bitmap */
536 /* bitmap[28:31]= Rate Adaptive id */
537 /* arg[0:4] = macid */
538 /* arg[5] = Short GI */
539 rtw_hal_add_ra_tid(padapter
, tx_ra_bitmap
, arg
, rssi_level
);
544 /* set ra_id, init_rate */
546 psta
->init_rate
= init_rate
;
549 DBG_88E("station aid %d exceed the max number\n", psta
->aid
);
553 static void update_bmc_sta(struct adapter
*padapter
)
556 unsigned char network_type
, raid
;
557 int i
, supportRateNum
= 0;
558 unsigned int tx_ra_bitmap
= 0;
559 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
560 struct wlan_bssid_ex
*pcur_network
= (struct wlan_bssid_ex
*)&pmlmepriv
->cur_network
.network
;
561 struct sta_info
*psta
= rtw_get_bcmc_stainfo(padapter
);
564 psta
->aid
= 0;/* default set to 0 */
565 psta
->mac_id
= psta
->aid
+ 1;
567 psta
->qos_option
= 0;
568 psta
->htpriv
.ht_option
= false;
570 psta
->ieee8021x_blocked
= 0;
572 memset((void *)&psta
->sta_stats
, 0, sizeof(struct stainfo_stats
));
574 /* prepare for add_RATid */
575 supportRateNum
= rtw_get_rateset_len((u8
*)&pcur_network
->SupportedRates
);
576 network_type
= rtw_check_network_type((u8
*)&pcur_network
->SupportedRates
, supportRateNum
, 1);
578 memcpy(psta
->bssrateset
, &pcur_network
->SupportedRates
, supportRateNum
);
579 psta
->bssratelen
= supportRateNum
;
581 /* b/g mode ra_bitmap */
582 for (i
= 0; i
< supportRateNum
; i
++) {
583 if (psta
->bssrateset
[i
])
584 tx_ra_bitmap
|= rtw_get_bit_value_from_ieee_value(psta
->bssrateset
[i
]&0x7f);
587 if (pcur_network
->Configuration
.DSConfig
> 14) {
588 /* force to A mode. 5G doesn't support CCK rates */
589 network_type
= WIRELESS_11A
;
590 tx_ra_bitmap
= 0x150; /* 6, 12, 24 Mbps */
592 /* force to b mode */
593 network_type
= WIRELESS_11B
;
597 raid
= networktype_to_raid(network_type
);
598 init_rate
= get_highest_rate_idx(tx_ra_bitmap
&0x0fffffff)&0x3f;
601 rtw_hal_set_odm_var(padapter
, HAL_ODM_STA_INFO
, psta
, true);
606 arg
= psta
->mac_id
&0x1f;
608 tx_ra_bitmap
|= ((raid
<<28)&0xf0000000);
609 DBG_88E("update_bmc_sta, mask = 0x%x, arg = 0x%x\n", tx_ra_bitmap
, arg
);
611 /* bitmap[0:27] = tx_rate_bitmap */
612 /* bitmap[28:31]= Rate Adaptive id */
613 /* arg[0:4] = macid */
614 /* arg[5] = Short GI */
615 rtw_hal_add_ra_tid(padapter
, tx_ra_bitmap
, arg
, 0);
617 /* set ra_id, init_rate */
619 psta
->init_rate
= init_rate
;
621 rtw_stassoc_hw_rpt(padapter
, psta
);
623 spin_lock_bh(&psta
->lock
);
624 psta
->state
= _FW_LINKED
;
625 spin_unlock_bh(&psta
->lock
);
628 DBG_88E("add_RATid_bmc_sta error!\n");
633 /* AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode */
634 /* MAC_ID = AID+1 for sta in ap/adhoc mode */
635 /* MAC_ID = 1 for bc/mc for sta/ap/adhoc */
636 /* MAC_ID = 0 for bssid for sta/ap/adhoc */
637 /* CAM_ID = 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
639 void update_sta_info_apmode(struct adapter
*padapter
, struct sta_info
*psta
)
641 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
642 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
643 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
644 struct ht_priv
*phtpriv_ap
= &pmlmepriv
->htpriv
;
645 struct ht_priv
*phtpriv_sta
= &psta
->htpriv
;
647 psta
->mac_id
= psta
->aid
+1;
648 DBG_88E("%s\n", __func__
);
651 rtw_hal_set_odm_var(padapter
, HAL_ODM_STA_INFO
, psta
, true);
653 if (psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
)
654 psta
->ieee8021x_blocked
= true;
656 psta
->ieee8021x_blocked
= false;
659 /* update sta's cap */
662 VCS_update(padapter
, psta
);
664 if (phtpriv_sta
->ht_option
) {
665 /* check if sta supports rx ampdu */
666 phtpriv_sta
->ampdu_enable
= phtpriv_ap
->ampdu_enable
;
668 /* check if sta support s Short GI */
669 if ((phtpriv_sta
->ht_cap
.cap_info
& phtpriv_ap
->ht_cap
.cap_info
) & (IEEE80211_HT_CAP_SGI_20
| IEEE80211_HT_CAP_SGI_40
))
670 phtpriv_sta
->sgi
= true;
673 if ((phtpriv_sta
->ht_cap
.cap_info
& phtpriv_ap
->ht_cap
.cap_info
) & IEEE80211_HT_CAP_SUP_WIDTH
) {
674 phtpriv_sta
->bwmode
= pmlmeext
->cur_bwmode
;
675 phtpriv_sta
->ch_offset
= pmlmeext
->cur_ch_offset
;
677 psta
->qos_option
= true;
679 phtpriv_sta
->ampdu_enable
= false;
680 phtpriv_sta
->sgi
= false;
681 phtpriv_sta
->bwmode
= HT_CHANNEL_WIDTH_20
;
682 phtpriv_sta
->ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
686 send_delba(padapter
, 0, psta
->hwaddr
);/* recipient */
689 send_delba(padapter
, 1, psta
->hwaddr
);/* originator */
690 phtpriv_sta
->agg_enable_bitmap
= 0x0;/* reset */
691 phtpriv_sta
->candidate_tid_bitmap
= 0x0;/* reset */
693 /* todo: init other variables */
695 memset((void *)&psta
->sta_stats
, 0, sizeof(struct stainfo_stats
));
697 spin_lock_bh(&psta
->lock
);
698 psta
->state
|= _FW_LINKED
;
699 spin_unlock_bh(&psta
->lock
);
702 static void update_hw_ht_param(struct adapter
*padapter
)
704 unsigned char max_AMPDU_len
;
705 unsigned char min_MPDU_spacing
;
706 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
707 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
709 DBG_88E("%s\n", __func__
);
711 /* handle A-MPDU parameter field */
713 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
714 AMPDU_para [4:2]:Min MPDU Start Spacing
716 max_AMPDU_len
= pmlmeinfo
->HT_caps
.u
.HT_cap_element
.AMPDU_para
& 0x03;
718 min_MPDU_spacing
= (pmlmeinfo
->HT_caps
.u
.HT_cap_element
.AMPDU_para
& 0x1c) >> 2;
720 rtw_hal_set_hwreg(padapter
, HW_VAR_AMPDU_MIN_SPACE
, (u8
*)(&min_MPDU_spacing
));
722 rtw_hal_set_hwreg(padapter
, HW_VAR_AMPDU_FACTOR
, (u8
*)(&max_AMPDU_len
));
725 /* Config SM Power Save setting */
727 pmlmeinfo
->SM_PS
= (le16_to_cpu(pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
) & 0x0C) >> 2;
728 if (pmlmeinfo
->SM_PS
== WLAN_HT_CAP_SM_PS_STATIC
)
729 DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__
);
732 static void start_bss_network(struct adapter
*padapter
, u8
*pbuf
)
735 u8 val8
, cur_channel
, cur_bwmode
, cur_ch_offset
;
739 struct registry_priv
*pregpriv
= &padapter
->registrypriv
;
740 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
741 struct security_priv
*psecuritypriv
= &(padapter
->securitypriv
);
742 struct wlan_bssid_ex
*pnetwork
= (struct wlan_bssid_ex
*)&pmlmepriv
->cur_network
.network
;
743 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
744 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
745 struct wlan_bssid_ex
*pnetwork_mlmeext
= &(pmlmeinfo
->network
);
746 struct HT_info_element
*pht_info
= NULL
;
748 bcn_interval
= (u16
)pnetwork
->Configuration
.BeaconPeriod
;
749 cur_channel
= pnetwork
->Configuration
.DSConfig
;
750 cur_bwmode
= HT_CHANNEL_WIDTH_20
;
751 cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
754 /* check if there is wps ie, */
755 /* if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, */
756 /* and at first time the security ie (RSN/WPA IE) will not include in beacon. */
757 if (!rtw_get_wps_ie(pnetwork
->IEs
+_FIXED_IE_LENGTH_
, pnetwork
->IELength
-_FIXED_IE_LENGTH_
, NULL
, NULL
))
758 pmlmeext
->bstart_bss
= true;
760 /* todo: update wmm, ht cap */
761 if (pmlmepriv
->qospriv
.qos_option
)
762 pmlmeinfo
->WMM_enable
= true;
763 if (pmlmepriv
->htpriv
.ht_option
) {
764 pmlmeinfo
->WMM_enable
= true;
765 pmlmeinfo
->HT_enable
= true;
767 update_hw_ht_param(padapter
);
770 if (pmlmepriv
->cur_network
.join_res
!= true) { /* setting only at first time */
771 /* WEP Key will be set before this function, do not clear CAM. */
772 if ((psecuritypriv
->dot11PrivacyAlgrthm
!= _WEP40_
) &&
773 (psecuritypriv
->dot11PrivacyAlgrthm
!= _WEP104_
))
774 flush_all_cam_entry(padapter
); /* clear CAM */
777 /* set MSR to AP_Mode */
778 Set_MSR(padapter
, _HW_STATE_AP_
);
781 rtw_hal_set_hwreg(padapter
, HW_VAR_BSSID
, pnetwork
->MacAddress
);
783 /* Set EDCA param reg */
784 acparm
= 0x002F3217; /* VO */
785 rtw_hal_set_hwreg(padapter
, HW_VAR_AC_PARAM_VO
, (u8
*)(&acparm
));
786 acparm
= 0x005E4317; /* VI */
787 rtw_hal_set_hwreg(padapter
, HW_VAR_AC_PARAM_VI
, (u8
*)(&acparm
));
789 rtw_hal_set_hwreg(padapter
, HW_VAR_AC_PARAM_BE
, (u8
*)(&acparm
));
790 acparm
= 0x0000A444; /* BK */
791 rtw_hal_set_hwreg(padapter
, HW_VAR_AC_PARAM_BK
, (u8
*)(&acparm
));
794 val8
= (psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) ? 0xcc : 0xcf;
795 rtw_hal_set_hwreg(padapter
, HW_VAR_SEC_CFG
, (u8
*)(&val8
));
797 /* Beacon Control related register */
798 rtw_hal_set_hwreg(padapter
, HW_VAR_BEACON_INTERVAL
, (u8
*)(&bcn_interval
));
800 UpdateBrateTbl(padapter
, pnetwork
->SupportedRates
);
801 rtw_hal_set_hwreg(padapter
, HW_VAR_BASIC_RATE
, pnetwork
->SupportedRates
);
803 if (!pmlmepriv
->cur_network
.join_res
) { /* setting only at first time */
804 /* turn on all dynamic functions */
805 Switch_DM_Func(padapter
, DYNAMIC_ALL_FUNC_ENABLE
, true);
807 /* set channel, bwmode */
808 p
= rtw_get_ie((pnetwork
->IEs
+ sizeof(struct ndis_802_11_fixed_ie
)), _HT_ADD_INFO_IE_
, &ie_len
, (pnetwork
->IELength
- sizeof(struct ndis_802_11_fixed_ie
)));
810 pht_info
= (struct HT_info_element
*)(p
+2);
812 if ((pregpriv
->cbw40_enable
) && (pht_info
->infos
[0] & BIT(2))) {
813 /* switch to the 40M Hz mode */
814 cur_bwmode
= HT_CHANNEL_WIDTH_40
;
815 switch (pht_info
->infos
[0] & 0x3) {
817 cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_LOWER
;
820 cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_UPPER
;
823 cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
828 /* TODO: need to judge the phy parameters on concurrent mode for single phy */
829 set_channel_bwmode(padapter
, cur_channel
, cur_ch_offset
, cur_bwmode
);
831 DBG_88E("CH =%d, BW =%d, offset =%d\n", cur_channel
, cur_bwmode
, cur_ch_offset
);
834 pmlmeext
->cur_channel
= cur_channel
;
835 pmlmeext
->cur_bwmode
= cur_bwmode
;
836 pmlmeext
->cur_ch_offset
= cur_ch_offset
;
837 pmlmeext
->cur_wireless_mode
= pmlmepriv
->cur_network
.network_type
;
839 /* update cur_wireless_mode */
840 update_wireless_mode(padapter
);
842 /* update capability after cur_wireless_mode updated */
843 update_capinfo(padapter
, rtw_get_capability((struct wlan_bssid_ex
*)pnetwork
));
845 /* let pnetwork_mlmeext == pnetwork_mlme. */
846 memcpy(pnetwork_mlmeext
, pnetwork
, pnetwork
->Length
);
848 if (pmlmeext
->bstart_bss
) {
849 update_beacon(padapter
, _TIM_IE_
, NULL
, false);
851 /* issue beacon frame */
852 if (send_beacon(padapter
) == _FAIL
)
853 DBG_88E("send_beacon, fail!\n");
856 /* update bc/mc sta_info */
857 update_bmc_sta(padapter
);
860 int rtw_check_beacon_data(struct adapter
*padapter
, u8
*pbuf
, int len
)
864 u8
*pHT_caps_ie
= NULL
;
865 u8
*pHT_info_ie
= NULL
;
866 struct sta_info
*psta
= NULL
;
867 u16 cap
, ht_cap
= false;
869 int group_cipher
, pairwise_cipher
;
870 u8 channel
, network_type
, supportRate
[NDIS_802_11_LENGTH_RATES_EX
];
871 int supportRateNum
= 0;
872 u8 OUI1
[] = {0x00, 0x50, 0xf2, 0x01};
873 u8 WMM_PARA_IE
[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
874 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
875 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
876 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
877 struct wlan_bssid_ex
*pbss_network
= (struct wlan_bssid_ex
*)&pmlmepriv
->cur_network
.network
;
878 u8
*ie
= pbss_network
->IEs
;
881 /* Supported rates */
883 /* WLAN_EID_COUNTRY */
884 /* ERP Information element */
885 /* Extended supported rates */
887 /* Wi-Fi Wireless Multimedia Extensions */
888 /* ht_capab, ht_oper */
891 DBG_88E("%s, len =%d\n", __func__
, len
);
893 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
900 pbss_network
->IELength
= len
;
902 memset(ie
, 0, MAX_IE_SZ
);
904 memcpy(ie
, pbuf
, pbss_network
->IELength
);
907 if (pbss_network
->InfrastructureMode
!= Ndis802_11APMode
)
910 pbss_network
->Rssi
= 0;
912 ether_addr_copy(pbss_network
->MacAddress
, myid(&(padapter
->eeprompriv
)));
914 /* beacon interval */
915 p
= rtw_get_beacon_interval_from_ie(ie
);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */
916 pbss_network
->Configuration
.BeaconPeriod
= get_unaligned_le16(p
);
919 cap
= get_unaligned_le16(ie
);
922 p
= rtw_get_ie(ie
+ _BEACON_IE_OFFSET_
, _SSID_IE_
, &ie_len
, (pbss_network
->IELength
- _BEACON_IE_OFFSET_
));
923 if (p
&& ie_len
> 0) {
924 memset(&pbss_network
->Ssid
, 0, sizeof(struct ndis_802_11_ssid
));
925 memcpy(pbss_network
->Ssid
.Ssid
, (p
+ 2), ie_len
);
926 pbss_network
->Ssid
.SsidLength
= ie_len
;
931 pbss_network
->Configuration
.Length
= 0;
932 p
= rtw_get_ie(ie
+ _BEACON_IE_OFFSET_
, _DSSET_IE_
, &ie_len
, (pbss_network
->IELength
- _BEACON_IE_OFFSET_
));
936 pbss_network
->Configuration
.DSConfig
= channel
;
938 memset(supportRate
, 0, NDIS_802_11_LENGTH_RATES_EX
);
939 /* get supported rates */
940 p
= rtw_get_ie(ie
+ _BEACON_IE_OFFSET_
, _SUPPORTEDRATES_IE_
, &ie_len
, (pbss_network
->IELength
- _BEACON_IE_OFFSET_
));
942 memcpy(supportRate
, p
+2, ie_len
);
943 supportRateNum
= ie_len
;
946 /* get ext_supported rates */
947 p
= rtw_get_ie(ie
+ _BEACON_IE_OFFSET_
, _EXT_SUPPORTEDRATES_IE_
, &ie_len
, pbss_network
->IELength
- _BEACON_IE_OFFSET_
);
949 memcpy(supportRate
+supportRateNum
, p
+2, ie_len
);
950 supportRateNum
+= ie_len
;
953 network_type
= rtw_check_network_type(supportRate
, supportRateNum
, channel
);
955 rtw_set_supported_rate(pbss_network
->SupportedRates
, network_type
);
958 p
= rtw_get_ie(ie
+ _BEACON_IE_OFFSET_
, _ERPINFO_IE_
, &ie_len
, (pbss_network
->IELength
- _BEACON_IE_OFFSET_
));
960 ERP_IE_handler(padapter
, (struct ndis_802_11_var_ie
*)p
);
962 /* update privacy/security */
964 pbss_network
->Privacy
= 1;
966 pbss_network
->Privacy
= 0;
968 psecuritypriv
->wpa_psk
= 0;
973 psecuritypriv
->wpa2_group_cipher
= _NO_PRIVACY_
;
974 psecuritypriv
->wpa2_pairwise_cipher
= _NO_PRIVACY_
;
975 p
= rtw_get_ie(ie
+ _BEACON_IE_OFFSET_
, _RSN_IE_2_
, &ie_len
, (pbss_network
->IELength
- _BEACON_IE_OFFSET_
));
976 if (p
&& ie_len
> 0) {
977 if (rtw_parse_wpa2_ie(p
, ie_len
+2, &group_cipher
, &pairwise_cipher
, NULL
) == _SUCCESS
) {
978 psecuritypriv
->dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
;
980 psecuritypriv
->dot8021xalg
= 1;/* psk, todo:802.1x */
981 psecuritypriv
->wpa_psk
|= BIT(1);
983 psecuritypriv
->wpa2_group_cipher
= group_cipher
;
984 psecuritypriv
->wpa2_pairwise_cipher
= pairwise_cipher
;
991 psecuritypriv
->wpa_group_cipher
= _NO_PRIVACY_
;
992 psecuritypriv
->wpa_pairwise_cipher
= _NO_PRIVACY_
;
993 for (p
= ie
+ _BEACON_IE_OFFSET_
;; p
+= (ie_len
+ 2)) {
994 p
= rtw_get_ie(p
, _SSN_IE_1_
, &ie_len
,
995 (pbss_network
->IELength
- _BEACON_IE_OFFSET_
- (ie_len
+ 2)));
996 if ((p
) && (!memcmp(p
+2, OUI1
, 4))) {
997 if (rtw_parse_wpa_ie(p
, ie_len
+2, &group_cipher
,
998 &pairwise_cipher
, NULL
) == _SUCCESS
) {
999 psecuritypriv
->dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
;
1001 psecuritypriv
->dot8021xalg
= 1;/* psk, todo:802.1x */
1003 psecuritypriv
->wpa_psk
|= BIT(0);
1005 psecuritypriv
->wpa_group_cipher
= group_cipher
;
1006 psecuritypriv
->wpa_pairwise_cipher
= pairwise_cipher
;
1010 if ((p
== NULL
) || (ie_len
== 0))
1016 pmlmepriv
->qospriv
.qos_option
= 0;
1017 if (pregistrypriv
->wmm_enable
) {
1018 for (p
= ie
+ _BEACON_IE_OFFSET_
;; p
+= (ie_len
+ 2)) {
1019 p
= rtw_get_ie(p
, _VENDOR_SPECIFIC_IE_
, &ie_len
,
1020 (pbss_network
->IELength
- _BEACON_IE_OFFSET_
- (ie_len
+ 2)));
1021 if ((p
) && !memcmp(p
+2, WMM_PARA_IE
, 6)) {
1022 pmlmepriv
->qospriv
.qos_option
= 1;
1024 *(p
+8) |= BIT(7);/* QoS Info, support U-APSD */
1026 /* disable all ACM bits since the WMM admission control is not supported */
1027 *(p
+ 10) &= ~BIT(4); /* BE */
1028 *(p
+ 14) &= ~BIT(4); /* BK */
1029 *(p
+ 18) &= ~BIT(4); /* VI */
1030 *(p
+ 22) &= ~BIT(4); /* VO */
1034 if ((p
== NULL
) || (ie_len
== 0))
1038 /* parsing HT_CAP_IE */
1039 p
= rtw_get_ie(ie
+ _BEACON_IE_OFFSET_
, _HT_CAPABILITY_IE_
, &ie_len
,
1040 (pbss_network
->IELength
- _BEACON_IE_OFFSET_
));
1041 if (p
&& ie_len
> 0) {
1043 struct rtw_ieee80211_ht_cap
*pht_cap
= (struct rtw_ieee80211_ht_cap
*)(p
+2);
1047 network_type
|= WIRELESS_11_24N
;
1049 rtw_hal_get_hwreg(padapter
, HW_VAR_RF_TYPE
, (u8
*)(&rf_type
));
1051 if ((psecuritypriv
->wpa_pairwise_cipher
& WPA_CIPHER_CCMP
) ||
1052 (psecuritypriv
->wpa2_pairwise_cipher
& WPA_CIPHER_CCMP
))
1053 pht_cap
->ampdu_params_info
|= (IEEE80211_HT_CAP_AMPDU_DENSITY
&(0x07<<2));
1055 pht_cap
->ampdu_params_info
|= (IEEE80211_HT_CAP_AMPDU_DENSITY
&0x00);
1057 /* set Max Rx AMPDU size to 64K */
1058 pht_cap
->ampdu_params_info
|= (IEEE80211_HT_CAP_AMPDU_FACTOR
& 0x03);
1060 if (rf_type
== RF_1T1R
) {
1061 pht_cap
->supp_mcs_set
[0] = 0xff;
1062 pht_cap
->supp_mcs_set
[1] = 0x0;
1064 memcpy(&pmlmepriv
->htpriv
.ht_cap
, p
+2, ie_len
);
1067 /* parsing HT_INFO_IE */
1068 p
= rtw_get_ie(ie
+ _BEACON_IE_OFFSET_
, _HT_ADD_INFO_IE_
, &ie_len
,
1069 (pbss_network
->IELength
- _BEACON_IE_OFFSET_
));
1070 if (p
&& ie_len
> 0)
1072 switch (network_type
) {
1074 pbss_network
->NetworkTypeInUse
= Ndis802_11DS
;
1078 case WIRELESS_11G_24N
:
1079 case WIRELESS_11BG_24N
:
1080 pbss_network
->NetworkTypeInUse
= Ndis802_11OFDM24
;
1083 pbss_network
->NetworkTypeInUse
= Ndis802_11OFDM5
;
1086 pbss_network
->NetworkTypeInUse
= Ndis802_11OFDM24
;
1090 pmlmepriv
->cur_network
.network_type
= network_type
;
1092 pmlmepriv
->htpriv
.ht_option
= false;
1094 if ((psecuritypriv
->wpa2_pairwise_cipher
& WPA_CIPHER_TKIP
) ||
1095 (psecuritypriv
->wpa_pairwise_cipher
& WPA_CIPHER_TKIP
)) {
1097 /* ht_cap = false; */
1101 if (pregistrypriv
->ht_enable
&& ht_cap
) {
1102 pmlmepriv
->htpriv
.ht_option
= true;
1103 pmlmepriv
->qospriv
.qos_option
= 1;
1105 if (pregistrypriv
->ampdu_enable
== 1)
1106 pmlmepriv
->htpriv
.ampdu_enable
= true;
1107 HT_caps_handler(padapter
, (struct ndis_802_11_var_ie
*)pHT_caps_ie
);
1109 HT_info_handler(padapter
, (struct ndis_802_11_var_ie
*)pHT_info_ie
);
1112 pbss_network
->Length
= get_wlan_bssid_ex_sz((struct wlan_bssid_ex
*)pbss_network
);
1114 /* issue beacon to start bss network */
1115 start_bss_network(padapter
, (u8
*)pbss_network
);
1117 /* alloc sta_info for ap itself */
1118 psta
= rtw_get_stainfo(&padapter
->stapriv
, pbss_network
->MacAddress
);
1120 psta
= rtw_alloc_stainfo(&padapter
->stapriv
, pbss_network
->MacAddress
);
1125 /* fix bug of flush_cam_entry at STOP AP mode */
1126 psta
->state
|= WIFI_AP_STATE
;
1127 rtw_indicate_connect(padapter
);
1128 pmlmepriv
->cur_network
.join_res
= true;/* for check if already set beacon */
1132 void rtw_set_macaddr_acl(struct adapter
*padapter
, int mode
)
1134 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1135 struct wlan_acl_pool
*pacl_list
= &pstapriv
->acl_list
;
1137 DBG_88E("%s, mode =%d\n", __func__
, mode
);
1139 pacl_list
->mode
= mode
;
1142 int rtw_acl_add_sta(struct adapter
*padapter
, u8
*addr
)
1144 struct list_head
*plist
, *phead
;
1147 struct rtw_wlan_acl_node
*paclnode
;
1148 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1149 struct wlan_acl_pool
*pacl_list
= &pstapriv
->acl_list
;
1150 struct __queue
*pacl_node_q
= &pacl_list
->acl_node_q
;
1152 DBG_88E("%s(acl_num =%d) =%pM\n", __func__
, pacl_list
->num
, (addr
));
1154 if ((NUM_ACL
-1) < pacl_list
->num
)
1157 spin_lock_bh(&(pacl_node_q
->lock
));
1159 phead
= get_list_head(pacl_node_q
);
1160 plist
= phead
->next
;
1162 while (phead
!= plist
) {
1163 paclnode
= container_of(plist
, struct rtw_wlan_acl_node
, list
);
1164 plist
= plist
->next
;
1166 if (!memcmp(paclnode
->addr
, addr
, ETH_ALEN
)) {
1167 if (paclnode
->valid
) {
1169 DBG_88E("%s, sta has been added\n", __func__
);
1175 spin_unlock_bh(&(pacl_node_q
->lock
));
1180 spin_lock_bh(&(pacl_node_q
->lock
));
1182 for (i
= 0; i
< NUM_ACL
; i
++) {
1183 paclnode
= &pacl_list
->aclnode
[i
];
1185 if (!paclnode
->valid
) {
1186 INIT_LIST_HEAD(&paclnode
->list
);
1188 ether_addr_copy(paclnode
->addr
, addr
);
1190 paclnode
->valid
= true;
1192 list_add_tail(&paclnode
->list
, get_list_head(pacl_node_q
));
1200 DBG_88E("%s, acl_num =%d\n", __func__
, pacl_list
->num
);
1202 spin_unlock_bh(&(pacl_node_q
->lock
));
1207 int rtw_acl_remove_sta(struct adapter
*padapter
, u8
*addr
)
1209 struct list_head
*plist
, *phead
;
1210 struct rtw_wlan_acl_node
*paclnode
;
1211 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1212 struct wlan_acl_pool
*pacl_list
= &pstapriv
->acl_list
;
1213 struct __queue
*pacl_node_q
= &pacl_list
->acl_node_q
;
1215 DBG_88E("%s(acl_num =%d) =%pM\n", __func__
, pacl_list
->num
, (addr
));
1217 spin_lock_bh(&(pacl_node_q
->lock
));
1219 phead
= get_list_head(pacl_node_q
);
1220 plist
= phead
->next
;
1222 while (phead
!= plist
) {
1223 paclnode
= container_of(plist
, struct rtw_wlan_acl_node
, list
);
1224 plist
= plist
->next
;
1226 if (!memcmp(paclnode
->addr
, addr
, ETH_ALEN
)) {
1227 if (paclnode
->valid
) {
1228 paclnode
->valid
= false;
1230 list_del_init(&paclnode
->list
);
1237 spin_unlock_bh(&(pacl_node_q
->lock
));
1239 DBG_88E("%s, acl_num =%d\n", __func__
, pacl_list
->num
);
1243 static void update_bcn_erpinfo_ie(struct adapter
*padapter
)
1245 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1246 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1247 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1248 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
1249 unsigned char *p
, *ie
= pnetwork
->IEs
;
1252 DBG_88E("%s, ERP_enable =%d\n", __func__
, pmlmeinfo
->ERP_enable
);
1254 if (!pmlmeinfo
->ERP_enable
)
1257 /* parsing ERP_IE */
1258 p
= rtw_get_ie(ie
+ _BEACON_IE_OFFSET_
, _ERPINFO_IE_
, &len
,
1259 (pnetwork
->IELength
- _BEACON_IE_OFFSET_
));
1261 struct ndis_802_11_var_ie
*pIE
= (struct ndis_802_11_var_ie
*)p
;
1263 if (pmlmepriv
->num_sta_non_erp
== 1)
1264 pIE
->data
[0] |= RTW_ERP_INFO_NON_ERP_PRESENT
|RTW_ERP_INFO_USE_PROTECTION
;
1266 pIE
->data
[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT
|RTW_ERP_INFO_USE_PROTECTION
);
1268 if (pmlmepriv
->num_sta_no_short_preamble
> 0)
1269 pIE
->data
[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE
;
1271 pIE
->data
[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE
);
1273 ERP_IE_handler(padapter
, pIE
);
1277 static void update_bcn_wps_ie(struct adapter
*padapter
)
1279 u8
*pwps_ie
= NULL
, *pwps_ie_src
;
1280 u8
*premainder_ie
, *pbackup_remainder_ie
= NULL
;
1281 uint wps_ielen
= 0, wps_offset
, remainder_ielen
;
1282 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1283 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1284 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1285 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
1286 unsigned char *ie
= pnetwork
->IEs
;
1287 u32 ielen
= pnetwork
->IELength
;
1289 DBG_88E("%s\n", __func__
);
1291 pwps_ie_src
= pmlmepriv
->wps_beacon_ie
;
1292 if (pwps_ie_src
== NULL
)
1295 pwps_ie
= rtw_get_wps_ie(ie
+_FIXED_IE_LENGTH_
, ielen
-_FIXED_IE_LENGTH_
, NULL
, &wps_ielen
);
1297 if (pwps_ie
== NULL
|| wps_ielen
== 0)
1300 wps_offset
= (uint
)(pwps_ie
-ie
);
1302 premainder_ie
= pwps_ie
+ wps_ielen
;
1304 remainder_ielen
= ielen
- wps_offset
- wps_ielen
;
1306 if (remainder_ielen
> 0) {
1307 pbackup_remainder_ie
= rtw_malloc(remainder_ielen
);
1308 if (pbackup_remainder_ie
)
1309 memcpy(pbackup_remainder_ie
, premainder_ie
, remainder_ielen
);
1312 wps_ielen
= (uint
)pwps_ie_src
[1];/* to get ie data len */
1313 if ((wps_offset
+wps_ielen
+2+remainder_ielen
) <= MAX_IE_SZ
) {
1314 memcpy(pwps_ie
, pwps_ie_src
, wps_ielen
+2);
1315 pwps_ie
+= (wps_ielen
+2);
1317 if (pbackup_remainder_ie
)
1318 memcpy(pwps_ie
, pbackup_remainder_ie
, remainder_ielen
);
1320 /* update IELength */
1321 pnetwork
->IELength
= wps_offset
+ (wps_ielen
+2) + remainder_ielen
;
1324 kfree(pbackup_remainder_ie
);
1327 static void update_bcn_vendor_spec_ie(struct adapter
*padapter
, u8
*oui
)
1329 DBG_88E("%s\n", __func__
);
1331 if (!memcmp(WPS_OUI
, oui
, 4))
1332 update_bcn_wps_ie(padapter
);
1334 DBG_88E("unknown OUI type!\n");
1337 void update_beacon(struct adapter
*padapter
, u8 ie_id
, u8
*oui
, u8 tx
)
1339 struct mlme_priv
*pmlmepriv
;
1340 struct mlme_ext_priv
*pmlmeext
;
1345 pmlmepriv
= &(padapter
->mlmepriv
);
1346 pmlmeext
= &(padapter
->mlmeextpriv
);
1348 if (!pmlmeext
->bstart_bss
)
1351 spin_lock_bh(&pmlmepriv
->bcn_update_lock
);
1355 update_BCNTIM(padapter
);
1358 update_bcn_erpinfo_ie(padapter
);
1360 case _VENDOR_SPECIFIC_IE_
:
1361 update_bcn_vendor_spec_ie(padapter
, oui
);
1367 pmlmepriv
->update_bcn
= true;
1369 spin_unlock_bh(&pmlmepriv
->bcn_update_lock
);
1372 set_tx_beacon_cmd(padapter
);
1377 Set to 0 (HT pure) under the following conditions
1378 - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
1379 - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
1380 Set to 1 (HT non-member protection) if there may be non-HT STAs
1381 in both the primary and the secondary channel
1382 Set to 2 if only HT STAs are associated in BSS,
1383 however and at least one 20 MHz HT STA is associated
1384 Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
1385 (currently non-GF HT station is considered as non-HT STA also)
1387 static int rtw_ht_operation_update(struct adapter
*padapter
)
1389 u16 cur_op_mode
, new_op_mode
;
1390 int op_mode_changes
= 0;
1391 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1392 struct ht_priv
*phtpriv_ap
= &pmlmepriv
->htpriv
;
1394 if (pmlmepriv
->htpriv
.ht_option
)
1397 DBG_88E("%s current operation mode = 0x%X\n",
1398 __func__
, pmlmepriv
->ht_op_mode
);
1400 if (!(pmlmepriv
->ht_op_mode
& HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
) &&
1401 pmlmepriv
->num_sta_ht_no_gf
) {
1402 pmlmepriv
->ht_op_mode
|=
1403 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
;
1405 } else if ((pmlmepriv
->ht_op_mode
&
1406 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
) &&
1407 pmlmepriv
->num_sta_ht_no_gf
== 0) {
1408 pmlmepriv
->ht_op_mode
&=
1409 ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
;
1413 if (!(pmlmepriv
->ht_op_mode
& HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT
) &&
1414 (pmlmepriv
->num_sta_no_ht
|| pmlmepriv
->olbc_ht
)) {
1415 pmlmepriv
->ht_op_mode
|= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT
;
1417 } else if ((pmlmepriv
->ht_op_mode
&
1418 HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT
) &&
1419 (pmlmepriv
->num_sta_no_ht
== 0 && !pmlmepriv
->olbc_ht
)) {
1420 pmlmepriv
->ht_op_mode
&=
1421 ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT
;
1425 /* Note: currently we switch to the MIXED op mode if HT non-greenfield
1426 * station is associated. Probably it's a theoretical case, since
1427 * it looks like all known HT STAs support greenfield.
1430 if (pmlmepriv
->num_sta_no_ht
||
1431 (pmlmepriv
->ht_op_mode
& HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
))
1432 new_op_mode
= OP_MODE_MIXED
;
1433 else if ((phtpriv_ap
->ht_cap
.cap_info
& IEEE80211_HT_CAP_SUP_WIDTH
) &&
1434 pmlmepriv
->num_sta_ht_20mhz
)
1435 new_op_mode
= OP_MODE_20MHZ_HT_STA_ASSOCED
;
1436 else if (pmlmepriv
->olbc_ht
)
1437 new_op_mode
= OP_MODE_MAY_BE_LEGACY_STAS
;
1439 new_op_mode
= OP_MODE_PURE
;
1441 cur_op_mode
= pmlmepriv
->ht_op_mode
& HT_INFO_OPERATION_MODE_OP_MODE_MASK
;
1442 if (cur_op_mode
!= new_op_mode
) {
1443 pmlmepriv
->ht_op_mode
&= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK
;
1444 pmlmepriv
->ht_op_mode
|= new_op_mode
;
1448 DBG_88E("%s new operation mode = 0x%X changes =%d\n",
1449 __func__
, pmlmepriv
->ht_op_mode
, op_mode_changes
);
1451 return op_mode_changes
;
1454 void associated_clients_update(struct adapter
*padapter
, u8 updated
)
1456 /* update associated stations cap. */
1458 struct list_head
*phead
, *plist
;
1459 struct sta_info
*psta
= NULL
;
1460 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1462 spin_lock_bh(&pstapriv
->asoc_list_lock
);
1464 phead
= &pstapriv
->asoc_list
;
1465 plist
= phead
->next
;
1467 /* check asoc_queue */
1468 while (phead
!= plist
) {
1469 psta
= container_of(plist
, struct sta_info
, asoc_list
);
1471 plist
= plist
->next
;
1473 VCS_update(padapter
, psta
);
1475 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
1479 /* called > TSR LEVEL for USB or SDIO Interface*/
1480 void bss_cap_update_on_sta_join(struct adapter
*padapter
, struct sta_info
*psta
)
1482 u8 beacon_updated
= false;
1483 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1484 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1486 if (!(psta
->flags
& WLAN_STA_SHORT_PREAMBLE
)) {
1487 if (!psta
->no_short_preamble_set
) {
1488 psta
->no_short_preamble_set
= 1;
1490 pmlmepriv
->num_sta_no_short_preamble
++;
1492 if ((pmlmeext
->cur_wireless_mode
> WIRELESS_11B
) &&
1493 (pmlmepriv
->num_sta_no_short_preamble
== 1)) {
1494 beacon_updated
= true;
1495 update_beacon(padapter
, 0xFF, NULL
, true);
1499 if (psta
->no_short_preamble_set
) {
1500 psta
->no_short_preamble_set
= 0;
1502 pmlmepriv
->num_sta_no_short_preamble
--;
1504 if ((pmlmeext
->cur_wireless_mode
> WIRELESS_11B
) &&
1505 (pmlmepriv
->num_sta_no_short_preamble
== 0)) {
1506 beacon_updated
= true;
1507 update_beacon(padapter
, 0xFF, NULL
, true);
1512 if (psta
->flags
& WLAN_STA_NONERP
) {
1513 if (!psta
->nonerp_set
) {
1514 psta
->nonerp_set
= 1;
1516 pmlmepriv
->num_sta_non_erp
++;
1518 if (pmlmepriv
->num_sta_non_erp
== 1) {
1519 beacon_updated
= true;
1520 update_beacon(padapter
, _ERPINFO_IE_
, NULL
, true);
1524 if (psta
->nonerp_set
) {
1525 psta
->nonerp_set
= 0;
1527 pmlmepriv
->num_sta_non_erp
--;
1529 if (pmlmepriv
->num_sta_non_erp
== 0) {
1530 beacon_updated
= true;
1531 update_beacon(padapter
, _ERPINFO_IE_
, NULL
, true);
1536 if (!(psta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
)) {
1537 if (!psta
->no_short_slot_time_set
) {
1538 psta
->no_short_slot_time_set
= 1;
1540 pmlmepriv
->num_sta_no_short_slot_time
++;
1542 if ((pmlmeext
->cur_wireless_mode
> WIRELESS_11B
) &&
1543 (pmlmepriv
->num_sta_no_short_slot_time
== 1)) {
1544 beacon_updated
= true;
1545 update_beacon(padapter
, 0xFF, NULL
, true);
1549 if (psta
->no_short_slot_time_set
) {
1550 psta
->no_short_slot_time_set
= 0;
1552 pmlmepriv
->num_sta_no_short_slot_time
--;
1554 if ((pmlmeext
->cur_wireless_mode
> WIRELESS_11B
) &&
1555 (pmlmepriv
->num_sta_no_short_slot_time
== 0)) {
1556 beacon_updated
= true;
1557 update_beacon(padapter
, 0xFF, NULL
, true);
1562 if (psta
->flags
& WLAN_STA_HT
) {
1563 u16 ht_capab
= psta
->htpriv
.ht_cap
.cap_info
;
1565 DBG_88E("HT: STA %pM HT Capabilities Info: 0x%04x\n",
1566 (psta
->hwaddr
), ht_capab
);
1568 if (psta
->no_ht_set
) {
1569 psta
->no_ht_set
= 0;
1570 pmlmepriv
->num_sta_no_ht
--;
1573 if ((ht_capab
& IEEE80211_HT_CAP_GRN_FLD
) == 0) {
1574 if (!psta
->no_ht_gf_set
) {
1575 psta
->no_ht_gf_set
= 1;
1576 pmlmepriv
->num_sta_ht_no_gf
++;
1578 DBG_88E("%s STA %pM - no greenfield, num of non-gf stations %d\n",
1579 __func__
, (psta
->hwaddr
),
1580 pmlmepriv
->num_sta_ht_no_gf
);
1583 if ((ht_capab
& IEEE80211_HT_CAP_SUP_WIDTH
) == 0) {
1584 if (!psta
->ht_20mhz_set
) {
1585 psta
->ht_20mhz_set
= 1;
1586 pmlmepriv
->num_sta_ht_20mhz
++;
1588 DBG_88E("%s STA %pM - 20 MHz HT, num of 20MHz HT STAs %d\n",
1589 __func__
, (psta
->hwaddr
),
1590 pmlmepriv
->num_sta_ht_20mhz
);
1593 if (!psta
->no_ht_set
) {
1594 psta
->no_ht_set
= 1;
1595 pmlmepriv
->num_sta_no_ht
++;
1597 if (pmlmepriv
->htpriv
.ht_option
) {
1598 DBG_88E("%s STA %pM - no HT, num of non-HT stations %d\n",
1599 __func__
, (psta
->hwaddr
),
1600 pmlmepriv
->num_sta_no_ht
);
1604 if (rtw_ht_operation_update(padapter
) > 0) {
1605 update_beacon(padapter
, _HT_CAPABILITY_IE_
, NULL
, false);
1606 update_beacon(padapter
, _HT_ADD_INFO_IE_
, NULL
, true);
1609 /* update associated stations cap. */
1610 associated_clients_update(padapter
, beacon_updated
);
1612 DBG_88E("%s, updated =%d\n", __func__
, beacon_updated
);
1615 u8
bss_cap_update_on_sta_leave(struct adapter
*padapter
, struct sta_info
*psta
)
1617 u8 beacon_updated
= false;
1618 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1619 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1622 return beacon_updated
;
1624 if (psta
->no_short_preamble_set
) {
1625 psta
->no_short_preamble_set
= 0;
1626 pmlmepriv
->num_sta_no_short_preamble
--;
1627 if (pmlmeext
->cur_wireless_mode
> WIRELESS_11B
&&
1628 pmlmepriv
->num_sta_no_short_preamble
== 0) {
1629 beacon_updated
= true;
1630 update_beacon(padapter
, 0xFF, NULL
, true);
1634 if (psta
->nonerp_set
) {
1635 psta
->nonerp_set
= 0;
1636 pmlmepriv
->num_sta_non_erp
--;
1637 if (pmlmepriv
->num_sta_non_erp
== 0) {
1638 beacon_updated
= true;
1639 update_beacon(padapter
, _ERPINFO_IE_
, NULL
, true);
1643 if (psta
->no_short_slot_time_set
) {
1644 psta
->no_short_slot_time_set
= 0;
1645 pmlmepriv
->num_sta_no_short_slot_time
--;
1646 if (pmlmeext
->cur_wireless_mode
> WIRELESS_11B
&&
1647 pmlmepriv
->num_sta_no_short_slot_time
== 0) {
1648 beacon_updated
= true;
1649 update_beacon(padapter
, 0xFF, NULL
, true);
1653 if (psta
->no_ht_gf_set
) {
1654 psta
->no_ht_gf_set
= 0;
1655 pmlmepriv
->num_sta_ht_no_gf
--;
1658 if (psta
->no_ht_set
) {
1659 psta
->no_ht_set
= 0;
1660 pmlmepriv
->num_sta_no_ht
--;
1663 if (psta
->ht_20mhz_set
) {
1664 psta
->ht_20mhz_set
= 0;
1665 pmlmepriv
->num_sta_ht_20mhz
--;
1668 if (rtw_ht_operation_update(padapter
) > 0) {
1669 update_beacon(padapter
, _HT_CAPABILITY_IE_
, NULL
, false);
1670 update_beacon(padapter
, _HT_ADD_INFO_IE_
, NULL
, true);
1673 /* update associated stations cap. */
1675 DBG_88E("%s, updated =%d\n", __func__
, beacon_updated
);
1677 return beacon_updated
;
1680 u8
ap_free_sta(struct adapter
*padapter
, struct sta_info
*psta
,
1681 bool active
, u16 reason
)
1683 u8 beacon_updated
= false;
1684 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1687 return beacon_updated
;
1689 /* tear down Rx AMPDU */
1690 send_delba(padapter
, 0, psta
->hwaddr
);/* recipient */
1692 /* tear down TX AMPDU */
1693 send_delba(padapter
, 1, psta
->hwaddr
);/* originator */
1694 psta
->htpriv
.agg_enable_bitmap
= 0x0;/* reset */
1695 psta
->htpriv
.candidate_tid_bitmap
= 0x0;/* reset */
1698 issue_deauth(padapter
, psta
->hwaddr
, reason
);
1700 /* clear cam entry / key */
1701 rtw_clearstakey_cmd(padapter
, (u8
*)psta
, (u8
)(psta
->mac_id
+ 3), true);
1704 spin_lock_bh(&psta
->lock
);
1705 psta
->state
&= ~_FW_LINKED
;
1706 spin_unlock_bh(&psta
->lock
);
1708 rtw_indicate_sta_disassoc_event(padapter
, psta
);
1710 report_del_sta_event(padapter
, psta
->hwaddr
, reason
);
1712 beacon_updated
= bss_cap_update_on_sta_leave(padapter
, psta
);
1714 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
1715 rtw_free_stainfo(padapter
, psta
);
1716 spin_unlock_bh(&(pstapriv
->sta_hash_lock
));
1718 return beacon_updated
;
1721 int rtw_ap_inform_ch_switch(struct adapter
*padapter
, u8 new_ch
, u8 ch_offset
)
1723 struct list_head
*phead
, *plist
;
1724 struct sta_info
*psta
= NULL
;
1725 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1726 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1727 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1728 u8 bc_addr
[ETH_ALEN
] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1730 if ((pmlmeinfo
->state
&0x03) != WIFI_FW_AP_STATE
)
1733 DBG_88E(FUNC_NDEV_FMT
" with ch:%u, offset:%u\n",
1734 FUNC_NDEV_ARG(padapter
->pnetdev
), new_ch
, ch_offset
);
1736 spin_lock_bh(&pstapriv
->asoc_list_lock
);
1737 phead
= &pstapriv
->asoc_list
;
1738 plist
= phead
->next
;
1740 /* for each sta in asoc_queue */
1741 while (phead
!= plist
) {
1742 psta
= container_of(plist
, struct sta_info
, asoc_list
);
1743 plist
= plist
->next
;
1745 issue_action_spct_ch_switch(padapter
, psta
->hwaddr
, new_ch
, ch_offset
);
1746 psta
->expire_to
= min_t(unsigned int, pstapriv
->expire_to
* 2, 5);
1748 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
1750 issue_action_spct_ch_switch(padapter
, bc_addr
, new_ch
, ch_offset
);
1755 int rtw_sta_flush(struct adapter
*padapter
)
1757 struct list_head
*phead
, *plist
;
1758 struct sta_info
*psta
= NULL
;
1759 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1760 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1761 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1762 u8 bc_addr
[ETH_ALEN
] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1764 DBG_88E(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(padapter
->pnetdev
));
1766 if ((pmlmeinfo
->state
&0x03) != WIFI_FW_AP_STATE
)
1769 spin_lock_bh(&pstapriv
->asoc_list_lock
);
1770 phead
= &pstapriv
->asoc_list
;
1771 plist
= phead
->next
;
1773 /* free sta asoc_queue */
1774 while (phead
!= plist
) {
1775 psta
= container_of(plist
, struct sta_info
, asoc_list
);
1777 plist
= plist
->next
;
1779 list_del_init(&psta
->asoc_list
);
1780 pstapriv
->asoc_list_cnt
--;
1782 ap_free_sta(padapter
, psta
, true, WLAN_REASON_DEAUTH_LEAVING
);
1784 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
1787 issue_deauth(padapter
, bc_addr
, WLAN_REASON_DEAUTH_LEAVING
);
1789 associated_clients_update(padapter
, true);
1794 /* called > TSR LEVEL for USB or SDIO Interface*/
1795 void sta_info_update(struct adapter
*padapter
, struct sta_info
*psta
)
1797 int flags
= psta
->flags
;
1798 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1800 /* update wmm cap. */
1801 if (WLAN_STA_WME
&flags
)
1802 psta
->qos_option
= 1;
1804 psta
->qos_option
= 0;
1806 if (pmlmepriv
->qospriv
.qos_option
== 0)
1807 psta
->qos_option
= 0;
1809 /* update 802.11n ht cap. */
1810 if (WLAN_STA_HT
&flags
) {
1811 psta
->htpriv
.ht_option
= true;
1812 psta
->qos_option
= 1;
1814 psta
->htpriv
.ht_option
= false;
1817 if (!pmlmepriv
->htpriv
.ht_option
)
1818 psta
->htpriv
.ht_option
= false;
1820 update_sta_info_apmode(padapter
, psta
);
1823 /* called >= TSR LEVEL for USB or SDIO Interface*/
1824 void ap_sta_info_defer_update(struct adapter
*padapter
, struct sta_info
*psta
)
1826 if (psta
->state
& _FW_LINKED
) {
1828 add_RATid(padapter
, psta
, 0);/* DM_RATR_STA_INIT */
1832 void start_ap_mode(struct adapter
*padapter
)
1835 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1836 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1837 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1838 struct wlan_acl_pool
*pacl_list
= &pstapriv
->acl_list
;
1840 pmlmepriv
->update_bcn
= false;
1842 pmlmeext
->bstart_bss
= false;
1844 pmlmepriv
->num_sta_non_erp
= 0;
1846 pmlmepriv
->num_sta_no_short_slot_time
= 0;
1848 pmlmepriv
->num_sta_no_short_preamble
= 0;
1850 pmlmepriv
->num_sta_ht_no_gf
= 0;
1851 pmlmepriv
->num_sta_no_ht
= 0;
1852 pmlmepriv
->num_sta_ht_20mhz
= 0;
1854 pmlmepriv
->olbc
= false;
1856 pmlmepriv
->olbc_ht
= false;
1858 pmlmepriv
->ht_op_mode
= 0;
1860 for (i
= 0; i
< NUM_STA
; i
++)
1861 pstapriv
->sta_aid
[i
] = NULL
;
1863 pmlmepriv
->wps_beacon_ie
= NULL
;
1864 pmlmepriv
->wps_probe_resp_ie
= NULL
;
1865 pmlmepriv
->wps_assoc_resp_ie
= NULL
;
1867 pmlmepriv
->p2p_beacon_ie
= NULL
;
1868 pmlmepriv
->p2p_probe_resp_ie
= NULL
;
1871 INIT_LIST_HEAD(&(pacl_list
->acl_node_q
.queue
));
1873 pacl_list
->mode
= 0;
1874 for (i
= 0; i
< NUM_ACL
; i
++) {
1875 INIT_LIST_HEAD(&pacl_list
->aclnode
[i
].list
);
1876 pacl_list
->aclnode
[i
].valid
= false;
1880 void stop_ap_mode(struct adapter
*padapter
)
1882 struct list_head
*phead
, *plist
;
1883 struct rtw_wlan_acl_node
*paclnode
;
1884 struct sta_info
*psta
= NULL
;
1885 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1886 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1887 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1888 struct wlan_acl_pool
*pacl_list
= &pstapriv
->acl_list
;
1889 struct __queue
*pacl_node_q
= &pacl_list
->acl_node_q
;
1891 pmlmepriv
->update_bcn
= false;
1892 pmlmeext
->bstart_bss
= false;
1894 /* reset and init security priv , this can refine with rtw_reset_securitypriv */
1895 memset((unsigned char *)&padapter
->securitypriv
, 0, sizeof(struct security_priv
));
1896 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeOpen
;
1897 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11WEPDisabled
;
1900 spin_lock_bh(&(pacl_node_q
->lock
));
1901 phead
= get_list_head(pacl_node_q
);
1902 plist
= phead
->next
;
1903 while (phead
!= plist
) {
1904 paclnode
= container_of(plist
, struct rtw_wlan_acl_node
, list
);
1905 plist
= plist
->next
;
1907 if (paclnode
->valid
) {
1908 paclnode
->valid
= false;
1910 list_del_init(&paclnode
->list
);
1915 spin_unlock_bh(&(pacl_node_q
->lock
));
1917 DBG_88E("%s, free acl_node_queue, num =%d\n", __func__
, pacl_list
->num
);
1919 rtw_sta_flush(padapter
);
1921 /* free_assoc_sta_resources */
1922 rtw_free_all_stainfo(padapter
);
1924 psta
= rtw_get_bcmc_stainfo(padapter
);
1925 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
1926 rtw_free_stainfo(padapter
, psta
);
1927 spin_unlock_bh(&(pstapriv
->sta_hash_lock
));
1929 rtw_init_bcmc_stainfo(padapter
);
1931 rtw_free_mlme_priv_ie_data(pmlmepriv
);
1934 #endif /* CONFIG_88EU_AP_MODE */