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 ******************************************************************************/
23 #include <osdep_service.h>
24 #include <drv_types.h>
29 extern unsigned char RTW_WPA_OUI[];
30 extern unsigned char WMM_OUI[];
31 extern unsigned char WPS_OUI[];
32 extern unsigned char P2P_OUI[];
33 extern unsigned char WFD_OUI[];
35 void init_mlme_ap_info(_adapter *padapter)
37 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
38 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
39 struct sta_priv *pstapriv = &padapter->stapriv;
40 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
42 spin_lock_init(&pmlmepriv->bcn_update_lock);
45 _rtw_init_queue(&pacl_list->acl_node_q);
47 start_ap_mode(padapter);
50 void free_mlme_ap_info(_adapter *padapter)
53 struct sta_info *psta=NULL;
54 struct sta_priv *pstapriv = &padapter->stapriv;
55 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
56 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
57 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
59 pmlmepriv->update_bcn = _FALSE;
60 pmlmeext->bstart_bss = _FALSE;
62 rtw_sta_flush(padapter);
64 pmlmeinfo->state = _HW_STATE_NOLINK_;
66 /* free_assoc_sta_resources */
67 rtw_free_all_stainfo(padapter);
69 /* free bc/mc sta_info */
70 psta = rtw_get_bcmc_stainfo(padapter);
71 spin_lock_bh(&(pstapriv->sta_hash_lock));
72 rtw_free_stainfo(padapter, psta);
73 spin_unlock_bh(&(pstapriv->sta_hash_lock));
76 static void update_BCNTIM(_adapter *padapter)
78 struct sta_priv *pstapriv = &padapter->stapriv;
79 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
80 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
81 WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);
82 unsigned char *pie = pnetwork_mlmeext->IEs;
83 u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
85 uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
87 tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);
89 p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);
90 if (p != NULL && tim_ielen>0) {
93 premainder_ie = p+tim_ielen;
95 tim_ie_offset = (int)(p -pie);
97 remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen;
99 /* append TIM IE from dst_ie offset */
104 /* calulate head_len */
105 offset = _FIXED_IE_LENGTH_;
107 /* get ssid_ie len */
108 p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SSID_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
112 /* get supported rates len */
113 p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
117 /* DS Parameter Set IE, len=3 */
120 premainder_ie = pie + offset;
122 remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen;
124 /* append TIM IE from offset */
125 dst_ie = pie + offset;
128 if(remainder_ielen>0) {
129 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
130 if(pbackup_remainder_ie && premainder_ie)
131 memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
136 if((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fc))
141 *dst_ie++= tim_ielen;
143 *dst_ie++=0;/* DTIM count */
144 *dst_ie++=1;/* DTIM peroid */
146 if(pstapriv->tim_bitmap&BIT(0))/* for bc/mc frames */
147 *dst_ie++ = BIT(0);/* bitmap ctrl */
152 *dst_ie++ = *(u8*)&tim_bitmap_le;
153 } else if(tim_ielen==5) {
154 memcpy(dst_ie, &tim_bitmap_le, 2);
158 /* copy remainder IE */
159 if(pbackup_remainder_ie) {
160 memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
162 rtw_mfree(pbackup_remainder_ie, remainder_ielen);
165 offset = (uint)(dst_ie - pie);
166 pnetwork_mlmeext->IELength = offset + remainder_ielen;
168 #ifndef CONFIG_INTERRUPT_BASED_TXBCN
169 #if defined(CONFIG_USB_HCI) || defined(CONFIG_GSPI_HCI)
170 set_tx_beacon_cmd(padapter);
172 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
175 void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len)
177 PNDIS_802_11_VARIABLE_IEs pIE;
179 u8 *pie = pnetwork->IEs;
180 u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
181 u32 i, offset, ielen, ie_offset, remainder_ielen = 0;
183 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;)
185 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
187 if (pIE->ElementID > index)
191 else if(pIE->ElementID == index) /* already exist the same IE */
201 i += (pIE->Length + 2);
204 if (p != NULL && ielen>0)
208 premainder_ie = p+ielen;
210 ie_offset = (int)(p -pie);
212 remainder_ielen = pnetwork->IELength - ie_offset - ielen;
220 if(remainder_ielen>0)
222 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
223 if(pbackup_remainder_ie && premainder_ie)
224 memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
230 memcpy(dst_ie, data, len);
233 /* copy remainder IE */
234 if(pbackup_remainder_ie)
236 memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
238 rtw_mfree(pbackup_remainder_ie, remainder_ielen);
241 offset = (uint)(dst_ie - pie);
242 pnetwork->IELength = offset + remainder_ielen;
245 void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index)
247 u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
248 uint offset, ielen, ie_offset, remainder_ielen = 0;
249 u8 *pie = pnetwork->IEs;
251 p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, index, &ielen, pnetwork->IELength - _FIXED_IE_LENGTH_);
252 if (p != NULL && ielen>0)
256 premainder_ie = p+ielen;
258 ie_offset = (int)(p -pie);
260 remainder_ielen = pnetwork->IELength - ie_offset - ielen;
265 if(remainder_ielen>0)
267 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
268 if(pbackup_remainder_ie && premainder_ie)
269 memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
272 /* copy remainder IE */
273 if(pbackup_remainder_ie)
275 memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
277 rtw_mfree(pbackup_remainder_ie, remainder_ielen);
280 offset = (uint)(dst_ie - pie);
281 pnetwork->IELength = offset + remainder_ielen;
284 u8 chk_sta_is_alive(struct sta_info *psta)
287 #ifdef DBG_EXPIRATION_CHK
288 DBG_8723A("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", expire_to:%u, %s%ssq_len:%u\n"
289 , MAC_ARG(psta->hwaddr)
290 , psta->rssi_stat.UndecoratedSmoothedPWDB
291 , STA_RX_PKTS_DIFF_ARG(psta)
293 , psta->state&WIFI_SLEEP_STATE?"PS, ":""
294 , psta->state&WIFI_STA_ALIVE_CHK_STATE?"SAC, ":""
299 if((psta->sta_stats.last_rx_data_pkts + psta->sta_stats.last_rx_ctrl_pkts) != (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts))
302 sta_update_last_rx_pkts(psta);
307 void expire_timeout_chk(_adapter *padapter)
310 _list *phead, *plist;
312 struct sta_info *psta=NULL;
313 struct sta_priv *pstapriv = &padapter->stapriv;
314 u8 chk_alive_num = 0;
315 char chk_alive_list[NUM_STA];
318 spin_lock_bh(&pstapriv->auth_list_lock);
320 phead = &pstapriv->auth_list;
321 plist = get_next(phead);
323 /* check auth_queue */
324 #ifdef DBG_EXPIRATION_CHK
325 if (rtw_end_of_queue_search(phead, plist) == _FALSE) {
326 DBG_8723A(FUNC_NDEV_FMT" auth_list, cnt:%u\n"
327 , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->auth_list_cnt);
330 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
332 psta = LIST_CONTAINOR(plist, struct sta_info, auth_list);
333 plist = get_next(plist);
335 if(psta->expire_to>0)
338 if (psta->expire_to == 0)
340 rtw_list_delete(&psta->auth_list);
341 pstapriv->auth_list_cnt--;
343 DBG_8723A("auth expire %02X%02X%02X%02X%02X%02X\n",
344 psta->hwaddr[0],psta->hwaddr[1],psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5]);
346 spin_unlock_bh(&pstapriv->auth_list_lock);
348 spin_lock_bh(&(pstapriv->sta_hash_lock));
349 rtw_free_stainfo(padapter, psta);
350 spin_unlock_bh(&(pstapriv->sta_hash_lock));
352 spin_lock_bh(&pstapriv->auth_list_lock);
358 spin_unlock_bh(&pstapriv->auth_list_lock);
362 spin_lock_bh(&pstapriv->asoc_list_lock);
364 phead = &pstapriv->asoc_list;
365 plist = get_next(phead);
367 /* check asoc_queue */
368 #ifdef DBG_EXPIRATION_CHK
369 if (rtw_end_of_queue_search(phead, plist) == _FALSE) {
370 DBG_8723A(FUNC_NDEV_FMT" asoc_list, cnt:%u\n"
371 , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->asoc_list_cnt);
374 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
376 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
377 plist = get_next(plist);
379 if (chk_sta_is_alive(psta) || !psta->expire_to) {
380 psta->expire_to = pstapriv->expire_to;
381 psta->keep_alive_trycnt = 0;
382 #ifdef CONFIG_TX_MCAST2UNI
383 psta->under_exist_checking = 0;
384 #endif /* CONFIG_TX_MCAST2UNI */
389 #ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
390 #ifdef CONFIG_TX_MCAST2UNI
391 #ifdef CONFIG_80211N_HT
392 if ( (psta->flags & WLAN_STA_HT) && (psta->htpriv.agg_enable_bitmap || psta->under_exist_checking) ) {
393 /* check sta by delba(addba) for 11n STA */
394 /* ToDo: use CCX report to check for all STAs */
395 if ( psta->expire_to <= (pstapriv->expire_to - 50 ) ) {
396 DBG_8723A("asoc expire by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2);
397 psta->under_exist_checking = 0;
399 } else if ( psta->expire_to <= (pstapriv->expire_to - 3) && (psta->under_exist_checking==0)) {
400 DBG_8723A("asoc check by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2);
401 psta->under_exist_checking = 1;
402 /* tear down TX AMPDU */
403 send_delba(padapter, 1, psta->hwaddr);/* originator */
404 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
405 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
408 #endif /* CONFIG_80211N_HT */
409 #endif /* CONFIG_TX_MCAST2UNI */
410 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
412 if (psta->expire_to <= 0)
414 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
415 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
417 if (padapter->registrypriv.wifi_spec == 1)
419 psta->expire_to = pstapriv->expire_to;
423 if (psta->state & WIFI_SLEEP_STATE) {
424 if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
425 /* to check if alive by another methods if staion is at ps mode. */
426 psta->expire_to = pstapriv->expire_to;
427 psta->state |= WIFI_STA_ALIVE_CHK_STATE;
429 /* to update bcn with tim_bitmap for this station */
430 pstapriv->tim_bitmap |= BIT(psta->aid);
431 update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
433 if(!pmlmeext->active_keep_alive_check)
438 if (pmlmeext->active_keep_alive_check) {
441 stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
442 if (stainfo_offset_valid(stainfo_offset)) {
443 chk_alive_list[chk_alive_num++] = stainfo_offset;
448 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
450 rtw_list_delete(&psta->asoc_list);
451 pstapriv->asoc_list_cnt--;
453 DBG_8723A("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);
454 updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);
458 /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
459 if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt)
460 && padapter->xmitpriv.free_xmitframe_cnt < ((NR_XMITFRAME/pstapriv->asoc_list_cnt)/2)
462 DBG_8723A("%s sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__
463 , MAC_ARG(psta->hwaddr)
464 , psta->sleepq_len, padapter->xmitpriv.free_xmitframe_cnt, pstapriv->asoc_list_cnt);
465 wakeup_sta_to_xmit(padapter, psta);
470 spin_unlock_bh(&pstapriv->asoc_list_lock);
472 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
475 u8 backup_oper_channel=0;
476 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
477 /* switch to correct channel of current network before issue keep-alive frames */
478 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
479 backup_oper_channel = rtw_get_oper_ch(padapter);
480 SelectChannel(padapter, pmlmeext->cur_channel);
483 /* issue null data to check sta alive*/
484 for (i = 0; i < chk_alive_num; i++) {
488 psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
489 if(!(psta->state &_FW_LINKED))
492 if (psta->state & WIFI_SLEEP_STATE)
493 ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50);
495 ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50);
497 psta->keep_alive_trycnt++;
500 DBG_8723A("asoc check, sta(" MAC_FMT ") is alive\n", MAC_ARG(psta->hwaddr));
501 psta->expire_to = pstapriv->expire_to;
502 psta->keep_alive_trycnt = 0;
505 else if (psta->keep_alive_trycnt <= 3)
507 DBG_8723A("ack check for asoc expire, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt);
512 psta->keep_alive_trycnt = 0;
514 DBG_8723A("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);
515 spin_lock_bh(&pstapriv->asoc_list_lock);
516 if (rtw_is_list_empty(&psta->asoc_list)==_FALSE) {
517 rtw_list_delete(&psta->asoc_list);
518 pstapriv->asoc_list_cnt--;
519 updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);
521 spin_unlock_bh(&pstapriv->asoc_list_lock);
525 if (backup_oper_channel>0) /* back to the original operation channel */
526 SelectChannel(padapter, backup_oper_channel);
528 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
530 associated_clients_update(padapter, updated);
533 void add_RATid(_adapter *padapter, struct sta_info *psta, u8 rssi_level)
538 unsigned char sta_band = 0, raid, shortGIrate = _FALSE;
540 unsigned int tx_ra_bitmap=0;
541 struct ht_priv *psta_ht = NULL;
542 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
543 WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
545 #ifdef CONFIG_80211N_HT
547 psta_ht = &psta->htpriv;
550 #endif /* CONFIG_80211N_HT */
552 if(!(psta->state & _FW_LINKED))
555 /* b/g mode ra_bitmap */
556 for (i=0; i<sizeof(psta->bssrateset); i++)
558 if (psta->bssrateset[i])
559 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
561 #ifdef CONFIG_80211N_HT
562 /* n mode ra_bitmap */
563 if(psta_ht->ht_option)
565 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
566 if(rf_type == RF_2T2R)
571 for (i=0; i<limit; i++) {
572 if (psta_ht->ht_cap.supp_mcs_set[i/8] & BIT(i%8))
573 tx_ra_bitmap |= BIT(i+12);
576 /* max short GI rate */
577 shortGIrate = psta_ht->sgi;
579 #endif /* CONFIG_80211N_HT */
581 if ( pcur_network->Configuration.DSConfig > 14 ) {
583 if (tx_ra_bitmap & 0xffff000)
584 sta_band |= WIRELESS_11_5N | WIRELESS_11A;
586 sta_band |= WIRELESS_11A;
588 if (tx_ra_bitmap & 0xffff000)
589 sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
590 else if (tx_ra_bitmap & 0xff0)
591 sta_band |= WIRELESS_11G |WIRELESS_11B;
593 sta_band |= WIRELESS_11B;
596 psta->wireless_mode = sta_band;
598 raid = networktype_to_raid(sta_band);
599 init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f;
601 if (psta->aid < NUM_STA)
605 arg = psta->mac_id&0x1f;
607 arg |= BIT(7);/* support entry 2~31 */
609 if (shortGIrate==_TRUE)
612 tx_ra_bitmap |= ((raid<<28)&0xf0000000);
614 DBG_8723A("%s=> mac_id:%d , raid:%d , bitmap=0x%x, arg=0x%x\n",
615 __FUNCTION__ , psta->mac_id, raid ,tx_ra_bitmap, arg);
617 /* bitmap[0:27] = tx_rate_bitmap */
618 /* bitmap[28:31]= Rate Adaptive id */
619 /* arg[0:4] = macid */
620 /* arg[5] = Short GI */
621 rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level);
623 if (shortGIrate==_TRUE)
626 /* set ra_id, init_rate */
628 psta->init_rate = init_rate;
633 DBG_8723A("station aid %d exceed the max number\n", psta->aid);
637 static void update_bmc_sta(_adapter *padapter)
641 unsigned char network_type, raid;
642 int i, supportRateNum = 0;
643 unsigned int tx_ra_bitmap=0;
644 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
645 WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
646 struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
650 psta->aid = 0;/* default set to 0 */
651 psta->mac_id = psta->aid + 1;
653 psta->qos_option = 0;
654 #ifdef CONFIG_80211N_HT
655 psta->htpriv.ht_option = _FALSE;
656 #endif /* CONFIG_80211N_HT */
658 psta->ieee8021x_blocked = 0;
660 memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
662 /* prepare for add_RATid */
663 supportRateNum = rtw_get_rateset_len((u8*)&pcur_network->SupportedRates);
664 network_type = rtw_check_network_type((u8*)&pcur_network->SupportedRates, supportRateNum, 1);
666 memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum);
667 psta->bssratelen = supportRateNum;
669 /* b/g mode ra_bitmap */
670 for (i=0; i<supportRateNum; i++)
672 if (psta->bssrateset[i])
673 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
676 if ( pcur_network->Configuration.DSConfig > 14 ) {
677 /* force to A mode. 5G doesn't support CCK rates */
678 network_type = WIRELESS_11A;
679 tx_ra_bitmap = 0x150; /* 6, 12, 24 Mbps */
681 /* force to b mode */
682 network_type = WIRELESS_11B;
686 raid = networktype_to_raid(network_type);
687 init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f;
690 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
695 arg = psta->mac_id&0x1f;
699 tx_ra_bitmap |= ((raid<<28)&0xf0000000);
701 DBG_8723A("update_bmc_sta, mask=0x%x, arg=0x%x\n", tx_ra_bitmap, arg);
703 /* bitmap[0:27] = tx_rate_bitmap */
704 /* bitmap[28:31]= Rate Adaptive id */
705 /* arg[0:4] = macid */
706 /* arg[5] = Short GI */
707 rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0);
711 /* set ra_id, init_rate */
713 psta->init_rate = init_rate;
715 rtw_stassoc_hw_rpt(padapter, psta);
717 spin_lock_bh(&psta->lock);
718 psta->state = _FW_LINKED;
719 spin_unlock_bh(&psta->lock);
724 DBG_8723A("add_RATid_bmc_sta error!\n");
729 /* AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode */
730 /* MAC_ID = AID+1 for sta in ap/adhoc mode */
731 /* MAC_ID = 1 for bc/mc for sta/ap/adhoc */
732 /* MAC_ID = 0 for bssid for sta/ap/adhoc */
733 /* CAM_ID = 0~3 for default key, cmd_id=macid + 3, macid=aid+1; */
735 void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta)
738 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
739 struct security_priv *psecuritypriv = &padapter->securitypriv;
740 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
741 #ifdef CONFIG_80211N_HT
742 struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
743 struct ht_priv *phtpriv_sta = &psta->htpriv;
744 #endif /* CONFIG_80211N_HT */
745 /* set intf_tag to if1 */
747 psta->mac_id = psta->aid+1;
748 DBG_8723A("%s\n",__FUNCTION__);
751 rtw_hal_set_odm_var(padapter,HAL_ODM_STA_INFO,psta,_TRUE);
753 if(psecuritypriv->dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)
754 psta->ieee8021x_blocked = _TRUE;
756 psta->ieee8021x_blocked = _FALSE;
758 /* update sta's cap */
761 VCS_update(padapter, psta);
762 #ifdef CONFIG_80211N_HT
764 if(phtpriv_sta->ht_option)
766 /* check if sta supports rx ampdu */
767 phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
769 /* check if sta support s Short GI */
770 if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40))
771 phtpriv_sta->sgi = _TRUE;
774 if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH)) {
775 /* phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_40; */
776 phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
777 phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
781 psta->qos_option = _TRUE;
786 phtpriv_sta->ampdu_enable = _FALSE;
788 phtpriv_sta->sgi = _FALSE;
789 phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
790 phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
794 send_delba(padapter, 0, psta->hwaddr);/* recipient */
797 send_delba(padapter, 1, psta->hwaddr);/* originator */
798 phtpriv_sta->agg_enable_bitmap = 0x0;/* reset */
799 phtpriv_sta->candidate_tid_bitmap = 0x0;/* reset */
800 #endif /* CONFIG_80211N_HT */
802 /* todo: init other variables */
804 memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
806 spin_lock_bh(&psta->lock);
807 psta->state |= _FW_LINKED;
808 spin_unlock_bh(&psta->lock);
811 static void update_hw_ht_param(_adapter *padapter)
813 unsigned char max_AMPDU_len;
814 unsigned char min_MPDU_spacing;
815 struct registry_priv *pregpriv = &padapter->registrypriv;
816 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
817 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
819 DBG_8723A("%s\n", __FUNCTION__);
821 /* handle A-MPDU parameter field */
823 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
824 AMPDU_para [4:2]:Min MPDU Start Spacing
826 max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
828 min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
830 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
832 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
835 /* Config SM Power Save setting */
837 pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
838 if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
839 DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__);
842 /* Config current HT Protection mode. */
844 /* pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3; */
847 static void start_bss_network(_adapter *padapter, u8 *pbuf)
850 u8 val8, cur_channel, cur_bwmode, cur_ch_offset;
854 struct registry_priv *pregpriv = &padapter->registrypriv;
855 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
856 struct security_priv* psecuritypriv=&(padapter->securitypriv);
857 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
858 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
859 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
860 WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);
861 struct HT_info_element *pht_info=NULL;
863 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
864 #endif /* CONFIG_P2P */
866 bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
867 cur_channel = pnetwork->Configuration.DSConfig;
868 cur_bwmode = HT_CHANNEL_WIDTH_20;;
869 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
871 /* check if there is wps ie, */
872 /* if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, */
873 /* and at first time the security ie ( RSN/WPA IE) will not include in beacon. */
874 if(NULL == rtw_get_wps_ie(pnetwork->IEs+_FIXED_IE_LENGTH_, pnetwork->IELength-_FIXED_IE_LENGTH_, NULL, NULL))
876 pmlmeext->bstart_bss = _TRUE;
879 /* todo: update wmm, ht cap */
880 /* pmlmeinfo->WMM_enable; */
881 /* pmlmeinfo->HT_enable; */
882 if(pmlmepriv->qospriv.qos_option)
883 pmlmeinfo->WMM_enable = _TRUE;
884 #ifdef CONFIG_80211N_HT
885 if(pmlmepriv->htpriv.ht_option)
887 pmlmeinfo->WMM_enable = _TRUE;
888 pmlmeinfo->HT_enable = _TRUE;
890 update_hw_ht_param(padapter);
892 #endif /* CONFIG_80211N_HT */
894 if(pmlmepriv->cur_network.join_res != _TRUE) /* setting only at first time */
896 /* WEP Key will be set before this function, do not clear CAM. */
897 if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_))
898 flush_all_cam_entry(padapter); /* clear CAM */
901 /* set MSR to AP_Mode */
902 Set_MSR(padapter, _HW_STATE_AP_);
905 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress);
907 /* Set EDCA param reg */
908 #ifdef CONFIG_CONCURRENT_MODE
911 acparm = 0x002F3217; /* VO */
913 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
914 acparm = 0x005E4317; /* VI */
915 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
917 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
918 acparm = 0x0000A444; /* BK */
919 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
922 val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
923 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
925 /* Beacon Control related register */
926 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));
928 UpdateBrateTbl(padapter, pnetwork->SupportedRates);
929 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
931 if(pmlmepriv->cur_network.join_res != _TRUE) /* setting only at first time */
933 /* u32 initialgain; */
935 /* initialgain = 0x1e; */
937 /* disable dynamic functions, such as high power, DIG */
938 /* Save_DM_Func_Flag(padapter); */
939 /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE); */
941 #ifdef CONFIG_CONCURRENT_MODE
942 if(padapter->adapter_type > PRIMARY_ADAPTER)
944 if(rtw_buddy_adapter_up(padapter))
946 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
948 /* turn on all dynamic functions on PRIMARY_ADAPTER, dynamic functions only runs at PRIMARY_ADAPTER */
949 Switch_DM_Func(pbuddy_adapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
951 /* rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
957 /* turn on all dynamic functions */
958 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
960 /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
964 #ifdef CONFIG_80211N_HT
965 /* set channel, bwmode */
966 p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
969 pht_info = (struct HT_info_element *)(p+2);
971 if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2)))
973 /* switch to the 40M Hz mode */
974 /* pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; */
975 cur_bwmode = HT_CHANNEL_WIDTH_40;
976 switch (pht_info->infos[0] & 0x3)
979 /* pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; */
980 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
984 /* pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; */
985 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
989 /* pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; */
990 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
997 #endif /* CONFIG_80211N_HT */
998 #ifdef CONFIG_DUALMAC_CONCURRENT
999 dc_set_ap_channel_bandwidth(padapter, cur_channel, cur_ch_offset, cur_bwmode);
1001 /* TODO: need to judge the phy parameters on concurrent mode for single phy */
1002 /* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
1003 #ifdef CONFIG_CONCURRENT_MODE
1004 if(!check_buddy_fwstate(padapter, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1006 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
1008 else if(check_buddy_fwstate(padapter, _FW_LINKED)==_TRUE)/* only second adapter can enter AP Mode */
1010 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
1011 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
1013 /* To sync cur_channel/cur_bwmode/cur_ch_offset with primary adapter */
1014 DBG_8723A("primary iface is at linked state, sync cur_channel/cur_bwmode/cur_ch_offset\n");
1015 DBG_8723A("primary adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
1016 DBG_8723A("second adapter, CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
1018 cur_channel = pbuddy_mlmeext->cur_channel;
1019 if(cur_bwmode == HT_CHANNEL_WIDTH_40)
1022 pht_info->infos[0] &= ~(BIT(0)|BIT(1));
1024 if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
1026 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
1028 /* to update cur_ch_offset value in beacon */
1031 switch(cur_ch_offset)
1033 case HAL_PRIME_CHNL_OFFSET_LOWER:
1034 pht_info->infos[0] |= 0x1;
1036 case HAL_PRIME_CHNL_OFFSET_UPPER:
1037 pht_info->infos[0] |= 0x3;
1039 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
1046 else if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20)
1048 cur_bwmode = HT_CHANNEL_WIDTH_20;
1049 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1051 if(cur_channel>0 && cur_channel<5)
1054 pht_info->infos[0] |= 0x1;
1056 cur_bwmode = HT_CHANNEL_WIDTH_40;
1057 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
1060 if(cur_channel>7 && cur_channel<(14+1))
1063 pht_info->infos[0] |= 0x3;
1065 cur_bwmode = HT_CHANNEL_WIDTH_40;
1066 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
1069 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
1074 /* to update channel value in beacon */
1075 pnetwork->Configuration.DSConfig = cur_channel;
1076 p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
1078 *(p + 2) = cur_channel;
1081 pht_info->primary_channel = cur_channel;
1084 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
1085 #endif /* CONFIG_CONCURRENT_MODE */
1087 DBG_8723A("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
1090 pmlmeext->cur_channel = cur_channel;
1091 pmlmeext->cur_bwmode = cur_bwmode;
1092 pmlmeext->cur_ch_offset = cur_ch_offset;
1093 #endif /* CONFIG_DUALMAC_CONCURRENT */
1094 pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;
1096 /* update cur_wireless_mode */
1097 update_wireless_mode(padapter);
1099 /* udpate capability after cur_wireless_mode updated */
1100 update_capinfo(padapter, rtw_get_capability((WLAN_BSSID_EX *)pnetwork));
1102 /* let pnetwork_mlmeext == pnetwork_mlme. */
1103 memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
1106 memcpy(pwdinfo->p2p_group_ssid, pnetwork->Ssid.Ssid, pnetwork->Ssid.SsidLength);
1107 pwdinfo->p2p_group_ssid_len = pnetwork->Ssid.SsidLength;
1108 #endif /* CONFIG_P2P */
1110 if(_TRUE == pmlmeext->bstart_bss)
1112 update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
1114 #ifndef CONFIG_INTERRUPT_BASED_TXBCN /* other case will tx beacon when bcn interrupt coming in. */
1115 #if defined(CONFIG_USB_HCI) || defined(CONFIG_GSPI_HCI)
1116 /* issue beacon frame */
1117 if(send_beacon(padapter)==_FAIL)
1119 DBG_8723A("issue_beacon, fail!\n");
1122 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
1126 /* update bc/mc sta_info */
1127 update_bmc_sta(padapter);
1129 /* pmlmeext->bstart_bss = _TRUE; */
1132 int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len)
1136 u8 *pHT_caps_ie=NULL;
1137 u8 *pHT_info_ie=NULL;
1138 struct sta_info *psta = NULL;
1139 u16 cap, ht_cap=_FALSE;
1141 int group_cipher, pairwise_cipher;
1142 u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
1143 int supportRateNum = 0;
1144 u8 OUI1[] = {0x00, 0x50, 0xf2,0x01};
1145 u8 wps_oui[4]={0x0,0x50,0xf2,0x04};
1146 u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
1147 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1148 struct security_priv *psecuritypriv = &padapter->securitypriv;
1149 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1150 WLAN_BSSID_EX *pbss_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
1151 struct sta_priv *pstapriv = &padapter->stapriv;
1152 u8 *ie = pbss_network->IEs;
1155 /* Supported rates */
1157 /* WLAN_EID_COUNTRY */
1158 /* ERP Information element */
1159 /* Extended supported rates */
1161 /* Wi-Fi Wireless Multimedia Extensions */
1162 /* ht_capab, ht_oper */
1165 DBG_8723A("%s, len=%d\n", __FUNCTION__, len);
1167 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
1173 pbss_network->IELength = len;
1175 memset(ie, 0, MAX_IE_SZ);
1177 memcpy(ie, pbuf, pbss_network->IELength);
1179 if(pbss_network->InfrastructureMode!=Ndis802_11APMode)
1182 pbss_network->Rssi = 0;
1184 memcpy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)), ETH_ALEN);
1186 /* beacon interval */
1187 p = rtw_get_beacon_interval_from_ie(ie);/* ie + 8; 8: TimeStamp, 2: Beacon Interval 2:Capability */
1188 /* pbss_network->Configuration.BeaconPeriod = le16_to_cpu(*(unsigned short*)p); */
1189 pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p);
1192 /* cap = *(unsigned short *)rtw_get_capability_from_ie(ie); */
1193 /* cap = le16_to_cpu(cap); */
1194 cap = RTW_GET_LE16(ie);
1197 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength -_BEACON_IE_OFFSET_));
1200 memset(&pbss_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
1201 memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);
1202 pbss_network->Ssid.SsidLength = ie_len;
1207 pbss_network->Configuration.Length = 0;
1208 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
1212 pbss_network->Configuration.DSConfig = channel;
1214 memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
1215 /* get supported rates */
1216 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
1219 memcpy(supportRate, p+2, ie_len);
1220 supportRateNum = ie_len;
1223 /* get ext_supported rates */
1224 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_);
1227 memcpy(supportRate+supportRateNum, p+2, ie_len);
1228 supportRateNum += ie_len;
1232 network_type = rtw_check_network_type(supportRate, supportRateNum, channel);
1234 rtw_set_supported_rate(pbss_network->SupportedRates, network_type);
1236 /* parsing ERP_IE */
1237 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
1240 ERP_IE_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)p);
1243 /* update privacy/security */
1245 pbss_network->Privacy = 1;
1247 pbss_network->Privacy = 0;
1249 psecuritypriv->wpa_psk = 0;
1252 group_cipher = 0; pairwise_cipher = 0;
1253 psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
1254 psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
1255 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
1258 if(rtw_parse_wpa2_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
1260 psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
1262 psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */
1263 psecuritypriv->wpa_psk |= BIT(1);
1265 psecuritypriv->wpa2_group_cipher = group_cipher;
1266 psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
1268 switch(group_cipher)
1270 case WPA_CIPHER_NONE:
1271 psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
1273 case WPA_CIPHER_WEP40:
1274 psecuritypriv->wpa2_group_cipher = _WEP40_;
1276 case WPA_CIPHER_TKIP:
1277 psecuritypriv->wpa2_group_cipher = _TKIP_;
1279 case WPA_CIPHER_CCMP:
1280 psecuritypriv->wpa2_group_cipher = _AES_;
1282 case WPA_CIPHER_WEP104:
1283 psecuritypriv->wpa2_group_cipher = _WEP104_;
1287 switch(pairwise_cipher)
1289 case WPA_CIPHER_NONE:
1290 psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
1292 case WPA_CIPHER_WEP40:
1293 psecuritypriv->wpa2_pairwise_cipher = _WEP40_;
1295 case WPA_CIPHER_TKIP:
1296 psecuritypriv->wpa2_pairwise_cipher = _TKIP_;
1298 case WPA_CIPHER_CCMP:
1299 psecuritypriv->wpa2_pairwise_cipher = _AES_;
1301 case WPA_CIPHER_WEP104:
1302 psecuritypriv->wpa2_pairwise_cipher = _WEP104_;
1312 group_cipher = 0; pairwise_cipher = 0;
1313 psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
1314 psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
1315 for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2))
1317 p = rtw_get_ie(p, _SSN_IE_1_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
1318 if ((p) && (!memcmp(p+2, OUI1, 4)))
1320 if(rtw_parse_wpa_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
1322 psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
1324 psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */
1326 psecuritypriv->wpa_psk |= BIT(0);
1328 psecuritypriv->wpa_group_cipher = group_cipher;
1329 psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
1332 switch(group_cipher)
1334 case WPA_CIPHER_NONE:
1335 psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
1337 case WPA_CIPHER_WEP40:
1338 psecuritypriv->wpa_group_cipher = _WEP40_;
1340 case WPA_CIPHER_TKIP:
1341 psecuritypriv->wpa_group_cipher = _TKIP_;
1343 case WPA_CIPHER_CCMP:
1344 psecuritypriv->wpa_group_cipher = _AES_;
1346 case WPA_CIPHER_WEP104:
1347 psecuritypriv->wpa_group_cipher = _WEP104_;
1351 switch(pairwise_cipher)
1353 case WPA_CIPHER_NONE:
1354 psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
1356 case WPA_CIPHER_WEP40:
1357 psecuritypriv->wpa_pairwise_cipher = _WEP40_;
1359 case WPA_CIPHER_TKIP:
1360 psecuritypriv->wpa_pairwise_cipher = _TKIP_;
1362 case WPA_CIPHER_CCMP:
1363 psecuritypriv->wpa_pairwise_cipher = _AES_;
1365 case WPA_CIPHER_WEP104:
1366 psecuritypriv->wpa_pairwise_cipher = _WEP104_;
1376 if ((p == NULL) || (ie_len == 0))
1385 pmlmepriv->qospriv.qos_option = 0;
1386 if(pregistrypriv->wmm_enable)
1388 for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2))
1390 p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
1391 if((p) && !memcmp(p+2, WMM_PARA_IE, 6))
1393 pmlmepriv->qospriv.qos_option = 1;
1395 *(p+8) |= BIT(7);/* QoS Info, support U-APSD */
1397 /* disable all ACM bits since the WMM admission control is not supported */
1398 *(p + 10) &= ~BIT(4); /* BE */
1399 *(p + 14) &= ~BIT(4); /* BK */
1400 *(p + 18) &= ~BIT(4); /* VI */
1401 *(p + 22) &= ~BIT(4); /* VO */
1406 if ((p == NULL) || (ie_len == 0))
1412 #ifdef CONFIG_80211N_HT
1413 /* parsing HT_CAP_IE */
1414 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
1419 struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2);
1424 network_type |= WIRELESS_11_24N;
1426 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1428 if((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
1429 (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
1431 pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
1435 pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
1438 pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03); /* set Max Rx AMPDU size to 64K */
1440 if(rf_type == RF_1T1R)
1442 pht_cap->supp_mcs_set[0] = 0xff;
1443 pht_cap->supp_mcs_set[1] = 0x0;
1446 memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len);
1450 /* parsing HT_INFO_IE */
1451 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
1456 #endif /* CONFIG_80211N_HT */
1457 switch(network_type)
1460 pbss_network->NetworkTypeInUse = Ndis802_11DS;
1464 case WIRELESS_11G_24N:
1465 case WIRELESS_11BG_24N:
1466 pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
1469 pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;
1472 pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
1476 pmlmepriv->cur_network.network_type = network_type;
1478 #ifdef CONFIG_80211N_HT
1479 pmlmepriv->htpriv.ht_option = _FALSE;
1481 if( (psecuritypriv->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
1482 (psecuritypriv->wpa_pairwise_cipher&WPA_CIPHER_TKIP))
1485 /* ht_cap = _FALSE; */
1489 if(pregistrypriv->ht_enable && ht_cap==_TRUE)
1491 pmlmepriv->htpriv.ht_option = _TRUE;
1492 pmlmepriv->qospriv.qos_option = 1;
1494 if(pregistrypriv->ampdu_enable==1)
1496 pmlmepriv->htpriv.ampdu_enable = _TRUE;
1499 HT_caps_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_caps_ie);
1501 HT_info_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_info_ie);
1505 pbss_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pbss_network);
1507 /* issue beacon to start bss network */
1508 start_bss_network(padapter, (u8*)pbss_network);
1510 /* alloc sta_info for ap itself */
1511 psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
1514 psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
1520 psta->state |= WIFI_AP_STATE; /* Aries, add,fix bug of flush_cam_entry at STOP AP mode , 0724 */
1521 rtw_indicate_connect( padapter);
1523 pmlmepriv->cur_network.join_res = _TRUE;/* for check if already set beacon */
1525 /* update bc/mc sta_info */
1526 /* update_bmc_sta(padapter); */
1531 void rtw_set_macaddr_acl(_adapter *padapter, int mode)
1533 struct sta_priv *pstapriv = &padapter->stapriv;
1534 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1536 DBG_8723A("%s, mode=%d\n", __func__, mode);
1538 pacl_list->mode = mode;
1541 int rtw_acl_add_sta(_adapter *padapter, u8 *addr)
1544 _list *plist, *phead;
1547 struct rtw_wlan_acl_node *paclnode;
1548 struct sta_priv *pstapriv = &padapter->stapriv;
1549 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1550 _queue *pacl_node_q =&pacl_list->acl_node_q;
1552 DBG_8723A("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));
1554 if((NUM_ACL-1) < pacl_list->num)
1557 spin_lock_bh(&(pacl_node_q->lock));
1559 phead = get_list_head(pacl_node_q);
1560 plist = get_next(phead);
1562 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
1564 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
1565 plist = get_next(plist);
1567 if(!memcmp(paclnode->addr, addr, ETH_ALEN))
1569 if(paclnode->valid == _TRUE)
1572 DBG_8723A("%s, sta has been added\n", __func__);
1578 spin_unlock_bh(&(pacl_node_q->lock));
1583 spin_lock_bh(&(pacl_node_q->lock));
1585 for(i=0; i< NUM_ACL; i++)
1587 paclnode = &pacl_list->aclnode[i];
1589 if(paclnode->valid == _FALSE)
1591 _rtw_init_listhead(&paclnode->list);
1593 memcpy(paclnode->addr, addr, ETH_ALEN);
1595 paclnode->valid = _TRUE;
1597 rtw_list_insert_tail(&paclnode->list, get_list_head(pacl_node_q));
1605 DBG_8723A("%s, acl_num=%d\n", __func__, pacl_list->num);
1607 spin_unlock_bh(&(pacl_node_q->lock));
1612 int rtw_acl_remove_sta(_adapter *padapter, u8 *addr)
1615 _list *plist, *phead;
1617 struct rtw_wlan_acl_node *paclnode;
1618 struct sta_priv *pstapriv = &padapter->stapriv;
1619 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1620 _queue *pacl_node_q =&pacl_list->acl_node_q;
1622 DBG_8723A("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));
1624 spin_lock_bh(&(pacl_node_q->lock));
1626 phead = get_list_head(pacl_node_q);
1627 plist = get_next(phead);
1629 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
1631 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
1632 plist = get_next(plist);
1634 if(!memcmp(paclnode->addr, addr, ETH_ALEN))
1636 if(paclnode->valid == _TRUE)
1638 paclnode->valid = _FALSE;
1640 rtw_list_delete(&paclnode->list);
1647 spin_unlock_bh(&(pacl_node_q->lock));
1649 DBG_8723A("%s, acl_num=%d\n", __func__, pacl_list->num);
1654 #ifdef CONFIG_NATIVEAP_MLME
1656 static void update_bcn_fixed_ie(_adapter *padapter)
1658 DBG_8723A("%s\n", __FUNCTION__);
1661 static void update_bcn_erpinfo_ie(_adapter *padapter)
1663 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1664 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1665 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1666 WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
1667 unsigned char *p, *ie = pnetwork->IEs;
1670 DBG_8723A("%s, ERP_enable=%d\n", __FUNCTION__, pmlmeinfo->ERP_enable);
1672 if(!pmlmeinfo->ERP_enable)
1675 /* parsing ERP_IE */
1676 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
1679 PNDIS_802_11_VARIABLE_IEs pIE = (PNDIS_802_11_VARIABLE_IEs)p;
1681 if (pmlmepriv->num_sta_non_erp == 1)
1682 pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION;
1684 pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION);
1686 if(pmlmepriv->num_sta_no_short_preamble > 0)
1687 pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
1689 pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);
1691 ERP_IE_handler(padapter, pIE);
1695 static void update_bcn_htcap_ie(_adapter *padapter)
1697 DBG_8723A("%s\n", __FUNCTION__);
1700 static void update_bcn_htinfo_ie(_adapter *padapter)
1702 DBG_8723A("%s\n", __FUNCTION__);
1705 static void update_bcn_rsn_ie(_adapter *padapter)
1707 DBG_8723A("%s\n", __FUNCTION__);
1710 static void update_bcn_wpa_ie(_adapter *padapter)
1712 DBG_8723A("%s\n", __FUNCTION__);
1715 static void update_bcn_wmm_ie(_adapter *padapter)
1717 DBG_8723A("%s\n", __FUNCTION__);
1720 static void update_bcn_wps_ie(_adapter *padapter)
1722 u8 *pwps_ie=NULL, *pwps_ie_src, *premainder_ie, *pbackup_remainder_ie=NULL;
1723 uint wps_ielen=0, wps_offset, remainder_ielen;
1724 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1725 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1726 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1727 WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
1728 unsigned char *ie = pnetwork->IEs;
1729 u32 ielen = pnetwork->IELength;
1731 DBG_8723A("%s\n", __FUNCTION__);
1733 pwps_ie = rtw_get_wps_ie(ie+_FIXED_IE_LENGTH_, ielen-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
1735 if(pwps_ie==NULL || wps_ielen==0)
1738 wps_offset = (uint)(pwps_ie-ie);
1740 premainder_ie = pwps_ie + wps_ielen;
1742 remainder_ielen = ielen - wps_offset - wps_ielen;
1744 if(remainder_ielen>0)
1746 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
1747 if(pbackup_remainder_ie)
1748 memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
1751 pwps_ie_src = pmlmepriv->wps_beacon_ie;
1752 if(pwps_ie_src == NULL)
1755 wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */
1756 if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
1758 memcpy(pwps_ie, pwps_ie_src, wps_ielen+2);
1759 pwps_ie += (wps_ielen+2);
1761 if(pbackup_remainder_ie)
1762 memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
1764 /* update IELength */
1765 pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen;
1768 if(pbackup_remainder_ie)
1769 rtw_mfree(pbackup_remainder_ie, remainder_ielen);
1772 static void update_bcn_p2p_ie(_adapter *padapter)
1776 static void update_bcn_vendor_spec_ie(_adapter *padapter, u8*oui)
1778 DBG_8723A("%s\n", __FUNCTION__);
1780 if (!memcmp(RTW_WPA_OUI, oui, 4))
1782 update_bcn_wpa_ie(padapter);
1784 else if (!memcmp(WMM_OUI, oui, 4))
1786 update_bcn_wmm_ie(padapter);
1788 else if (!memcmp(WPS_OUI, oui, 4))
1790 update_bcn_wps_ie(padapter);
1792 else if (!memcmp(P2P_OUI, oui, 4))
1794 update_bcn_p2p_ie(padapter);
1798 DBG_8723A("unknown OUI type!\n");
1802 void update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
1805 struct mlme_priv *pmlmepriv;
1806 struct mlme_ext_priv *pmlmeext;
1807 /* struct mlme_ext_info *pmlmeinfo; */
1809 /* DBG_8723A("%s\n", __FUNCTION__); */
1814 pmlmepriv = &(padapter->mlmepriv);
1815 pmlmeext = &(padapter->mlmeextpriv);
1816 /* pmlmeinfo = &(pmlmeext->mlmext_info); */
1818 if(_FALSE == pmlmeext->bstart_bss)
1821 spin_lock_bh(&pmlmepriv->bcn_update_lock);
1827 update_bcn_fixed_ie(padapter);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */
1833 update_BCNTIM(padapter);
1839 update_bcn_erpinfo_ie(padapter);
1843 case _HT_CAPABILITY_IE_:
1845 update_bcn_htcap_ie(padapter);
1851 update_bcn_rsn_ie(padapter);
1855 case _HT_ADD_INFO_IE_:
1857 update_bcn_htinfo_ie(padapter);
1861 case _VENDOR_SPECIFIC_IE_:
1863 update_bcn_vendor_spec_ie(padapter, oui);
1871 pmlmepriv->update_bcn = _TRUE;
1873 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
1875 #ifndef CONFIG_INTERRUPT_BASED_TXBCN
1876 #if defined(CONFIG_USB_HCI) || defined(CONFIG_GSPI_HCI)
1879 set_tx_beacon_cmd(padapter);
1883 /* PCI will issue beacon when BCN interrupt occurs. */
1886 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
1889 #ifdef CONFIG_80211N_HT
1893 Set to 0 (HT pure) under the followign conditions
1894 - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
1895 - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
1896 Set to 1 (HT non-member protection) if there may be non-HT STAs
1897 in both the primary and the secondary channel
1898 Set to 2 if only HT STAs are associated in BSS,
1899 however and at least one 20 MHz HT STA is associated
1900 Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
1901 (currently non-GF HT station is considered as non-HT STA also)
1903 static int rtw_ht_operation_update(_adapter *padapter)
1905 u16 cur_op_mode, new_op_mode;
1906 int op_mode_changes = 0;
1907 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1908 struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
1910 if(pmlmepriv->htpriv.ht_option == _TRUE)
1913 /* if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed) */
1916 DBG_8723A("%s current operation mode=0x%X\n",
1917 __FUNCTION__, pmlmepriv->ht_op_mode);
1919 if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)
1920 && pmlmepriv->num_sta_ht_no_gf) {
1921 pmlmepriv->ht_op_mode |=
1922 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
1924 } else if ((pmlmepriv->ht_op_mode &
1925 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
1926 pmlmepriv->num_sta_ht_no_gf == 0) {
1927 pmlmepriv->ht_op_mode &=
1928 ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
1932 if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
1933 (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
1934 pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
1936 } else if ((pmlmepriv->ht_op_mode &
1937 HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
1938 (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
1939 pmlmepriv->ht_op_mode &=
1940 ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
1944 /* Note: currently we switch to the MIXED op mode if HT non-greenfield
1945 * station is associated. Probably it's a theoretical case, since
1946 * it looks like all known HT STAs support greenfield.
1949 if (pmlmepriv->num_sta_no_ht ||
1950 (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
1951 new_op_mode = OP_MODE_MIXED;
1952 else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH)
1953 && pmlmepriv->num_sta_ht_20mhz)
1954 new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
1955 else if (pmlmepriv->olbc_ht)
1956 new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
1958 new_op_mode = OP_MODE_PURE;
1960 cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
1961 if (cur_op_mode != new_op_mode) {
1962 pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
1963 pmlmepriv->ht_op_mode |= new_op_mode;
1967 DBG_8723A("%s new operation mode=0x%X changes=%d\n",
1968 __FUNCTION__, pmlmepriv->ht_op_mode, op_mode_changes);
1970 return op_mode_changes;
1973 #endif /* CONFIG_80211N_HT */
1975 void associated_clients_update(_adapter *padapter, u8 updated)
1977 /* update associcated stations cap. */
1978 if(updated == _TRUE)
1981 _list *phead, *plist;
1982 struct sta_info *psta=NULL;
1983 struct sta_priv *pstapriv = &padapter->stapriv;
1985 spin_lock_bh(&pstapriv->asoc_list_lock);
1987 phead = &pstapriv->asoc_list;
1988 plist = get_next(phead);
1990 /* check asoc_queue */
1991 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
1993 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
1995 plist = get_next(plist);
1997 VCS_update(padapter, psta);
2000 spin_unlock_bh(&pstapriv->asoc_list_lock);
2005 /* called > TSR LEVEL for USB or SDIO Interface*/
2006 void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta)
2008 u8 beacon_updated = _FALSE;
2009 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2010 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2013 if (!(psta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
2014 !psta->no_short_preamble_set) {
2015 psta->no_short_preamble_set = 1;
2016 pmlmepriv->num_sta_no_short_preamble++;
2017 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
2018 (pmlmepriv->num_sta_no_short_preamble == 1))
2019 ieee802_11_set_beacons(hapd->iface);
2023 if(!(psta->flags & WLAN_STA_SHORT_PREAMBLE))
2025 if(!psta->no_short_preamble_set)
2027 psta->no_short_preamble_set = 1;
2029 pmlmepriv->num_sta_no_short_preamble++;
2031 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
2032 (pmlmepriv->num_sta_no_short_preamble == 1))
2034 beacon_updated = _TRUE;
2035 update_beacon(padapter, 0xFF, NULL, _TRUE);
2042 if(psta->no_short_preamble_set)
2044 psta->no_short_preamble_set = 0;
2046 pmlmepriv->num_sta_no_short_preamble--;
2048 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
2049 (pmlmepriv->num_sta_no_short_preamble == 0))
2051 beacon_updated = _TRUE;
2052 update_beacon(padapter, 0xFF, NULL, _TRUE);
2059 if (psta->flags & WLAN_STA_NONERP && !psta->nonerp_set) {
2060 psta->nonerp_set = 1;
2061 pmlmepriv->num_sta_non_erp++;
2062 if (pmlmepriv->num_sta_non_erp == 1)
2063 ieee802_11_set_beacons(hapd->iface);
2067 if(psta->flags & WLAN_STA_NONERP)
2069 if(!psta->nonerp_set)
2071 psta->nonerp_set = 1;
2073 pmlmepriv->num_sta_non_erp++;
2075 if (pmlmepriv->num_sta_non_erp == 1)
2077 beacon_updated = _TRUE;
2078 update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
2085 if(psta->nonerp_set)
2087 psta->nonerp_set = 0;
2089 pmlmepriv->num_sta_non_erp--;
2091 if (pmlmepriv->num_sta_non_erp == 0)
2093 beacon_updated = _TRUE;
2094 update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
2101 if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT) &&
2102 !psta->no_short_slot_time_set) {
2103 psta->no_short_slot_time_set = 1;
2104 pmlmepriv->num_sta_no_short_slot_time++;
2105 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
2106 (pmlmepriv->num_sta_no_short_slot_time == 1))
2107 ieee802_11_set_beacons(hapd->iface);
2111 if(!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT))
2113 if(!psta->no_short_slot_time_set)
2115 psta->no_short_slot_time_set = 1;
2117 pmlmepriv->num_sta_no_short_slot_time++;
2119 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
2120 (pmlmepriv->num_sta_no_short_slot_time == 1))
2122 beacon_updated = _TRUE;
2123 update_beacon(padapter, 0xFF, NULL, _TRUE);
2130 if(psta->no_short_slot_time_set)
2132 psta->no_short_slot_time_set = 0;
2134 pmlmepriv->num_sta_no_short_slot_time--;
2136 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
2137 (pmlmepriv->num_sta_no_short_slot_time == 0))
2139 beacon_updated = _TRUE;
2140 update_beacon(padapter, 0xFF, NULL, _TRUE);
2145 #ifdef CONFIG_80211N_HT
2147 if (psta->flags & WLAN_STA_HT)
2149 u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
2151 DBG_8723A("HT: STA " MAC_FMT " HT Capabilities "
2152 "Info: 0x%04x\n", MAC_ARG(psta->hwaddr), ht_capab);
2154 if (psta->no_ht_set) {
2155 psta->no_ht_set = 0;
2156 pmlmepriv->num_sta_no_ht--;
2159 if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
2160 if (!psta->no_ht_gf_set) {
2161 psta->no_ht_gf_set = 1;
2162 pmlmepriv->num_sta_ht_no_gf++;
2164 DBG_8723A("%s STA " MAC_FMT " - no "
2165 "greenfield, num of non-gf stations %d\n",
2166 __FUNCTION__, MAC_ARG(psta->hwaddr),
2167 pmlmepriv->num_sta_ht_no_gf);
2170 if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) {
2171 if (!psta->ht_20mhz_set) {
2172 psta->ht_20mhz_set = 1;
2173 pmlmepriv->num_sta_ht_20mhz++;
2175 DBG_8723A("%s STA " MAC_FMT " - 20 MHz HT, "
2176 "num of 20MHz HT STAs %d\n",
2177 __FUNCTION__, MAC_ARG(psta->hwaddr),
2178 pmlmepriv->num_sta_ht_20mhz);
2184 if (!psta->no_ht_set) {
2185 psta->no_ht_set = 1;
2186 pmlmepriv->num_sta_no_ht++;
2188 if(pmlmepriv->htpriv.ht_option == _TRUE) {
2189 DBG_8723A("%s STA " MAC_FMT
2190 " - no HT, num of non-HT stations %d\n",
2191 __FUNCTION__, MAC_ARG(psta->hwaddr),
2192 pmlmepriv->num_sta_no_ht);
2196 if (rtw_ht_operation_update(padapter) > 0)
2198 update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);
2199 update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);
2202 #endif /* CONFIG_80211N_HT */
2204 /* update associcated stations cap. */
2205 associated_clients_update(padapter, beacon_updated);
2207 DBG_8723A("%s, updated=%d\n", __func__, beacon_updated);
2210 u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta)
2212 u8 beacon_updated = _FALSE;
2213 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2214 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2217 return beacon_updated;
2219 if (psta->no_short_preamble_set) {
2220 psta->no_short_preamble_set = 0;
2221 pmlmepriv->num_sta_no_short_preamble--;
2222 if (pmlmeext->cur_wireless_mode > WIRELESS_11B
2223 && pmlmepriv->num_sta_no_short_preamble == 0)
2225 beacon_updated = _TRUE;
2226 update_beacon(padapter, 0xFF, NULL, _TRUE);
2230 if (psta->nonerp_set) {
2231 psta->nonerp_set = 0;
2232 pmlmepriv->num_sta_non_erp--;
2233 if (pmlmepriv->num_sta_non_erp == 0)
2235 beacon_updated = _TRUE;
2236 update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
2240 if (psta->no_short_slot_time_set) {
2241 psta->no_short_slot_time_set = 0;
2242 pmlmepriv->num_sta_no_short_slot_time--;
2243 if (pmlmeext->cur_wireless_mode > WIRELESS_11B
2244 && pmlmepriv->num_sta_no_short_slot_time == 0)
2246 beacon_updated = _TRUE;
2247 update_beacon(padapter, 0xFF, NULL, _TRUE);
2251 #ifdef CONFIG_80211N_HT
2253 if (psta->no_ht_gf_set) {
2254 psta->no_ht_gf_set = 0;
2255 pmlmepriv->num_sta_ht_no_gf--;
2258 if (psta->no_ht_set) {
2259 psta->no_ht_set = 0;
2260 pmlmepriv->num_sta_no_ht--;
2263 if (psta->ht_20mhz_set) {
2264 psta->ht_20mhz_set = 0;
2265 pmlmepriv->num_sta_ht_20mhz--;
2268 if (rtw_ht_operation_update(padapter) > 0)
2270 update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);
2271 update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);
2274 #endif /* CONFIG_80211N_HT */
2276 /* update associcated stations cap. */
2278 DBG_8723A("%s, updated=%d\n", __func__, beacon_updated);
2280 return beacon_updated;
2283 u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason)
2286 u8 beacon_updated = _FALSE;
2287 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2288 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2289 struct sta_priv *pstapriv = &padapter->stapriv;
2292 return beacon_updated;
2294 if (active == _TRUE)
2296 #ifdef CONFIG_80211N_HT
2297 /* tear down Rx AMPDU */
2298 send_delba(padapter, 0, psta->hwaddr);/* recipient */
2300 /* tear down TX AMPDU */
2301 send_delba(padapter, 1, psta->hwaddr);/* originator */
2303 #endif /* CONFIG_80211N_HT */
2305 issue_deauth(padapter, psta->hwaddr, reason);
2308 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
2309 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
2311 /* report_del_sta_event(padapter, psta->hwaddr, reason); */
2313 /* clear cam entry / key */
2314 /* clear_cam_entry(padapter, (psta->mac_id + 3)); */
2315 rtw_clearstakey_cmd(padapter, (u8*)psta, (u8)(psta->mac_id + 3), _TRUE);
2317 spin_lock_bh(&psta->lock);
2318 psta->state &= ~_FW_LINKED;
2319 spin_unlock_bh(&psta->lock);
2321 #ifdef CONFIG_IOCTL_CFG80211
2323 #ifdef COMPAT_KERNEL_RELEASE
2324 rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
2325 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
2326 rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
2327 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */
2328 /* will call rtw_cfg80211_indicate_sta_disassoc() in cmd_thread for old API context */
2329 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */
2331 #endif /* CONFIG_IOCTL_CFG80211 */
2333 rtw_indicate_sta_disassoc_event(padapter, psta);
2336 report_del_sta_event(padapter, psta->hwaddr, reason);
2338 beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
2340 spin_lock_bh(&(pstapriv->sta_hash_lock));
2341 rtw_free_stainfo(padapter, psta);
2342 spin_unlock_bh(&(pstapriv->sta_hash_lock));
2344 return beacon_updated;
2347 int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset)
2350 _list *phead, *plist;
2352 struct sta_info *psta = NULL;
2353 struct sta_priv *pstapriv = &padapter->stapriv;
2354 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2355 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2356 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
2358 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2361 DBG_8723A(FUNC_NDEV_FMT" with ch:%u, offset:%u\n",
2362 FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset);
2364 spin_lock_bh(&pstapriv->asoc_list_lock);
2365 phead = &pstapriv->asoc_list;
2366 plist = get_next(phead);
2368 /* for each sta in asoc_queue */
2369 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
2371 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
2372 plist = get_next(plist);
2374 issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset);
2375 psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2);
2377 spin_unlock_bh(&pstapriv->asoc_list_lock);
2379 issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset);
2384 int rtw_sta_flush(_adapter *padapter)
2387 _list *phead, *plist;
2389 struct sta_info *psta = NULL;
2390 struct sta_priv *pstapriv = &padapter->stapriv;
2391 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2392 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2393 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
2394 u8 chk_alive_num = 0;
2395 char chk_alive_list[NUM_STA];
2398 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
2400 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2403 spin_lock_bh(&pstapriv->asoc_list_lock);
2404 phead = &pstapriv->asoc_list;
2405 plist = get_next(phead);
2407 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
2410 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
2411 plist = get_next(plist);
2413 /* Remove sta from asoc_list */
2414 rtw_list_delete(&psta->asoc_list);
2415 pstapriv->asoc_list_cnt--;
2417 /* Keep sta for ap_free_sta() beyond this asoc_list loop */
2418 stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
2419 if (stainfo_offset_valid(stainfo_offset)) {
2420 chk_alive_list[chk_alive_num++] = stainfo_offset;
2423 spin_unlock_bh(&pstapriv->asoc_list_lock);
2425 /* For each sta in chk_alive_list, call ap_free_sta */
2426 for (i = 0; i < chk_alive_num; i++) {
2427 psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
2428 ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
2431 issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
2433 associated_clients_update(padapter, _TRUE);
2438 /* called > TSR LEVEL for USB or SDIO Interface*/
2439 void sta_info_update(_adapter *padapter, struct sta_info *psta)
2441 int flags = psta->flags;
2442 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2444 /* update wmm cap. */
2445 if(WLAN_STA_WME&flags)
2446 psta->qos_option = 1;
2448 psta->qos_option = 0;
2450 if(pmlmepriv->qospriv.qos_option == 0)
2451 psta->qos_option = 0;
2453 #ifdef CONFIG_80211N_HT
2454 /* update 802.11n ht cap. */
2455 if(WLAN_STA_HT&flags)
2457 psta->htpriv.ht_option = _TRUE;
2458 psta->qos_option = 1;
2462 psta->htpriv.ht_option = _FALSE;
2465 if(pmlmepriv->htpriv.ht_option == _FALSE)
2466 psta->htpriv.ht_option = _FALSE;
2469 update_sta_info_apmode(padapter, psta);
2472 /* called >= TSR LEVEL for USB or SDIO Interface*/
2473 void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta)
2475 if(psta->state & _FW_LINKED)
2478 add_RATid(padapter, psta, 0);/* DM_RATR_STA_INIT */
2482 /* restore hw setting from sw data structures */
2483 void rtw_ap_restore_network(_adapter *padapter)
2485 struct mlme_priv *mlmepriv = &padapter->mlmepriv;
2486 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2487 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2488 struct sta_priv * pstapriv = &padapter->stapriv;
2489 struct sta_info *psta;
2490 struct security_priv* psecuritypriv=&(padapter->securitypriv);
2492 _list *phead, *plist;
2493 u8 chk_alive_num = 0;
2494 char chk_alive_list[NUM_STA];
2497 rtw_setopmode_cmd(padapter, Ndis802_11APMode);
2499 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
2501 start_bss_network(padapter, (u8*)&mlmepriv->cur_network.network);
2503 if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
2504 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))
2506 /* restore group key, WEP keys is restored in ips_leave() */
2507 rtw_set_key(padapter, psecuritypriv, psecuritypriv->dot118021XGrpKeyid, 0);
2510 /* per sta pairwise key and settings */
2511 if((padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_) &&
2512 (padapter->securitypriv.dot11PrivacyAlgrthm != _AES_)) {
2516 spin_lock_bh(&pstapriv->asoc_list_lock);
2518 phead = &pstapriv->asoc_list;
2519 plist = get_next(phead);
2521 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
2524 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
2525 plist = get_next(plist);
2527 stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
2528 if (stainfo_offset_valid(stainfo_offset)) {
2529 chk_alive_list[chk_alive_num++] = stainfo_offset;
2533 spin_unlock_bh(&pstapriv->asoc_list_lock);
2535 for (i = 0; i < chk_alive_num; i++) {
2536 psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
2539 DBG_8723A(FUNC_ADPT_FMT" sta_info is null\n", FUNC_ADPT_ARG(padapter));
2541 else if(psta->state &_FW_LINKED)
2543 Update_RA_Entry(padapter, psta);
2545 rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE);
2550 void start_ap_mode(_adapter *padapter)
2553 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2554 struct sta_priv *pstapriv = &padapter->stapriv;
2555 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2556 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
2558 pmlmepriv->update_bcn = _FALSE;
2560 /* init_mlme_ap_info(padapter); */
2561 pmlmeext->bstart_bss = _FALSE;
2563 pmlmepriv->num_sta_non_erp = 0;
2565 pmlmepriv->num_sta_no_short_slot_time = 0;
2567 pmlmepriv->num_sta_no_short_preamble = 0;
2569 pmlmepriv->num_sta_ht_no_gf = 0;
2570 #ifdef CONFIG_80211N_HT
2571 pmlmepriv->num_sta_no_ht = 0;
2572 #endif /* CONFIG_80211N_HT */
2573 pmlmepriv->num_sta_ht_20mhz = 0;
2575 pmlmepriv->olbc = _FALSE;
2577 pmlmepriv->olbc_ht = _FALSE;
2579 #ifdef CONFIG_80211N_HT
2580 pmlmepriv->ht_op_mode = 0;
2583 for(i=0; i<NUM_STA; i++)
2584 pstapriv->sta_aid[i] = NULL;
2586 pmlmepriv->wps_beacon_ie = NULL;
2587 pmlmepriv->wps_probe_resp_ie = NULL;
2588 pmlmepriv->wps_assoc_resp_ie = NULL;
2590 pmlmepriv->p2p_beacon_ie = NULL;
2591 pmlmepriv->p2p_probe_resp_ie = NULL;
2594 _rtw_init_listhead(&(pacl_list->acl_node_q.queue));
2596 pacl_list->mode = 0;
2597 for(i = 0; i < NUM_ACL; i++) {
2598 _rtw_init_listhead(&pacl_list->aclnode[i].list);
2599 pacl_list->aclnode[i].valid = _FALSE;
2603 void stop_ap_mode(_adapter *padapter)
2606 _list *phead, *plist;
2607 struct rtw_wlan_acl_node *paclnode;
2608 struct sta_info *psta=NULL;
2609 struct sta_priv *pstapriv = &padapter->stapriv;
2610 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2611 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2612 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
2613 _queue *pacl_node_q =&pacl_list->acl_node_q;
2615 pmlmepriv->update_bcn = _FALSE;
2616 pmlmeext->bstart_bss = _FALSE;
2618 /* reset and init security priv , this can refine with rtw_reset_securitypriv */
2619 memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv));
2620 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
2621 padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
2624 spin_lock_bh(&(pacl_node_q->lock));
2625 phead = get_list_head(pacl_node_q);
2626 plist = get_next(phead);
2627 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
2629 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
2630 plist = get_next(plist);
2632 if(paclnode->valid == _TRUE)
2634 paclnode->valid = _FALSE;
2636 rtw_list_delete(&paclnode->list);
2641 spin_unlock_bh(&(pacl_node_q->lock));
2643 DBG_8723A("%s, free acl_node_queue, num=%d\n", __func__, pacl_list->num);
2645 rtw_sta_flush(padapter);
2647 /* free_assoc_sta_resources */
2648 rtw_free_all_stainfo(padapter);
2650 psta = rtw_get_bcmc_stainfo(padapter);
2651 spin_lock_bh(&(pstapriv->sta_hash_lock));
2652 rtw_free_stainfo(padapter, psta);
2653 spin_unlock_bh(&(pstapriv->sta_hash_lock));
2655 rtw_init_bcmc_stainfo(padapter);
2657 rtw_free_mlme_priv_ie_data(pmlmepriv);
2660 #endif /* CONFIG_NATIVEAP_MLME */
2661 #endif /* CONFIG_AP_MODE */