/* ========================================================================== Description: This routine is called at initialization. It returns a channel number that complies to regulation domain and less interference with current enviornment. Return: ch - channel number that NOTE: The retruned channel number is guaranteed to comply to current regulation domain that recorded in pAd->CommonCfg.CountryRegion Usage: 1.) iwpriv ra0 set AutoChannelSel=1 Ues the number of AP and inference status to choose 2.) iwpriv ra0 set AutoChannelSel=2 Ues the False CCA count and Rssi to choose ========================================================================== */ UCHAR APAutoSelectChannel( IN PRTMP_ADAPTER pAd, IN ChannelSel_Alg Alg) { UCHAR ch = 0, i; /* passive scan channel 1-14. collect statistics */ /* In the autochannel select case. AP didn't get channel yet. So have no way to determine which Band AP used by channel number. */ /* Init some structures before doing AutoChannelSelect() */ APAutoChannelInit(pAd); if (( Alg == ChannelAlgRandom ) && (pAd->pChannelInfo->IsABand == TRUE)) { /*for Dfs */ ch = SelectClearChannelRandom(pAd); } else { #ifdef MICROWAVE_OVEN_SUPPORT pAd->CommonCfg.MO_Cfg.bEnable = FALSE; AsicMeasureFalseCCA(pAd); #endif /*find RSSI in each channel */ for (i=0; i<pAd->ChannelListNum; i++) { AsicSwitchChannel(pAd, pAd->ChannelList[i].Channel, TRUE); AsicLockChannel(pAd, pAd->ChannelList[i].Channel);/*do nothing */ pAd->ApCfg.current_channel_index = i; pAd->ApCfg.AutoChannel_Channel = pAd->ChannelList[i].Channel; #ifdef AP_QLOAD_SUPPORT if (QLOAD_DOES_ALARM_OCCUR(pAd)) { /* QLOAD ALARM, ever alarm from QLOAD module */ OS_WAIT(400); /* wait for 400 ms at each channel. */ } else #endif /* AP_QLOAD_SUPPORT */ { OS_WAIT(200); /* wait for 200 ms at each channel. */ } UpdateChannelInfo(pAd, i,Alg); } ch = SelectBestChannel(pAd, Alg); } return ch; }
/* ========================================================================== Description: This routine is called at initialization. It returns a channel number that complies to regulation domain and less interference with current enviornment. Return: ch - channel number that NOTE: The retruned channel number is guaranteed to comply to current regulation domain that recorded in pAd->CommonCfg.CountryRegion Usage: 1.) iwpriv ra0 set AutoChannelSel=1 Ues the number of AP and inference status to choose 2.) iwpriv ra0 set AutoChannelSel=2 Ues the False CCA count and Rssi to choose ========================================================================== */ UCHAR APAutoSelectChannel( IN PRTMP_ADAPTER pAd, IN ChannelSel_Alg Alg) { UCHAR ch = 0, i; // passive scan channel 1-14. collect statistics // In the autochannel select case. AP didn't get channel yet. // So have no way to determine which Band AP used by channel number. // // Init some structures before doing AutoChannelSelect() // APAutoChannelInit(pAd); if (( Alg == ChannelAlgRandom ) && (pAd->pChannelInfo->IsABand == TRUE)) { //for Dfs ch = SelectClearChannelRandom(pAd); } else { //find RSSI in each channel // for (i=0; i<pAd->ChannelListNum; i++) { AsicSwitchChannel(pAd, pAd->ChannelList[i].Channel, TRUE); AsicLockChannel(pAd, pAd->ChannelList[i].Channel);//do nothing pAd->ApCfg.current_channel_index = i; pAd->ApCfg.AutoChannel_Channel = pAd->ChannelList[i].Channel; #ifdef AP_QLOAD_SUPPORT if (QLOAD_DOES_ALARM_OCCUR(pAd)) { /* QLOAD ALARM, ever alarm from QLOAD module */ OS_WAIT(400); // wait for 400 ms at each channel. } else #endif { OS_WAIT(200); // wait for 200 ms at each channel. } UpdateChannelInfo(pAd, i,Alg); } ch = SelectBestChannel(pAd, Alg); } return ch; }
/* ========================================================================== Description: This routine is called at initialization. It returns a channel number that complies to regulation domain and less interference with current enviornment. Return: ch - channel number that NOTE: The retruned channel number is guaranteed to comply to current regulation domain that recorded in pAd->CommonCfg.CountryRegion Usage: 1.) iwpriv ra0 set AutoChannelSel=1 Ues the number of AP and inference status to choose 2.) iwpriv ra0 set AutoChannelSel=2 Ues the False CCA count and Rssi to choose ========================================================================== */ UCHAR APAutoSelectChannel(RTMP_ADAPTER *pAd, ChannelSel_Alg Alg) { UCHAR ch = 0; #ifndef SUPPORT_ACS_BY_SCAN UCHAR i = 0; #endif /* passive scan channel 1-14. collect statistics */ DBGPRINT(RT_DEBUG_TRACE, ("Entering ACS (Alg=%d)...\n", Alg)); /* In the autochannel select case. AP didn't get channel yet. So have no way to determine which Band AP used by channel number. */ /* Init some structures before doing AutoChannelSelect() */ APAutoChannelInit(pAd); if (( Alg == ChannelAlgRandom ) && (pAd->pChannelInfo->IsABand == TRUE)) { /*for Dfs */ DBGPRINT(RT_DEBUG_TRACE, ("ACS: Select from random\n")); ch = SelectClearChannelRandom(pAd); } else { #ifndef SUPPORT_ACS_BY_SCAN /*find RSSI in each channel */ DBGPRINT(RT_DEBUG_TRACE, ("Start ACS scan (total channel = %d, stay_time = %dms)\n", pAd->ChannelListNum, AUTO_CHANNEL_SEL_TIMEOUT)); for (i=0; i<pAd->ChannelListNum; i++) { AsicSwitchChannel(pAd, pAd->ChannelList[i].Channel, TRUE); AsicLockChannel(pAd, pAd->ChannelList[i].Channel); /*do nothing */ pAd->ApCfg.current_channel_index = i; pAd->ApCfg.AutoChannel_Channel = pAd->ChannelList[i].Channel; OS_WAIT(AUTO_CHANNEL_SEL_TIMEOUT); /* wait for 200 ms at each channel. */ UpdateChannelInfo(pAd, i, Alg); } DBGPRINT(RT_DEBUG_TRACE, ("ACS scan complete)\n")); #ifdef SUPPORT_ACS_ALL_CHANNEL_RANK if ((ch = ACS_PerformAlgorithm(pAd, Alg)) <= 0) { /* return ch is the total number of channels in the rank list */ DBGPRINT(RT_DEBUG_ERROR, ("ACS: Error perform algorithm!\n")); } else DBGPRINT(RT_DEBUG_ERROR, ("ACS: Perform algorithm OK (ch_count=%d)!\n", ch)); #else ch = SelectBestChannel(pAd, Alg); #endif /* SUPPORT_ACS_ALL_CHANNEL_RANK */ #endif /* SUPPORT_ACS_BY_SCAN */ } return ch; }
static INT scan_ch_restore(RTMP_ADAPTER *pAd, UCHAR OpMode) { #ifdef CONFIG_STA_SUPPORT USHORT Status; #endif /* CONFIG_STA_SUPPORT */ INT bw, ch; if (pAd->CommonCfg.BBPCurrentBW != pAd->hw_cfg.bbp_bw) { rtmp_bbp_set_bw(pAd, pAd->hw_cfg.bbp_bw); AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); ch = pAd->CommonCfg.CentralChannel; } else { AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); ch = pAd->CommonCfg.Channel; } switch(pAd->CommonCfg.BBPCurrentBW) { case BW_80: bw = 80; break; case BW_40: bw = 40; break; case BW_10: bw = 10; break; case BW_20: default: bw =20; break; } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to %dMHz channel %d, Total BSS[%02d]\n", bw, ch, pAd->ScanTab.BssNr)); #ifdef CONFIG_STA_SUPPORT if (OpMode == OPMODE_STA) { /* If all peer Ad-hoc clients leave, driver would do LinkDown and LinkUp. In LinkUp, CommonCfg.Ssid would copy SSID from MlmeAux. To prevent SSID is zero or wrong in Beacon, need to recover MlmeAux.SSID here. */ if (ADHOC_ON(pAd)) { NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen; NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); } /* To prevent data lost. Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done */ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd))) { RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE), pAd->CommonCfg.bAPSDForcePowerSave ? PWR_SAVE : pAd->StaCfg.Psm); DBGPRINT(RT_DEBUG_TRACE, ("%s -- Send null frame\n", __FUNCTION__)); } #ifdef RT_CFG80211_SUPPORT if (pAd->ApCfg.ApCliTab[MAIN_MBSSID].Valid && RTMP_CFG80211_VIF_P2P_CLI_ON(pAd)) { DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_NULL: PWR_ACTIVE SCAN_END\n")); RT_CFG80211_P2P_CLI_SEND_NULL_FRAME(pAd, PWR_ACTIVE); } #endif /* RT_CFG80211_SUPPORT */ /* keep the latest scan channel, could be 0 for scan complete, or other channel*/ pAd->StaCfg.LastScanChannel = pAd->MlmeAux.Channel; pAd->StaCfg.ScanChannelCnt = 0; /* Suspend scanning and Resume TxData for Fast Scanning*/ if ((pAd->MlmeAux.Channel != 0) && (pAd->StaCfg.bImprovedScan)) /* it is scan pending*/ { pAd->Mlme.SyncMachine.CurrState = SCAN_PENDING; Status = MLME_SUCCESS; DBGPRINT(RT_DEBUG_WARN, ("bFastRoamingScan ~~~ Get back to send data ~~~\n")); RTMPResumeMsduTransmission(pAd); } else { pAd->StaCfg.BssNr = pAd->ScanTab.BssNr; pAd->StaCfg.bImprovedScan = FALSE; pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0); RTMP_MLME_HANDLER(pAd); } } #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) { #ifdef P2P_APCLI_SUPPORT /* P2P CLIENT in WSC Scan or Re-Connect scanning. */ if (P2P_CLI_ON(pAd) && (ApScanRunning(pAd) == TRUE)) { /*MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_JOIN_REQ_TIMEOUT, 0, NULL, 0);*/ DBGPRINT(RT_DEBUG_INFO, ("%s:: Scan Done! reset APCLI CTRL State Machine!\n", __FUNCTION__)); pAd->ApCfg.ApCliTab[0].CtrlCurrState = APCLI_CTRL_DISCONNECTED; } #endif /* P2P_APCLI_SUPPORT */ pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE; RTMPResumeMsduTransmission(pAd); /* iwpriv set auto channel selection*/ /* scanned all channels*/ if (pAd->ApCfg.bAutoChannelAtBootup==TRUE) { pAd->CommonCfg.Channel = SelectBestChannel(pAd, pAd->ApCfg.AutoChannelAlg); pAd->ApCfg.bAutoChannelAtBootup = FALSE; #ifdef DOT11_N_SUPPORT N_ChannelCheck(pAd); #endif /* DOT11_N_SUPPORT */ APStop(pAd); APStartUp(pAd); } if (!((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == TRUE))) AsicEnableBssSync(pAd); } #endif /* CONFIG_AP_SUPPORT */ return TRUE; }
static INT scan_ch_restore(RTMP_ADAPTER *pAd, UCHAR OpMode) { INT bw, ch; if (pAd->CommonCfg.BBPCurrentBW != pAd->hw_cfg.bbp_bw) bbp_set_bw(pAd, pAd->hw_cfg.bbp_bw); #ifdef DOT11_VHT_AC if (pAd->hw_cfg.bbp_bw == BW_80) ch = pAd->CommonCfg.vht_cent_ch; else #endif /* DOT11_VHT_AC */ if (pAd->hw_cfg.bbp_bw == BW_40) ch = pAd->CommonCfg.CentralChannel; else ch = pAd->CommonCfg.Channel; ASSERT((ch != 0)); AsicSwitchChannel(pAd, ch, FALSE); AsicLockChannel(pAd, ch); switch(pAd->CommonCfg.BBPCurrentBW) { case BW_80: bw = 80; break; case BW_40: bw = 40; break; case BW_10: bw = 10; break; case BW_20: default: bw =20; break; } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to %dMHz channel %d, Total BSS[%02d]\n", bw, ch, pAd->ScanTab.BssNr)); #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) { #ifdef APCLI_SUPPORT #ifdef APCLI_AUTO_CONNECT_SUPPORT if (pAd->ApCfg.ApCliAutoConnectRunning == TRUE) { if (!ApCliAutoConnectExec(pAd)) { DBGPRINT(RT_DEBUG_ERROR, ("Error in %s\n", __FUNCTION__)); } } #endif /* APCLI_AUTO_CONNECT_SUPPORT */ #endif /* APCLI_SUPPORT */ pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE; RTMPResumeMsduTransmission(pAd); /* iwpriv set auto channel selection*/ /* scanned all channels*/ if (pAd->ApCfg.bAutoChannelAtBootup==TRUE) { pAd->CommonCfg.Channel = SelectBestChannel(pAd, pAd->ApCfg.AutoChannelAlg); pAd->ApCfg.bAutoChannelAtBootup = FALSE; #ifdef DOT11_N_SUPPORT N_ChannelCheck(pAd); #endif /* DOT11_N_SUPPORT */ APStop(pAd); APStartUp(pAd); } if (!((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == TRUE) && (pAd->Dot11_H.RDMode != RD_NORMAL_MODE))) AsicEnableBssSync(pAd, pAd->CommonCfg.BeaconPeriod); } #endif /* CONFIG_AP_SUPPORT */ return TRUE; }
/* ========================================================================== Description: Scan next channel ========================================================================== */ VOID ScanNextChannel( IN PRTMP_ADAPTER pAd) { HEADER_802_11 Hdr80211; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; UCHAR SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0; UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME; BOOLEAN ScanPending = FALSE; #ifdef RALINK_ATE // Nothing to do in ATE mode. if (ATE_ON(pAd)) return; #endif // RALINK_ATE // if ((pAd->MlmeAux.Channel == 0) || ScanPending) { if ((pAd->CommonCfg.BBPCurrentBW == BW_40) ) { AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); BBPValue &= (~0x18); BBPValue |= 0x10; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr)); } else { AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); } #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE; RTMPResumeMsduTransmission(pAd); // iwpriv set auto channel selection // scanned all channels if (pAd->ApCfg.bAutoChannelAtBootup==TRUE) { pAd->CommonCfg.Channel = SelectBestChannel(pAd, pAd->ApCfg.AutoChannelAlg); pAd->ApCfg.bAutoChannelAtBootup = FALSE; #ifdef DOT11_N_SUPPORT N_ChannelCheck(pAd); #endif // DOT11_N_SUPPORT // APStop(pAd); APStartUp(pAd); } if (!((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == TRUE))) { AsicEnableBssSync(pAd); } } #endif // CONFIG_AP_SUPPORT // } else {
INT scan_ch_restore(RTMP_ADAPTER *pAd, UCHAR OpMode) { INT bw, ch; if (pAd->CommonCfg.BBPCurrentBW != pAd->hw_cfg.bbp_bw) rtmp_bbp_set_bw(pAd, pAd->hw_cfg.bbp_bw); if (pAd->hw_cfg.bbp_bw == BW_80) ch = pAd->CommonCfg.vht_cent_ch; else if (pAd->hw_cfg.bbp_bw == BW_40) ch = pAd->CommonCfg.CentralChannel; else ch = pAd->CommonCfg.Channel; ASSERT((ch != 0)); AsicSwitchChannel(pAd, ch, FALSE); AsicLockChannel(pAd, ch); switch(pAd->CommonCfg.BBPCurrentBW) { case BW_80: bw = 80; break; case BW_40: bw = 40; break; case BW_10: bw = 10; break; case BW_20: default: bw =20; break; } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to %dMHz channel %d, Total BSS[%02d]\n", bw, ch, pAd->ScanTab.BssNr)); #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) { #ifdef APCLI_SUPPORT #ifdef APCLI_AUTO_CONNECT_SUPPORT if (pAd->ApCfg.ApCliAutoConnectRunning == TRUE) { if (!ApCliAutoConnectExec(pAd)) { DBGPRINT(RT_DEBUG_ERROR, ("Error in %s\n", __FUNCTION__)); } } #endif /* APCLI_AUTO_CONNECT_SUPPORT */ #endif /* APCLI_SUPPORT */ pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE; RTMPResumeMsduTransmission(pAd); /* keep the latest scan channel, could be 0 for scan complete, or other channel */ pAd->ApCfg.LastScanChannel = pAd->MlmeAux.Channel; pAd->ApCfg.ScanChannelCnt=0; /* Suspend scanning and Resume TxData for Fast Scanning */ if ((pAd->MlmeAux.Channel != 0) && (pAd->ApCfg.bImprovedScan)) { pAd->Mlme.ApSyncMachine.CurrState = AP_SCAN_PENDING; DBGPRINT(RT_DEBUG_TRACE, ("bImprovedScan ~~ Get back to send data\n")); } else pAd->ApCfg.bImprovedScan = FALSE; #ifdef CON_WPS if (pAd->conWscStatus != CON_WPS_STATUS_DISABLED) { MlmeEnqueue(pAd, AP_SYNC_STATE_MACHINE, APMT2_MLME_SCAN_COMPLETE, 0, NULL,0 ); RTMP_MLME_HANDLER(pAd); } #endif /* CON_WPS*/ /* iwpriv set auto channel selection*/ /* scanned all channels*/ if (pAd->ApCfg.bAutoChannelAtBootup==TRUE) { pAd->CommonCfg.Channel = SelectBestChannel(pAd, pAd->ApCfg.AutoChannelAlg); pAd->ApCfg.bAutoChannelAtBootup = FALSE; #ifdef DOT11_N_SUPPORT N_ChannelCheck(pAd); #endif /* DOT11_N_SUPPORT */ APStop(pAd); APStartUp(pAd); } if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == TRUE) && RadarChannelCheck(pAd, pAd->CommonCfg.Channel) && pAd->Dot11_H.RDMode != RD_SWITCHING_MODE) { if (pAd->Dot11_H.InServiceMonitorCount) { pAd->Dot11_H.RDMode = RD_NORMAL_MODE; AsicEnableBssSync(pAd); } else { pAd->Dot11_H.RDMode = RD_SILENCE_MODE; } } else { AsicEnableBssSync(pAd); } } #endif /* CONFIG_AP_SUPPORT */ return TRUE; }
static INT scan_ch_restore(RTMP_ADAPTER *pAd, UCHAR OpMode) { INT bw, ch; if (pAd->CommonCfg.BBPCurrentBW != pAd->hw_cfg.bbp_bw) { rtmp_bbp_set_bw(pAd, pAd->hw_cfg.bbp_bw); AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); ch = pAd->CommonCfg.CentralChannel; } else { AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); ch = pAd->CommonCfg.Channel; } switch(pAd->CommonCfg.BBPCurrentBW) { case BW_80: bw = 80; break; case BW_40: bw = 40; break; case BW_10: bw = 10; break; case BW_20: default: bw =20; break; } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to %dMHz channel %d, Total BSS[%02d]\n", bw, ch, pAd->ScanTab.BssNr)); #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) { pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE; RTMPResumeMsduTransmission(pAd); /* iwpriv set auto channel selection*/ /* scanned all channels*/ if (pAd->ApCfg.bAutoChannelAtBootup==TRUE) { pAd->CommonCfg.Channel = SelectBestChannel(pAd, pAd->ApCfg.AutoChannelAlg); pAd->ApCfg.bAutoChannelAtBootup = FALSE; #ifdef DOT11_N_SUPPORT N_ChannelCheck(pAd); #endif /* DOT11_N_SUPPORT */ APStop(pAd); APStartUp(pAd); } if (!((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == TRUE))) AsicEnableBssSync(pAd); } #endif /* CONFIG_AP_SUPPORT */ return TRUE; }