/* ========================================================================== Description: APCLI MLME JOIN req state machine procedure ========================================================================== */ static VOID ApCliCtrlJoinReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { APCLI_MLME_JOIN_REQ_STRUCT JoinReq; PAPCLI_STRUCT pApCliEntry; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState; #ifdef WSC_AP_SUPPORT PWSC_CTRL pWpsCtrl = &pAd->ApCfg.ApCliTab[ifIndex].WscControl; #endif /* WSC_AP_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Start Probe Req.\n", __FUNCTION__)); if (ifIndex >= MAX_APCLI_NUM) return; if (ApScanRunning(pAd) == TRUE) return; pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; NdisZeroMemory(&JoinReq, sizeof(APCLI_MLME_JOIN_REQ_STRUCT)); if (!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) { COPY_MAC_ADDR(JoinReq.Bssid, pApCliEntry->CfgApCliBssid); } #ifdef WSC_AP_SUPPORT if ((pWpsCtrl->WscConfMode != WSC_DISABLE) && (pWpsCtrl->bWscTrigger == TRUE)) { ULONG bss_idx = 0; NdisZeroMemory(JoinReq.Ssid, MAX_LEN_OF_SSID); JoinReq.SsidLen = pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscSsid.SsidLength; NdisMoveMemory(JoinReq.Ssid, pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscSsid.Ssid, JoinReq.SsidLen); { bss_idx = BssSsidTableSearch(&pAd->ScanTab, pAd->P2pCfg.Bssid, (PCHAR)JoinReq.Ssid, JoinReq.SsidLen, pAd->CommonCfg.Channel); if (bss_idx == BSS_NOT_FOUND) { *pCurrState = APCLI_CTRL_PROBE; ApSiteSurvey(pAd, NULL, SCAN_WSC_ACTIVE, FALSE); return; } else { BOOLEAN Cancelled; INT old_conf_mode = pWpsCtrl->WscConfMode, old_wsc_mode = pWpsCtrl->WscMode; ADD_HTINFO RootApHtInfo, ApHtInfo; UCHAR channel = pAd->CommonCfg.Channel, RootApChannel = pAd->ScanTab.BssEntry[bss_idx].Channel; UCHAR RootApCentralChannel = pAd->ScanTab.BssEntry[bss_idx].CentralChannel; ApHtInfo = pAd->CommonCfg.AddHTInfo.AddHtInfo; RootApHtInfo = pAd->ScanTab.BssEntry[bss_idx].AddHtInfo.AddHtInfo; if (INFRA_ON(pAd) && (pAd->StaActive.SupportedHtPhy.ExtChanOffset != RootApHtInfo.ExtChanOffset) && (pAd->StaActive.SupportedHtPhy.ChannelWidth == BW_40)) { DBGPRINT(RT_DEBUG_OFF, ("%s :: Channel offset = %d not match INFRA Channel offset %d .\n", __FUNCTION__, pAd->MlmeAux.CentralChannel, RootApCentralChannel)); P2pLinkDown(pAd, P2P_CONNECT_FAIL); return; } if ((RootApChannel != channel) || ((RootApCentralChannel != RootApChannel) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (ApHtInfo.ExtChanOffset != RootApHtInfo.ExtChanOffset))) { STRING ChStr[5] = {0}; if (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) { if (RootApHtInfo.ExtChanOffset == EXTCHA_ABOVE) Set_HtExtcha_Proc(pAd, "1"); else Set_HtExtcha_Proc(pAd, "0"); } sprintf(ChStr, "%d", pAd->ScanTab.BssEntry[bss_idx].Channel); Set_Channel_Proc(pAd, ChStr); /* ApStop will call WscStop, we need to reset WscConfMode, WscMode & bWscTrigger here. */ pWpsCtrl->WscState = WSC_STATE_START; pWpsCtrl->WscStatus = STATUS_WSC_START_ASSOC; pWpsCtrl->WscMode = old_wsc_mode; pWpsCtrl->WscConfMode = old_conf_mode; pWpsCtrl->bWscTrigger = TRUE; return; } else { pAd->CommonCfg.Channel = pAd->ScanTab.BssEntry[bss_idx].Channel; AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); } } } } else #endif /* WSC_AP_SUPPORT */ if (pApCliEntry->CfgSsidLen != 0) { ULONG bss_idx = 0; bss_idx = BssSsidTableSearch(&pAd->ScanTab, JoinReq.Bssid, (PCHAR)pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, pAd->CommonCfg.Channel); if (bss_idx == BSS_NOT_FOUND) { DBGPRINT(RT_DEBUG_TRACE, ("%s:: can't find SSID[%s] in ScanTab.\n", __FUNCTION__, pApCliEntry->CfgSsid)); *pCurrState = APCLI_CTRL_PROBE; ApSiteSurvey(pAd, NULL, SCAN_ACTIVE, FALSE); return; } DBGPRINT(RT_DEBUG_TRACE, ("%s:: find SSID[%ld][%s] channel[%d-%d] in ScanTab.\n", __FUNCTION__, bss_idx, pApCliEntry->CfgSsid, pAd->ScanTab.BssEntry[bss_idx].Channel, pAd->ScanTab.BssEntry[bss_idx].CentralChannel)); /* BssSearch Table has found the pEntry, send Prob Req. directly */ pAd->CommonCfg.Channel = pAd->ScanTab.BssEntry[bss_idx].Channel; AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); JoinReq.SsidLen = pApCliEntry->CfgSsidLen; NdisMoveMemory(&(JoinReq.Ssid), pApCliEntry->CfgSsid, JoinReq.SsidLen); } if (pApCliEntry->CfgSsidLen == 0) { DBGPRINT(RT_DEBUG_TRACE, ("%s:: ApCliEntry SSID Len is 0 !!!.\n", __FUNCTION__)); *pCurrState = APCLI_CTRL_PROBE; ApSiteSurvey(pAd, NULL, SCAN_WSC_ACTIVE, FALSE); return; } DBGPRINT(RT_DEBUG_TRACE, ("(%s) Probe Ssid=%s, Bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, JoinReq.Ssid, JoinReq.Bssid[0], JoinReq.Bssid[1], JoinReq.Bssid[2], JoinReq.Bssid[3], JoinReq.Bssid[4], JoinReq.Bssid[5])); *pCurrState = APCLI_CTRL_PROBE; MlmeEnqueue(pAd, APCLI_SYNC_STATE_MACHINE, APCLI_MT2_MLME_PROBE_REQ, sizeof(APCLI_MLME_JOIN_REQ_STRUCT), &JoinReq, ifIndex); return; }
BOOLEAN CFG80211DRV_OpsSetChannel( VOID *pAdOrg, VOID *pData) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; CMD_RTPRIV_IOCTL_80211_CHAN *pChan; UINT8 ChanId; UINT8 IfType; UINT8 ChannelType; STRING ChStr[5] = { 0 }; #ifdef DOT11_N_SUPPORT UCHAR BW_Old; BOOLEAN FlgIsChanged; #endif /* DOT11_N_SUPPORT */ /* init */ pChan = (CMD_RTPRIV_IOCTL_80211_CHAN *)pData; ChanId = pChan->ChanId; IfType = pChan->IfType; ChannelType = pChan->ChanType; #ifdef DOT11_N_SUPPORT if (IfType != RT_CMD_80211_IFTYPE_MONITOR) { /* get channel BW */ FlgIsChanged = FALSE; BW_Old = pAd->CommonCfg.RegTransmitSetting.field.BW; /* set to new channel BW */ if (ChannelType == RT_CMD_80211_CHANTYPE_HT20) { pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; FlgIsChanged = TRUE; } else if ((ChannelType == RT_CMD_80211_CHANTYPE_HT40MINUS) || (ChannelType == RT_CMD_80211_CHANTYPE_HT40PLUS)) { /* not support NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS */ /* i.e. primary channel = 36, secondary channel must be 40 */ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; FlgIsChanged = TRUE; } /* End of if */ CFG80211DBG(RT_DEBUG_ERROR, ("80211> New BW = %d\n", pAd->CommonCfg.RegTransmitSetting.field.BW)); /* change HT/non-HT mode (do NOT change wireless mode here) */ if (((ChannelType == RT_CMD_80211_CHANTYPE_NOHT) && (pAd->CommonCfg.HT_Disable == 0)) || ((ChannelType != RT_CMD_80211_CHANTYPE_NOHT) && (pAd->CommonCfg.HT_Disable == 1))) { if (ChannelType == RT_CMD_80211_CHANTYPE_NOHT) pAd->CommonCfg.HT_Disable = 1; else pAd->CommonCfg.HT_Disable = 0; /* End of if */ FlgIsChanged = TRUE; CFG80211DBG(RT_DEBUG_ERROR, ("80211> HT Disable = %d\n", pAd->CommonCfg.HT_Disable)); } /* End of if */ } else { /* for monitor mode */ FlgIsChanged = TRUE; pAd->CommonCfg.HT_Disable = 0; pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; } /* End of if */ if (FlgIsChanged == TRUE) SetCommonHT(pAd); /* End of if */ #endif /* DOT11_N_SUPPORT */ /* switch to the channel */ sprintf(ChStr, "%d", ChanId); if (Set_Channel_Proc(pAd, ChStr) == FALSE) { CFG80211DBG(RT_DEBUG_ERROR, ("80211> Change channel fail!\n")); } /* End of if */ return TRUE; }
/* ========================================================================== Description: APCLI MLME JOIN req state machine procedure ========================================================================== */ static VOID ApCliCtrlJoinReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { APCLI_MLME_JOIN_REQ_STRUCT JoinReq; PAPCLI_STRUCT pApCliEntry; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState; #ifdef WSC_AP_SUPPORT PWSC_CTRL pWpsCtrl = &pAd->ApCfg.ApCliTab[ifIndex].WscControl; #endif /* WSC_AP_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Start Probe Req.\n", __FUNCTION__)); if (ifIndex >= MAX_APCLI_NUM) return; if (ApScanRunning(pAd) == TRUE) return; pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; NdisZeroMemory(&JoinReq, sizeof(APCLI_MLME_JOIN_REQ_STRUCT)); if (!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) { COPY_MAC_ADDR(JoinReq.Bssid, pApCliEntry->CfgApCliBssid); } #ifdef WSC_AP_SUPPORT if ((pWpsCtrl->WscConfMode != WSC_DISABLE) && (pWpsCtrl->bWscTrigger == TRUE)) { ULONG bss_idx = 0; NdisZeroMemory(JoinReq.Ssid, MAX_LEN_OF_SSID); JoinReq.SsidLen = pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscSsid.SsidLength; NdisMoveMemory(JoinReq.Ssid, pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscSsid.Ssid, JoinReq.SsidLen); if (pWpsCtrl->WscMode == 1) /* PIN */ { bss_idx = BssSsidTableSearchBySSID(&pAd->ScanTab, (PUCHAR)(JoinReq.Ssid), JoinReq.SsidLen); if (bss_idx == BSS_NOT_FOUND) { ApSiteSurvey(pAd, NULL, SCAN_WSC_ACTIVE, FALSE); return; } else { INT old_conf_mode = pWpsCtrl->WscConfMode; ADD_HTINFO RootApHtInfo, ApHtInfo; UCHAR channel = pAd->CommonCfg.Channel, RootApChannel = pAd->ScanTab.BssEntry[bss_idx].Channel; UCHAR RootApCentralChannel = pAd->ScanTab.BssEntry[bss_idx].CentralChannel; ApHtInfo = pAd->CommonCfg.AddHTInfo.AddHtInfo; RootApHtInfo = pAd->ScanTab.BssEntry[bss_idx].AddHtInfo.AddHtInfo; if ((RootApChannel != channel) || ((RootApCentralChannel != RootApChannel) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (ApHtInfo.ExtChanOffset != RootApHtInfo.ExtChanOffset))) { STRING ChStr[5] = {0}; if (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) { if (RootApHtInfo.ExtChanOffset == EXTCHA_ABOVE) Set_HtExtcha_Proc(pAd, "1"); else Set_HtExtcha_Proc(pAd, "0"); } snprintf(ChStr, sizeof(ChStr), "%d", pAd->ScanTab.BssEntry[bss_idx].Channel); Set_Channel_Proc(pAd, ChStr); /* ApStop will call WscStop, we need to reset WscConfMode, WscMode & bWscTrigger here. */ pWpsCtrl->WscState = WSC_STATE_START; pWpsCtrl->WscStatus = STATUS_WSC_START_ASSOC; pWpsCtrl->WscMode = 1; pWpsCtrl->WscConfMode = old_conf_mode; pWpsCtrl->bWscTrigger = TRUE; return; } } } } else #endif /* WSC_AP_SUPPORT */ if (pApCliEntry->CfgSsidLen != 0) { JoinReq.SsidLen = pApCliEntry->CfgSsidLen; NdisMoveMemory(&(JoinReq.Ssid), pApCliEntry->CfgSsid, JoinReq.SsidLen); } DBGPRINT(RT_DEBUG_TRACE, ("(%s) Probe Ssid=%s, Bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, JoinReq.Ssid, JoinReq.Bssid[0], JoinReq.Bssid[1], JoinReq.Bssid[2], JoinReq.Bssid[3], JoinReq.Bssid[4], JoinReq.Bssid[5])); *pCurrState = APCLI_CTRL_PROBE; MlmeEnqueue(pAd, APCLI_SYNC_STATE_MACHINE, APCLI_MT2_MLME_PROBE_REQ, sizeof(APCLI_MLME_JOIN_REQ_STRUCT), &JoinReq, ifIndex); return; }
BOOLEAN CFG80211DRV_OpsSetChannel( VOID *pAdOrg, VOID *pData) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; CMD_RTPRIV_IOCTL_80211_CHAN *pChan; UINT8 ChanId; UINT8 IfType; UINT8 ChannelType; STRING ChStr[5] = { 0 }; #ifdef DOT11_N_SUPPORT UCHAR BW_Old; BOOLEAN FlgIsChanged; #endif /* DOT11_N_SUPPORT */ /* init */ pChan = (CMD_RTPRIV_IOCTL_80211_CHAN *)pData; ChanId = pChan->ChanId; IfType = pChan->IfType; ChannelType = pChan->ChanType; #ifdef DOT11_N_SUPPORT if (IfType != RT_CMD_80211_IFTYPE_MONITOR) { /* get channel BW */ FlgIsChanged = FALSE; BW_Old = pAd->CommonCfg.RegTransmitSetting.field.BW; /* set to new channel BW */ if (ChannelType == RT_CMD_80211_CHANTYPE_HT20) { pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; FlgIsChanged = TRUE; } else if ((ChannelType == RT_CMD_80211_CHANTYPE_HT40MINUS) || (ChannelType == RT_CMD_80211_CHANTYPE_HT40PLUS)) { /* not support NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS */ /* i.e. primary channel = 36, secondary channel must be 40 */ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; FlgIsChanged = TRUE; } /* End of if */ CFG80211DBG(RT_DEBUG_ERROR, ("80211> New BW = %d\n", pAd->CommonCfg.RegTransmitSetting.field.BW)); /* change HT/non-HT mode (do NOT change wireless mode here) */ if (((ChannelType == RT_CMD_80211_CHANTYPE_NOHT) && (pAd->CommonCfg.HT_Disable == 0)) || ((ChannelType != RT_CMD_80211_CHANTYPE_NOHT) && (pAd->CommonCfg.HT_Disable == 1))) { if (ChannelType == RT_CMD_80211_CHANTYPE_NOHT) pAd->CommonCfg.HT_Disable = 1; else pAd->CommonCfg.HT_Disable = 0; /* End of if */ FlgIsChanged = TRUE; CFG80211DBG(RT_DEBUG_ERROR, ("80211> HT Disable = %d\n", pAd->CommonCfg.HT_Disable)); } /* End of if */ } else { /* for monitor mode */ FlgIsChanged = TRUE; pAd->CommonCfg.HT_Disable = 0; pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; } /* End of if */ if (FlgIsChanged == TRUE) SetCommonHT(pAd); /* End of if */ #endif /* DOT11_N_SUPPORT */ /* switch to the channel */ sprintf(ChStr, "%d", ChanId); if (Set_Channel_Proc(pAd, ChStr) == FALSE) { CFG80211DBG(RT_DEBUG_ERROR, ("80211> Change channel fail!\n")); } /* End of if */ #ifdef CONFIG_STA_SUPPORT #ifdef DOT11_N_SUPPORT if ((IfType == RT_CMD_80211_IFTYPE_STATION) && (FlgIsChanged == TRUE)) { /* 1. Station mode; 2. New BW settings is 20MHz but current BW is not 20MHz; 3. New BW settings is 40MHz but current BW is 20MHz; Re-connect to the AP due to BW 20/40 or HT/non-HT change. */ Set_SSID_Proc(pAd, (PSTRING)pAd->CommonCfg.Ssid); } /* End of if */ #endif /* DOT11_N_SUPPORT */ if (IfType == RT_CMD_80211_IFTYPE_ADHOC) { /* update IBSS beacon */ MlmeUpdateTxRates(pAd, FALSE, 0); MakeIbssBeacon(pAd); AsicEnableIbssSync(pAd); Set_SSID_Proc(pAd, (PSTRING)pAd->CommonCfg.Ssid); } /* End of if */ if (IfType == RT_CMD_80211_IFTYPE_MONITOR) { /* reset monitor mode in the new channel */ Set_NetworkType_Proc(pAd, "Monitor"); RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, pChan->MonFilterFlag); } /* End of if */ #endif /* CONFIG_STA_SUPPORT */ return TRUE; }