1 /******************************************************************************
\r
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
\r
5 * This program is free software; you can redistribute it and/or modify it
\r
6 * under the terms of version 2 of the GNU General Public License as
\r
7 * published by the Free Software Foundation.
\r
9 * This program is distributed in the hope that it will be useful, but WITHOUT
\r
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
14 * You should have received a copy of the GNU General Public License along with
\r
15 * this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
\r
19 ******************************************************************************/
\r
22 #include <drv_types.h>
\r
25 #ifdef CONFIG_AP_MODE
\r
27 extern unsigned char RTW_WPA_OUI[];
\r
28 extern unsigned char WMM_OUI[];
\r
29 extern unsigned char WPS_OUI[];
\r
30 extern unsigned char P2P_OUI[];
\r
31 extern unsigned char WFD_OUI[];
\r
33 void init_mlme_ap_info(_adapter *padapter)
\r
35 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
36 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
37 struct sta_priv *pstapriv = &padapter->stapriv;
\r
38 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
\r
41 _rtw_spinlock_init(&pmlmepriv->bcn_update_lock);
\r
44 _rtw_init_queue(&pacl_list->acl_node_q);
\r
46 //pmlmeext->bstart_bss = _FALSE;
\r
48 start_ap_mode(padapter);
\r
51 void free_mlme_ap_info(_adapter *padapter)
\r
54 struct sta_info *psta=NULL;
\r
55 struct sta_priv *pstapriv = &padapter->stapriv;
\r
56 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
57 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
58 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
60 //stop_ap_mode(padapter);
\r
62 pmlmepriv->update_bcn = _FALSE;
\r
63 pmlmeext->bstart_bss = _FALSE;
\r
65 rtw_sta_flush(padapter);
\r
67 pmlmeinfo->state = _HW_STATE_NOLINK_;
\r
69 //free_assoc_sta_resources
\r
70 rtw_free_all_stainfo(padapter);
\r
72 //free bc/mc sta_info
\r
73 psta = rtw_get_bcmc_stainfo(padapter);
\r
74 _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
\r
75 rtw_free_stainfo(padapter, psta);
\r
76 _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
\r
79 _rtw_spinlock_free(&pmlmepriv->bcn_update_lock);
\r
83 static void update_BCNTIM(_adapter *padapter)
\r
85 struct sta_priv *pstapriv = &padapter->stapriv;
\r
86 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
87 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
88 WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);
\r
89 unsigned char *pie = pnetwork_mlmeext->IEs;
\r
91 //DBG_871X("%s\n", __FUNCTION__);
\r
94 //if(pstapriv->tim_bitmap)
\r
97 u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
\r
99 uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
\r
101 tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);
\r
103 p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);
\r
104 if (p != NULL && tim_ielen>0)
\r
108 premainder_ie = p+tim_ielen;
\r
110 tim_ie_offset = (sint)(p -pie);
\r
112 remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen;
\r
114 //append TIM IE from dst_ie offset
\r
121 //calucate head_len
\r
122 offset = _FIXED_IE_LENGTH_;
\r
124 /* get ssid_ie len */
\r
125 p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SSID_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
\r
127 offset += tmp_len+2;
\r
129 // get supported rates len
\r
130 p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
\r
133 offset += tmp_len+2;
\r
136 //DS Parameter Set IE, len=3
\r
139 premainder_ie = pie + offset;
\r
141 remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen;
\r
143 //append TIM IE from offset
\r
144 dst_ie = pie + offset;
\r
149 if(remainder_ielen>0)
\r
151 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
\r
152 if(pbackup_remainder_ie && premainder_ie)
\r
153 _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
\r
156 *dst_ie++=_TIM_IE_;
\r
158 if((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fe))
\r
163 *dst_ie++= tim_ielen;
\r
165 *dst_ie++=0;//DTIM count
\r
166 *dst_ie++=1;//DTIM peroid
\r
168 if(pstapriv->tim_bitmap&BIT(0))//for bc/mc frames
\r
169 *dst_ie++ = BIT(0);//bitmap ctrl
\r
177 if(pstapriv->tim_bitmap&0x00fe)
\r
178 pvb = (u8)tim_bitmap_le;
\r
179 else if(pstapriv->tim_bitmap&0xff00)
\r
180 pvb = (u8)(tim_bitmap_le>>8);
\r
182 pvb = (u8)tim_bitmap_le;
\r
187 else if(tim_ielen==5)
\r
189 _rtw_memcpy(dst_ie, &tim_bitmap_le, 2);
\r
193 //copy remainder IE
\r
194 if(pbackup_remainder_ie)
\r
196 _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
\r
198 rtw_mfree(pbackup_remainder_ie, remainder_ielen);
\r
201 offset = (uint)(dst_ie - pie);
\r
202 pnetwork_mlmeext->IELength = offset + remainder_ielen;
\r
207 void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len)
\r
209 PNDIS_802_11_VARIABLE_IEs pIE;
\r
210 u8 bmatch = _FALSE;
\r
211 u8 *pie = pnetwork->IEs;
\r
212 u8 *p=NULL, *dst_ie=NULL, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
\r
213 u32 i, offset, ielen, ie_offset, remainder_ielen = 0;
\r
215 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;)
\r
217 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
\r
219 if (pIE->ElementID > index)
\r
223 else if(pIE->ElementID == index) // already exist the same IE
\r
226 ielen = pIE->Length;
\r
232 ielen = pIE->Length;
\r
233 i += (pIE->Length + 2);
\r
236 if (p != NULL && ielen>0)
\r
240 premainder_ie = p+ielen;
\r
242 ie_offset = (sint)(p -pie);
\r
244 remainder_ielen = pnetwork->IELength - ie_offset - ielen;
\r
249 dst_ie = (p+ielen);
\r
252 if(remainder_ielen>0)
\r
254 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
\r
255 if(pbackup_remainder_ie && premainder_ie)
\r
256 _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
\r
262 _rtw_memcpy(dst_ie, data, len);
\r
265 //copy remainder IE
\r
266 if(pbackup_remainder_ie)
\r
268 _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
\r
270 rtw_mfree(pbackup_remainder_ie, remainder_ielen);
\r
273 offset = (uint)(dst_ie - pie);
\r
274 pnetwork->IELength = offset + remainder_ielen;
\r
277 void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index)
\r
279 u8 *p, *dst_ie=NULL, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
\r
280 uint offset, ielen, ie_offset, remainder_ielen = 0;
\r
281 u8 *pie = pnetwork->IEs;
\r
283 p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, index, &ielen, pnetwork->IELength - _FIXED_IE_LENGTH_);
\r
284 if (p != NULL && ielen>0)
\r
288 premainder_ie = p+ielen;
\r
290 ie_offset = (sint)(p -pie);
\r
292 remainder_ielen = pnetwork->IELength - ie_offset - ielen;
\r
300 if(remainder_ielen>0)
\r
302 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
\r
303 if(pbackup_remainder_ie && premainder_ie)
\r
304 _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
\r
307 //copy remainder IE
\r
308 if(pbackup_remainder_ie)
\r
310 _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
\r
312 rtw_mfree(pbackup_remainder_ie, remainder_ielen);
\r
315 offset = (uint)(dst_ie - pie);
\r
316 pnetwork->IELength = offset + remainder_ielen;
\r
320 u8 chk_sta_is_alive(struct sta_info *psta);
\r
321 u8 chk_sta_is_alive(struct sta_info *psta)
\r
324 #ifdef DBG_EXPIRATION_CHK
\r
325 DBG_871X("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", expire_to:%u, %s%ssq_len:%u\n"
\r
326 , MAC_ARG(psta->hwaddr)
\r
327 , psta->rssi_stat.UndecoratedSmoothedPWDB
\r
328 //, STA_RX_PKTS_ARG(psta)
\r
329 , STA_RX_PKTS_DIFF_ARG(psta)
\r
331 , psta->state&WIFI_SLEEP_STATE?"PS, ":""
\r
332 , psta->state&WIFI_STA_ALIVE_CHK_STATE?"SAC, ":""
\r
337 //if(sta_last_rx_pkts(psta) == sta_rx_pkts(psta))
\r
338 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))
\r
341 if(psta->state&WIFI_SLEEP_STATE)
\r
350 sta_update_last_rx_pkts(psta);
\r
355 void expire_timeout_chk(_adapter *padapter)
\r
358 _list *phead, *plist;
\r
359 u8 updated = _FALSE;
\r
360 struct sta_info *psta=NULL;
\r
361 struct sta_priv *pstapriv = &padapter->stapriv;
\r
362 u8 chk_alive_num = 0;
\r
363 char chk_alive_list[NUM_STA];
\r
367 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
\r
369 phead = &pstapriv->auth_list;
\r
370 plist = get_next(phead);
\r
373 #ifdef DBG_EXPIRATION_CHK
\r
374 if (rtw_end_of_queue_search(phead, plist) == _FALSE) {
\r
375 DBG_871X(FUNC_NDEV_FMT" auth_list, cnt:%u\n"
\r
376 , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->auth_list_cnt);
\r
379 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
381 psta = LIST_CONTAINOR(plist, struct sta_info, auth_list);
\r
382 \r plist = get_next(plist);
\r
385 #ifdef CONFIG_ATMEL_RC_PATCH
\r
386 if (_TRUE == _rtw_memcmp((void *)(pstapriv->atmel_rc_pattern), (void *)(psta->hwaddr), ETH_ALEN))
\r
388 if (psta->flag_atmel_rc)
\r
391 if(psta->expire_to>0)
\r
394 if (psta->expire_to == 0)
\r
396 rtw_list_delete(&psta->auth_list);
\r
397 pstapriv->auth_list_cnt--;
\r
399 DBG_871X("auth expire %02X%02X%02X%02X%02X%02X\n",
\r
400 psta->hwaddr[0],psta->hwaddr[1],psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5]);
\r
402 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
\r
404 _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
\r
405 rtw_free_stainfo(padapter, psta);
\r
406 _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
\r
408 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
\r
414 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
\r
418 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
420 phead = &pstapriv->asoc_list;
\r
421 plist = get_next(phead);
\r
424 #ifdef DBG_EXPIRATION_CHK
\r
425 if (rtw_end_of_queue_search(phead, plist) == _FALSE) {
\r
426 DBG_871X(FUNC_NDEV_FMT" asoc_list, cnt:%u\n"
\r
427 , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->asoc_list_cnt);
\r
430 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
432 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
433 plist = get_next(plist);
\r
434 #ifdef CONFIG_ATMEL_RC_PATCH
\r
435 DBG_871X("%s:%d psta=%p, %02x,%02x||%02x,%02x \n\n", __func__, __LINE__,
\r
436 psta,pstapriv->atmel_rc_pattern[0], pstapriv->atmel_rc_pattern[5], psta->hwaddr[0], psta->hwaddr[5]);
\r
437 if (_TRUE == _rtw_memcmp((void *)pstapriv->atmel_rc_pattern, (void *)(psta->hwaddr), ETH_ALEN))
\r
439 if (psta->flag_atmel_rc)
\r
441 DBG_871X("%s: debug line:%d \n", __func__, __LINE__);
\r
443 #ifdef CONFIG_AUTO_AP_MODE
\r
447 if (chk_sta_is_alive(psta) || !psta->expire_to) {
\r
448 psta->expire_to = pstapriv->expire_to;
\r
449 psta->keep_alive_trycnt = 0;
\r
450 #ifdef CONFIG_TX_MCAST2UNI
\r
451 psta->under_exist_checking = 0;
\r
452 #endif // CONFIG_TX_MCAST2UNI
\r
457 #ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
\r
458 #ifdef CONFIG_80211N_HT
\r
459 #ifdef CONFIG_TX_MCAST2UNI
\r
460 if ( (psta->flags & WLAN_STA_HT) && (psta->htpriv.agg_enable_bitmap || psta->under_exist_checking) ) {
\r
461 // check sta by delba(addba) for 11n STA
\r
462 // ToDo: use CCX report to check for all STAs
\r
463 //DBG_871X("asoc check by DELBA/ADDBA! (pstapriv->expire_to=%d s)(psta->expire_to=%d s), [%02x, %d]\n", pstapriv->expire_to*2, psta->expire_to*2, psta->htpriv.agg_enable_bitmap, psta->under_exist_checking);
\r
465 if ( psta->expire_to <= (pstapriv->expire_to - 50 ) ) {
\r
466 DBG_871X("asoc expire by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2);
\r
467 psta->under_exist_checking = 0;
\r
468 psta->expire_to = 0;
\r
469 } else if ( psta->expire_to <= (pstapriv->expire_to - 3) && (psta->under_exist_checking==0)) {
\r
470 DBG_871X("asoc check by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2);
\r
471 psta->under_exist_checking = 1;
\r
472 //tear down TX AMPDU
\r
473 send_delba(padapter, 1, psta->hwaddr);// // originator
\r
474 psta->htpriv.agg_enable_bitmap = 0x0;//reset
\r
475 psta->htpriv.candidate_tid_bitmap = 0x0;//reset
\r
478 #endif //CONFIG_TX_MCAST2UNI
\r
479 #endif //CONFIG_80211N_HT
\r
480 #endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK
\r
482 if (psta->expire_to <= 0)
\r
484 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
486 if (padapter->registrypriv.wifi_spec == 1)
\r
488 psta->expire_to = pstapriv->expire_to;
\r
492 #ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
\r
493 #ifdef CONFIG_80211N_HT
\r
495 #define KEEP_ALIVE_TRYCNT (3)
\r
497 if(psta->keep_alive_trycnt > 0 && psta->keep_alive_trycnt <= KEEP_ALIVE_TRYCNT)
\r
499 if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
\r
500 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
\r
502 psta->keep_alive_trycnt = 0;
\r
505 else if((psta->keep_alive_trycnt > KEEP_ALIVE_TRYCNT) && !(psta->state & WIFI_STA_ALIVE_CHK_STATE))
\r
507 psta->keep_alive_trycnt = 0;
\r
509 if((psta->htpriv.ht_option==_TRUE) && (psta->htpriv.ampdu_enable==_TRUE))
\r
511 uint priority = 1; //test using BK
\r
514 //issued = (psta->htpriv.agg_enable_bitmap>>priority)&0x1;
\r
515 issued |= (psta->htpriv.candidate_tid_bitmap>>priority)&0x1;
\r
519 if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE))
\r
521 psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
\r
523 if (psta->state & WIFI_SLEEP_STATE)
\r
524 psta->expire_to = 2; // 2x2=4 sec
\r
526 psta->expire_to = 1; // 2 sec
\r
528 psta->state |= WIFI_STA_ALIVE_CHK_STATE;
\r
530 //add_ba_hdl(padapter, (u8*)paddbareq_parm);
\r
532 DBG_871X("issue addba_req to check if sta alive, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt);
\r
534 issue_action_BA(padapter, psta->hwaddr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)priority);
\r
536 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
\r
538 psta->keep_alive_trycnt++;
\r
544 if(psta->keep_alive_trycnt > 0 && psta->state & WIFI_STA_ALIVE_CHK_STATE)
\r
546 psta->keep_alive_trycnt = 0;
\r
547 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
\r
548 DBG_871X("change to another methods to check alive if staion is at ps mode\n");
\r
551 #endif //CONFIG_80211N_HT
\r
552 #endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK
\r
553 if (psta->state & WIFI_SLEEP_STATE) {
\r
554 if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
\r
555 //to check if alive by another methods if staion is at ps mode.
\r
556 psta->expire_to = pstapriv->expire_to;
\r
557 psta->state |= WIFI_STA_ALIVE_CHK_STATE;
\r
559 //DBG_871X("alive chk, sta:" MAC_FMT " is at ps mode!\n", MAC_ARG(psta->hwaddr));
\r
561 //to update bcn with tim_bitmap for this station
\r
562 pstapriv->tim_bitmap |= BIT(psta->aid);
\r
563 update_beacon(padapter, _TIM_IE_, NULL, _TRUE);
\r
565 if(!pmlmeext->active_keep_alive_check)
\r
569 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
\r
570 if (pmlmeext->active_keep_alive_check) {
\r
571 int stainfo_offset;
\r
573 stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
\r
574 if (stainfo_offset_valid(stainfo_offset)) {
\r
575 chk_alive_list[chk_alive_num++] = stainfo_offset;
\r
580 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
\r
581 rtw_list_delete(&psta->asoc_list);
\r
582 pstapriv->asoc_list_cnt--;
\r
583 DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);
\r
584 updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);
\r
588 /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
\r
589 if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt)
\r
590 && padapter->xmitpriv.free_xmitframe_cnt < ((NR_XMITFRAME/pstapriv->asoc_list_cnt)/2)
\r
592 DBG_871X("%s sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__
\r
593 , MAC_ARG(psta->hwaddr)
\r
594 , psta->sleepq_len, padapter->xmitpriv.free_xmitframe_cnt, pstapriv->asoc_list_cnt);
\r
595 wakeup_sta_to_xmit(padapter, psta);
\r
600 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
602 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
\r
603 if (chk_alive_num) {
\r
605 u8 backup_oper_channel=0;
\r
606 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
607 /* switch to correct channel of current network before issue keep-alive frames */
\r
608 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
\r
609 backup_oper_channel = rtw_get_oper_ch(padapter);
\r
610 SelectChannel(padapter, pmlmeext->cur_channel);
\r
613 /* issue null data to check sta alive*/
\r
614 for (i = 0; i < chk_alive_num; i++) {
\r
617 psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
\r
618 #ifdef CONFIG_ATMEL_RC_PATCH
\r
619 if (_TRUE == _rtw_memcmp( pstapriv->atmel_rc_pattern, psta->hwaddr, ETH_ALEN))
\r
621 if (psta->flag_atmel_rc)
\r
624 if(!(psta->state &_FW_LINKED))
\r
627 if (psta->state & WIFI_SLEEP_STATE)
\r
628 ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50);
\r
630 ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50);
\r
632 psta->keep_alive_trycnt++;
\r
633 if (ret == _SUCCESS)
\r
635 DBG_871X("asoc check, sta(" MAC_FMT ") is alive\n", MAC_ARG(psta->hwaddr));
\r
636 psta->expire_to = pstapriv->expire_to;
\r
637 psta->keep_alive_trycnt = 0;
\r
640 else if (psta->keep_alive_trycnt <= 3)
\r
642 DBG_871X("ack check for asoc expire, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt);
\r
643 psta->expire_to = 1;
\r
647 psta->keep_alive_trycnt = 0;
\r
648 DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);
\r
649 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
650 if (rtw_is_list_empty(&psta->asoc_list)==_FALSE) {
\r
651 rtw_list_delete(&psta->asoc_list);
\r
652 pstapriv->asoc_list_cnt--;
\r
653 updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);
\r
655 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
659 if (backup_oper_channel>0) /* back to the original operation channel */
\r
660 SelectChannel(padapter, backup_oper_channel);
\r
662 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
\r
664 associated_clients_update(padapter, updated);
\r
667 void add_RATid(_adapter *padapter, struct sta_info *psta, u8 rssi_level)
\r
671 unsigned char sta_band = 0, shortGIrate = _FALSE;
\r
672 unsigned int tx_ra_bitmap=0;
\r
673 struct ht_priv *psta_ht = NULL;
\r
674 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
675 WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
\r
677 #ifdef CONFIG_80211N_HT
\r
679 psta_ht = &psta->htpriv;
\r
682 #endif //CONFIG_80211N_HT
\r
684 if(!(psta->state & _FW_LINKED))
\r
688 if(get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R)
\r
690 //is this a 2r STA?
\r
691 if((pstat->tx_ra_bitmap & 0x0ff00000) != 0 && !(priv->pshare->has_2r_sta & BIT(pstat->aid)))
\r
693 priv->pshare->has_2r_sta |= BIT(pstat->aid);
\r
694 if(rtw_read16(padapter, 0x102501f6) != 0xffff)
\r
696 rtw_write16(padapter, 0x102501f6, 0xffff);
\r
697 reset_1r_sta_RA(priv, 0xffff);
\r
698 Switch_1SS_Antenna(priv, 3);
\r
701 else// bg or 1R STA?
\r
703 if((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len && priv->pshare->has_2r_sta == 0)
\r
705 if(rtw_read16(padapter, 0x102501f6) != 0x7777)
\r
707 rtw_write16(padapter, 0x102501f6,0x7777);
\r
708 reset_1r_sta_RA(priv, 0x7777);
\r
709 Switch_1SS_Antenna(priv, 2);
\r
716 if ((pstat->rssi_level < 1) || (pstat->rssi_level > 3))
\r
718 if (pstat->rssi >= priv->pshare->rf_ft_var.raGoDownUpper)
\r
719 pstat->rssi_level = 1;
\r
720 else if ((pstat->rssi >= priv->pshare->rf_ft_var.raGoDown20MLower) ||
\r
721 ((priv->pshare->is_40m_bw) && (pstat->ht_cap_len) &&
\r
722 (pstat->rssi >= priv->pshare->rf_ft_var.raGoDown40MLower) &&
\r
723 (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SUPPORT_CH_WDTH_))))
\r
724 pstat->rssi_level = 2;
\r
726 pstat->rssi_level = 3;
\r
729 // rate adaptive by rssi
\r
730 if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len)
\r
732 if ((get_rf_mimo_mode(priv) == MIMO_1T2R) || (get_rf_mimo_mode(priv) == MIMO_1T1R))
\r
734 switch (pstat->rssi_level) {
\r
736 pstat->tx_ra_bitmap &= 0x100f0000;
\r
739 pstat->tx_ra_bitmap &= 0x100ff000;
\r
742 if (priv->pshare->is_40m_bw)
\r
743 pstat->tx_ra_bitmap &= 0x100ff005;
\r
745 pstat->tx_ra_bitmap &= 0x100ff001;
\r
752 switch (pstat->rssi_level) {
\r
754 pstat->tx_ra_bitmap &= 0x1f0f0000;
\r
757 pstat->tx_ra_bitmap &= 0x1f0ff000;
\r
760 if (priv->pshare->is_40m_bw)
\r
761 pstat->tx_ra_bitmap &= 0x000ff005;
\r
763 pstat->tx_ra_bitmap &= 0x000ff001;
\r
768 // Don't need to mask high rates due to new rate adaptive parameters
\r
769 //if (pstat->is_broadcom_sta) // use MCS12 as the highest rate vs. Broadcom sta
\r
770 // pstat->tx_ra_bitmap &= 0x81ffffff;
\r
772 // NIC driver will report not supporting MCS15 and MCS14 in asoc req
\r
773 //if (pstat->is_rtl8190_sta && !pstat->is_2t_mimo_sta)
\r
774 // pstat->tx_ra_bitmap &= 0x83ffffff; // if Realtek 1x2 sta, don't use MCS15 and MCS14
\r
777 else if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) && isErpSta(pstat))
\r
779 switch (pstat->rssi_level) {
\r
781 pstat->tx_ra_bitmap &= 0x00000f00;
\r
784 pstat->tx_ra_bitmap &= 0x00000ff0;
\r
787 pstat->tx_ra_bitmap &= 0x00000ff5;
\r
793 pstat->tx_ra_bitmap &= 0x0000000d;
\r
796 // disable tx short GI when station cannot rx MCS15(AP is 2T2R)
\r
797 // disable tx short GI when station cannot rx MCS7 (AP is 1T2R or 1T1R)
\r
798 // if there is only 1r STA and we are 2T2R, DO NOT mask SGI rate
\r
799 if ((!(pstat->tx_ra_bitmap & 0x8000000) && (priv->pshare->has_2r_sta > 0) && (get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R)) ||
\r
800 (!(pstat->tx_ra_bitmap & 0x80000) && (get_rf_mimo_mode(padapter) != RTL8712_RF_2T2R)))
\r
802 pstat->tx_ra_bitmap &= ~BIT(28);
\r
806 rtw_hal_update_sta_rate_mask(padapter, psta);
\r
807 tx_ra_bitmap = psta->ra_mask;
\r
809 shortGIrate = query_ra_short_GI(psta);
\r
811 if ( pcur_network->Configuration.DSConfig > 14 ) {
\r
813 if (tx_ra_bitmap & 0xffff000)
\r
814 sta_band |= WIRELESS_11_5N ;
\r
816 if (tx_ra_bitmap & 0xff0)
\r
817 sta_band |= WIRELESS_11A;
\r
820 #ifdef CONFIG_80211AC_VHT
\r
821 if (psta->vhtpriv.vht_option) {
\r
822 sta_band = WIRELESS_11_5AC;
\r
827 if (tx_ra_bitmap & 0xffff000)
\r
828 sta_band |= WIRELESS_11_24N;
\r
830 if (tx_ra_bitmap & 0xff0)
\r
831 sta_band |= WIRELESS_11G;
\r
833 if (tx_ra_bitmap & 0x0f)
\r
834 sta_band |= WIRELESS_11B;
\r
837 psta->wireless_mode = sta_band;
\r
838 psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
\r
840 if (psta->aid < NUM_STA)
\r
844 arg[0] = psta->mac_id;
\r
845 arg[1] = psta->raid;
\r
846 arg[2] = shortGIrate;
\r
847 arg[3] = psta->init_rate;
\r
849 DBG_871X("%s=> mac_id:%d , raid:%d , shortGIrate=%d, bitmap=0x%x\n",
\r
850 __FUNCTION__ , psta->mac_id, psta->raid ,shortGIrate, tx_ra_bitmap);
\r
852 rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level);
\r
856 DBG_871X("station aid %d exceed the max number\n", psta->aid);
\r
861 void update_bmc_sta(_adapter *padapter)
\r
864 unsigned char network_type;
\r
865 int supportRateNum = 0;
\r
866 unsigned int tx_ra_bitmap=0;
\r
867 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
868 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
869 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
870 WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
\r
871 struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
\r
875 psta->aid = 0;//default set to 0
\r
876 //psta->mac_id = psta->aid+4;
\r
877 psta->mac_id = psta->aid + 1;//mac_id=1 for bc/mc stainfo
\r
879 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
\r
881 psta->qos_option = 0;
\r
882 #ifdef CONFIG_80211N_HT
\r
883 psta->htpriv.ht_option = _FALSE;
\r
884 #endif //CONFIG_80211N_HT
\r
886 psta->ieee8021x_blocked = 0;
\r
888 _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
\r
890 //psta->dot118021XPrivacy = _NO_PRIVACY_;//!!! remove it, because it has been set before this.
\r
892 //prepare for add_RATid
\r
893 supportRateNum = rtw_get_rateset_len((u8*)&pcur_network->SupportedRates);
\r
894 network_type = rtw_check_network_type((u8*)&pcur_network->SupportedRates, supportRateNum, pcur_network->Configuration.DSConfig);
\r
895 if (IsSupportedTxCCK(network_type)) {
\r
896 network_type = WIRELESS_11B;
\r
898 else if (network_type == WIRELESS_INVALID) { // error handling
\r
899 if ( pcur_network->Configuration.DSConfig > 14 )
\r
900 network_type = WIRELESS_11A;
\r
902 network_type = WIRELESS_11B;
\r
904 update_sta_basic_rate(psta, network_type);
\r
905 psta->wireless_mode = network_type;
\r
907 rtw_hal_update_sta_rate_mask(padapter, psta);
\r
908 tx_ra_bitmap = psta->ra_mask;
\r
910 psta->raid = rtw_hal_networktype_to_raid(padapter,psta);
\r
913 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
\r
915 //if(pHalData->fw_ractrl == _TRUE)
\r
919 arg[0] = psta->mac_id;
\r
920 arg[1] = psta->raid;
\r
922 arg[3] = psta->init_rate;
\r
924 DBG_871X("%s=> mac_id:%d , raid:%d , bitmap=0x%x\n",
\r
925 __FUNCTION__ , psta->mac_id, psta->raid , tx_ra_bitmap);
\r
927 rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0);
\r
930 rtw_sta_media_status_rpt(padapter, psta, 1);
\r
932 _enter_critical_bh(&psta->lock, &irqL);
\r
933 psta->state = _FW_LINKED;
\r
934 _exit_critical_bh(&psta->lock, &irqL);
\r
939 DBG_871X("add_RATid_bmc_sta error!\n");
\r
945 //AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode
\r
946 //MAC_ID = AID+1 for sta in ap/adhoc mode
\r
947 //MAC_ID = 1 for bc/mc for sta/ap/adhoc
\r
948 //MAC_ID = 0 for bssid for sta/ap/adhoc
\r
949 //CAM_ID = //0~3 for default key, cmd_id=macid + 3, macid=aid+1;
\r
951 void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta)
\r
954 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
955 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
956 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
957 #ifdef CONFIG_80211N_HT
\r
958 struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
\r
959 struct ht_priv *phtpriv_sta = &psta->htpriv;
\r
960 #endif //CONFIG_80211N_HT
\r
961 //set intf_tag to if1
\r
962 //psta->intf_tag = 0;
\r
964 DBG_871X("%s\n",__FUNCTION__);
\r
966 //psta->mac_id = psta->aid+4;
\r
967 //psta->mac_id = psta->aid+1;//alloc macid when call rtw_alloc_stainfo(),
\r
968 //release macid when call rtw_free_stainfo()
\r
971 rtw_hal_set_odm_var(padapter,HAL_ODM_STA_INFO,psta,_TRUE);
\r
973 if(psecuritypriv->dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)
\r
974 psta->ieee8021x_blocked = _TRUE;
\r
976 psta->ieee8021x_blocked = _FALSE;
\r
982 VCS_update(padapter, psta);
\r
983 #ifdef CONFIG_80211N_HT
\r
985 if(phtpriv_sta->ht_option)
\r
987 //check if sta supports rx ampdu
\r
988 phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
\r
990 //check if sta support s Short GI 20M
\r
991 if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))
\r
993 phtpriv_sta->sgi_20m = _TRUE;
\r
995 //check if sta support s Short GI 40M
\r
996 if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_40))
\r
998 phtpriv_sta->sgi_40m = _TRUE;
\r
1002 if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
\r
1004 phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
\r
1005 psta->bw_mode = CHANNEL_WIDTH_40;
\r
1009 psta->bw_mode = CHANNEL_WIDTH_20;
\r
1012 psta->qos_option = _TRUE;
\r
1016 phtpriv_sta->ampdu_enable = _FALSE;
\r
1018 phtpriv_sta->sgi_20m = _FALSE;
\r
1019 phtpriv_sta->sgi_40m = _FALSE;
\r
1020 psta->bw_mode = CHANNEL_WIDTH_20;
\r
1021 phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
1025 send_delba(padapter, 0, psta->hwaddr);// recipient
\r
1028 send_delba(padapter, 1, psta->hwaddr);// // originator
\r
1029 phtpriv_sta->agg_enable_bitmap = 0x0;//reset
\r
1030 phtpriv_sta->candidate_tid_bitmap = 0x0;//reset
\r
1031 #endif //CONFIG_80211N_HT
\r
1033 #ifdef CONFIG_80211AC_VHT
\r
1034 update_sta_vht_info_apmode(padapter, psta);
\r
1037 //todo: init other variables
\r
1039 _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
\r
1043 //add_RATid(padapter, psta);//move to ap_sta_info_defer_update()
\r
1046 _enter_critical_bh(&psta->lock, &irqL);
\r
1047 psta->state |= _FW_LINKED;
\r
1048 _exit_critical_bh(&psta->lock, &irqL);
\r
1053 static void update_hw_ht_param(_adapter *padapter)
\r
1055 unsigned char max_AMPDU_len;
\r
1056 unsigned char min_MPDU_spacing;
\r
1057 struct registry_priv *pregpriv = &padapter->registrypriv;
\r
1058 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
1059 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
1061 DBG_871X("%s\n", __FUNCTION__);
\r
1064 //handle A-MPDU parameter field
\r
1066 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
\r
1067 AMPDU_para [4:2]:Min MPDU Start Spacing
\r
1069 max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
\r
1071 min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
\r
1073 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
\r
1075 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
\r
1078 // Config SM Power Save setting
\r
1080 pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
\r
1081 if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
\r
1084 //update the MCS rates
\r
1085 for (i = 0; i < 16; i++)
\r
1087 pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
\r
1089 DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__);
\r
1093 // Config current HT Protection mode.
\r
1095 //pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
\r
1099 void start_bss_network(_adapter *padapter, u8 *pbuf)
\r
1102 u8 val8, cur_channel, cur_bwmode, cur_ch_offset;
\r
1106 struct registry_priv *pregpriv = &padapter->registrypriv;
\r
1107 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
1108 struct security_priv* psecuritypriv=&(padapter->securitypriv);
\r
1109 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
\r
1110 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
1111 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
1112 WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);
\r
1113 struct HT_info_element *pht_info=NULL;
\r
1115 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
\r
1116 #endif //CONFIG_P2P
\r
1117 u8 cbw40_enable=0;
\r
1118 u8 change_band = _FALSE;
\r
1120 //DBG_871X("%s\n", __FUNCTION__);
\r
1122 bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
\r
1123 cur_channel = pnetwork->Configuration.DSConfig;
\r
1124 cur_bwmode = CHANNEL_WIDTH_20;
\r
1125 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
1128 //check if there is wps ie,
\r
1129 //if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd,
\r
1130 //and at first time the security ie ( RSN/WPA IE) will not include in beacon.
\r
1131 if(NULL == rtw_get_wps_ie(pnetwork->IEs+_FIXED_IE_LENGTH_, pnetwork->IELength-_FIXED_IE_LENGTH_, NULL, NULL))
\r
1133 pmlmeext->bstart_bss = _TRUE;
\r
1136 //todo: update wmm, ht cap
\r
1137 //pmlmeinfo->WMM_enable;
\r
1138 //pmlmeinfo->HT_enable;
\r
1139 if(pmlmepriv->qospriv.qos_option)
\r
1140 pmlmeinfo->WMM_enable = _TRUE;
\r
1141 #ifdef CONFIG_80211N_HT
\r
1142 if(pmlmepriv->htpriv.ht_option)
\r
1144 pmlmeinfo->WMM_enable = _TRUE;
\r
1145 pmlmeinfo->HT_enable = _TRUE;
\r
1146 //pmlmeinfo->HT_info_enable = _TRUE;
\r
1147 //pmlmeinfo->HT_caps_enable = _TRUE;
\r
1149 update_hw_ht_param(padapter);
\r
1151 #endif //#CONFIG_80211N_HT
\r
1153 #ifdef CONFIG_80211AC_VHT
\r
1154 if(pmlmepriv->vhtpriv.vht_option) {
\r
1155 pmlmeinfo->VHT_enable = _TRUE;
\r
1156 update_hw_vht_param(padapter);
\r
1158 #endif //CONFIG_80211AC_VHT
\r
1160 if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at first time
\r
1162 //WEP Key will be set before this function, do not clear CAM.
\r
1163 if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_))
\r
1164 flush_all_cam_entry(padapter); //clear CAM
\r
1167 //set MSR to AP_Mode
\r
1168 Set_MSR(padapter, _HW_STATE_AP_);
\r
1171 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress);
\r
1173 //Set EDCA param reg
\r
1174 #ifdef CONFIG_CONCURRENT_MODE
\r
1175 acparm = 0x005ea42b;
\r
1177 acparm = 0x002F3217; // VO
\r
1179 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
\r
1180 acparm = 0x005E4317; // VI
\r
1181 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
\r
1182 //acparm = 0x00105320; // BE
\r
1183 acparm = 0x005ea42b;
\r
1184 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
\r
1185 acparm = 0x0000A444; // BK
\r
1186 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
\r
1189 val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
\r
1190 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
\r
1192 //Beacon Control related register
\r
1193 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));
\r
1195 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
\r
1197 if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at first time
\r
1199 //u32 initialgain;
\r
1201 //initialgain = 0x1e;
\r
1204 //disable dynamic functions, such as high power, DIG
\r
1205 //Save_DM_Func_Flag(padapter);
\r
1206 //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
\r
1208 //turn on all dynamic functions
\r
1209 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
\r
1211 //rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
\r
1214 #ifdef CONFIG_80211N_HT
\r
1215 //set channel, bwmode
\r
1216 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)));
\r
1219 pht_info = (struct HT_info_element *)(p+2);
\r
1221 if (cur_channel > 14) {
\r
1222 if ((pregpriv->bw_mode & 0xf0) > 0)
\r
1225 if ((pregpriv->bw_mode & 0x0f) > 0)
\r
1229 if ((cbw40_enable) && (pht_info->infos[0] & BIT(2)))
\r
1231 //switch to the 40M Hz mode
\r
1232 //pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;
\r
1233 cur_bwmode = CHANNEL_WIDTH_40;
\r
1234 switch (pht_info->infos[0] & 0x3)
\r
1237 //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
\r
1238 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
\r
1242 //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
\r
1243 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
\r
1247 //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
1248 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
1255 #endif //CONFIG_80211N_HT
\r
1257 #ifdef CONFIG_80211AC_VHT
\r
1258 p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTOperation, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
\r
1261 if(GET_VHT_OPERATION_ELE_CHL_WIDTH(p+2) >= 1) {
\r
1262 cur_bwmode = CHANNEL_WIDTH_80;
\r
1267 #ifdef CONFIG_DUALMAC_CONCURRENT
\r
1268 dc_set_ap_channel_bandwidth(padapter, cur_channel, cur_ch_offset, cur_bwmode);
\r
1269 #else //!CONFIG_DUALMAC_CONCURRENT
\r
1270 #ifdef CONFIG_CONCURRENT_MODE
\r
1271 //TODO: need to judge the phy parameters on concurrent mode for single phy
\r
1272 concurrent_set_ap_chbw(padapter, cur_channel, cur_ch_offset, cur_bwmode);
\r
1273 #else //!CONFIG_CONCURRENT_MODE
\r
1274 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
\r
1275 DBG_871X("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
\r
1276 pmlmeext->cur_channel = cur_channel;
\r
1277 pmlmeext->cur_bwmode = cur_bwmode;
\r
1278 pmlmeext->cur_ch_offset = cur_ch_offset;
\r
1279 #endif //!CONFIG_CONCURRENT_MODE
\r
1280 #endif //!CONFIG_DUALMAC_CONCURRENT
\r
1282 pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;
\r
1284 //let pnetwork_mlmeext == pnetwork_mlme.
\r
1285 _rtw_memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
\r
1287 //update cur_wireless_mode
\r
1288 update_wireless_mode(padapter);
\r
1290 //update RRSR after set channel and bandwidth
\r
1291 UpdateBrateTbl(padapter, pnetwork->SupportedRates);
\r
1292 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
\r
1294 //udpate capability after cur_wireless_mode updated
\r
1295 update_capinfo(padapter, rtw_get_capability((WLAN_BSSID_EX *)pnetwork));
\r
1299 _rtw_memcpy(pwdinfo->p2p_group_ssid, pnetwork->Ssid.Ssid, pnetwork->Ssid.SsidLength);
\r
1300 pwdinfo->p2p_group_ssid_len = pnetwork->Ssid.SsidLength;
\r
1301 #endif //CONFIG_P2P
\r
1303 if(_TRUE == pmlmeext->bstart_bss)
\r
1305 update_beacon(padapter, _TIM_IE_, NULL, _TRUE);
\r
1307 #ifndef CONFIG_INTERRUPT_BASED_TXBCN //other case will tx beacon when bcn interrupt coming in.
\r
1308 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
\r
1309 //issue beacon frame
\r
1310 if(send_beacon(padapter)==_FAIL)
\r
1312 DBG_871X("issue_beacon, fail!\n");
\r
1315 #endif //!CONFIG_INTERRUPT_BASED_TXBCN
\r
1320 //update bc/mc sta_info
\r
1321 update_bmc_sta(padapter);
\r
1323 //pmlmeext->bstart_bss = _TRUE;
\r
1327 int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len)
\r
1331 u8 *pHT_caps_ie=NULL;
\r
1332 u8 *pHT_info_ie=NULL;
\r
1333 struct sta_info *psta = NULL;
\r
1334 u16 cap, ht_cap=_FALSE;
\r
1336 int group_cipher, pairwise_cipher;
\r
1337 u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
\r
1338 int supportRateNum = 0;
\r
1339 u8 OUI1[] = {0x00, 0x50, 0xf2,0x01};
\r
1340 u8 wps_oui[4]={0x0,0x50,0xf2,0x04};
\r
1341 u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
\r
1342 struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
1343 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1344 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
1345 WLAN_BSSID_EX *pbss_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
\r
1346 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1347 u8 *ie = pbss_network->IEs;
\r
1348 u8 vht_cap=_FALSE;
\r
1351 /* Supported rates */
\r
1353 /* WLAN_EID_COUNTRY */
\r
1354 /* ERP Information element */
\r
1355 /* Extended supported rates */
\r
1357 /* Wi-Fi Wireless Multimedia Extensions */
\r
1358 /* ht_capab, ht_oper */
\r
1361 DBG_871X("%s, len=%d\n", __FUNCTION__, len);
\r
1363 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
\r
1370 pbss_network->IELength = len;
\r
1372 _rtw_memset(ie, 0, MAX_IE_SZ);
\r
1374 _rtw_memcpy(ie, pbuf, pbss_network->IELength);
\r
1377 if(pbss_network->InfrastructureMode!=Ndis802_11APMode)
\r
1380 pbss_network->Rssi = 0;
\r
1382 _rtw_memcpy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
1385 p = rtw_get_beacon_interval_from_ie(ie);//ie + 8; // 8: TimeStamp, 2: Beacon Interval 2:Capability
\r
1386 //pbss_network->Configuration.BeaconPeriod = le16_to_cpu(*(unsigned short*)p);
\r
1387 pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p);
\r
1390 //cap = *(unsigned short *)rtw_get_capability_from_ie(ie);
\r
1391 //cap = le16_to_cpu(cap);
\r
1392 cap = RTW_GET_LE16(ie);
\r
1395 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength -_BEACON_IE_OFFSET_));
\r
1398 _rtw_memset(&pbss_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
\r
1399 _rtw_memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);
\r
1400 pbss_network->Ssid.SsidLength = ie_len;
\r
1405 pbss_network->Configuration.Length = 0;
\r
1406 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
\r
1408 channel = *(p + 2);
\r
1410 pbss_network->Configuration.DSConfig = channel;
\r
1413 _rtw_memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
\r
1414 // get supported rates
\r
1415 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
\r
1418 _rtw_memcpy(supportRate, p+2, ie_len);
\r
1419 supportRateNum = ie_len;
\r
1422 //get ext_supported rates
\r
1423 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_);
\r
1426 _rtw_memcpy(supportRate+supportRateNum, p+2, ie_len);
\r
1427 supportRateNum += ie_len;
\r
1431 network_type = rtw_check_network_type(supportRate, supportRateNum, channel);
\r
1433 rtw_set_supported_rate(pbss_network->SupportedRates, network_type);
\r
1437 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
\r
1440 ERP_IE_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)p);
\r
1443 //update privacy/security
\r
1445 pbss_network->Privacy = 1;
\r
1447 pbss_network->Privacy = 0;
\r
1449 psecuritypriv->wpa_psk = 0;
\r
1452 group_cipher = 0; pairwise_cipher = 0;
\r
1453 psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
\r
1454 psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
\r
1455 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
\r
1458 if(rtw_parse_wpa2_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
1460 psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
1462 psecuritypriv->dot8021xalg = 1;//psk, todo:802.1x
\r
1463 psecuritypriv->wpa_psk |= BIT(1);
\r
1465 psecuritypriv->wpa2_group_cipher = group_cipher;
\r
1466 psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
\r
1468 switch(group_cipher)
\r
1470 case WPA_CIPHER_NONE:
\r
1471 psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
\r
1473 case WPA_CIPHER_WEP40:
\r
1474 psecuritypriv->wpa2_group_cipher = _WEP40_;
\r
1476 case WPA_CIPHER_TKIP:
\r
1477 psecuritypriv->wpa2_group_cipher = _TKIP_;
\r
1479 case WPA_CIPHER_CCMP:
\r
1480 psecuritypriv->wpa2_group_cipher = _AES_;
\r
1482 case WPA_CIPHER_WEP104:
\r
1483 psecuritypriv->wpa2_group_cipher = _WEP104_;
\r
1487 switch(pairwise_cipher)
\r
1489 case WPA_CIPHER_NONE:
\r
1490 psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
\r
1492 case WPA_CIPHER_WEP40:
\r
1493 psecuritypriv->wpa2_pairwise_cipher = _WEP40_;
\r
1495 case WPA_CIPHER_TKIP:
\r
1496 psecuritypriv->wpa2_pairwise_cipher = _TKIP_;
\r
1498 case WPA_CIPHER_CCMP:
\r
1499 psecuritypriv->wpa2_pairwise_cipher = _AES_;
\r
1501 case WPA_CIPHER_WEP104:
\r
1502 psecuritypriv->wpa2_pairwise_cipher = _WEP104_;
\r
1512 group_cipher = 0; pairwise_cipher = 0;
\r
1513 psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
\r
1514 psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
\r
1515 for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2))
\r
1517 p = rtw_get_ie(p, _SSN_IE_1_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
\r
1518 if ((p) && (_rtw_memcmp(p+2, OUI1, 4)))
\r
1520 if(rtw_parse_wpa_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
1522 psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
1524 psecuritypriv->dot8021xalg = 1;//psk, todo:802.1x
\r
1526 psecuritypriv->wpa_psk |= BIT(0);
\r
1528 psecuritypriv->wpa_group_cipher = group_cipher;
\r
1529 psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
\r
1532 switch(group_cipher)
\r
1534 case WPA_CIPHER_NONE:
\r
1535 psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
\r
1537 case WPA_CIPHER_WEP40:
\r
1538 psecuritypriv->wpa_group_cipher = _WEP40_;
\r
1540 case WPA_CIPHER_TKIP:
\r
1541 psecuritypriv->wpa_group_cipher = _TKIP_;
\r
1543 case WPA_CIPHER_CCMP:
\r
1544 psecuritypriv->wpa_group_cipher = _AES_;
\r
1546 case WPA_CIPHER_WEP104:
\r
1547 psecuritypriv->wpa_group_cipher = _WEP104_;
\r
1551 switch(pairwise_cipher)
\r
1553 case WPA_CIPHER_NONE:
\r
1554 psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
\r
1556 case WPA_CIPHER_WEP40:
\r
1557 psecuritypriv->wpa_pairwise_cipher = _WEP40_;
\r
1559 case WPA_CIPHER_TKIP:
\r
1560 psecuritypriv->wpa_pairwise_cipher = _TKIP_;
\r
1562 case WPA_CIPHER_CCMP:
\r
1563 psecuritypriv->wpa_pairwise_cipher = _AES_;
\r
1565 case WPA_CIPHER_WEP104:
\r
1566 psecuritypriv->wpa_pairwise_cipher = _WEP104_;
\r
1576 if ((p == NULL) || (ie_len == 0))
\r
1585 pmlmepriv->qospriv.qos_option = 0;
\r
1586 if(pregistrypriv->wmm_enable)
\r
1588 for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2))
\r
1590 p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
\r
1591 if((p) && _rtw_memcmp(p+2, WMM_PARA_IE, 6))
\r
1593 pmlmepriv->qospriv.qos_option = 1;
\r
1595 *(p+8) |= BIT(7);//QoS Info, support U-APSD
\r
1597 /* disable all ACM bits since the WMM admission control is not supported */
\r
1598 *(p + 10) &= ~BIT(4); /* BE */
\r
1599 *(p + 14) &= ~BIT(4); /* BK */
\r
1600 *(p + 18) &= ~BIT(4); /* VI */
\r
1601 *(p + 22) &= ~BIT(4); /* VO */
\r
1606 if ((p == NULL) || (ie_len == 0))
\r
1612 #ifdef CONFIG_80211N_HT
\r
1613 //parsing HT_CAP_IE
\r
1614 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
\r
1619 struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2);
\r
1625 network_type |= WIRELESS_11_24N;
\r
1628 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
\r
1630 if((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
\r
1631 (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
\r
1633 pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
\r
1637 pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
\r
1640 pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03); //set Max Rx AMPDU size to 64K
\r
1642 if(rf_type == RF_1T1R)
\r
1644 pht_cap->supp_mcs_set[0] = 0xff;
\r
1645 pht_cap->supp_mcs_set[1] = 0x0;
\r
1648 _rtw_memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len);
\r
1652 //parsing HT_INFO_IE
\r
1653 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
\r
1658 #endif //CONFIG_80211N_HT
\r
1659 switch(network_type)
\r
1661 case WIRELESS_11B:
\r
1662 pbss_network->NetworkTypeInUse = Ndis802_11DS;
\r
1664 case WIRELESS_11G:
\r
1665 case WIRELESS_11BG:
\r
1666 case WIRELESS_11G_24N:
\r
1667 case WIRELESS_11BG_24N:
\r
1668 pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
\r
1670 case WIRELESS_11A:
\r
1671 pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;
\r
1674 pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
\r
1678 pmlmepriv->cur_network.network_type = network_type;
\r
1680 #ifdef CONFIG_80211N_HT
\r
1681 pmlmepriv->htpriv.ht_option = _FALSE;
\r
1683 if( (psecuritypriv->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
\r
1684 (psecuritypriv->wpa_pairwise_cipher&WPA_CIPHER_TKIP))
\r
1687 //ht_cap = _FALSE;
\r
1691 if(pregistrypriv->ht_enable && ht_cap==_TRUE)
\r
1693 pmlmepriv->htpriv.ht_option = _TRUE;
\r
1694 pmlmepriv->qospriv.qos_option = 1;
\r
1696 if(pregistrypriv->ampdu_enable==1)
\r
1698 pmlmepriv->htpriv.ampdu_enable = _TRUE;
\r
1701 HT_caps_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_caps_ie);
\r
1703 HT_info_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_info_ie);
\r
1707 #ifdef CONFIG_80211AC_VHT
\r
1709 //Parsing VHT CAP IE
\r
1710 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
\r
1715 //Parsing VHT OPERATION IE
\r
1718 pmlmepriv->vhtpriv.vht_option = _FALSE;
\r
1719 // if channel in 5G band, then add vht ie .
\r
1720 if ((pbss_network->Configuration.DSConfig > 14) &&
\r
1721 (pmlmepriv->htpriv.ht_option == _TRUE) &&
\r
1722 (pregistrypriv->vht_enable))
\r
1724 if(vht_cap == _TRUE)
\r
1726 pmlmepriv->vhtpriv.vht_option = _TRUE;
\r
1728 else if(pregistrypriv->vht_enable == 2) // auto enabled
\r
1730 u8 cap_len, operation_len;
\r
1732 rtw_vht_use_default_setting(padapter);
\r
1734 // VHT Capabilities element
\r
1735 cap_len = rtw_build_vht_cap_ie(padapter, pbss_network->IEs + pbss_network->IELength);
\r
1736 pbss_network->IELength += cap_len;
\r
1738 // VHT Operation element
\r
1739 operation_len = rtw_build_vht_operation_ie(padapter, pbss_network->IEs + pbss_network->IELength, pbss_network->Configuration.DSConfig);
\r
1740 pbss_network->IELength += operation_len;
\r
1742 pmlmepriv->vhtpriv.vht_option = _TRUE;
\r
1745 #endif //CONFIG_80211AC_VHT
\r
1747 pbss_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pbss_network);
\r
1749 //issue beacon to start bss network
\r
1750 //start_bss_network(padapter, (u8*)pbss_network);
\r
1751 rtw_startbss_cmd(padapter, RTW_CMDF_WAIT_ACK);
\r
1754 //alloc sta_info for ap itself
\r
1755 psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
\r
1758 psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
\r
1759 if (psta == NULL)
\r
1764 psta->state |= WIFI_AP_STATE; //Aries, add,fix bug of flush_cam_entry at STOP AP mode , 0724
\r
1765 rtw_indicate_connect( padapter);
\r
1767 pmlmepriv->cur_network.join_res = _TRUE;//for check if already set beacon
\r
1769 //update bc/mc sta_info
\r
1770 //update_bmc_sta(padapter);
\r
1776 void rtw_set_macaddr_acl(_adapter *padapter, int mode)
\r
1778 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1779 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
\r
1781 DBG_871X("%s, mode=%d\n", __func__, mode);
\r
1783 pacl_list->mode = mode;
\r
1786 int rtw_acl_add_sta(_adapter *padapter, u8 *addr)
\r
1789 _list *plist, *phead;
\r
1790 u8 added = _FALSE;
\r
1792 struct rtw_wlan_acl_node *paclnode;
\r
1793 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1794 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
\r
1795 _queue *pacl_node_q =&pacl_list->acl_node_q;
\r
1797 DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));
\r
1799 if((NUM_ACL-1) < pacl_list->num)
\r
1803 _enter_critical_bh(&(pacl_node_q->lock), &irqL);
\r
1805 phead = get_list_head(pacl_node_q);
\r
1806 plist = get_next(phead);
\r
1808 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
1810 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
\r
1811 plist = get_next(plist);
\r
1813 if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN))
\r
1815 if(paclnode->valid == _TRUE)
\r
1818 DBG_871X("%s, sta has been added\n", __func__);
\r
1824 _exit_critical_bh(&(pacl_node_q->lock), &irqL);
\r
1827 if(added == _TRUE)
\r
1831 _enter_critical_bh(&(pacl_node_q->lock), &irqL);
\r
1833 for(i=0; i< NUM_ACL; i++)
\r
1835 paclnode = &pacl_list->aclnode[i];
\r
1837 if(paclnode->valid == _FALSE)
\r
1839 _rtw_init_listhead(&paclnode->list);
\r
1841 _rtw_memcpy(paclnode->addr, addr, ETH_ALEN);
\r
1843 paclnode->valid = _TRUE;
\r
1845 rtw_list_insert_tail(&paclnode->list, get_list_head(pacl_node_q));
\r
1853 DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num);
\r
1855 _exit_critical_bh(&(pacl_node_q->lock), &irqL);
\r
1860 int rtw_acl_remove_sta(_adapter *padapter, u8 *addr)
\r
1863 _list *plist, *phead;
\r
1865 struct rtw_wlan_acl_node *paclnode;
\r
1866 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1867 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
\r
1868 _queue *pacl_node_q =&pacl_list->acl_node_q;
\r
1869 u8 baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; //Baddr is used for clearing acl_list
\r
1871 DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));
\r
1873 _enter_critical_bh(&(pacl_node_q->lock), &irqL);
\r
1875 phead = get_list_head(pacl_node_q);
\r
1876 plist = get_next(phead);
\r
1878 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
1880 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
\r
1881 plist = get_next(plist);
\r
1883 if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN) || _rtw_memcmp(baddr, addr, ETH_ALEN))
\r
1885 if(paclnode->valid == _TRUE)
\r
1887 paclnode->valid = _FALSE;
\r
1889 rtw_list_delete(&paclnode->list);
\r
1896 _exit_critical_bh(&(pacl_node_q->lock), &irqL);
\r
1898 DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num);
\r
1904 u8 rtw_ap_set_pairwise_key(_adapter *padapter, struct sta_info *psta)
\r
1906 struct cmd_obj* ph2c;
\r
1907 struct set_stakey_parm *psetstakey_para;
\r
1908 struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
\r
1911 ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
\r
1912 if ( ph2c == NULL){
\r
1917 psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm));
\r
1918 if(psetstakey_para==NULL){
\r
1919 rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj));
\r
1924 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
\r
1927 psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy;
\r
1929 _rtw_memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);
\r
1931 _rtw_memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
\r
1934 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
\r
1942 static int rtw_ap_set_key(_adapter *padapter, u8 *key, u8 alg, int keyid, u8 set_tx)
\r
1945 struct cmd_obj* pcmd;
\r
1946 struct setkey_parm *psetkeyparm;
\r
1947 struct cmd_priv *pcmdpriv=&(padapter->cmdpriv);
\r
1950 //DBG_871X("%s\n", __FUNCTION__);
\r
1952 pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
\r
1957 psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm));
\r
1958 if(psetkeyparm==NULL){
\r
1959 rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj));
\r
1964 _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
\r
1966 psetkeyparm->keyid=(u8)keyid;
\r
1967 if (is_wep_enc(alg))
\r
1968 padapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);
\r
1970 psetkeyparm->algorithm = alg;
\r
1972 psetkeyparm->set_tx = set_tx;
\r
1983 case _TKIP_WTMIC_:
\r
1990 _rtw_memcpy(&(psetkeyparm->key[0]), key, keylen);
\r
1992 pcmd->cmdcode = _SetKey_CMD_;
\r
1993 pcmd->parmbuf = (u8 *)psetkeyparm;
\r
1994 pcmd->cmdsz = (sizeof(struct setkey_parm));
\r
1999 _rtw_init_listhead(&pcmd->list);
\r
2001 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
\r
2008 int rtw_ap_set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid)
\r
2010 DBG_871X("%s\n", __FUNCTION__);
\r
2012 return rtw_ap_set_key(padapter, key, alg, keyid, 1);
\r
2015 int rtw_ap_set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid, u8 set_tx)
\r
2028 alg =_NO_PRIVACY_;
\r
2031 DBG_871X("%s\n", __FUNCTION__);
\r
2033 return rtw_ap_set_key(padapter, key, alg, keyid, set_tx);
\r
2036 #ifdef CONFIG_NATIVEAP_MLME
\r
2038 static void update_bcn_fixed_ie(_adapter *padapter)
\r
2040 DBG_871X("%s\n", __FUNCTION__);
\r
2044 static void update_bcn_erpinfo_ie(_adapter *padapter)
\r
2046 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2047 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
2048 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2049 WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
\r
2050 unsigned char *p, *ie = pnetwork->IEs;
\r
2053 DBG_871X("%s, ERP_enable=%d\n", __FUNCTION__, pmlmeinfo->ERP_enable);
\r
2055 if(!pmlmeinfo->ERP_enable)
\r
2059 p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
\r
2062 PNDIS_802_11_VARIABLE_IEs pIE = (PNDIS_802_11_VARIABLE_IEs)p;
\r
2064 if (pmlmepriv->num_sta_non_erp == 1)
\r
2065 pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION;
\r
2067 pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION);
\r
2069 if(pmlmepriv->num_sta_no_short_preamble > 0)
\r
2070 pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
\r
2072 pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);
\r
2074 ERP_IE_handler(padapter, pIE);
\r
2079 static void update_bcn_htcap_ie(_adapter *padapter)
\r
2081 DBG_871X("%s\n", __FUNCTION__);
\r
2085 static void update_bcn_htinfo_ie(_adapter *padapter)
\r
2087 DBG_871X("%s\n", __FUNCTION__);
\r
2091 static void update_bcn_rsn_ie(_adapter *padapter)
\r
2093 DBG_871X("%s\n", __FUNCTION__);
\r
2097 static void update_bcn_wpa_ie(_adapter *padapter)
\r
2099 DBG_871X("%s\n", __FUNCTION__);
\r
2103 static void update_bcn_wmm_ie(_adapter *padapter)
\r
2105 DBG_871X("%s\n", __FUNCTION__);
\r
2109 static void update_bcn_wps_ie(_adapter *padapter)
\r
2111 u8 *pwps_ie=NULL, *pwps_ie_src, *premainder_ie, *pbackup_remainder_ie=NULL;
\r
2112 uint wps_ielen=0, wps_offset, remainder_ielen;
\r
2113 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2114 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
2115 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2116 WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
\r
2117 unsigned char *ie = pnetwork->IEs;
\r
2118 u32 ielen = pnetwork->IELength;
\r
2121 DBG_871X("%s\n", __FUNCTION__);
\r
2123 pwps_ie = rtw_get_wps_ie(ie+_FIXED_IE_LENGTH_, ielen-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
\r
2125 if(pwps_ie==NULL || wps_ielen==0)
\r
2128 pwps_ie_src = pmlmepriv->wps_beacon_ie;
\r
2129 if(pwps_ie_src == NULL)
\r
2132 wps_offset = (uint)(pwps_ie-ie);
\r
2134 premainder_ie = pwps_ie + wps_ielen;
\r
2136 remainder_ielen = ielen - wps_offset - wps_ielen;
\r
2138 if(remainder_ielen>0)
\r
2140 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
\r
2141 if(pbackup_remainder_ie)
\r
2142 _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
\r
2145 wps_ielen = (uint)pwps_ie_src[1];//to get ie data len
\r
2146 if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
\r
2148 _rtw_memcpy(pwps_ie, pwps_ie_src, wps_ielen+2);
\r
2149 pwps_ie += (wps_ielen+2);
\r
2151 if(pbackup_remainder_ie)
\r
2152 _rtw_memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
\r
2155 pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen;
\r
2158 if(pbackup_remainder_ie)
\r
2159 rtw_mfree(pbackup_remainder_ie, remainder_ielen);
\r
2163 static void update_bcn_p2p_ie(_adapter *padapter)
\r
2168 static void update_bcn_vendor_spec_ie(_adapter *padapter, u8*oui)
\r
2170 DBG_871X("%s\n", __FUNCTION__);
\r
2172 if(_rtw_memcmp(RTW_WPA_OUI, oui, 4))
\r
2174 update_bcn_wpa_ie(padapter);
\r
2176 else if(_rtw_memcmp(WMM_OUI, oui, 4))
\r
2178 update_bcn_wmm_ie(padapter);
\r
2180 else if(_rtw_memcmp(WPS_OUI, oui, 4))
\r
2182 update_bcn_wps_ie(padapter);
\r
2184 else if(_rtw_memcmp(P2P_OUI, oui, 4))
\r
2186 update_bcn_p2p_ie(padapter);
\r
2190 DBG_871X("unknown OUI type!\n");
\r
2196 void update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
\r
2199 struct mlme_priv *pmlmepriv;
\r
2200 struct mlme_ext_priv *pmlmeext;
\r
2201 //struct mlme_ext_info *pmlmeinfo;
\r
2203 //DBG_871X("%s\n", __FUNCTION__);
\r
2208 pmlmepriv = &(padapter->mlmepriv);
\r
2209 pmlmeext = &(padapter->mlmeextpriv);
\r
2210 //pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2212 if(_FALSE == pmlmeext->bstart_bss)
\r
2215 _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
\r
2221 update_bcn_fixed_ie(padapter);//8: TimeStamp, 2: Beacon Interval 2:Capability
\r
2227 update_BCNTIM(padapter);
\r
2231 case _ERPINFO_IE_:
\r
2233 update_bcn_erpinfo_ie(padapter);
\r
2237 case _HT_CAPABILITY_IE_:
\r
2239 update_bcn_htcap_ie(padapter);
\r
2245 update_bcn_rsn_ie(padapter);
\r
2249 case _HT_ADD_INFO_IE_:
\r
2251 update_bcn_htinfo_ie(padapter);
\r
2255 case _VENDOR_SPECIFIC_IE_:
\r
2257 update_bcn_vendor_spec_ie(padapter, oui);
\r
2265 pmlmepriv->update_bcn = _TRUE;
\r
2267 _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
\r
2269 #ifndef CONFIG_INTERRUPT_BASED_TXBCN
\r
2270 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
\r
2273 //send_beacon(padapter);//send_beacon must execute on TSR level
\r
2274 set_tx_beacon_cmd(padapter);
\r
2278 //PCI will issue beacon when BCN interrupt occurs.
\r
2281 #endif //!CONFIG_INTERRUPT_BASED_TXBCN
\r
2285 #ifdef CONFIG_80211N_HT
\r
2289 Set to 0 (HT pure) under the followign conditions
\r
2290 - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
\r
2291 - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
\r
2292 Set to 1 (HT non-member protection) if there may be non-HT STAs
\r
2293 in both the primary and the secondary channel
\r
2294 Set to 2 if only HT STAs are associated in BSS,
\r
2295 however and at least one 20 MHz HT STA is associated
\r
2296 Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
\r
2297 (currently non-GF HT station is considered as non-HT STA also)
\r
2299 static int rtw_ht_operation_update(_adapter *padapter)
\r
2301 u16 cur_op_mode, new_op_mode;
\r
2302 int op_mode_changes = 0;
\r
2303 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2304 struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
\r
2306 if(pmlmepriv->htpriv.ht_option == _TRUE)
\r
2309 //if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)
\r
2312 DBG_871X("%s current operation mode=0x%X\n",
\r
2313 __FUNCTION__, pmlmepriv->ht_op_mode);
\r
2315 if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)
\r
2316 && pmlmepriv->num_sta_ht_no_gf) {
\r
2317 pmlmepriv->ht_op_mode |=
\r
2318 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
\r
2319 op_mode_changes++;
\r
2320 } else if ((pmlmepriv->ht_op_mode &
\r
2321 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
\r
2322 pmlmepriv->num_sta_ht_no_gf == 0) {
\r
2323 pmlmepriv->ht_op_mode &=
\r
2324 ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
\r
2325 op_mode_changes++;
\r
2328 if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
\r
2329 (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
\r
2330 pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
\r
2331 op_mode_changes++;
\r
2332 } else if ((pmlmepriv->ht_op_mode &
\r
2333 HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
\r
2334 (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
\r
2335 pmlmepriv->ht_op_mode &=
\r
2336 ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
\r
2337 op_mode_changes++;
\r
2340 /* Note: currently we switch to the MIXED op mode if HT non-greenfield
\r
2341 * station is associated. Probably it's a theoretical case, since
\r
2342 * it looks like all known HT STAs support greenfield.
\r
2345 if (pmlmepriv->num_sta_no_ht ||
\r
2346 (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
\r
2347 new_op_mode = OP_MODE_MIXED;
\r
2348 else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH)
\r
2349 && pmlmepriv->num_sta_ht_20mhz)
\r
2350 new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
\r
2351 else if (pmlmepriv->olbc_ht)
\r
2352 new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
\r
2354 new_op_mode = OP_MODE_PURE;
\r
2356 cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
\r
2357 if (cur_op_mode != new_op_mode) {
\r
2358 pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
\r
2359 pmlmepriv->ht_op_mode |= new_op_mode;
\r
2360 op_mode_changes++;
\r
2363 DBG_871X("%s new operation mode=0x%X changes=%d\n",
\r
2364 __FUNCTION__, pmlmepriv->ht_op_mode, op_mode_changes);
\r
2366 return op_mode_changes;
\r
2370 #endif /* CONFIG_80211N_HT */
\r
2372 void associated_clients_update(_adapter *padapter, u8 updated)
\r
2374 //update associcated stations cap.
\r
2375 if(updated == _TRUE)
\r
2378 _list *phead, *plist;
\r
2379 struct sta_info *psta=NULL;
\r
2380 struct sta_priv *pstapriv = &padapter->stapriv;
\r
2382 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
2384 phead = &pstapriv->asoc_list;
\r
2385 plist = get_next(phead);
\r
2387 //check asoc_queue
\r
2388 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
2390 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
2392 plist = get_next(plist);
\r
2394 VCS_update(padapter, psta);
\r
2397 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
2403 /* called > TSR LEVEL for USB or SDIO Interface*/
\r
2404 void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta)
\r
2406 u8 beacon_updated = _FALSE;
\r
2407 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2408 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
2412 if (!(psta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
\r
2413 !psta->no_short_preamble_set) {
\r
2414 psta->no_short_preamble_set = 1;
\r
2415 pmlmepriv->num_sta_no_short_preamble++;
\r
2416 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
\r
2417 (pmlmepriv->num_sta_no_short_preamble == 1))
\r
2418 ieee802_11_set_beacons(hapd->iface);
\r
2423 if(!(psta->flags & WLAN_STA_SHORT_PREAMBLE))
\r
2425 if(!psta->no_short_preamble_set)
\r
2427 psta->no_short_preamble_set = 1;
\r
2429 pmlmepriv->num_sta_no_short_preamble++;
\r
2431 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
\r
2432 (pmlmepriv->num_sta_no_short_preamble == 1))
\r
2434 beacon_updated = _TRUE;
\r
2435 update_beacon(padapter, 0xFF, NULL, _TRUE);
\r
2442 if(psta->no_short_preamble_set)
\r
2444 psta->no_short_preamble_set = 0;
\r
2446 pmlmepriv->num_sta_no_short_preamble--;
\r
2448 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
\r
2449 (pmlmepriv->num_sta_no_short_preamble == 0))
\r
2451 beacon_updated = _TRUE;
\r
2452 update_beacon(padapter, 0xFF, NULL, _TRUE);
\r
2459 if (psta->flags & WLAN_STA_NONERP && !psta->nonerp_set) {
\r
2460 psta->nonerp_set = 1;
\r
2461 pmlmepriv->num_sta_non_erp++;
\r
2462 if (pmlmepriv->num_sta_non_erp == 1)
\r
2463 ieee802_11_set_beacons(hapd->iface);
\r
2467 if(psta->flags & WLAN_STA_NONERP)
\r
2469 if(!psta->nonerp_set)
\r
2471 psta->nonerp_set = 1;
\r
2473 pmlmepriv->num_sta_non_erp++;
\r
2475 if (pmlmepriv->num_sta_non_erp == 1)
\r
2477 beacon_updated = _TRUE;
\r
2478 update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
\r
2485 if(psta->nonerp_set)
\r
2487 psta->nonerp_set = 0;
\r
2489 pmlmepriv->num_sta_non_erp--;
\r
2491 if (pmlmepriv->num_sta_non_erp == 0)
\r
2493 beacon_updated = _TRUE;
\r
2494 update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
\r
2502 if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT) &&
\r
2503 !psta->no_short_slot_time_set) {
\r
2504 psta->no_short_slot_time_set = 1;
\r
2505 pmlmepriv->num_sta_no_short_slot_time++;
\r
2506 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
\r
2507 (pmlmepriv->num_sta_no_short_slot_time == 1))
\r
2508 ieee802_11_set_beacons(hapd->iface);
\r
2512 if(!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT))
\r
2514 if(!psta->no_short_slot_time_set)
\r
2516 psta->no_short_slot_time_set = 1;
\r
2518 pmlmepriv->num_sta_no_short_slot_time++;
\r
2520 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
\r
2521 (pmlmepriv->num_sta_no_short_slot_time == 1))
\r
2523 beacon_updated = _TRUE;
\r
2524 update_beacon(padapter, 0xFF, NULL, _TRUE);
\r
2531 if(psta->no_short_slot_time_set)
\r
2533 psta->no_short_slot_time_set = 0;
\r
2535 pmlmepriv->num_sta_no_short_slot_time--;
\r
2537 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
\r
2538 (pmlmepriv->num_sta_no_short_slot_time == 0))
\r
2540 beacon_updated = _TRUE;
\r
2541 update_beacon(padapter, 0xFF, NULL, _TRUE);
\r
2546 #ifdef CONFIG_80211N_HT
\r
2548 if (psta->flags & WLAN_STA_HT)
\r
2550 u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
\r
2552 DBG_871X("HT: STA " MAC_FMT " HT Capabilities "
\r
2553 "Info: 0x%04x\n", MAC_ARG(psta->hwaddr), ht_capab);
\r
2555 if (psta->no_ht_set) {
\r
2556 psta->no_ht_set = 0;
\r
2557 pmlmepriv->num_sta_no_ht--;
\r
2560 if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
\r
2561 if (!psta->no_ht_gf_set) {
\r
2562 psta->no_ht_gf_set = 1;
\r
2563 pmlmepriv->num_sta_ht_no_gf++;
\r
2565 DBG_871X("%s STA " MAC_FMT " - no "
\r
2566 "greenfield, num of non-gf stations %d\n",
\r
2567 __FUNCTION__, MAC_ARG(psta->hwaddr),
\r
2568 pmlmepriv->num_sta_ht_no_gf);
\r
2571 if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) {
\r
2572 if (!psta->ht_20mhz_set) {
\r
2573 psta->ht_20mhz_set = 1;
\r
2574 pmlmepriv->num_sta_ht_20mhz++;
\r
2576 DBG_871X("%s STA " MAC_FMT " - 20 MHz HT, "
\r
2577 "num of 20MHz HT STAs %d\n",
\r
2578 __FUNCTION__, MAC_ARG(psta->hwaddr),
\r
2579 pmlmepriv->num_sta_ht_20mhz);
\r
2585 if (!psta->no_ht_set) {
\r
2586 psta->no_ht_set = 1;
\r
2587 pmlmepriv->num_sta_no_ht++;
\r
2589 if(pmlmepriv->htpriv.ht_option == _TRUE) {
\r
2590 DBG_871X("%s STA " MAC_FMT
\r
2591 " - no HT, num of non-HT stations %d\n",
\r
2592 __FUNCTION__, MAC_ARG(psta->hwaddr),
\r
2593 pmlmepriv->num_sta_no_ht);
\r
2597 if (rtw_ht_operation_update(padapter) > 0)
\r
2599 update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);
\r
2600 update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);
\r
2603 #endif /* CONFIG_80211N_HT */
\r
2605 //update associcated stations cap.
\r
2606 associated_clients_update(padapter, beacon_updated);
\r
2608 DBG_871X("%s, updated=%d\n", __func__, beacon_updated);
\r
2612 u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta)
\r
2614 u8 beacon_updated = _FALSE;
\r
2615 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2616 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
2619 return beacon_updated;
\r
2621 if (psta->no_short_preamble_set) {
\r
2622 psta->no_short_preamble_set = 0;
\r
2623 pmlmepriv->num_sta_no_short_preamble--;
\r
2624 if (pmlmeext->cur_wireless_mode > WIRELESS_11B
\r
2625 && pmlmepriv->num_sta_no_short_preamble == 0)
\r
2627 beacon_updated = _TRUE;
\r
2628 update_beacon(padapter, 0xFF, NULL, _TRUE);
\r
2632 if (psta->nonerp_set) {
\r
2633 psta->nonerp_set = 0;
\r
2634 pmlmepriv->num_sta_non_erp--;
\r
2635 if (pmlmepriv->num_sta_non_erp == 0)
\r
2637 beacon_updated = _TRUE;
\r
2638 update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
\r
2642 if (psta->no_short_slot_time_set) {
\r
2643 psta->no_short_slot_time_set = 0;
\r
2644 pmlmepriv->num_sta_no_short_slot_time--;
\r
2645 if (pmlmeext->cur_wireless_mode > WIRELESS_11B
\r
2646 && pmlmepriv->num_sta_no_short_slot_time == 0)
\r
2648 beacon_updated = _TRUE;
\r
2649 update_beacon(padapter, 0xFF, NULL, _TRUE);
\r
2653 #ifdef CONFIG_80211N_HT
\r
2655 if (psta->no_ht_gf_set) {
\r
2656 psta->no_ht_gf_set = 0;
\r
2657 pmlmepriv->num_sta_ht_no_gf--;
\r
2660 if (psta->no_ht_set) {
\r
2661 psta->no_ht_set = 0;
\r
2662 pmlmepriv->num_sta_no_ht--;
\r
2665 if (psta->ht_20mhz_set) {
\r
2666 psta->ht_20mhz_set = 0;
\r
2667 pmlmepriv->num_sta_ht_20mhz--;
\r
2670 if (rtw_ht_operation_update(padapter) > 0)
\r
2672 update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);
\r
2673 update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);
\r
2676 #endif /* CONFIG_80211N_HT */
\r
2678 //update associcated stations cap.
\r
2679 //associated_clients_update(padapter, beacon_updated); //move it to avoid deadlock
\r
2681 DBG_871X("%s, updated=%d\n", __func__, beacon_updated);
\r
2683 return beacon_updated;
\r
2687 u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason)
\r
2690 u8 beacon_updated = _FALSE;
\r
2691 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2692 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
2693 struct sta_priv *pstapriv = &padapter->stapriv;
\r
2696 return beacon_updated;
\r
2698 if (active == _TRUE)
\r
2700 #ifdef CONFIG_80211N_HT
\r
2701 //tear down Rx AMPDU
\r
2702 send_delba(padapter, 0, psta->hwaddr);// recipient
\r
2704 //tear down TX AMPDU
\r
2705 send_delba(padapter, 1, psta->hwaddr);// // originator
\r
2707 #endif //CONFIG_80211N_HT
\r
2709 issue_deauth(padapter, psta->hwaddr, reason);
\r
2712 psta->htpriv.agg_enable_bitmap = 0x0;//reset
\r
2713 psta->htpriv.candidate_tid_bitmap = 0x0;//reset
\r
2716 //report_del_sta_event(padapter, psta->hwaddr, reason);
\r
2718 //clear cam entry / key
\r
2719 //clear_cam_entry(padapter, (psta->mac_id + 3));
\r
2720 rtw_clearstakey_cmd(padapter, (u8*)psta, (u8)rtw_get_camid(psta->mac_id), _TRUE);
\r
2723 _enter_critical_bh(&psta->lock, &irqL);
\r
2724 psta->state &= ~_FW_LINKED;
\r
2725 _exit_critical_bh(&psta->lock, &irqL);
\r
2727 #ifdef CONFIG_IOCTL_CFG80211
\r
2729 #ifdef COMPAT_KERNEL_RELEASE
\r
2730 rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
\r
2731 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
2732 rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
\r
2733 #else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
2734 /* will call rtw_cfg80211_indicate_sta_disassoc() in cmd_thread for old API context */
\r
2735 #endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
2737 #endif //CONFIG_IOCTL_CFG80211
\r
2739 rtw_indicate_sta_disassoc_event(padapter, psta);
\r
2742 report_del_sta_event(padapter, psta->hwaddr, reason);
\r
2744 beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
\r
2746 _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
\r
2747 rtw_free_stainfo(padapter, psta);
\r
2748 _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
\r
2751 return beacon_updated;
\r
2755 int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset)
\r
2758 _list *phead, *plist;
\r
2760 struct sta_info *psta = NULL;
\r
2761 struct sta_priv *pstapriv = &padapter->stapriv;
\r
2762 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
2763 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2764 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
\r
2766 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
\r
2769 DBG_871X(FUNC_NDEV_FMT" with ch:%u, offset:%u\n",
\r
2770 FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset);
\r
2772 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
2773 phead = &pstapriv->asoc_list;
\r
2774 plist = get_next(phead);
\r
2776 /* for each sta in asoc_queue */
\r
2777 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
2779 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
2780 plist = get_next(plist);
\r
2782 issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset);
\r
2783 psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2);
\r
2785 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
2787 issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset);
\r
2792 int rtw_sta_flush(_adapter *padapter)
\r
2795 _list *phead, *plist;
\r
2797 struct sta_info *psta = NULL;
\r
2798 struct sta_priv *pstapriv = &padapter->stapriv;
\r
2799 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
2800 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2801 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
\r
2803 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
\r
2805 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
\r
2809 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
2810 phead = &pstapriv->asoc_list;
\r
2811 plist = get_next(phead);
\r
2813 //free sta asoc_queue
\r
2814 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
2816 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
2818 plist = get_next(plist);
\r
2820 rtw_list_delete(&psta->asoc_list);
\r
2821 pstapriv->asoc_list_cnt--;
\r
2823 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
2824 ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
\r
2825 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
2827 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
2830 issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
\r
2832 associated_clients_update(padapter, _TRUE);
\r
2838 /* called > TSR LEVEL for USB or SDIO Interface*/
\r
2839 void sta_info_update(_adapter *padapter, struct sta_info *psta)
\r
2841 int flags = psta->flags;
\r
2842 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2846 if(WLAN_STA_WME&flags)
\r
2847 psta->qos_option = 1;
\r
2849 psta->qos_option = 0;
\r
2851 if(pmlmepriv->qospriv.qos_option == 0)
\r
2852 psta->qos_option = 0;
\r
2855 #ifdef CONFIG_80211N_HT
\r
2856 //update 802.11n ht cap.
\r
2857 if(WLAN_STA_HT&flags)
\r
2859 psta->htpriv.ht_option = _TRUE;
\r
2860 psta->qos_option = 1;
\r
2864 psta->htpriv.ht_option = _FALSE;
\r
2867 if(pmlmepriv->htpriv.ht_option == _FALSE)
\r
2868 psta->htpriv.ht_option = _FALSE;
\r
2871 #ifdef CONFIG_80211AC_VHT
\r
2872 //update 802.11AC vht cap.
\r
2873 if(WLAN_STA_VHT&flags)
\r
2875 psta->vhtpriv.vht_option = _TRUE;
\r
2879 psta->vhtpriv.vht_option = _FALSE;
\r
2882 if(pmlmepriv->vhtpriv.vht_option == _FALSE)
\r
2883 psta->vhtpriv.vht_option = _FALSE;
\r
2887 update_sta_info_apmode(padapter, psta);
\r
2892 /* called >= TSR LEVEL for USB or SDIO Interface*/
\r
2893 void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta)
\r
2895 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
2896 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2898 if(psta->state & _FW_LINKED)
\r
2900 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
\r
2903 add_RATid(padapter, psta, 0);//DM_RATR_STA_INIT
\r
2906 /* restore hw setting from sw data structures */
\r
2907 void rtw_ap_restore_network(_adapter *padapter)
\r
2909 struct mlme_priv *mlmepriv = &padapter->mlmepriv;
\r
2910 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
2911 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2912 struct sta_priv * pstapriv = &padapter->stapriv;
\r
2913 struct sta_info *psta;
\r
2914 struct security_priv* psecuritypriv=&(padapter->securitypriv);
\r
2916 _list *phead, *plist;
\r
2917 u8 chk_alive_num = 0;
\r
2918 char chk_alive_list[NUM_STA];
\r
2921 rtw_setopmode_cmd(padapter, Ndis802_11APMode,_FALSE);
\r
2923 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
\r
2925 start_bss_network(padapter, (u8*)&mlmepriv->cur_network.network);
\r
2927 if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
\r
2928 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))
\r
2930 /* restore group key, WEP keys is restored in ips_leave() */
\r
2931 rtw_set_key(padapter, psecuritypriv, psecuritypriv->dot118021XGrpKeyid, 0,_FALSE);
\r
2934 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
2936 phead = &pstapriv->asoc_list;
\r
2937 plist = get_next(phead);
\r
2939 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
\r
2940 int stainfo_offset;
\r
2942 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
2943 plist = get_next(plist);
\r
2945 stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
\r
2946 if (stainfo_offset_valid(stainfo_offset)) {
\r
2947 chk_alive_list[chk_alive_num++] = stainfo_offset;
\r
2951 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
2953 for (i = 0; i < chk_alive_num; i++) {
\r
2954 psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
\r
2956 if (psta == NULL) {
\r
2957 DBG_871X(FUNC_ADPT_FMT" sta_info is null\n", FUNC_ADPT_ARG(padapter));
\r
2958 } else if (psta->state &_FW_LINKED) {
\r
2959 Update_RA_Entry(padapter, psta);
\r
2961 /* per sta pairwise key and settings */
\r
2962 if( (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
\r
2963 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))
\r
2965 rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE,_FALSE);
\r
2972 void start_ap_mode(_adapter *padapter)
\r
2975 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2976 struct sta_priv *pstapriv = &padapter->stapriv;
\r
2977 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
2978 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
\r
2980 pmlmepriv->update_bcn = _FALSE;
\r
2982 //init_mlme_ap_info(padapter);
\r
2983 pmlmeext->bstart_bss = _FALSE;
\r
2985 pmlmepriv->num_sta_non_erp = 0;
\r
2987 pmlmepriv->num_sta_no_short_slot_time = 0;
\r
2989 pmlmepriv->num_sta_no_short_preamble = 0;
\r
2991 pmlmepriv->num_sta_ht_no_gf = 0;
\r
2992 #ifdef CONFIG_80211N_HT
\r
2993 pmlmepriv->num_sta_no_ht = 0;
\r
2994 #endif //CONFIG_80211N_HT
\r
2995 pmlmepriv->num_sta_ht_20mhz = 0;
\r
2997 pmlmepriv->olbc = _FALSE;
\r
2999 pmlmepriv->olbc_ht = _FALSE;
\r
3001 #ifdef CONFIG_80211N_HT
\r
3002 pmlmepriv->ht_op_mode = 0;
\r
3005 for(i=0; i<NUM_STA; i++)
\r
3006 pstapriv->sta_aid[i] = NULL;
\r
3008 pmlmepriv->wps_beacon_ie = NULL;
\r
3009 pmlmepriv->wps_probe_resp_ie = NULL;
\r
3010 pmlmepriv->wps_assoc_resp_ie = NULL;
\r
3012 pmlmepriv->p2p_beacon_ie = NULL;
\r
3013 pmlmepriv->p2p_probe_resp_ie = NULL;
\r
3017 _rtw_init_listhead(&(pacl_list->acl_node_q.queue));
\r
3018 pacl_list->num = 0;
\r
3019 pacl_list->mode = 0;
\r
3020 for(i = 0; i < NUM_ACL; i++)
\r
3022 _rtw_init_listhead(&pacl_list->aclnode[i].list);
\r
3023 pacl_list->aclnode[i].valid = _FALSE;
\r
3028 void stop_ap_mode(_adapter *padapter)
\r
3031 _list *phead, *plist;
\r
3032 struct rtw_wlan_acl_node *paclnode;
\r
3033 struct sta_info *psta=NULL;
\r
3034 struct sta_priv *pstapriv = &padapter->stapriv;
\r
3035 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
3036 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
3037 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
\r
3038 _queue *pacl_node_q =&pacl_list->acl_node_q;
\r
3040 pmlmepriv->update_bcn = _FALSE;
\r
3041 pmlmeext->bstart_bss = _FALSE;
\r
3042 //_rtw_spinlock_free(&pmlmepriv->bcn_update_lock);
\r
3044 //reset and init security priv , this can refine with rtw_reset_securitypriv
\r
3045 _rtw_memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv));
\r
3046 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
\r
3047 padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
\r
3050 _enter_critical_bh(&(pacl_node_q->lock), &irqL);
\r
3051 phead = get_list_head(pacl_node_q);
\r
3052 plist = get_next(phead);
\r
3053 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
3055 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
\r
3056 plist = get_next(plist);
\r
3058 if(paclnode->valid == _TRUE)
\r
3060 paclnode->valid = _FALSE;
\r
3062 rtw_list_delete(&paclnode->list);
\r
3064 pacl_list->num--;
\r
3067 _exit_critical_bh(&(pacl_node_q->lock), &irqL);
\r
3069 DBG_871X("%s, free acl_node_queue, num=%d\n", __func__, pacl_list->num);
\r
3071 rtw_sta_flush(padapter);
\r
3073 //free_assoc_sta_resources
\r
3074 rtw_free_all_stainfo(padapter);
\r
3076 psta = rtw_get_bcmc_stainfo(padapter);
\r
3077 _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
\r
3078 rtw_free_stainfo(padapter, psta);
\r
3079 _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
\r
3081 rtw_init_bcmc_stainfo(padapter);
\r
3083 rtw_free_mlme_priv_ie_data(pmlmepriv);
\r
3085 #ifdef CONFIG_BT_COEXIST
\r
3086 rtw_btcoex_MediaStatusNotify(padapter, 0); //disconnect
\r
3091 #endif //CONFIG_NATIVEAP_MLME
\r
3093 #ifdef CONFIG_CONCURRENT_MODE
\r
3094 void concurrent_set_ap_chbw(_adapter *padapter, u8 channel, u8 channel_offset, u8 bwmode)
\r
3098 u8 cur_channel, cur_bwmode, cur_ch_offset, change_band;
\r
3099 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
3100 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
\r
3101 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3102 struct HT_info_element *pht_info=NULL;
\r
3104 cur_channel = channel;
\r
3105 cur_bwmode = bwmode;
\r
3106 cur_ch_offset = channel_offset;
\r
3107 change_band = _FALSE;
\r
3109 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)));
\r
3112 pht_info = (struct HT_info_element *)(p+2);
\r
3116 if(!check_buddy_fwstate(padapter, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY))
\r
3118 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
\r
3120 else if(check_buddy_fwstate(padapter, _FW_LINKED)==_TRUE)//only second adapter can enter AP Mode
\r
3122 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
\r
3123 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
3125 //To sync cur_channel/cur_bwmode/cur_ch_offset with primary adapter
\r
3126 DBG_871X("primary iface is at linked state, sync cur_channel/cur_bwmode/cur_ch_offset\n");
\r
3127 DBG_871X("primary adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
\r
3128 DBG_871X("second adapter, CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
\r
3130 if((cur_channel <= 14 && pbuddy_mlmeext->cur_channel >= 36) ||
\r
3131 (cur_channel >= 36 && pbuddy_mlmeext->cur_channel <= 14))
\r
3132 change_band = _TRUE;
\r
3134 cur_channel = pbuddy_mlmeext->cur_channel;
\r
3136 #ifdef CONFIG_80211AC_VHT
\r
3137 if(cur_bwmode == CHANNEL_WIDTH_80)
\r
3139 u8 *pvht_cap_ie, *pvht_op_ie;
\r
3140 int vht_cap_ielen, vht_op_ielen;
\r
3142 pvht_cap_ie = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTCapability, &vht_cap_ielen, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
\r
3143 pvht_op_ie = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTOperation, &vht_op_ielen, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
\r
3145 if(pbuddy_mlmeext->cur_channel <= 14) // downgrade to 20/40Mhz
\r
3147 //modify vht cap ie
\r
3148 if( pvht_cap_ie && vht_cap_ielen)
\r
3150 SET_VHT_CAPABILITY_ELE_SHORT_GI80M(pvht_cap_ie+2, 0);
\r
3153 //modify vht op ie
\r
3154 if( pvht_op_ie && vht_op_ielen)
\r
3156 SET_VHT_OPERATION_ELE_CHL_WIDTH(pvht_op_ie+2, 0); //change to 20/40Mhz
\r
3157 SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(pvht_op_ie+2, 0);
\r
3158 SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(pvht_op_ie+2, 0);
\r
3159 //SET_VHT_OPERATION_ELE_BASIC_MCS_SET(p+2, 0xFFFF);
\r
3160 cur_bwmode = CHANNEL_WIDTH_40;
\r
3167 cur_bwmode = CHANNEL_WIDTH_80;
\r
3169 if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40 ||
\r
3170 pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_80)
\r
3172 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
\r
3174 else if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_20)
\r
3176 cur_ch_offset = rtw_get_offset_by_ch(cur_channel);
\r
3179 //modify ht info ie
\r
3181 pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
\r
3183 switch(cur_ch_offset)
\r
3185 case HAL_PRIME_CHNL_OFFSET_LOWER:
\r
3187 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
\r
3188 //cur_bwmode = CHANNEL_WIDTH_40;
\r
3190 case HAL_PRIME_CHNL_OFFSET_UPPER:
\r
3192 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
\r
3193 //cur_bwmode = CHANNEL_WIDTH_40;
\r
3195 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
\r
3198 pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
\r
3199 cur_bwmode = CHANNEL_WIDTH_20;
\r
3200 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
3204 //modify vht op ie
\r
3205 center_freq = rtw_get_center_ch(cur_channel, cur_bwmode, HAL_PRIME_CHNL_OFFSET_LOWER);
\r
3206 if( pvht_op_ie && vht_op_ielen)
\r
3207 SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(pvht_op_ie+2, center_freq);
\r
3209 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
\r
3214 #endif //CONFIG_80211AC_VHT
\r
3216 if(cur_bwmode == CHANNEL_WIDTH_40)
\r
3219 pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
\r
3221 if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40 ||
\r
3222 pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_80)
\r
3224 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
\r
3226 //to update cur_ch_offset value in beacon
\r
3229 switch(cur_ch_offset)
\r
3231 case HAL_PRIME_CHNL_OFFSET_LOWER:
\r
3232 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
\r
3234 case HAL_PRIME_CHNL_OFFSET_UPPER:
\r
3235 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
\r
3237 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
\r
3244 else if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_20)
\r
3246 cur_ch_offset = rtw_get_offset_by_ch(cur_channel);
\r
3248 switch(cur_ch_offset)
\r
3250 case HAL_PRIME_CHNL_OFFSET_LOWER:
\r
3252 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
\r
3253 cur_bwmode = CHANNEL_WIDTH_40;
\r
3255 case HAL_PRIME_CHNL_OFFSET_UPPER:
\r
3257 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
\r
3258 cur_bwmode = CHANNEL_WIDTH_40;
\r
3260 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
\r
3263 pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
\r
3264 cur_bwmode = CHANNEL_WIDTH_20;
\r
3265 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
3271 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
\r
3276 //follow buddy's ch/bw/ch_offset setting, needn't set ch_bw again.
\r
3277 //set_channel_bwmode(padapter, cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
\r
3280 // to update channel value in beacon
\r
3281 pnetwork->Configuration.DSConfig = cur_channel;
\r
3282 p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
\r
3284 *(p + 2) = cur_channel;
\r
3287 pht_info->primary_channel = cur_channel;
\r
3290 DBG_871X("%s, CH=%d, BW=%d, offset=%d\n", __FUNCTION__, cur_channel, cur_bwmode, cur_ch_offset);
\r
3292 pmlmeext->cur_channel = cur_channel;
\r
3293 pmlmeext->cur_bwmode = cur_bwmode;
\r
3294 pmlmeext->cur_ch_offset = cur_ch_offset;
\r
3296 //buddy interface band is different from current interface, update ERP, support rate, ext support rate IE
\r
3297 if(change_band == _TRUE)
\r
3298 change_band_update_ie(padapter, pnetwork);
\r
3301 #endif //CONFIG_CONCURRENT_MODE
\r
3303 #endif //CONFIG_AP_MODE
\r