pmlmepriv->update_bcn = _FALSE;\r
pmlmeext->bstart_bss = _FALSE; \r
\r
- rtw_sta_flush(padapter);\r
+ rtw_sta_flush(padapter, _TRUE);\r
\r
pmlmeinfo->state = _HW_STATE_NOLINK_;\r
\r
WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);\r
unsigned char *pie = pnetwork_mlmeext->IEs;\r
\r
+/*\r
//DBG_871X("%s\n", __FUNCTION__);\r
\r
//update TIM IE\r
//if(pstapriv->tim_bitmap)\r
- if(_TRUE)\r
- {\r
- u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;\r
+*/\r
+ if (_TRUE) {\r
+ u8 *p, *dst_ie, *premainder_ie = NULL, *pbackup_remainder_ie = NULL;\r
u16 tim_bitmap_le;\r
uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen; \r
\r
tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);\r
\r
p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);\r
- if (p != NULL && tim_ielen>0)\r
- {\r
+ if (p != NULL && tim_ielen > 0) {\r
tim_ielen += 2;\r
\r
- premainder_ie = p+tim_ielen;\r
+ premainder_ie = p + tim_ielen;\r
\r
tim_ie_offset = (sint)(p -pie);\r
\r
remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen;\r
\r
- //append TIM IE from dst_ie offset\r
+ /*append TIM IE from dst_ie offset*/\r
dst_ie = p;\r
- }\r
- else\r
- {\r
+ } else {\r
tim_ielen = 0;\r
\r
- //calucate head_len \r
+ /*calculate head_len*/\r
offset = _FIXED_IE_LENGTH_;\r
\r
/* get ssid_ie len */\r
if (p != NULL)\r
offset += tmp_len+2;\r
\r
- // get supported rates len\r
+ /*get supported rates len*/\r
p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_)); \r
if (p != NULL) \r
{ \r
offset += tmp_len+2;\r
}\r
\r
- //DS Parameter Set IE, len=3 \r
+ /*DS Parameter Set IE, len=3*/\r
offset += 3;\r
\r
premainder_ie = pie + offset;\r
\r
remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen; \r
\r
- //append TIM IE from offset\r
+ /*append TIM IE from offset*/\r
dst_ie = pie + offset;\r
\r
}\r
-\r
\r
- if(remainder_ielen>0)\r
- {\r
+ if (remainder_ielen > 0) {\r
pbackup_remainder_ie = rtw_malloc(remainder_ielen);\r
if(pbackup_remainder_ie && premainder_ie)\r
_rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);\r
\r
*dst_ie++=_TIM_IE_;\r
\r
- if((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fe)) \r
+ if ((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fe)) \r
tim_ielen = 5;\r
else\r
tim_ielen = 4;\r
\r
- *dst_ie++= tim_ielen;\r
+ *dst_ie++ = tim_ielen;\r
\r
- *dst_ie++=0;//DTIM count\r
- *dst_ie++=1;//DTIM peroid\r
+ *dst_ie++ = 0;/*DTIM count*/\r
+ *dst_ie++ = 1;/*DTIM period*/\r
\r
- if(pstapriv->tim_bitmap&BIT(0))//for bc/mc frames\r
- *dst_ie++ = BIT(0);//bitmap ctrl \r
+ if (pstapriv->tim_bitmap & BIT(0))/*for bc/mc frames*/\r
+ *dst_ie++ = BIT(0);/*bitmap ctrl */\r
else\r
*dst_ie++ = 0;\r
\r
- if(tim_ielen==4)\r
- {\r
- u8 pvb=0;\r
+ if (tim_ielen == 4) {\r
+ u8 pvb = 0;\r
\r
- if(pstapriv->tim_bitmap&0x00fe)\r
+ if (pstapriv->tim_bitmap & 0x00fe)\r
pvb = (u8)tim_bitmap_le;\r
- else if(pstapriv->tim_bitmap&0xff00) \r
- pvb = (u8)(tim_bitmap_le>>8);\r
+ else if (pstapriv->tim_bitmap & 0xff00) \r
+ pvb = (u8)(tim_bitmap_le >> 8);\r
else\r
pvb = (u8)tim_bitmap_le;\r
\r
*dst_ie++ = pvb;\r
\r
- } \r
- else if(tim_ielen==5)\r
- {\r
+ } else if (tim_ielen == 5) {\r
_rtw_memcpy(dst_ie, &tim_bitmap_le, 2);\r
- dst_ie+=2; \r
+ dst_ie += 2; \r
} \r
\r
- //copy remainder IE\r
- if(pbackup_remainder_ie)\r
- {\r
+ /*copy remainder IE*/\r
+ if (pbackup_remainder_ie) {\r
_rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);\r
\r
rtw_mfree(pbackup_remainder_ie, remainder_ielen);\r
//add_ba_hdl(padapter, (u8*)paddbareq_parm);\r
\r
DBG_871X("issue addba_req to check if sta alive, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt);\r
- \r
- issue_action_BA(padapter, psta->hwaddr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)priority); \r
+\r
+ issue_addba_req(padapter, psta->hwaddr, (u8)priority);\r
\r
_set_timer(&psta->addba_retry_timer, ADDBA_TO);\r
\r
rtw_list_delete(&psta->asoc_list);\r
pstapriv->asoc_list_cnt--;\r
DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);\r
- updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);\r
+ updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);\r
} \r
else\r
{\r
if (rtw_is_list_empty(&psta->asoc_list)==_FALSE) {\r
rtw_list_delete(&psta->asoc_list);\r
pstapriv->asoc_list_cnt--;\r
- updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);\r
+ updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);\r
}\r
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
\r
}\r
#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */\r
\r
- associated_clients_update(padapter, updated);\r
+ associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);\r
}\r
\r
void add_RATid(_adapter *padapter, struct sta_info *psta, u8 rssi_level)\r
int i;\r
u8 rf_type;\r
unsigned char sta_band = 0, shortGIrate = _FALSE;\r
- unsigned int tx_ra_bitmap=0;\r
+ u64 tx_ra_bitmap = 0;\r
struct ht_priv *psta_ht = NULL;\r
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;\r
psta->wireless_mode = sta_band;\r
psta->raid = rtw_hal_networktype_to_raid(padapter, psta);\r
\r
- if (psta->aid < NUM_STA) \r
+ if (psta->aid < NUM_STA)\r
{\r
u8 arg[4] = {0};\r
\r
arg[2] = shortGIrate;\r
arg[3] = psta->init_rate;\r
\r
- DBG_871X("%s=> mac_id:%d , raid:%d , shortGIrate=%d, bitmap=0x%x\n", \r
- __FUNCTION__ , psta->mac_id, psta->raid ,shortGIrate, tx_ra_bitmap);\r
-\r
+ DBG_871X("%s=> mac_id:%d , raid:%d , shortGIrate=%d, tx_ra_bitmap:0x%016llx, networkType:0x%02x\n", \r
+ __FUNCTION__, psta->mac_id, psta->raid, shortGIrate, tx_ra_bitmap, psta->wireless_mode);\r
+ \r
rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level);\r
}\r
else \r
_irqL irqL;\r
unsigned char network_type;\r
int supportRateNum = 0;\r
- unsigned int tx_ra_bitmap=0;\r
+ u64 tx_ra_bitmap = 0;\r
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);\r
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); \r
WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; \r
struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);\r
\r
if(psta)\r
{\r
psta->aid = 0;//default set to 0\r
-\r
- pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;\r
-\r
psta->qos_option = 0;\r
#ifdef CONFIG_80211N_HT \r
psta->htpriv.ht_option = _FALSE;\r
\r
psta->raid = rtw_hal_networktype_to_raid(padapter,psta);\r
\r
- //ap mode\r
- rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);\r
-\r
//if(pHalData->fw_ractrl == _TRUE)\r
{\r
u8 arg[4] = {0};\r
arg[2] = 0;\r
arg[3] = psta->init_rate;\r
\r
- DBG_871X("%s=> mac_id:%d , raid:%d , bitmap=0x%x\n", \r
+ DBG_871X("%s=> mac_id:%d , raid:%d , bitmap=0x%016llx\n", \r
__FUNCTION__ , psta->mac_id, psta->raid , tx_ra_bitmap);\r
\r
rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0);\r
else\r
{ \r
psta->bw_mode = CHANNEL_WIDTH_20;\r
- } \r
+ }\r
\r
+ if (psta->ht_40mhz_intolerant)\r
+ psta->bw_mode = CHANNEL_WIDTH_20;\r
+ \r
if(pmlmeext->cur_bwmode < psta->bw_mode)\r
{\r
psta->bw_mode = pmlmeext->cur_bwmode;\r
}\r
\r
#ifdef CONFIG_BEAMFORMING\r
- // Config Tx beamforming setting\r
+ /*Config Tx beamforming setting*/\r
if (TEST_FLAG(phtpriv_ap->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) && \r
GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP((u8 *)(&phtpriv_sta->ht_cap)))\r
{\r
SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);\r
+ /*Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/\r
+ SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS((u8 *)(&phtpriv_sta->ht_cap)) << 6);\r
}\r
\r
if (TEST_FLAG(phtpriv_ap->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&\r
GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP((u8 *)(&phtpriv_sta->ht_cap)))\r
{\r
SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);\r
+ /*Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/\r
+ SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS((u8 *)(&phtpriv_sta->ht_cap)) << 4);\r
}\r
-\r
if (cur_beamform_cap) {\r
DBG_871X("Client STA(%d) HT Beamforming Cap = 0x%02X\n", psta->aid, cur_beamform_cap);\r
}\r
-#endif //CONFIG_BEAMFORMING\r
+#endif /*CONFIG_BEAMFORMING*/\r
}\r
else\r
{\r
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;\r
#endif //CONFIG_80211N_HT\r
\r
-\r
psta->wireless_mode = pmlmeext->cur_wireless_mode;\r
\r
psta->bssratelen = rtw_get_rateset_len(pnetwork->SupportedRates);\r
#endif //CONFIG_80211AC_VHT\r
\r
#endif //CONFIG_80211N_HT\r
+\r
+ psta->state |= WIFI_AP_STATE; /* Aries, add,fix bug of flush_cam_entry at STOP AP mode , 0724 */\r
+}\r
+\r
+static void rtw_set_hw_wmm_param(_adapter *padapter)\r
+{\r
+ u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime;\r
+ u8 acm_mask;\r
+ u16 TXOP;\r
+ u32 acParm, i;\r
+ u32 edca[4], inx[4];\r
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;\r
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);\r
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;\r
+ struct registry_priv *pregpriv = &padapter->registrypriv;\r
+\r
+ acm_mask = 0;\r
+\r
+ if (IsSupported5G(pmlmeext->cur_wireless_mode) || \r
+ (pmlmeext->cur_wireless_mode & WIRELESS_11_24N))\r
+ aSifsTime = 16;\r
+ else\r
+ aSifsTime = 10;\r
+\r
+ if (pmlmeinfo->WMM_enable == 0) {\r
+ padapter->mlmepriv.acm_mask = 0;\r
+\r
+ AIFS = aSifsTime + (2 * pmlmeinfo->slotTime);\r
+\r
+ if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11A)) {\r
+ ECWMin = 4;\r
+ ECWMax = 10;\r
+ } else if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {\r
+ ECWMin = 5;\r
+ ECWMax = 10;\r
+ } else {\r
+ ECWMin = 4;\r
+ ECWMax = 10;\r
+ }\r
+\r
+ TXOP = 0;\r
+ acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);\r
+ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));\r
+ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));\r
+ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));\r
+\r
+ ECWMin = 2;\r
+ ECWMax = 3;\r
+ TXOP = 0x2f;\r
+ acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);\r
+ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));\r
+ \r
+ } else {\r
+ edca[0] = edca[1] = edca[2] = edca[3] = 0;\r
+\r
+ /*TODO:*/\r
+ acm_mask = 0;\r
+ padapter->mlmepriv.acm_mask = acm_mask;\r
+\r
+ /*\r
+ //BK\r
+ //AIFS = AIFSN * slot time + SIFS - r2t phy delay\r
+ */\r
+ AIFS = (7 * pmlmeinfo->slotTime) + aSifsTime;\r
+ ECWMin = 4;\r
+ ECWMax = 10;\r
+ TXOP = 0; \r
+ acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);\r
+ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));\r
+ edca[XMIT_BK_QUEUE] = acParm;\r
+ DBG_871X("WMM(BK): %x\n", acParm);\r
+ \r
+ /* BE */\r
+ AIFS = (3 * pmlmeinfo->slotTime) + aSifsTime;\r
+ ECWMin = 4;\r
+ ECWMax = 6;\r
+ TXOP = 0; \r
+ acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);\r
+ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));\r
+ edca[XMIT_BE_QUEUE] = acParm;\r
+ DBG_871X("WMM(BE): %x\n", acParm);\r
+\r
+ /* VI */\r
+ AIFS = (1 * pmlmeinfo->slotTime) + aSifsTime;\r
+ ECWMin = 3;\r
+ ECWMax = 4;\r
+ TXOP = 94; \r
+ acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);\r
+ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));\r
+ edca[XMIT_VI_QUEUE] = acParm;\r
+ DBG_871X("WMM(VI): %x\n", acParm);\r
+\r
+ /* VO */\r
+ AIFS = (1 * pmlmeinfo->slotTime) + aSifsTime;\r
+ ECWMin = 2;\r
+ ECWMax = 3;\r
+ TXOP = 47; \r
+ acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);\r
+ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));\r
+ edca[XMIT_VO_QUEUE] = acParm;\r
+ DBG_871X("WMM(VO): %x\n", acParm);\r
+\r
+ \r
+ if (padapter->registrypriv.acm_method == 1)\r
+ rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask));\r
+ else\r
+ padapter->mlmepriv.acm_mask = acm_mask;\r
+\r
+ inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;\r
+\r
+ if (pregpriv->wifi_spec == 1) {\r
+ u32 j, tmp, change_inx = _FALSE;\r
+\r
+ /* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */\r
+ for (i = 0 ; i < 4 ; i++) {\r
+ for (j = i+1 ; j < 4 ; j++) {\r
+ /* compare CW and AIFS */\r
+ if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF)) {\r
+ change_inx = _TRUE;\r
+ } else if ((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF)) {\r
+ /* compare TXOP */\r
+ if ((edca[j] >> 16) > (edca[i] >> 16))\r
+ change_inx = _TRUE;\r
+ }\r
+ \r
+ if (change_inx) {\r
+ tmp = edca[i];\r
+ edca[i] = edca[j];\r
+ edca[j] = tmp;\r
+\r
+ tmp = inx[i];\r
+ inx[i] = inx[j];\r
+ inx[j] = tmp;\r
+\r
+ change_inx = _FALSE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ for (i = 0 ; i < 4 ; i++) {\r
+ pxmitpriv->wmm_para_seq[i] = inx[i];\r
+ DBG_871X("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]);\r
+ }\r
+ \r
+ }\r
+ \r
}\r
\r
static void update_hw_ht_param(_adapter *padapter)\r
\r
}\r
\r
-void start_bss_network(_adapter *padapter, u8 *pbuf)\r
+static void rtw_ap_check_scan(_adapter *padapter)\r
{\r
- u8 *p;\r
- u8 val8, cur_channel, cur_bwmode, cur_ch_offset;\r
+ _irqL irqL;\r
+ _list *plist, *phead;\r
+ u32 delta_time, lifetime;\r
+ struct wlan_network *pnetwork = NULL;\r
+ WLAN_BSSID_EX *pbss = NULL; \r
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); \r
+ _queue *queue = &(pmlmepriv->scanned_queue);\r
+ u8 do_scan = _FALSE;\r
+\r
+ lifetime = SCANQUEUE_LIFETIME; /* 20 sec */\r
+\r
+ _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);\r
+ phead = get_list_head(queue);\r
+ if (rtw_end_of_queue_search(phead, get_next(phead)) == _TRUE)\r
+ if (padapter->registrypriv.wifi_spec)\r
+ do_scan = _TRUE;\r
+ _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);\r
+\r
+#ifdef CONFIG_AUTO_CHNL_SEL_NHM\r
+ if (padapter->registrypriv.acs_auto_scan) {\r
+ do_scan = _TRUE;\r
+ rtw_acs_start(padapter, _TRUE);\r
+ }\r
+#endif\r
+ \r
+ if (_TRUE == do_scan) {\r
+ DBG_871X("%s : drv scans by itself and wait_completed\n", __func__);\r
+ rtw_drv_scan_by_self(padapter);\r
+ rtw_scan_wait_completed(padapter);\r
+ }\r
+ \r
+#ifdef CONFIG_AUTO_CHNL_SEL_NHM\r
+ if (padapter->registrypriv.acs_auto_scan)\r
+ rtw_acs_start(padapter, _FALSE);\r
+#endif \r
+ _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);\r
+\r
+ phead = get_list_head(queue);\r
+ plist = get_next(phead);\r
+\r
+ while (1) {\r
+ \r
+ if (rtw_end_of_queue_search(phead, plist) == _TRUE)\r
+ break;\r
+\r
+ pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);\r
+ \r
+ if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0\r
+ && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE\r
+ && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))) { \r
+ delta_time = (u32) rtw_get_passing_time_ms(pnetwork->last_scanned);\r
+ \r
+ if (delta_time < lifetime) {\r
+\r
+ uint ie_len = 0; \r
+ u8 *pbuf = NULL;\r
+ u8 *ie = NULL;\r
+ \r
+ pbss = &pnetwork->network;\r
+ ie = pbss->IEs;\r
+ \r
+ /*check if HT CAP INFO IE exists or not*/\r
+ pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss->IELength - _BEACON_IE_OFFSET_));\r
+ if (pbuf == NULL) {\r
+ /* HT CAP INFO IE don't exist, it is b/g mode bss.*/\r
+ \r
+ if (pmlmepriv->olbc == _FALSE)\r
+ pmlmepriv->olbc = _TRUE;\r
+\r
+ if (pmlmepriv->olbc_ht == _FALSE)\r
+ pmlmepriv->olbc_ht = _TRUE;\r
+ } \r
+ } \r
+ }\r
+\r
+ plist = get_next(plist); \r
+ \r
+ }\r
+ \r
+ _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);\r
+\r
+ pmlmepriv->num_sta_no_ht = 0; /* reset to 0 after ap do scanning*/\r
+ \r
+}\r
+\r
+void rtw_start_bss_hdl_after_chbw_decided(_adapter *adapter)\r
+{\r
+ WLAN_BSSID_EX *pnetwork = &(adapter->mlmepriv.cur_network.network);\r
+ struct sta_info *sta = NULL;\r
+\r
+ /* update cur_wireless_mode */\r
+ update_wireless_mode(adapter);\r
+\r
+ /* update RRSR and RTS_INIT_RATE register after set channel and bandwidth */\r
+ UpdateBrateTbl(adapter, pnetwork->SupportedRates);\r
+ rtw_hal_set_hwreg(adapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);\r
+\r
+ /* update capability after cur_wireless_mode updated */\r
+ update_capinfo(adapter, rtw_get_capability(pnetwork));\r
+\r
+ /* update bc/mc sta_info */\r
+ update_bmc_sta(adapter);\r
+\r
+ /* update AP's sta info */\r
+ sta = rtw_get_stainfo(&adapter->stapriv, pnetwork->MacAddress);\r
+ if (!sta) {\r
+ DBG_871X(FUNC_ADPT_FMT" !sta for macaddr="MAC_FMT"\n", FUNC_ADPT_ARG(adapter), MAC_ARG(pnetwork->MacAddress));\r
+ rtw_warn_on(1);\r
+ return;\r
+ }\r
+\r
+ update_ap_info(adapter, sta);\r
+}\r
+\r
+void start_bss_network(_adapter *padapter, struct createbss_parm *parm)\r
+{\r
+#define DUMP_ADAPTERS_STATUS 0\r
+\r
+ u8 val8;\r
u16 bcn_interval;\r
- u32 acparm; \r
- int ie_len; \r
+ u32 acparm;\r
struct registry_priv *pregpriv = &padapter->registrypriv;\r
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
struct security_priv* psecuritypriv=&(padapter->securitypriv); \r
- WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;\r
+ WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; /* used as input */\r
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);\r
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);\r
WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);\r
- struct HT_info_element *pht_info=NULL;\r
-#ifdef CONFIG_P2P\r
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);\r
-#endif //CONFIG_P2P\r
- u8 cbw40_enable=0;\r
- u8 change_band = _FALSE;\r
- \r
- //DBG_871X("%s\n", __FUNCTION__);\r
+ u8 req_ch, req_bw, req_offset;\r
+ bool ch_setting_changed = _FALSE;\r
+ u8 ch_to_set = 0, bw_to_set, offset_to_set;\r
+ u8 doiqk = _FALSE;\r
+\r
+ if (parm->req_ch == 0) {\r
+ /* change to unspecificed ch, bw, offset, get from IE */\r
+ goto get_cbhw_from_ie;\r
+ } else if (parm->req_ch > 0) {\r
+ /* change ch, bw, offset */\r
+ req_ch = parm->req_ch;\r
+ req_bw = parm->req_bw;\r
+ req_offset = parm->req_offset;\r
+ goto change_chbw;\r
+ }\r
\r
bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod; \r
- cur_channel = pnetwork->Configuration.DSConfig;\r
- cur_bwmode = CHANNEL_WIDTH_20;\r
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;\r
- \r
\r
//check if there is wps ie, \r
//if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd,\r
//Beacon Control related register\r
rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));\r
\r
- rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);\r
-\r
+#if 0\r
if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at first time\r
{\r
//u32 initialgain;\r
\r
\r
//disable dynamic functions, such as high power, DIG\r
- //Save_DM_Func_Flag(padapter);\r
- //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);\r
+ /*rtw_phydm_ability_backup(padapter);*/\r
+ /*rtw_phydm_func_disable_all(padapter);*/\r
\r
//turn on all dynamic functions \r
- Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);\r
+ /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);*/\r
\r
- //rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));\r
+ /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/\r
\r
}\r
-#ifdef CONFIG_80211N_HT\r
- //set channel, bwmode \r
- 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
- if( p && ie_len)\r
- {\r
- pht_info = (struct HT_info_element *)(p+2);\r
-\r
- if (cur_channel > 14) {\r
- if ((pregpriv->bw_mode & 0xf0) > 0)\r
- cbw40_enable = 1;\r
- } else {\r
- if ((pregpriv->bw_mode & 0x0f) > 0)\r
- cbw40_enable = 1;\r
- }\r
+#endif\r
\r
- if ((cbw40_enable) && (pht_info->infos[0] & BIT(2)))\r
- {\r
- //switch to the 40M Hz mode\r
- //pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;\r
- cur_bwmode = CHANNEL_WIDTH_40;\r
- switch (pht_info->infos[0] & 0x3)\r
- {\r
- case 1:\r
- //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;\r
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;\r
- break;\r
- \r
- case 3:\r
- //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;\r
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; \r
- break;\r
- \r
- default:\r
- //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;\r
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;\r
- break;\r
- } \r
- \r
- }\r
- \r
- }\r
-#endif //CONFIG_80211N_HT\r
+get_cbhw_from_ie:\r
+ rtw_ies_get_chbw(pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)\r
+ , pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)\r
+ , &req_ch, &req_bw, &req_offset);\r
\r
-#ifdef CONFIG_80211AC_VHT\r
- 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
- if( p && ie_len)\r
- {\r
- if(GET_VHT_OPERATION_ELE_CHL_WIDTH(p+2) >= 1) {\r
- cur_bwmode = CHANNEL_WIDTH_80;\r
- }\r
- }\r
-#endif\r
+change_chbw:\r
+ rtw_warn_on(req_ch == 0);\r
\r
-#ifdef CONFIG_DUALMAC_CONCURRENT\r
- dc_set_ap_channel_bandwidth(padapter, cur_channel, cur_ch_offset, cur_bwmode);\r
-#else //!CONFIG_DUALMAC_CONCURRENT \r
-#ifdef CONFIG_CONCURRENT_MODE\r
- //TODO: need to judge the phy parameters on concurrent mode for single phy\r
- concurrent_set_ap_chbw(padapter, cur_channel, cur_ch_offset, cur_bwmode);\r
-#else //!CONFIG_CONCURRENT_MODE\r
- set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);\r
- DBG_871X("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);\r
- pmlmeext->cur_channel = cur_channel; \r
- pmlmeext->cur_bwmode = cur_bwmode;\r
- pmlmeext->cur_ch_offset = cur_ch_offset;\r
-#endif //!CONFIG_CONCURRENT_MODE\r
-#endif //!CONFIG_DUALMAC_CONCURRENT\r
-\r
- pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;\r
+ ch_setting_changed = rtw_ap_chbw_decision(padapter, req_ch, req_bw, req_offset\r
+ , &ch_to_set, &bw_to_set, &offset_to_set);\r
\r
//let pnetwork_mlmeext == pnetwork_mlme.\r
_rtw_memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);\r
\r
- //update cur_wireless_mode\r
- update_wireless_mode(padapter);\r
+ rtw_start_bss_hdl_after_chbw_decided(padapter);\r
\r
- //update RRSR after set channel and bandwidth\r
- UpdateBrateTbl(padapter, pnetwork->SupportedRates);\r
- rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);\r
+ #if defined(CONFIG_DFS_MASTER)\r
+ rtw_dfs_master_status_apply(padapter, MLME_AP_STARTED);\r
+ #endif\r
+\r
+ doiqk = _TRUE;\r
+ rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);\r
+ \r
+ if (ch_to_set != 0)\r
+ set_channel_bwmode(padapter, ch_to_set, offset_to_set, bw_to_set);\r
+\r
+ doiqk = _FALSE;\r
+ rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);\r
+ if (DUMP_ADAPTERS_STATUS) {\r
+ DBG_871X(FUNC_ADPT_FMT" done\n", FUNC_ADPT_ARG(padapter));\r
+ dump_adapters_status(RTW_DBGDUMP , adapter_to_dvobj(padapter));\r
+ }\r
\r
- //udpate capability after cur_wireless_mode updated\r
- update_capinfo(padapter, rtw_get_capability((WLAN_BSSID_EX *)pnetwork));\r
+ if (_TRUE == pmlmeext->bstart_bss\r
+ && !check_fwstate(pmlmepriv, WIFI_SITE_MONITOR)\r
+ && !check_fwstate(pmlmepriv, WIFI_OP_CH_SWITCHING)\r
+ #ifdef CONFIG_CONCURRENT_MODE\r
+ && !check_buddy_fwstate(padapter, WIFI_SITE_MONITOR)\r
+ #endif\r
+ ) {\r
\r
+ if ((pmlmepriv->olbc == _TRUE) || (pmlmepriv->olbc_ht == _TRUE)) {\r
\r
-#ifdef CONFIG_P2P\r
- _rtw_memcpy(pwdinfo->p2p_group_ssid, pnetwork->Ssid.Ssid, pnetwork->Ssid.SsidLength); \r
- pwdinfo->p2p_group_ssid_len = pnetwork->Ssid.SsidLength;\r
-#endif //CONFIG_P2P\r
+ /* AP is not starting a 40 MHz BSS in presence of an 802.11g BSS. */\r
+\r
+ pmlmepriv->ht_op_mode &= (~HT_INFO_OPERATION_MODE_OP_MODE_MASK);\r
+ pmlmepriv->ht_op_mode |= OP_MODE_MAY_BE_LEGACY_STAS;\r
+ update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _FALSE);\r
+ }\r
\r
- if(_TRUE == pmlmeext->bstart_bss)\r
- {\r
update_beacon(padapter, _TIM_IE_, NULL, _TRUE);\r
\r
-#ifndef CONFIG_INTERRUPT_BASED_TXBCN //other case will tx beacon when bcn interrupt coming in.\r
-#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)\r
- //issue beacon frame\r
- if(send_beacon(padapter)==_FAIL)\r
- {\r
+ #if !defined(CONFIG_INTERRUPT_BASED_TXBCN)\r
+ #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)\r
+ /* other case will tx beacon when bcn interrupt coming in. */\r
+ if (send_beacon(padapter) == _FAIL)\r
DBG_871X("issue_beacon, fail!\n");\r
- }\r
-#endif \r
-#endif //!CONFIG_INTERRUPT_BASED_TXBCN\r
- \r
+ #endif \r
+ #endif /* !defined(CONFIG_INTERRUPT_BASED_TXBCN) */\r
}\r
\r
-\r
- //update bc/mc sta_info\r
- update_bmc_sta(padapter);\r
- \r
- //pmlmeext->bstart_bss = _TRUE;\r
+ /*Set EDCA param reg after update cur_wireless_mode & update_capinfo*/\r
+ if (pregpriv->wifi_spec == 1)\r
+ rtw_set_hw_wmm_param(padapter);\r
\r
+ /*pmlmeext->bstart_bss = _TRUE;*/\r
}\r
\r
int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len)\r
u8 *p;\r
u8 *pHT_caps_ie=NULL;\r
u8 *pHT_info_ie=NULL;\r
- struct sta_info *psta = NULL;\r
u16 cap, ht_cap=_FALSE;\r
uint ie_len = 0;\r
int group_cipher, pairwise_cipher; \r
struct sta_priv *pstapriv = &padapter->stapriv;\r
u8 *ie = pbss_network->IEs;\r
u8 vht_cap=_FALSE;\r
-\r
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);\r
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);\r
+ u8 rf_num = 0;\r
+ \r
/* SSID */\r
/* Supported rates */\r
/* DS Params */\r
if(pbss_network->InfrastructureMode!=Ndis802_11APMode)\r
return _FAIL;\r
\r
+\r
+ rtw_ap_check_scan(padapter);\r
+ \r
+\r
pbss_network->Rssi = 0;\r
\r
- _rtw_memcpy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
+ _rtw_memcpy(pbss_network->MacAddress, adapter_mac_addr(padapter), ETH_ALEN);\r
\r
//beacon interval\r
p = rtw_get_beacon_interval_from_ie(ie);//ie + 8; // 8: TimeStamp, 2: Beacon Interval 2:Capability\r
_rtw_memset(&pbss_network->Ssid, 0, sizeof(NDIS_802_11_SSID));\r
_rtw_memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);\r
pbss_network->Ssid.SsidLength = ie_len;\r
- } \r
+ #ifdef CONFIG_P2P\r
+ _rtw_memcpy(padapter->wdinfo.p2p_group_ssid, pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);\r
+ padapter->wdinfo.p2p_group_ssid_len = pbss_network->Ssid.SsidLength;\r
+ #endif\r
+ }\r
\r
//chnnel\r
channel = 0;\r
\r
rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);\r
pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & max_rx_ampdu_factor); //set Max Rx AMPDU size to 64K\r
+ \r
+ _rtw_memcpy(&(pmlmeinfo->HT_caps), pht_cap, sizeof(struct HT_caps_element));\r
\r
/* Update Supported MCS Set field */\r
{\r
set_mcs_rate_by_mask(HT_CAP_ELE_RX_MCS_MAP(pht_cap), MCS_RATE_1R);\r
break;\r
case RF_2T2R:\r
- default:\r
set_mcs_rate_by_mask(HT_CAP_ELE_RX_MCS_MAP(pht_cap), MCS_RATE_2R);\r
+ break;\r
+ case RF_3T3R:\r
+ set_mcs_rate_by_mask(HT_CAP_ELE_RX_MCS_MAP(pht_cap), MCS_RATE_3R);\r
+ break;\r
+ default:\r
+ DBG_871X("[warning] rf_type %d is not expected\n", rf_type);\r
}\r
for (i = 0; i < 10; i++)\r
*(HT_CAP_ELE_RX_MCS_MAP(pht_cap)+i) &= padapter->mlmeextpriv.default_supported_mcs_set[i];\r
SET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pht_cap, 1);\r
// Compressed Steering Number Antennas\r
SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pht_cap, 1);\r
+ rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMER_CAP, (u8 *)&rf_num);\r
+ SET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pht_cap, rf_num); \r
}\r
\r
// HT Beamformee\r
SET_HT_CAP_TXBF_RECEIVE_NDP_CAP(pht_cap, 1);\r
// Explicit Compressed Beamforming Feedback Capable\r
SET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pht_cap, 2);\r
+ rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMEE_CAP, (u8 *)&rf_num);\r
+ SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pht_cap, rf_num);\r
}\r
#endif //CONFIG_BEAMFORMING\r
\r
\r
pmlmepriv->vhtpriv.vht_option = _FALSE;\r
// if channel in 5G band, then add vht ie .\r
- if ((pbss_network->Configuration.DSConfig > 14) && \r
- (pmlmepriv->htpriv.ht_option == _TRUE) &&\r
- (pregistrypriv->vht_enable)) \r
- {\r
- if(vht_cap == _TRUE)\r
- {\r
+ if ((pbss_network->Configuration.DSConfig > 14)\r
+ && (pmlmepriv->htpriv.ht_option == _TRUE)\r
+ && REGSTY_IS_11AC_ENABLE(pregistrypriv)\r
+ && hal_chk_proto_cap(padapter, PROTO_CAP_11AC)\r
+ && (!pmlmepriv->country_ent || COUNTRY_CHPLAN_EN_11AC(pmlmepriv->country_ent))\r
+ ) {\r
+ if (vht_cap == _TRUE)\r
pmlmepriv->vhtpriv.vht_option = _TRUE;\r
- }\r
- else if(pregistrypriv->vht_enable == 2) // auto enabled\r
- {\r
+ else if (REGSTY_IS_11AC_AUTO(pregistrypriv)) {\r
u8 cap_len, operation_len;\r
\r
rtw_vht_use_default_setting(padapter);\r
\r
+ {\r
+ /* VHT Operation mode notifiy bit in Extended IE (127) */\r
+ uint len = 0;\r
+ \r
+ SET_EXT_CAPABILITY_ELE_OP_MODE_NOTIF(pmlmepriv->ext_capab_ie_data, 1);\r
+ pmlmepriv->ext_capab_ie_len = 10;\r
+ rtw_set_ie(pbss_network->IEs + pbss_network->IELength, EID_EXTCapability, 8, pmlmepriv->ext_capab_ie_data, &len);\r
+ pbss_network->IELength += pmlmepriv->ext_capab_ie_len;\r
+ }\r
+ \r
// VHT Capabilities element\r
cap_len = rtw_build_vht_cap_ie(padapter, pbss_network->IEs + pbss_network->IELength);\r
pbss_network->IELength += cap_len;\r
\r
pbss_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pbss_network);\r
\r
- //issue beacon to start bss network\r
- //start_bss_network(padapter, (u8*)pbss_network);\r
- rtw_startbss_cmd(padapter, RTW_CMDF_WAIT_ACK);\r
- \r
+ rtw_ies_get_chbw(pbss_network->IEs + _BEACON_IE_OFFSET_, pbss_network->IELength - _BEACON_IE_OFFSET_\r
+ , &pmlmepriv->ori_ch, &pmlmepriv->ori_bw, &pmlmepriv->ori_offset);\r
+ rtw_warn_on(pmlmepriv->ori_ch == 0);\r
\r
- //alloc sta_info for ap itself\r
- psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);\r
- if(!psta)\r
- {\r
- psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);\r
- if (psta == NULL) \r
- { \r
+{\r
+ /* alloc sta_info for ap itself */\r
+\r
+ struct sta_info *sta;\r
+\r
+ sta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);\r
+ if (!sta) {\r
+ sta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);\r
+ if (sta == NULL) \r
return _FAIL;\r
- } \r
}\r
+}\r
+\r
+ rtw_startbss_cmd(padapter, RTW_CMDF_WAIT_ACK);\r
\r
- // update AP's sta info \r
- update_ap_info(padapter, psta);\r
- \r
- psta->state |= WIFI_AP_STATE; //Aries, add,fix bug of flush_cam_entry at STOP AP mode , 0724 \r
rtw_indicate_connect( padapter);\r
\r
pmlmepriv->cur_network.join_res = _TRUE;//for check if already set beacon\r
return rtw_ap_set_key(padapter, key, alg, keyid, set_tx);\r
}\r
\r
-#ifdef CONFIG_NATIVEAP_MLME\r
-\r
-static void update_bcn_fixed_ie(_adapter *padapter)\r
+u8 rtw_ap_bmc_frames_hdl(_adapter *padapter)\r
{\r
- DBG_871X("%s\n", __FUNCTION__);\r
+#define HIQ_XMIT_COUNTS (6)\r
+ _irqL irqL;\r
+ struct sta_info *psta_bmc;\r
+ _list *xmitframe_plist, *xmitframe_phead;\r
+ struct xmit_frame *pxmitframe = NULL;\r
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;\r
+ struct sta_priv *pstapriv = &padapter->stapriv;\r
+ bool update_tim = _FALSE;\r
\r
-}\r
\r
-static void update_bcn_erpinfo_ie(_adapter *padapter)\r
-{\r
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);\r
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);\r
- WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);\r
- unsigned char *p, *ie = pnetwork->IEs;\r
- u32 len = 0;\r
+ if (padapter->registrypriv.wifi_spec != 1)\r
+ return H2C_SUCCESS;\r
\r
- DBG_871X("%s, ERP_enable=%d\n", __FUNCTION__, pmlmeinfo->ERP_enable);\r
+ \r
+ psta_bmc = rtw_get_bcmc_stainfo(padapter);\r
+ if (!psta_bmc)\r
+ return H2C_SUCCESS;\r
\r
- if(!pmlmeinfo->ERP_enable)\r
- return;\r
\r
- //parsing ERP_IE\r
- p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));\r
- if(p && len>0)\r
- {\r
- PNDIS_802_11_VARIABLE_IEs pIE = (PNDIS_802_11_VARIABLE_IEs)p;\r
+ _enter_critical_bh(&pxmitpriv->lock, &irqL);\r
\r
- if (pmlmepriv->num_sta_non_erp == 1)\r
- pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION;\r
- else\r
- pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION);\r
+ if ((pstapriv->tim_bitmap & BIT(0)) && (psta_bmc->sleepq_len > 0)) {\r
+ int tx_counts = 0;\r
+ \r
+ _update_beacon(padapter, _TIM_IE_, NULL, _FALSE, "update TIM with TIB=1");\r
\r
- if(pmlmepriv->num_sta_no_short_preamble > 0)\r
- pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;\r
- else\r
- pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);\r
- \r
- ERP_IE_handler(padapter, pIE);\r
- }\r
- \r
-}\r
+ DBG_871X("sleepq_len of bmc_sta = %d\n", psta_bmc->sleepq_len);\r
\r
-static void update_bcn_htcap_ie(_adapter *padapter)\r
-{\r
- DBG_871X("%s\n", __FUNCTION__);\r
+ xmitframe_phead = get_list_head(&psta_bmc->sleep_q);\r
+ xmitframe_plist = get_next(xmitframe_phead);\r
\r
-}\r
+ while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {\r
+ pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);\r
\r
-static void update_bcn_htinfo_ie(_adapter *padapter)\r
-{ \r
- DBG_871X("%s\n", __FUNCTION__);\r
+ xmitframe_plist = get_next(xmitframe_plist);\r
\r
-}\r
+ rtw_list_delete(&pxmitframe->list);\r
\r
-static void update_bcn_rsn_ie(_adapter *padapter)\r
-{\r
- DBG_871X("%s\n", __FUNCTION__);\r
+ psta_bmc->sleepq_len--;\r
+ tx_counts++;\r
+ \r
+ if (psta_bmc->sleepq_len > 0)\r
+ pxmitframe->attrib.mdata = 1;\r
+ else\r
+ pxmitframe->attrib.mdata = 0;\r
\r
-}\r
+ if (tx_counts == HIQ_XMIT_COUNTS)\r
+ pxmitframe->attrib.mdata = 0;\r
+ \r
+ pxmitframe->attrib.triggered = 1;\r
\r
-static void update_bcn_wpa_ie(_adapter *padapter)\r
-{\r
- DBG_871X("%s\n", __FUNCTION__);\r
+ if (xmitframe_hiq_filter(pxmitframe) == _TRUE)\r
+ pxmitframe->attrib.qsel = QSLT_HIGH;/*HIQ*/\r
\r
-}\r
+ rtw_hal_xmitframe_enqueue(padapter, pxmitframe);\r
+\r
+ if (tx_counts == HIQ_XMIT_COUNTS)\r
+ break;\r
+ \r
+ }\r
+\r
+ } else {\r
+ if (psta_bmc->sleepq_len == 0) {\r
+ \r
+ /*DBG_871X("sleepq_len of bmc_sta = %d\n", psta_bmc->sleepq_len);*/\r
+ \r
+ if (pstapriv->tim_bitmap & BIT(0))\r
+ update_tim = _TRUE;\r
+\r
+ pstapriv->tim_bitmap &= ~BIT(0);\r
+ pstapriv->sta_dz_bitmap &= ~BIT(0);\r
+\r
+ if (update_tim == _TRUE) {\r
+ DBG_871X("clear TIB\n");\r
+ _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "bmc sleepq and HIQ empty");\r
+ } \r
+ }\r
+ }\r
+\r
+ _exit_critical_bh(&pxmitpriv->lock, &irqL);\r
+\r
+/*\r
+ //HIQ Check\r
+ rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty);\r
+\r
+ while (_FALSE == empty && rtw_get_passing_time_ms(start) < 3000)\r
+ {\r
+ rtw_msleep_os(100);\r
+ rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty);\r
+ }\r
+\r
+\r
+ printk("check if hiq empty=%d\n", empty);\r
+*/\r
+\r
+ return H2C_SUCCESS;\r
+}\r
+\r
+#ifdef CONFIG_NATIVEAP_MLME\r
+\r
+static void associated_stainfo_update(_adapter *padapter, struct sta_info *psta, u32 sta_info_type)\r
+{\r
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
+\r
+ DBG_871X("%s: "MAC_FMT", updated_type=0x%x\n", __func__, MAC_ARG(psta->hwaddr), sta_info_type);\r
+ \r
+ if (sta_info_type & STA_INFO_UPDATE_BW) {\r
+\r
+ if ((psta->flags & WLAN_STA_HT) && !psta->ht_20mhz_set) {\r
+ if (pmlmepriv->sw_to_20mhz) {\r
+ psta->bw_mode = CHANNEL_WIDTH_20;\r
+ /*psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;*/\r
+ psta->htpriv.sgi_40m = _FALSE; \r
+ } else {\r
+ /*TODO: Switch back to 40MHZ?80MHZ*/\r
+ }\r
+ } \r
+ }\r
+\r
+/*\r
+ if (sta_info_type & STA_INFO_UPDATE_RATE) {\r
+ \r
+ }\r
+*/ \r
+\r
+ if (sta_info_type & STA_INFO_UPDATE_PROTECTION_MODE)\r
+ VCS_update(padapter, psta);\r
+ \r
+/*\r
+ if (sta_info_type & STA_INFO_UPDATE_CAP) {\r
+ \r
+ }\r
+\r
+ if (sta_info_type & STA_INFO_UPDATE_HT_CAP) {\r
+ \r
+ }\r
+\r
+ if (sta_info_type & STA_INFO_UPDATE_VHT_CAP) {\r
+ \r
+ } \r
+*/\r
+\r
+}\r
+\r
+static void update_bcn_ext_capab_ie(_adapter *padapter)\r
+{\r
+ sint ie_len = 0;\r
+ unsigned char *pbuf;\r
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);\r
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);\r
+ WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);\r
+ u8 *ie = pnetwork->IEs; \r
+ u8 null_extcap_data[8] = {0};\r
+ \r
+ pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_CAP_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));\r
+ if (pbuf && ie_len > 0)\r
+ rtw_remove_bcn_ie(padapter, pnetwork, _EXT_CAP_IE_);\r
+\r
+ if ((pmlmepriv->ext_capab_ie_len > 0) && \r
+ (_rtw_memcmp(pmlmepriv->ext_capab_ie_data, null_extcap_data, sizeof(null_extcap_data)) == _FALSE))\r
+ rtw_add_bcn_ie(padapter, pnetwork, _EXT_CAP_IE_, pmlmepriv->ext_capab_ie_data, pmlmepriv->ext_capab_ie_len);\r
+ \r
+}\r
+\r
+static void update_bcn_fixed_ie(_adapter *padapter)\r
+{\r
+ DBG_871X("%s\n", __FUNCTION__);\r
+\r
+}\r
+\r
+static void update_bcn_erpinfo_ie(_adapter *padapter)\r
+{\r
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);\r
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);\r
+ WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);\r
+ unsigned char *p, *ie = pnetwork->IEs;\r
+ u32 len = 0;\r
+\r
+ DBG_871X("%s, ERP_enable=%d\n", __FUNCTION__, pmlmeinfo->ERP_enable);\r
+\r
+ if(!pmlmeinfo->ERP_enable)\r
+ return;\r
+\r
+ //parsing ERP_IE\r
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));\r
+ if(p && len>0)\r
+ {\r
+ PNDIS_802_11_VARIABLE_IEs pIE = (PNDIS_802_11_VARIABLE_IEs)p;\r
+\r
+ if (pmlmepriv->num_sta_non_erp == 1)\r
+ pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION;\r
+ else\r
+ pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION);\r
+\r
+ if(pmlmepriv->num_sta_no_short_preamble > 0)\r
+ pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;\r
+ else\r
+ pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);\r
+ \r
+ ERP_IE_handler(padapter, pIE);\r
+ }\r
+ \r
+}\r
+\r
+static void update_bcn_htcap_ie(_adapter *padapter)\r
+{\r
+ DBG_871X("%s\n", __FUNCTION__);\r
\r
-static void update_bcn_wmm_ie(_adapter *padapter)\r
-{\r
- DBG_871X("%s\n", __FUNCTION__);\r
- \r
+}\r
+\r
+static void update_bcn_htinfo_ie(_adapter *padapter)\r
+{ \r
+ /*\r
+ u8 beacon_updated = _FALSE;\r
+ u32 sta_info_update_type = STA_INFO_UPDATE_NONE; \r
+ */\r
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);\r
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);\r
+ WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);\r
+ unsigned char *p, *ie = pnetwork->IEs;\r
+ u32 len = 0; \r
+\r
+ if (pmlmepriv->htpriv.ht_option == _FALSE) \r
+ return;\r
+\r
+ if (pmlmeinfo->HT_info_enable != 1)\r
+ return;\r
+\r
+\r
+ DBG_871X("%s current operation mode=0x%X\n",\r
+ __FUNCTION__, pmlmepriv->ht_op_mode);\r
+\r
+ DBG_871X("num_sta_40mhz_intolerant(%d), 20mhz_width_req(%d), intolerant_ch_rpt(%d), olbc(%d)\n", \r
+ pmlmepriv->num_sta_40mhz_intolerant, pmlmepriv->ht_20mhz_width_req, pmlmepriv->ht_intolerant_ch_reported, pmlmepriv->olbc);\r
+\r
+ /*parsing HT_INFO_IE, currently only update ht_op_mode - pht_info->infos[1] & pht_info->infos[2] for wifi logo test*/\r
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));\r
+ if (p && len > 0) {\r
+ struct HT_info_element *pht_info = NULL;\r
+ \r
+ pht_info = (struct HT_info_element *)(p + 2); \r
+\r
+ /* for STA Channel Width/Secondary Channel Offset*/\r
+ if ((pmlmepriv->sw_to_20mhz == 0) && (pmlmeext->cur_channel <= 14)) {\r
+ if ((pmlmepriv->num_sta_40mhz_intolerant > 0) || (pmlmepriv->ht_20mhz_width_req == _TRUE) \r
+ || (pmlmepriv->ht_intolerant_ch_reported == _TRUE) || (pmlmepriv->olbc == _TRUE)) {\r
+ SET_HT_OP_ELE_2ND_CHL_OFFSET(pht_info, 0);\r
+ SET_HT_OP_ELE_STA_CHL_WIDTH(pht_info, 0);\r
+\r
+ pmlmepriv->sw_to_20mhz = 1;\r
+ /*\r
+ sta_info_update_type |= STA_INFO_UPDATE_BW;\r
+ beacon_updated = _TRUE;\r
+ */\r
+ \r
+ DBG_871X("%s:switching to 20Mhz\n", __FUNCTION__); \r
+\r
+ /*TODO : cur_bwmode/cur_ch_offset switches to 20Mhz*/\r
+ }\r
+ } else {\r
+\r
+ if ((pmlmepriv->num_sta_40mhz_intolerant == 0) && (pmlmepriv->ht_20mhz_width_req == _FALSE) \r
+ && (pmlmepriv->ht_intolerant_ch_reported == _FALSE) && (pmlmepriv->olbc == _FALSE)) {\r
+\r
+ if (pmlmeext->cur_bwmode >= CHANNEL_WIDTH_40) {\r
+ \r
+ SET_HT_OP_ELE_STA_CHL_WIDTH(pht_info, 1);\r
+\r
+ SET_HT_OP_ELE_2ND_CHL_OFFSET(pht_info, \r
+ (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) ? \r
+ HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE : HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW);\r
+ \r
+ pmlmepriv->sw_to_20mhz = 0;\r
+ /*\r
+ sta_info_update_type |= STA_INFO_UPDATE_BW;\r
+ beacon_updated = _TRUE;\r
+ */\r
+ \r
+ DBG_871X("%s:switching back to 40Mhz\n", __FUNCTION__); \r
+ }\r
+ }\r
+ }\r
+\r
+ /* to update ht_op_mode*/\r
+ *(u16 *)(pht_info->infos + 1) = cpu_to_le16(pmlmepriv->ht_op_mode);\r
+ \r
+ } \r
+\r
+ /*associated_clients_update(padapter, beacon_updated, sta_info_update_type);*/\r
+\r
+}\r
+\r
+static void update_bcn_rsn_ie(_adapter *padapter)\r
+{\r
+ DBG_871X("%s\n", __FUNCTION__);\r
+\r
+}\r
+\r
+static void update_bcn_wpa_ie(_adapter *padapter)\r
+{\r
+ DBG_871X("%s\n", __FUNCTION__);\r
+\r
+}\r
+\r
+static void update_bcn_wmm_ie(_adapter *padapter)\r
+{\r
+ DBG_871X("%s\n", __FUNCTION__);\r
+ \r
}\r
\r
static void update_bcn_wps_ie(_adapter *padapter)\r
\r
break;\r
\r
+ case _EXT_CAP_IE_:\r
+\r
+ update_bcn_ext_capab_ie(padapter);\r
+\r
+ break;\r
+ \r
case _VENDOR_SPECIFIC_IE_:\r
\r
update_bcn_vendor_spec_ie(padapter, oui);\r
\r
#ifdef CONFIG_80211N_HT\r
\r
+void rtw_process_public_act_bsscoex(_adapter *padapter, u8 *pframe, uint frame_len)\r
+{\r
+ struct sta_info *psta;\r
+ struct sta_priv *pstapriv = &padapter->stapriv;\r
+ u8 beacon_updated = _FALSE;\r
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
+ u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); \r
+ uint frame_body_len = frame_len - sizeof(struct rtw_ieee80211_hdr_3addr);\r
+ u8 category, action;\r
+\r
+ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));\r
+ if (psta == NULL) \r
+ return;\r
+\r
+\r
+ category = frame_body[0];\r
+ action = frame_body[1];\r
+\r
+ if (frame_body_len > 0) {\r
+ if ((frame_body[2] == EID_BSSCoexistence) && (frame_body[3] > 0)) { \r
+ u8 ie_data = frame_body[4];\r
+\r
+ if (ie_data & RTW_WLAN_20_40_BSS_COEX_40MHZ_INTOL) {\r
+ if (psta->ht_40mhz_intolerant == 0) { \r
+ psta->ht_40mhz_intolerant = 1;\r
+ pmlmepriv->num_sta_40mhz_intolerant++;\r
+ beacon_updated = _TRUE;\r
+ } \r
+ } else if (ie_data & RTW_WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ) { \r
+ if (pmlmepriv->ht_20mhz_width_req == _FALSE) { \r
+ pmlmepriv->ht_20mhz_width_req = _TRUE; \r
+ beacon_updated = _TRUE;\r
+ } \r
+ } else\r
+ beacon_updated = _FALSE;\r
+ } \r
+ }\r
+\r
+ if (frame_body_len > 8) {\r
+ /* if EID_BSSIntolerantChlReport ie exists */\r
+ if ((frame_body[5] == EID_BSSIntolerantChlReport) && (frame_body[6] > 0)) {\r
+ /*todo:*/\r
+ if (pmlmepriv->ht_intolerant_ch_reported == _FALSE) { \r
+ pmlmepriv->ht_intolerant_ch_reported = _TRUE; \r
+ beacon_updated = _TRUE;\r
+ }\r
+ } \r
+ }\r
+\r
+ if (beacon_updated) {\r
+ \r
+ update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);\r
+ \r
+ associated_stainfo_update(padapter, psta, STA_INFO_UPDATE_BW);\r
+ }\r
+\r
+ \r
+ \r
+}\r
+\r
+void rtw_process_ht_action_smps(_adapter *padapter, u8 *ta, u8 ctrl_field)\r
+{\r
+ u8 e_field, m_field;\r
+ struct sta_info *psta;\r
+ struct sta_priv *pstapriv = &padapter->stapriv;\r
+\r
+ psta = rtw_get_stainfo(pstapriv, ta);\r
+ if (psta == NULL) \r
+ return;\r
+\r
+ e_field = (ctrl_field & BIT(0)) ? 1 : 0;\r
+ m_field = (ctrl_field & BIT(1)) ? 1 : 0; \r
+\r
+ if (e_field) {\r
+\r
+ /* enable */\r
+ /* 0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/\r
+ \r
+ if (m_field) /*mode*/\r
+ psta->htpriv.smps_cap = 1;\r
+ else\r
+ psta->htpriv.smps_cap = 0;\r
+ } else {\r
+ /*disable*/\r
+ psta->htpriv.smps_cap = 3;\r
+ }\r
+\r
+ rtw_dm_ra_mask_wk_cmd(padapter, (u8 *)psta);\r
+\r
+}\r
+\r
/*\r
op_mode\r
Set to 0 (HT pure) under the followign conditions\r
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;\r
\r
- if(pmlmepriv->htpriv.ht_option == _TRUE) \r
+ if (pmlmepriv->htpriv.ht_option == _FALSE) \r
return 0;\r
\r
- //if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)\r
- // return 0;\r
+ /*if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)\r
+ return 0;*/\r
\r
DBG_871X("%s current operation mode=0x%X\n",\r
__FUNCTION__, pmlmepriv->ht_op_mode);\r
* it looks like all known HT STAs support greenfield.\r
*/\r
new_op_mode = 0;\r
- if (pmlmepriv->num_sta_no_ht ||\r
- (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))\r
+ if (pmlmepriv->num_sta_no_ht /*||\r
+ (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)*/)\r
new_op_mode = OP_MODE_MIXED;\r
else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH)\r
&& pmlmepriv->num_sta_ht_20mhz)\r
\r
#endif /* CONFIG_80211N_HT */\r
\r
-void associated_clients_update(_adapter *padapter, u8 updated)\r
+void associated_clients_update(_adapter *padapter, u8 updated, u32 sta_info_type)\r
{\r
//update associcated stations cap.\r
if(updated == _TRUE)\r
\r
plist = get_next(plist);\r
\r
- VCS_update(padapter, psta); \r
+ associated_stainfo_update(padapter, psta, sta_info_type); \r
}\r
\r
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
pmlmepriv->num_sta_ht_20mhz);\r
}\r
\r
+\r
+ if (ht_capab & RTW_IEEE80211_HT_CAP_40MHZ_INTOLERANT) {\r
+\r
+ if (!psta->ht_40mhz_intolerant) {\r
+ psta->ht_40mhz_intolerant = 1;\r
+ pmlmepriv->num_sta_40mhz_intolerant++;\r
+ DBG_871X("%s STA " MAC_FMT " - HT_CAP_40MHZ_INTOLERANT is set\n" ,\r
+ __FUNCTION__, MAC_ARG(psta->hwaddr));\r
+ beacon_updated = _TRUE;\r
+ }\r
+ \r
+/*\r
+ if (pmlmepriv->ht_40mhz_intolerant == _FALSE) {\r
+ \r
+ pmlmepriv->ht_40mhz_intolerant = _TRUE; \r
+ \r
+ DBG_871X("%s STA " MAC_FMT " - HT_CAP_40MHZ_INTOLERANT is set\n" ,\r
+ __FUNCTION__, MAC_ARG(psta->hwaddr));\r
+\r
+ beacon_updated = _TRUE;\r
+ }\r
+*/ \r
+\r
+ /*update ext_capab_ie_len & ext_capab_ie_data for beacon, probersp, assocrsp.*/\r
+ if (pmlmepriv->ext_capab_ie_len == 0)\r
+ pmlmepriv->ext_capab_ie_len = 1;\r
+ SET_EXT_CAPABILITY_ELE_BSS_COEXIST(pmlmepriv->ext_capab_ie_data, 1);\r
+\r
+ update_beacon(padapter, _EXT_CAP_IE_, NULL, _FALSE);\r
+ } \r
+ \r
} \r
else \r
{\r
}\r
}\r
\r
- if (rtw_ht_operation_update(padapter) > 0)\r
- {\r
+ if (rtw_ht_operation_update(padapter) > 0) {\r
update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);\r
update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);\r
+ /*beacon_updated = _TRUE;*/\r
} \r
\r
#endif /* CONFIG_80211N_HT */\r
\r
//update associcated stations cap.\r
- associated_clients_update(padapter, beacon_updated);\r
+ associated_clients_update(padapter, beacon_updated, STA_INFO_UPDATE_ALL);\r
\r
DBG_871X("%s, updated=%d\n", __func__, beacon_updated);\r
\r
pmlmepriv->num_sta_ht_20mhz--;\r
}\r
\r
- if (rtw_ht_operation_update(padapter) > 0)\r
- {\r
+ if (psta->ht_40mhz_intolerant) {\r
+ psta->ht_40mhz_intolerant = 0;\r
+ pmlmepriv->num_sta_40mhz_intolerant--;\r
+\r
+ /*update ext_capab_ie_len & ext_capab_ie_data for beacon, probersp, assocrsp.*/\r
+ if ((pmlmepriv->ext_capab_ie_len > 0) && (pmlmepriv->num_sta_40mhz_intolerant == 0)) {\r
+ SET_EXT_CAPABILITY_ELE_BSS_COEXIST(pmlmepriv->ext_capab_ie_data, 0);\r
+ update_beacon(padapter, _EXT_CAP_IE_, NULL, _FALSE);\r
+ }\r
+ \r
+ beacon_updated = _TRUE;\r
+\r
+ update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _FALSE);\r
+ }\r
+\r
+ if (rtw_ht_operation_update(padapter) > 0) {\r
update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);\r
update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);\r
}\r
\r
#endif /* CONFIG_80211N_HT */\r
\r
- //update associcated stations cap.\r
- //associated_clients_update(padapter, beacon_updated); //move it to avoid deadlock\r
-\r
+ /* update associated stations cap.\r
+ associated_clients_update(padapter, beacon_updated, STA_INFO_UPDATE_ALL); //move it to avoid deadlock\r
+ */\r
+ \r
DBG_871X("%s, updated=%d\n", __func__, beacon_updated);\r
\r
return beacon_updated;\r
\r
}\r
\r
-u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason)\r
+u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason, bool enqueue)\r
{\r
_irqL irqL;\r
u8 beacon_updated = _FALSE;\r
psta->htpriv.agg_enable_bitmap = 0x0;//reset\r
psta->htpriv.candidate_tid_bitmap = 0x0;//reset\r
\r
-\r
- //report_del_sta_event(padapter, psta->hwaddr, reason);\r
-\r
//clear cam entry / key\r
- rtw_clearstakey_cmd(padapter, psta, _TRUE);\r
+ rtw_clearstakey_cmd(padapter, psta, enqueue);\r
\r
\r
_enter_critical_bh(&psta->lock, &irqL);\r
rtw_indicate_sta_disassoc_event(padapter, psta);\r
}\r
\r
- report_del_sta_event(padapter, psta->hwaddr, reason);\r
+ report_del_sta_event(padapter, psta->hwaddr, reason, enqueue, _FALSE);\r
\r
beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);\r
\r
return ret;\r
}\r
\r
-int rtw_sta_flush(_adapter *padapter)\r
+int rtw_sta_flush(_adapter *padapter, bool enqueue)\r
{\r
_irqL irqL;\r
_list *phead, *plist;\r
- int ret=0; \r
+ int ret = 0;\r
struct sta_info *psta = NULL; \r
struct sta_priv *pstapriv = &padapter->stapriv;\r
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;\r
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);\r
u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};\r
+ u8 flush_num = 0;\r
+ char flush_list[NUM_STA];\r
+ int i;\r
\r
- if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)\r
+ if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)\r
return ret;\r
\r
DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));\r
+\r
+ /* pick sta from sta asoc_queue */\r
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
phead = &pstapriv->asoc_list;\r
plist = get_next(phead);\r
+ while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {\r
+ int stainfo_offset;\r
\r
- //free sta asoc_queue\r
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)\r
- {\r
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);\r
- \r
plist = get_next(plist);\r
\r
rtw_list_delete(&psta->asoc_list);\r
pstapriv->asoc_list_cnt--;\r
\r
- //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
- ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);\r
- //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
+ stainfo_offset = rtw_stainfo_offset(pstapriv, psta);\r
+ if (stainfo_offset_valid(stainfo_offset))\r
+ flush_list[flush_num++] = stainfo_offset;\r
+ else\r
+ rtw_warn_on(1);\r
}\r
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
\r
+ /* call ap_free_sta() for each sta picked */\r
+ for (i = 0; i < flush_num; i++) {\r
+ psta = rtw_get_stainfo_by_offset(pstapriv, flush_list[i]);\r
+ ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, enqueue);\r
+ }\r
\r
issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);\r
\r
- associated_clients_update(padapter, _TRUE);\r
+ associated_clients_update(padapter, _TRUE, STA_INFO_UPDATE_ALL);\r
\r
return ret;\r
-\r
}\r
\r
/* called > TSR LEVEL for USB or SDIO Interface*/\r
{\r
psta->htpriv.ht_option = _TRUE;\r
psta->qos_option = 1; \r
+\r
+ psta->htpriv.smps_cap = (psta->htpriv.ht_cap.cap_info & IEEE80211_HT_CAP_SM_PS)>>2;\r
}\r
else \r
{\r
/* called >= TSR LEVEL for USB or SDIO Interface*/\r
void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta)\r
{\r
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;\r
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);\r
-\r
- if(psta->state & _FW_LINKED)\r
- {\r
- pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;\r
- \r
+ if (psta->state & _FW_LINKED) {\r
//add ratid\r
add_RATid(padapter, psta, 0);//DM_RATR_STA_INIT\r
} \r
\r
set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);\r
\r
- start_bss_network(padapter, (u8*)&mlmepriv->cur_network.network);\r
+ rtw_startbss_cmd(padapter, RTW_CMDF_DIRECTLY);\r
\r
if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||\r
(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))\r
if( (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||\r
(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))\r
{\r
- rtw_setstakey_cmd(padapter, psta, _TRUE,_FALSE);\r
+ rtw_setstakey_cmd(padapter, psta, UNICAST_KEY,_FALSE);\r
} \r
}\r
}\r
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
struct sta_priv *pstapriv = &padapter->stapriv;\r
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;\r
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);\r
struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;\r
\r
pmlmepriv->update_bcn = _FALSE;\r
\r
- //init_mlme_ap_info(padapter);\r
+ /*init_mlme_ap_info(padapter);*/\r
+ \r
pmlmeext->bstart_bss = _FALSE;\r
\r
pmlmepriv->num_sta_non_erp = 0;\r
#ifdef CONFIG_80211N_HT\r
pmlmepriv->num_sta_no_ht = 0;\r
#endif //CONFIG_80211N_HT\r
+ pmlmeinfo->HT_info_enable = 0;\r
+ pmlmeinfo->HT_caps_enable = 0;\r
+ pmlmeinfo->HT_enable = 0;\r
+ \r
pmlmepriv->num_sta_ht_20mhz = 0;\r
-\r
+ pmlmepriv->num_sta_40mhz_intolerant = 0;\r
pmlmepriv->olbc = _FALSE;\r
-\r
pmlmepriv->olbc_ht = _FALSE;\r
\r
#ifdef CONFIG_80211N_HT\r
+ pmlmepriv->ht_20mhz_width_req = _FALSE;\r
+ pmlmepriv->ht_intolerant_ch_reported = _FALSE;\r
pmlmepriv->ht_op_mode = 0;\r
+ pmlmepriv->sw_to_20mhz = 0;\r
#endif\r
\r
- for(i=0; i<NUM_STA; i++)\r
- pstapriv->sta_aid[i] = NULL;\r
+ _rtw_memset(pmlmepriv->ext_capab_ie_data, 0, sizeof(pmlmepriv->ext_capab_ie_data));\r
+ pmlmepriv->ext_capab_ie_len = 0;\r
\r
-/* to avoid memory leak issue, don't set to NULL directly\r
- pmlmepriv->wps_beacon_ie = NULL; \r
- pmlmepriv->wps_probe_resp_ie = NULL;\r
- pmlmepriv->wps_assoc_resp_ie = NULL;\r
- \r
- pmlmepriv->p2p_beacon_ie = NULL;\r
- pmlmepriv->p2p_probe_resp_ie = NULL;\r
-*/\r
+ for (i = 0 ; i < NUM_STA ; i++)\r
+ pstapriv->sta_aid[i] = NULL;\r
\r
//for ACL \r
_rtw_init_listhead(&(pacl_list->acl_node_q.queue));\r
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;\r
padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;\r
\r
+ #ifdef CONFIG_DFS_MASTER\r
+ rtw_dfs_master_status_apply(padapter, MLME_AP_STOPPED);\r
+ #endif\r
+\r
+ /* free scan queue */\r
+ rtw_free_network_queue(padapter, _TRUE);\r
+\r
//for ACL\r
_enter_critical_bh(&(pacl_node_q->lock), &irqL);\r
phead = get_list_head(pacl_node_q);\r
\r
DBG_871X("%s, free acl_node_queue, num=%d\n", __func__, pacl_list->num);\r
\r
- rtw_sta_flush(padapter);\r
+ rtw_sta_flush(padapter, _TRUE);\r
\r
//free_assoc_sta_resources \r
rtw_free_all_stainfo(padapter);\r
\r
#endif //CONFIG_NATIVEAP_MLME\r
\r
-#ifdef CONFIG_CONCURRENT_MODE\r
-void concurrent_set_ap_chbw(_adapter *padapter, u8 channel, u8 channel_offset, u8 bwmode)\r
+void rtw_ap_update_bss_chbw(_adapter *adapter, WLAN_BSSID_EX *bss, u8 ch, u8 bw, u8 offset)\r
{\r
- u8 *p;\r
- int ie_len=0;\r
- u8 cur_channel, cur_bwmode, cur_ch_offset, change_band;\r
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
- WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;\r
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);\r
- struct HT_info_element *pht_info=NULL;\r
- \r
- cur_channel = channel;\r
- cur_bwmode = bwmode;\r
- cur_ch_offset = channel_offset;\r
- change_band = _FALSE;\r
- \r
- 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
- if( p && ie_len)\r
- {\r
- pht_info = (struct HT_info_element *)(p+2);\r
- }\r
+#define UPDATE_VHT_CAP 1\r
+#define UPDATE_HT_CAP 1\r
\r
- \r
- if(!check_buddy_fwstate(padapter, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY))\r
+#ifdef CONFIG_80211AC_VHT\r
{\r
- set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);\r
+ struct vht_priv *vhtpriv = &adapter->mlmepriv.vhtpriv;\r
+ u8 *vht_cap_ie, *vht_op_ie;\r
+ int vht_cap_ielen, vht_op_ielen;\r
+ u8 center_freq;\r
+\r
+ vht_cap_ie = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTCapability, &vht_cap_ielen, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs)));\r
+ vht_op_ie = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTOperation, &vht_op_ielen, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs)));\r
+ center_freq = rtw_get_center_ch(ch, bw, offset);\r
+\r
+ /* update vht cap ie */\r
+ if (vht_cap_ie && vht_cap_ielen) {\r
+ #if UPDATE_VHT_CAP\r
+ /* if ((bw == CHANNEL_WIDTH_160 || bw == CHANNEL_WIDTH_80_80) && pvhtpriv->sgi_160m)\r
+ SET_VHT_CAPABILITY_ELE_SHORT_GI160M(pvht_cap_ie + 2, 1);\r
+ else */\r
+ SET_VHT_CAPABILITY_ELE_SHORT_GI160M(vht_cap_ie + 2, 0);\r
+\r
+ if (bw >= CHANNEL_WIDTH_80 && vhtpriv->sgi_80m)\r
+ SET_VHT_CAPABILITY_ELE_SHORT_GI80M(vht_cap_ie + 2, 1);\r
+ else\r
+ SET_VHT_CAPABILITY_ELE_SHORT_GI80M(vht_cap_ie + 2, 0);\r
+ #endif\r
+ }\r
+\r
+ /* update vht op ie */\r
+ if (vht_op_ie && vht_op_ielen) {\r
+ if (bw < CHANNEL_WIDTH_80) {\r
+ SET_VHT_OPERATION_ELE_CHL_WIDTH(vht_op_ie + 2, 0);\r
+ SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(vht_op_ie + 2, 0);\r
+ SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(vht_op_ie + 2, 0);\r
+ } else if (bw == CHANNEL_WIDTH_80) {\r
+ SET_VHT_OPERATION_ELE_CHL_WIDTH(vht_op_ie + 2, 1);\r
+ SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(vht_op_ie + 2, center_freq);\r
+ SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(vht_op_ie + 2, 0);\r
+ } else {\r
+ DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" unsupported BW:%u\n", FUNC_ADPT_ARG(adapter), bw);\r
+ rtw_warn_on(1);\r
+ }\r
+ }\r
}\r
- else if(check_buddy_fwstate(padapter, _FW_LINKED)==_TRUE)\r
+#endif /* CONFIG_80211AC_VHT */\r
+#ifdef CONFIG_80211N_HT\r
{\r
- _adapter *pbuddy_adapter = padapter->pbuddy_adapter; \r
- struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;\r
-\r
- //To sync cur_channel/cur_bwmode/cur_ch_offset with buddy adapter\r
- DBG_871X(ADPT_FMT" is at linked state\n", ADPT_ARG(pbuddy_adapter));\r
- DBG_871X(ADPT_FMT": CH=%d, BW=%d, offset=%d\n", ADPT_ARG(pbuddy_adapter), pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);\r
- DBG_871X(ADPT_FMT": CH=%d, BW=%d, offset=%d\n", ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);\r
+ struct ht_priv *htpriv = &adapter->mlmepriv.htpriv;\r
+ u8 *ht_cap_ie, *ht_op_ie;\r
+ int ht_cap_ielen, ht_op_ielen;\r
+\r
+ ht_cap_ie = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_HTCapability, &ht_cap_ielen, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs)));\r
+ ht_op_ie = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_HTInfo, &ht_op_ielen, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs)));\r
+\r
+ /* update ht cap ie */\r
+ if (ht_cap_ie && ht_cap_ielen) {\r
+ #if UPDATE_HT_CAP\r
+ if (bw >= CHANNEL_WIDTH_40)\r
+ SET_HT_CAP_ELE_CHL_WIDTH(ht_cap_ie + 2, 1);\r
+ else\r
+ SET_HT_CAP_ELE_CHL_WIDTH(ht_cap_ie + 2, 0);\r
\r
- if((cur_channel <= 14 && pbuddy_mlmeext->cur_channel >= 36) ||\r
- (cur_channel >= 36 && pbuddy_mlmeext->cur_channel <= 14))\r
- change_band = _TRUE;\r
+ if (bw >= CHANNEL_WIDTH_40 && htpriv->sgi_40m)\r
+ SET_HT_CAP_ELE_SHORT_GI40M(ht_cap_ie + 2, 1);\r
+ else\r
+ SET_HT_CAP_ELE_SHORT_GI40M(ht_cap_ie + 2, 0);\r
\r
- cur_channel = pbuddy_mlmeext->cur_channel;\r
+ if (htpriv->sgi_20m)\r
+ SET_HT_CAP_ELE_SHORT_GI20M(ht_cap_ie + 2, 1);\r
+ else\r
+ SET_HT_CAP_ELE_SHORT_GI20M(ht_cap_ie + 2, 0);\r
+ #endif\r
+ }\r
\r
-#ifdef CONFIG_80211AC_VHT\r
- if(cur_bwmode == CHANNEL_WIDTH_80)\r
- {\r
- u8 *pvht_cap_ie, *pvht_op_ie;\r
- int vht_cap_ielen, vht_op_ielen;\r
- \r
- 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
- 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
- \r
- if(pbuddy_mlmeext->cur_channel <= 14) // downgrade to 20/40Mhz\r
- {\r
- //modify vht cap ie\r
- if( pvht_cap_ie && vht_cap_ielen)\r
- {\r
- SET_VHT_CAPABILITY_ELE_SHORT_GI80M(pvht_cap_ie+2, 0);\r
- }\r
- \r
- //modify vht op ie\r
- if( pvht_op_ie && vht_op_ielen)\r
- {\r
- SET_VHT_OPERATION_ELE_CHL_WIDTH(pvht_op_ie+2, 0); //change to 20/40Mhz\r
- SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(pvht_op_ie+2, 0);\r
- SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(pvht_op_ie+2, 0);\r
- //SET_VHT_OPERATION_ELE_BASIC_MCS_SET(p+2, 0xFFFF); \r
- cur_bwmode = CHANNEL_WIDTH_40;\r
- } \r
+ /* update ht op ie */\r
+ if (ht_op_ie && ht_op_ielen) {\r
+ SET_HT_OP_ELE_PRI_CHL(ht_op_ie + 2, ch);\r
+ switch (offset) {\r
+ case HAL_PRIME_CHNL_OFFSET_LOWER:\r
+ SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op_ie + 2, SCA);\r
+ break;\r
+ case HAL_PRIME_CHNL_OFFSET_UPPER:\r
+ SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op_ie + 2, SCB);\r
+ break;\r
+ case HAL_PRIME_CHNL_OFFSET_DONT_CARE:\r
+ default:\r
+ SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op_ie + 2, SCN);\r
+ break;\r
}\r
+\r
+ if (bw >= CHANNEL_WIDTH_40)\r
+ SET_HT_OP_ELE_STA_CHL_WIDTH(ht_op_ie + 2, 1);\r
else\r
- {\r
- u8 center_freq;\r
- \r
- cur_bwmode = CHANNEL_WIDTH_80;\r
- \r
- if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40 ||\r
- pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_80)\r
- {\r
- cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;\r
- }\r
- else if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_20)\r
- {\r
- cur_ch_offset = rtw_get_offset_by_ch(cur_channel);\r
- } \r
+ SET_HT_OP_ELE_STA_CHL_WIDTH(ht_op_ie + 2, 0);\r
+ }\r
+ }\r
+#endif /* CONFIG_80211N_HT */\r
\r
- //modify ht info ie\r
- if(pht_info)\r
- pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;\r
- \r
- switch(cur_ch_offset)\r
- {\r
- case HAL_PRIME_CHNL_OFFSET_LOWER:\r
- if(pht_info)\r
- pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE; \r
- //cur_bwmode = CHANNEL_WIDTH_40;\r
- break;\r
- case HAL_PRIME_CHNL_OFFSET_UPPER:\r
- if(pht_info)\r
- pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW; \r
- //cur_bwmode = CHANNEL_WIDTH_40;\r
- break;\r
- case HAL_PRIME_CHNL_OFFSET_DONT_CARE: \r
- default:\r
- if(pht_info)\r
- pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;\r
- cur_bwmode = CHANNEL_WIDTH_20;\r
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;\r
- break; \r
- }\r
+{\r
+ u8 *p;\r
+ int ie_len;\r
+ u8 old_ch = bss->Configuration.DSConfig;\r
+ bool change_band = _FALSE;\r
\r
- //modify vht op ie\r
- center_freq = rtw_get_center_ch(cur_channel, cur_bwmode, HAL_PRIME_CHNL_OFFSET_LOWER);\r
- if( pvht_op_ie && vht_op_ielen)\r
- SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(pvht_op_ie+2, center_freq);\r
+ if ((ch <= 14 && old_ch >= 36) || (ch >= 36 && old_ch <= 14))\r
+ change_band = _TRUE;\r
\r
- set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);\r
- \r
- }\r
- \r
- }\r
-#endif //CONFIG_80211AC_VHT\r
+ /* update channel in IE */\r
+ p = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs)));\r
+ if (p && ie_len > 0)\r
+ *(p + 2) = ch;\r
\r
- if(cur_bwmode == CHANNEL_WIDTH_40)\r
- {\r
- if(pht_info)\r
- pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;\r
- \r
- if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40 ||\r
- pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_80)\r
- {\r
- cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;\r
+ bss->Configuration.DSConfig = ch;\r
\r
- //to update cur_ch_offset value in beacon\r
- if(pht_info)\r
- { \r
- switch(cur_ch_offset)\r
- {\r
- case HAL_PRIME_CHNL_OFFSET_LOWER:\r
- pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;\r
- break;\r
- case HAL_PRIME_CHNL_OFFSET_UPPER:\r
- pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;\r
- break;\r
- case HAL_PRIME_CHNL_OFFSET_DONT_CARE: \r
- default: \r
- break; \r
+ /* band is changed, update ERP, support rate, ext support rate IE */\r
+ if (change_band == _TRUE)\r
+ change_band_update_ie(adapter, bss, ch);\r
+}\r
+\r
+}\r
+\r
+bool rtw_ap_chbw_decision(_adapter *adapter, u8 req_ch, u8 req_bw, u8 req_offset\r
+ , u8 *ch, u8 *bw, u8 *offset)\r
+{\r
+ u8 dec_ch, dec_bw, dec_offset;\r
+ u8 u_ch = 0, u_offset, u_bw;\r
+ bool changed = _FALSE;\r
+ struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);\r
+ u8 sta_num;\r
+ u8 ld_sta_num;\r
+ u8 lg_sta_num;\r
+ u8 ap_num;\r
+ u8 ld_ap_num;\r
+ bool set_u_ch = _FALSE, set_dec_ch = _FALSE;\r
+\r
+ dec_ch = req_ch;\r
+ dec_bw = req_bw;\r
+ dec_offset = req_offset;\r
+ \r
+ rtw_dev_iface_status_no_self(adapter, &sta_num, &ld_sta_num, &lg_sta_num, &ap_num, &ld_ap_num);\r
+ DBG_871X(FUNC_ADPT_FMT" ld_sta_num:%u, lg_sta_num%u, ap_num:%u\n"\r
+ , FUNC_ADPT_ARG(adapter), ld_sta_num, lg_sta_num, ap_num);\r
+\r
+ if (ld_sta_num || ap_num) {\r
+ /* has linked STA or AP mode, follow */\r
+\r
+ rtw_warn_on(!rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset));\r
+\r
+ DBG_871X(FUNC_ADPT_FMT" union no self: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);\r
+ DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), req_ch, req_bw, req_offset);\r
+\r
+ rtw_adjust_chbw(adapter, u_ch, &dec_bw, &dec_offset);\r
+\r
+ rtw_sync_chbw(&dec_ch, &dec_bw, &dec_offset\r
+ , &u_ch, &u_bw, &u_offset);\r
+\r
+ rtw_ap_update_bss_chbw(adapter, &(adapter->mlmepriv.cur_network.network)\r
+ , dec_ch, dec_bw, dec_offset);\r
+\r
+ set_u_ch = _TRUE;\r
+ } else if (lg_sta_num) {\r
+ /* has linking STA */\r
+\r
+ rtw_warn_on(!rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset));\r
+\r
+ DBG_871X(FUNC_ADPT_FMT" union no self: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);\r
+ DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), req_ch, req_bw, req_offset);\r
+\r
+ rtw_adjust_chbw(adapter, dec_ch, &dec_bw, &dec_offset);\r
+ \r
+ if (rtw_is_chbw_grouped(u_ch, u_bw, u_offset, dec_ch, dec_bw, dec_offset)) {\r
+\r
+ rtw_sync_chbw(&dec_ch, &dec_bw, &dec_offset\r
+ , &u_ch, &u_bw, &u_offset);\r
+\r
+ rtw_ap_update_bss_chbw(adapter, &(adapter->mlmepriv.cur_network.network)\r
+ , dec_ch, dec_bw, dec_offset);\r
+\r
+ set_u_ch = _TRUE;\r
+ } else {\r
+ /* set this for possible ch change when join down*/\r
+ set_fwstate(&adapter->mlmepriv, WIFI_OP_CH_SWITCHING);\r
+ }\r
+ } else {\r
+ /* single AP mode */\r
+\r
+ DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), req_ch, req_bw, req_offset);\r
+ rtw_adjust_chbw(adapter, dec_ch, &dec_bw, &dec_offset);\r
+\r
+ #if defined(CONFIG_DFS_MASTER)\r
+ /* check NOL */\r
+ if (rtw_chset_is_ch_non_ocp(mlmeext->channel_set, dec_ch, dec_bw, dec_offset)) {\r
+ /* choose 5G DFS channel for debug */\r
+ if (adapter_to_rfctl(adapter)->dbg_dfs_master_choose_dfs_ch_first\r
+ && rtw_choose_available_chbw(adapter, req_bw, &dec_ch, &dec_bw, &dec_offset, RTW_CHF_2G|RTW_CHF_NON_DFS) == _TRUE) {\r
+ DBG_871X(FUNC_ADPT_FMT" choose 5G DFS channel for debug\n", FUNC_ADPT_ARG(adapter));\r
+ } else \r
+ /* choose from 5G no DFS */\r
+ if (rtw_choose_available_chbw(adapter, req_bw, &dec_ch, &dec_bw, &dec_offset, RTW_CHF_2G|RTW_CHF_DFS) == _FALSE) {\r
+ /* including 5G DFS, not long CAC */\r
+ if (rtw_choose_available_chbw(adapter, req_bw, &dec_ch, &dec_bw, &dec_offset, RTW_CHF_2G|RTW_CHF_LONG_CAC) == _FALSE) {\r
+ /* including 5G DFS, long CAC */\r
+ if (rtw_choose_available_chbw(adapter, req_bw, &dec_ch, &dec_bw, &dec_offset, RTW_CHF_2G) == _FALSE) {\r
+ /* including 2.4G channel */\r
+ if (rtw_choose_available_chbw(adapter, req_bw, &dec_ch, &dec_bw, &dec_offset, RTW_CHF_5G) == _FALSE) {\r
+ DBG_871X(FUNC_ADPT_FMT" no available ch\n", FUNC_ADPT_ARG(adapter));\r
+ rtw_warn_on(1);\r
+ }\r
}\r
- } \r
- \r
+ }\r
}\r
- else if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_20)\r
- {\r
- cur_ch_offset = rtw_get_offset_by_ch(cur_channel);\r
+ }\r
+ #endif /* defined(CONFIG_DFS_MASTER) */\r
\r
- switch(cur_ch_offset)\r
- {\r
- case HAL_PRIME_CHNL_OFFSET_LOWER:\r
- if(pht_info)\r
- pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE; \r
- cur_bwmode = CHANNEL_WIDTH_40;\r
- break;\r
- case HAL_PRIME_CHNL_OFFSET_UPPER:\r
- if(pht_info)\r
- pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW; \r
- cur_bwmode = CHANNEL_WIDTH_40;\r
- break;\r
- case HAL_PRIME_CHNL_OFFSET_DONT_CARE: \r
- default:\r
- if(pht_info)\r
- pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;\r
- cur_bwmode = CHANNEL_WIDTH_20;\r
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;\r
- break; \r
- } \r
- \r
- }\r
+ rtw_ap_update_bss_chbw(adapter, &(adapter->mlmepriv.cur_network.network)\r
+ , dec_ch, dec_bw, dec_offset);\r
\r
- set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);\r
- \r
- }\r
- else\r
- {\r
- set_channel_bwmode(padapter, cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);\r
- } \r
+ set_dec_ch = _TRUE;\r
+ }\r
\r
- // to update channel value in beacon\r
- pnetwork->Configuration.DSConfig = cur_channel; \r
- 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
- if(p && ie_len>0)\r
- *(p + 2) = cur_channel;\r
- \r
- if(pht_info)\r
- pht_info->primary_channel = cur_channel;\r
+ if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY)\r
+ #ifdef CONFIG_CONCURRENT_MODE\r
+ || check_buddy_fwstate(adapter, _FW_UNDER_SURVEY)\r
+ #endif\r
+ ) {\r
+ /* scanning, leave ch setting to scan state machine */\r
+ set_u_ch = set_dec_ch = _FALSE;\r
}\r
\r
- DBG_871X(FUNC_ADPT_FMT" CH=%d, BW=%d, offset=%d\n", FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);\r
+ if (mlmeext->cur_channel != dec_ch\r
+ || mlmeext->cur_bwmode != dec_bw\r
+ || mlmeext->cur_ch_offset != dec_offset)\r
+ changed = _TRUE;\r
\r
- pmlmeext->cur_channel = cur_channel; \r
- pmlmeext->cur_bwmode = cur_bwmode;\r
- pmlmeext->cur_ch_offset = cur_ch_offset;\r
+ if (changed == _TRUE && rtw_linked_check(adapter) == _TRUE) {\r
+ #ifdef CONFIG_SPCT_CH_SWITCH\r
+ if (1)\r
+ rtw_ap_inform_ch_switch(adapter, dec_ch, dec_offset);\r
+ else\r
+ #endif\r
+ rtw_sta_flush(adapter, _FALSE);\r
+ }\r
+\r
+ mlmeext->cur_channel = dec_ch;\r
+ mlmeext->cur_bwmode = dec_bw;\r
+ mlmeext->cur_ch_offset = dec_offset;\r
+\r
+ if (u_ch != 0)\r
+ DBG_871X(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);\r
\r
- //buddy interface band is different from current interface, update ERP, support rate, ext support rate IE\r
- if(change_band == _TRUE)\r
- change_band_update_ie(padapter, pnetwork);\r
+ DBG_871X(FUNC_ADPT_FMT" dec: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), dec_ch, dec_bw, dec_offset);\r
+\r
+ if (set_u_ch == _TRUE) {\r
+ *ch = u_ch;\r
+ *bw = u_bw;\r
+ *offset = u_offset;\r
+ } else if (set_dec_ch == _TRUE) {\r
+ *ch = dec_ch;\r
+ *bw = dec_bw;\r
+ *offset = dec_offset;\r
+ } \r
\r
+ return changed;\r
}\r
-#endif //CONFIG_CONCURRENT_MODE\r
\r
#endif //CONFIG_AP_MODE\r
\r