BOOLEAN wmode_band_equal(UCHAR smode, UCHAR tmode) { BOOLEAN eq = FALSE; UCHAR *str1, *str2; if ((WMODE_CAP_5G(smode) == WMODE_CAP_5G(tmode)) && (WMODE_CAP_2G(smode) == WMODE_CAP_2G(tmode))) eq = TRUE; str1 = wmode_2_str(smode); str2 = wmode_2_str(tmode); if (str1 && str2) { DBGPRINT(RT_DEBUG_TRACE, ("Old WirelessMode:%s(0x%x), " "New WirelessMode:%s(0x%x)!\n", str1, smode, str2, tmode)); } if (str1) os_free_mem(NULL, str1); if (str2) os_free_mem(NULL, str2); return eq; }
/* ========================================================================== Description: Set Wireless Mode for MBSS Return: TRUE if all parameters are OK, FALSE otherwise ========================================================================== */ INT RT_CfgSetMbssWirelessMode(RTMP_ADAPTER *pAd, PSTRING arg) { INT cfg_mode; UCHAR wmode; RTMP_CHIP_CAP *pChipCap = &pAd->chipCap; cfg_mode = simple_strtol(arg, 0, 10); wmode = cfgmode_2_wmode((UCHAR)cfg_mode); if ((wmode == WMODE_INVALID) || (!wmode_valid(pAd, wmode))) { DBGPRINT(RT_DEBUG_ERROR, ("%s(): Invalid wireless mode(%d, wmode=0x%x), ChipCap(%s)\n", __FUNCTION__, cfg_mode, wmode, BAND_STR[pAd->chipCap.phy_caps & 0x3])); return FALSE; } if (WMODE_CAP_5G(wmode) && WMODE_CAP_2G(wmode)) { DBGPRINT(RT_DEBUG_ERROR, ("AP cannot support 2.4G/5G band mxied mode!\n")); return FALSE; } #if defined(MT76x2) && defined(DOT11_VHT_AC) if (pChipCap->ac_off_mode && WMODE_CAP_AC(wmode)) { DBGPRINT(RT_DEBUG_ERROR, ("it doesn't support VHT AC!\n")); wmode &= ~(WMODE_AC); } #endif /* MT76x2 */ if (pAd->ApCfg.BssidNum > 1) { /* pAd->CommonCfg.PhyMode = maximum capability of all MBSS */ if (wmode_band_equal(pAd->CommonCfg.PhyMode, wmode) == TRUE) { wmode = RT_CfgMbssWirelessModeMaxGet(pAd); DBGPRINT(RT_DEBUG_TRACE, ("mbss> Maximum phy mode = %d!\n", wmode)); } else { UINT32 IdBss; /* replace all phy mode with the one with different band */ DBGPRINT(RT_DEBUG_TRACE, ("mbss> Different band with the current one!\n")); DBGPRINT(RT_DEBUG_TRACE, ("mbss> Reset band of all BSS to the new one!\n")); for(IdBss=0; IdBss<pAd->ApCfg.BssidNum; IdBss++) pAd->ApCfg.MBSSID[IdBss].wdev.PhyMode = wmode; } } pAd->CommonCfg.PhyMode = wmode; pAd->CommonCfg.cfg_wmode = wmode; return TRUE; }
/* ========================================================================== Description: This routine sets the current PhyMode for calculating the dirtyness. Return: none NOTE: ========================================================================== */ void CheckPhyModeIsABand( IN PRTMP_ADAPTER pAd) { pAd->pChannelInfo->IsABand = (WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) ? TRUE : FALSE; return; }
static BOOLEAN wmode_valid(RTMP_ADAPTER *pAd, enum WIFI_MODE wmode) { if ((WMODE_CAP_5G(wmode) && (!PHY_CAP_5G(pAd->chipCap.phy_caps))) || (WMODE_CAP_2G(wmode) && (!PHY_CAP_2G(pAd->chipCap.phy_caps))) || (WMODE_CAP_N(wmode) && RTMP_TEST_MORE_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DOT_11N)) ) return FALSE; else return TRUE; }
static BOOLEAN wmode_valid_and_correct(RTMP_ADAPTER *pAd, UCHAR* wmode) { BOOLEAN ret = TRUE; if (WMODE_CAP_5G(*wmode) && (!PHY_CAP_5G(pAd->chipCap.phy_caps))) *wmode = *wmode & ~(WMODE_A | WMODE_AN | WMODE_AC); else if (WMODE_CAP_2G(*wmode) && (!PHY_CAP_2G(pAd->chipCap.phy_caps))) *wmode = *wmode & ~(WMODE_B | WMODE_G | WMODE_GN); else if (WMODE_CAP_N(*wmode) && RTMP_TEST_MORE_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DOT_11N)) *wmode = *wmode & ~(WMODE_GN | WMODE_AN); if (*wmode == 0 ) ret = FALSE; return ret; }
INT BndStrg_SetInfFlags(PRTMP_ADAPTER pAd, PBND_STRG_CLI_TABLE table, BOOLEAN bInfReady) { INT ret_val = BND_STRG_SUCCESS; BNDSTRG_MSG msg; if (WMODE_CAP_5G(pAd->CommonCfg.PhyMode) && (table->b5GInfReady ^ bInfReady)) { table->b5GInfReady = bInfReady; msg.Action = INF_STATUS_RSP_5G; msg.b5GInfReady = table->b5GInfReady; RtmpOSWrielessEventSend( pAd->net_dev, RT_WLAN_EVENT_CUSTOM, OID_BNDSTRG_MSG, NULL, (UCHAR *)&msg, sizeof(msg)); BND_STRG_DBGPRINT(RT_DEBUG_OFF, (BLUE("%s(): BSS (%02x:%02x:%02x:%02x:%02x:%02x)") BLUE(" set 5G Inf %s.\n") , __FUNCTION__, PRINT_MAC(pAd->ApCfg.MBSSID[0].wdev.bssid), bInfReady ? "ready" : "not ready")); } else if (table->b2GInfReady ^ bInfReady) { table->b2GInfReady = bInfReady; msg.Action = INF_STATUS_RSP_2G; msg.b2GInfReady = table->b2GInfReady; RtmpOSWrielessEventSend( pAd->net_dev, RT_WLAN_EVENT_CUSTOM, OID_BNDSTRG_MSG, NULL, (UCHAR *)&msg, sizeof(msg)); BND_STRG_DBGPRINT(RT_DEBUG_OFF, (BLUE("%s(): BSS (%02x:%02x:%02x:%02x:%02x:%02x)") BLUE(" set 2G Inf %s.\n") , __FUNCTION__, PRINT_MAC(pAd->ApCfg.MBSSID[0].wdev.bssid), bInfReady ? "ready" : "not ready")); } return ret_val; }
INT BndStrg_TableInit(PRTMP_ADAPTER pAd, PBND_STRG_CLI_TABLE table) { INT ret_val = BND_STRG_SUCCESS; if (table->bInitialized == TRUE) return BND_STRG_SUCCESS; NdisZeroMemory(table, sizeof(BND_STRG_CLI_TABLE)); OS_NdisAllocateSpinLock(&table->Lock); if (WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) table->Band = BAND_5G; else table->Band = BAND_24G; BndStrg_SetInfFlags(pAd, table, TRUE); table->Ops = &D_BndStrgOps; table->RssiDiff = BND_STRG_RSSI_DIFF; table->RssiLow = BND_STRG_RSSI_LOW; table->AgeTime = BND_STRG_AGE_TIME; table->HoldTime = BND_STRG_HOLD_TIME; table->CheckTime_5G = BND_STRG_CHECK_TIME_5G; table->AutoOnOffThrd = BND_STRG_AUTO_ONOFF_THRD; table->AlgCtrl.ConditionCheck = fBND_STRG_CND_5G_RSSI; table->AlgCtrl.FrameCheck = fBND_STRG_FRM_CHK_PRB_REQ | \ fBND_STRG_FRM_CHK_ATH_REQ; table->priv = (VOID *) pAd; table->bInitialized = TRUE; if (ret_val != BND_STRG_SUCCESS) { BND_STRG_DBGPRINT(RT_DEBUG_ERROR, ("Error in %s(), error code = %d!\n", __FUNCTION__, ret_val)); } return BND_STRG_SUCCESS; }
/* ========================================================================== Description: Scan next channel ========================================================================== */ VOID ScanNextChannel( IN PRTMP_ADAPTER pAd, IN UCHAR OpMode) { UCHAR ScanType = pAd->MlmeAux.ScanType; UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME; BOOLEAN ScanPending = FALSE; RALINK_TIMER_STRUCT *sc_timer; UINT stay_time = 0; #ifdef RALINK_ATE /* Nothing to do in ATE mode. */ if (ATE_ON(pAd)) return; #endif /* RALINK_ATE */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (MONITOR_ON(pAd)) return; } ScanPending = ((pAd->StaCfg.bImprovedScan) && (pAd->StaCfg.ScanChannelCnt>=7)); #endif /* CONFIG_STA_SUPPORT */ #ifdef RT_CFG80211_SUPPORT #ifdef CONFIG_STA_SUPPORT if ( (pAd->pCfg80211ChanList != NULL) && (pAd->MlmeAux.Channel != 0)) { UINT32 ChanId; for ( ChanId = 0 ; ChanId <pAd->Cfg80211ChanListLan ; ChanId++ ) { if ( pAd->pCfg80211ChanList[ChanId] >= pAd->MlmeAux.Channel ) { pAd->MlmeAux.Channel = pAd->pCfg80211ChanList[ChanId]; break; } } } #endif /* CONFIG_STA_SUPPORT */ #endif /* RT_CFG80211_SUPPORT */ if ((pAd->MlmeAux.Channel == 0) || ScanPending) { scan_ch_restore(pAd, OpMode); } #ifdef RTMP_MAC_USB #ifdef CONFIG_STA_SUPPORT else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (OpMode == OPMODE_STA)) { pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE); } #endif /* CONFIG_STA_SUPPORT */ #endif /* RTMP_MAC_USB */ else { #ifdef CONFIG_STA_SUPPORT if (OpMode == OPMODE_STA) { /* BBP and RF are not accessible in PS mode, we has to wake them up first*/ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) AsicForceWakeup(pAd, TRUE); /* leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON*/ if (pAd->StaCfg.Psm == PWR_SAVE) RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE); } #endif /* CONFIG_STA_SUPPORT */ AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE); AsicLockChannel(pAd, pAd->MlmeAux.Channel); #ifdef CONFIG_STA_SUPPORT if (OpMode == OPMODE_STA) { BOOLEAN bScanPassive = FALSE; if (pAd->MlmeAux.Channel > 14) { if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel)) bScanPassive = TRUE; } #ifdef CARRIER_DETECTION_SUPPORT if (pAd->CommonCfg.CarrierDetect.Enable == TRUE) bScanPassive = TRUE; #endif /* CARRIER_DETECTION_SUPPORT */ if (bScanPassive) { ScanType = SCAN_PASSIVE; ScanTimeIn5gChannel = MIN_CHANNEL_TIME; } } #endif /* CONFIG_STA_SUPPORT */ /* Check if channel if passive scan under current regulatory domain */ if (CHAN_PropertyCheck(pAd, pAd->MlmeAux.Channel, CHANNEL_PASSIVE_SCAN) == TRUE) ScanType = SCAN_PASSIVE; if (OpMode == OPMODE_AP) sc_timer = &pAd->MlmeAux.APScanTimer; else sc_timer = &pAd->MlmeAux.ScanTimer; /* We need to shorten active scan time in order for WZC connect issue */ /* Chnage the channel scan time for CISCO stuff based on its IAPP announcement */ if (ScanType == FAST_SCAN_ACTIVE) stay_time = FAST_ACTIVE_SCAN_TIME; else /* must be SCAN_PASSIVE or SCAN_ACTIVE*/ { #ifdef CONFIG_STA_SUPPORT pAd->StaCfg.ScanChannelCnt++; #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if ((OpMode == OPMODE_AP) && (pAd->ApCfg.bAutoChannelAtBootup)) stay_time = AUTO_CHANNEL_SEL_TIMEOUT; else #endif /* CONFIG_AP_SUPPORT */ if (WMODE_CAP_2G(pAd->CommonCfg.PhyMode) && WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) { if (pAd->MlmeAux.Channel > 14) stay_time = ScanTimeIn5gChannel; else stay_time = MIN_CHANNEL_TIME; } else stay_time = MAX_CHANNEL_TIME; } RTMPSetTimer(sc_timer, stay_time); if (SCAN_MODE_ACT(ScanType)) { if (scan_active(pAd, OpMode, ScanType) == FALSE) return; } /* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse*/ #ifdef CONFIG_STA_SUPPORT if (OpMode == OPMODE_STA) pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN; #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) pAd->Mlme.ApSyncMachine.CurrState = AP_SCAN_LISTEN; #endif /* CONFIG_AP_SUPPORT */ } }
/* ========================================================================== Description: Scan next channel ========================================================================== */ VOID ScanNextChannel(RTMP_ADAPTER *pAd, UCHAR OpMode) { UCHAR ScanType = SCAN_TYPE_MAX; UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME; BOOLEAN ScanPending = FALSE; RALINK_TIMER_STRUCT *sc_timer = NULL; UINT stay_time = 0; #ifdef CONFIG_ATE /* Nothing to do in ATE mode. */ if (ATE_ON(pAd)) return; #endif /* CONFIG_ATE */ #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) ScanType = pAd->ScanCtrl.ScanType; #endif /* CONFIG_AP_SUPPORT */ if (ScanType == SCAN_TYPE_MAX) { DBGPRINT(RT_DEBUG_ERROR, ("%s():Incorrect ScanType!\n", __FUNCTION__)); return; } #ifdef RT_CFG80211_SUPPORT /* Since the Channel List is from Upper layer */ if (CFG80211DRV_OpsScanRunning(pAd)) pAd->ScanCtrl.Channel = CFG80211DRV_OpsScanGetNextChannel(pAd); #endif /* RT_CFG80211_SUPPORT */ if ((pAd->ScanCtrl.Channel == 0) || ScanPending) { scan_ch_restore(pAd, OpMode); } else { AsicSwitchChannel(pAd, pAd->ScanCtrl.Channel, TRUE); AsicLockChannel(pAd, pAd->ScanCtrl.Channel); /* Check if channel if passive scan under current regulatory domain */ if (CHAN_PropertyCheck(pAd, pAd->ScanCtrl.Channel, CHANNEL_PASSIVE_SCAN) == TRUE) ScanType = SCAN_PASSIVE; #if defined(DPA_T) || defined(WIFI_REGION32_HIDDEN_SSID_SUPPORT) /* Ch 12~14 is passive scan, No matter DFS and 80211H setting is y or n */ if ((pAd->ScanCtrl.Channel >= 12) && (pAd->ScanCtrl.Channel <= 14)) ScanType = SCAN_PASSIVE; #endif /* DPA_T */ #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) sc_timer = &pAd->ScanCtrl.APScanTimer; #endif /* CONFIG_AP_SUPPORT */ if (!sc_timer) { DBGPRINT(RT_DEBUG_ERROR, ("%s():ScanTimer not assigned!\n", __FUNCTION__)); return; } /* We need to shorten active scan time in order for WZC connect issue */ /* Chnage the channel scan time for CISCO stuff based on its IAPP announcement */ if (ScanType == FAST_SCAN_ACTIVE) stay_time = FAST_ACTIVE_SCAN_TIME; else /* must be SCAN_PASSIVE or SCAN_ACTIVE*/ { #ifdef CONFIG_AP_SUPPORT if ((OpMode == OPMODE_AP) && (pAd->ApCfg.bAutoChannelAtBootup)) stay_time = AUTO_CHANNEL_SEL_TIMEOUT; else #endif /* CONFIG_AP_SUPPORT */ if (WMODE_CAP_2G(pAd->CommonCfg.PhyMode) && WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) { if (pAd->ScanCtrl.Channel > 14) stay_time = ScanTimeIn5gChannel; else stay_time = MIN_CHANNEL_TIME; } else stay_time = MAX_CHANNEL_TIME; } #ifdef RT_CFG80211_SUPPORT //CFG_TODO: for testing. /* Since the Channel List is from Upper layer */ if (CFG80211DRV_OpsScanRunning(pAd) && (pAd->cfg80211_ctrl.Cfg80211ChanListLen == 1)) stay_time = 500; #endif /* RT_CFG80211_SUPPORT */ RTMPSetTimer(sc_timer, stay_time); if (SCAN_MODE_ACT(ScanType)) { if (scan_active(pAd, OpMode, ScanType) == FALSE) return; } /* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse*/ #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) pAd->Mlme.ApSyncMachine.CurrState = AP_SCAN_LISTEN; #endif /* CONFIG_AP_SUPPORT */ } }
/* ========================================================================== Description: Scan next channel ========================================================================== */ VOID ScanNextChannel( IN PRTMP_ADAPTER pAd, IN UCHAR OpMode) { UCHAR ScanType = pAd->MlmeAux.ScanType; UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME; BOOLEAN ScanPending = FALSE; RALINK_TIMER_STRUCT *sc_timer = NULL; UINT stay_time = 0; #ifdef RALINK_ATE /* Nothing to do in ATE mode. */ if (ATE_ON(pAd)) return; #endif /* RALINK_ATE */ #ifdef CONFIG_AP_SUPPORT ScanPending = ((pAd->ApCfg.bImprovedScan) && (pAd->ApCfg.ScanChannelCnt>=3));//7 #endif if ((pAd->MlmeAux.Channel == 0) || ScanPending) { scan_ch_restore(pAd, OpMode); } else { AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE); AsicLockChannel(pAd, pAd->MlmeAux.Channel); { BOOLEAN bScanPassive = FALSE; if (pAd->MlmeAux.Channel > 14) { if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel)) bScanPassive = TRUE; } #ifdef CARRIER_DETECTION_SUPPORT if (pAd->CommonCfg.CarrierDetect.Enable == TRUE) bScanPassive = TRUE; #endif /* CARRIER_DETECTION_SUPPORT */ if (bScanPassive) { ScanType = SCAN_PASSIVE; ScanTimeIn5gChannel = MIN_CHANNEL_TIME; } } /* Check if channel if passive scan under current regulatory domain */ if (CHAN_PropertyCheck(pAd, pAd->MlmeAux.Channel, CHANNEL_PASSIVE_SCAN) == TRUE) ScanType = SCAN_PASSIVE; if (OpMode == OPMODE_AP) sc_timer = &pAd->MlmeAux.APScanTimer; else sc_timer = &pAd->MlmeAux.ScanTimer; /* We need to shorten active scan time in order for WZC connect issue */ /* Chnage the channel scan time for CISCO stuff based on its IAPP announcement */ #ifdef CONFIG_AP_SUPPORT if (ScanType == FAST_SCAN_ACTIVE) { RTMPSetTimer(&pAd->MlmeAux.APScanTimer, MIN_CHANNEL_TIME);//Carter test MIN_CHANNEL_TIME instead of Fast_Scan_Time pAd->ApCfg.ScanChannelCnt++; } else /* must be SCAN_PASSIVE or SCAN_ACTIVE*/ #endif { #ifdef CONFIG_AP_SUPPORT pAd->ApCfg.ScanChannelCnt++; if ((OpMode == OPMODE_AP) && (pAd->ApCfg.bAutoChannelAtBootup)) stay_time = AUTO_CHANNEL_SEL_TIMEOUT; else #endif /* CONFIG_AP_SUPPORT */ if (WMODE_CAP_2G(pAd->CommonCfg.PhyMode) && WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) { if (pAd->MlmeAux.Channel > 14) stay_time = ScanTimeIn5gChannel; else stay_time = MIN_CHANNEL_TIME; } else stay_time = MAX_CHANNEL_TIME; } RTMPSetTimer(sc_timer, stay_time); if (SCAN_MODE_ACT(ScanType)) { if (scan_active(pAd, OpMode, ScanType) == FALSE) return; } /* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse*/ #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) pAd->Mlme.ApSyncMachine.CurrState = AP_SCAN_LISTEN; #endif /* CONFIG_AP_SUPPORT */ } }
/* ========================================================================== Description: Scan next channel ========================================================================== */ VOID ScanNextChannel( IN PRTMP_ADAPTER pAd, IN UCHAR OpMode) { UCHAR ScanType = pAd->MlmeAux.ScanType; UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME; BOOLEAN ScanPending = FALSE; RALINK_TIMER_STRUCT *sc_timer; UINT stay_time = 0; #ifdef RALINK_ATE /* Nothing to do in ATE mode. */ if (ATE_ON(pAd)) return; #endif /* RALINK_ATE */ if ((pAd->MlmeAux.Channel == 0) || ScanPending) { scan_ch_restore(pAd, OpMode); } #ifdef RTMP_MAC_USB #endif /* RTMP_MAC_USB */ else { AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE); AsicLockChannel(pAd, pAd->MlmeAux.Channel); /* Check if channel if passive scan under current regulatory domain */ if (CHAN_PropertyCheck(pAd, pAd->MlmeAux.Channel, CHANNEL_PASSIVE_SCAN) == TRUE) ScanType = SCAN_PASSIVE; if (OpMode == OPMODE_AP) sc_timer = &pAd->MlmeAux.APScanTimer; else sc_timer = &pAd->MlmeAux.ScanTimer; /* We need to shorten active scan time in order for WZC connect issue */ /* Chnage the channel scan time for CISCO stuff based on its IAPP announcement */ if (ScanType == FAST_SCAN_ACTIVE) stay_time = FAST_ACTIVE_SCAN_TIME; else /* must be SCAN_PASSIVE or SCAN_ACTIVE*/ { #ifdef CONFIG_AP_SUPPORT if ((OpMode == OPMODE_AP) && (pAd->ApCfg.bAutoChannelAtBootup)) stay_time = AUTO_CHANNEL_SEL_TIMEOUT; else #endif /* CONFIG_AP_SUPPORT */ if (WMODE_CAP_2G(pAd->CommonCfg.PhyMode) && WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) { if (pAd->MlmeAux.Channel > 14) stay_time = ScanTimeIn5gChannel; else stay_time = MIN_CHANNEL_TIME; } #ifdef WIFI_P2P_CONCURRENT_FAST_SCAN /* If this is not PASSIVE scan && Fast scan is enabled, we shorten the chanenl dwell time */ else if (ScanType != SCAN_PASSIVE && pAd->StaCfg.bImprovedScan) stay_time = FAST_ACTIVE_SCAN_TIME; #endif /* WIFI_P2P_CONCURRENT_FAST_SCAN */ else stay_time = MAX_CHANNEL_TIME; } RTMPSetTimer(sc_timer, stay_time); if (SCAN_MODE_ACT(ScanType)) { if (scan_active(pAd, OpMode, ScanType) == FALSE) return; } /* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse*/ #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) pAd->Mlme.ApSyncMachine.CurrState = AP_SCAN_LISTEN; #endif /* CONFIG_AP_SUPPORT */ } }
/* ========================================================================== Description: Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type, and 3) PHY-mode user selected. The outcome is used by driver when doing site survey. IRQL = PASSIVE_LEVEL IRQL = DISPATCH_LEVEL ========================================================================== */ VOID BuildChannelList(RTMP_ADAPTER *pAd) { UCHAR i, j, index=0, num=0; PCH_DESC pChDesc = NULL; BOOLEAN bRegionFound = FALSE; PUCHAR pChannelList; PUCHAR pChannelListFlag; NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER)); /* if not 11a-only mode, channel list starts from 2.4Ghz band*/ if (!WMODE_5G_ONLY(pAd->CommonCfg.PhyMode)) { for (i = 0; i < Country_Region_GroupNum_2GHZ; i++) { if ((pAd->CommonCfg.CountryRegion & 0x7f) == Country_Region_ChDesc_2GHZ[i].RegionIndex) { pChDesc = Country_Region_ChDesc_2GHZ[i].pChDesc; num = TotalChNum(pChDesc); bRegionFound = TRUE; break; } } if (!bRegionFound) { DBGPRINT(RT_DEBUG_ERROR,("CountryRegion=%d not support", pAd->CommonCfg.CountryRegion)); return; } if (num > 0) { os_alloc_mem(NULL, (UCHAR **)&pChannelList, num * sizeof(UCHAR)); if (!pChannelList) { DBGPRINT(RT_DEBUG_ERROR,("%s:Allocate memory for ChannelList failed\n", __FUNCTION__)); return; } os_alloc_mem(NULL, (UCHAR **)&pChannelListFlag, num * sizeof(UCHAR)); if (!pChannelListFlag) { DBGPRINT(RT_DEBUG_ERROR,("%s:Allocate memory for ChannelListFlag failed\n", __FUNCTION__)); os_free_mem(NULL, pChannelList); return; } for (i = 0; i < num; i++) { pChannelList[i] = GetChannel_2GHZ(pChDesc, i); pChannelListFlag[i] = GetChannelFlag(pChDesc, i); } for (i = 0; i < num; i++) { for (j = 0; j < MAX_NUM_OF_CHANNELS; j++) { if (pChannelList[i] == pAd->TxPower[j].Channel) NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER)); pAd->ChannelList[index + i].Flags = pChannelListFlag[i]; } #ifdef DOT11_N_SUPPORT if (N_ChannelGroupCheck(pAd, pAd->ChannelList[index + i].Channel)) pAd->ChannelList[index + i].Flags |= CHANNEL_40M_CAP; #ifdef DOT11_VHT_AC if (vht80_channel_group(pAd, pAd->ChannelList[index + i].Channel)) pAd->ChannelList[index + i].Flags |= CHANNEL_80M_CAP; #endif /* DOT11_VHT_AC */ #endif /* DOT11_N_SUPPORT */ pAd->ChannelList[index+i].MaxTxPwr = 20; } index += num; os_free_mem(NULL, pChannelList); os_free_mem(NULL, pChannelListFlag); } bRegionFound = FALSE; num = 0; } if (WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) { for (i = 0; i < Country_Region_GroupNum_5GHZ; i++) { if ((pAd->CommonCfg.CountryRegionForABand & 0x7f) == Country_Region_ChDesc_5GHZ[i].RegionIndex) { pChDesc = Country_Region_ChDesc_5GHZ[i].pChDesc; num = TotalChNum(pChDesc); bRegionFound = TRUE; break; } } if (!bRegionFound) { DBGPRINT(RT_DEBUG_ERROR,("CountryRegionABand=%d not support", pAd->CommonCfg.CountryRegionForABand)); return; } if (num > 0) { UCHAR RadarCh[16]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144}; #ifdef CONFIG_AP_SUPPORT UCHAR q=0; #endif /* CONFIG_AP_SUPPORT */ os_alloc_mem(NULL, (UCHAR **)&pChannelList, num * sizeof(UCHAR)); if (!pChannelList) { DBGPRINT(RT_DEBUG_ERROR,("%s:Allocate memory for ChannelList failed\n", __FUNCTION__)); return; } os_alloc_mem(NULL, (UCHAR **)&pChannelListFlag, num * sizeof(UCHAR)); if (!pChannelListFlag) { DBGPRINT(RT_DEBUG_ERROR,("%s:Allocate memory for ChannelListFlag failed\n", __FUNCTION__)); os_free_mem(NULL, pChannelList); return; } for (i = 0; i < num; i++) { pChannelList[i] = GetChannel_5GHZ(pChDesc, i); pChannelListFlag[i] = GetChannelFlag(pChDesc, i); } #ifdef CONFIG_AP_SUPPORT for (i = 0; i < num; i++) { if((pAd->CommonCfg.bIEEE80211H == 0)|| ((pAd->CommonCfg.bIEEE80211H == 1) && (pAd->CommonCfg.RDDurRegion != FCC))) { pChannelList[q] = GetChannel_5GHZ(pChDesc, i); pChannelListFlag[q] = GetChannelFlag(pChDesc, i); q++; } /*Based on the requiremnt of FCC, some channles could not be used anymore when test DFS function.*/ else if ((pAd->CommonCfg.bIEEE80211H == 1) && (pAd->CommonCfg.RDDurRegion == FCC) && (pAd->Dot11_H.bDFSIndoor == 1)) { if((GetChannel_5GHZ(pChDesc, i) < 116) || (GetChannel_5GHZ(pChDesc, i) > 128)) { pChannelList[q] = GetChannel_5GHZ(pChDesc, i); pChannelListFlag[q] = GetChannelFlag(pChDesc, i); q++; } } else if ((pAd->CommonCfg.bIEEE80211H == 1) && (pAd->CommonCfg.RDDurRegion == FCC) && (pAd->Dot11_H.bDFSIndoor == 0)) { if((GetChannel_5GHZ(pChDesc, i) < 100) || (GetChannel_5GHZ(pChDesc, i) > 140) ) { pChannelList[q] = GetChannel_5GHZ(pChDesc, i); pChannelListFlag[q] = GetChannelFlag(pChDesc, i); q++; } } } num = q; #endif /* CONFIG_AP_SUPPORT */ for (i=0; i<num; i++) { for (j=0; j<MAX_NUM_OF_CHANNELS; j++) { if (pChannelList[i] == pAd->TxPower[j].Channel) NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER)); pAd->ChannelList[index + i].Flags = pChannelListFlag[i]; } #ifdef DOT11_N_SUPPORT if (N_ChannelGroupCheck(pAd, pAd->ChannelList[index + i].Channel)) pAd->ChannelList[index + i].Flags |= CHANNEL_40M_CAP; #ifdef DOT11_VHT_AC if (vht80_channel_group(pAd, pAd->ChannelList[index + i].Channel)) pAd->ChannelList[index + i].Flags |= CHANNEL_80M_CAP; #endif /* DOT11_VHT_AC */ #endif /* DOT11_N_SUPPORT */ for (j=0; j<16; j++) { if (pChannelList[i] == RadarCh[j]) { pAd->ChannelList[index+i].DfsReq = TRUE; #ifdef SMART_MESH pAd->ChannelList[index+i].bDfsAPExist = FALSE; #endif /* SMART_MESH */ } } #ifdef SMART_MESH pAd->ChannelList[index+i].FalseCCA = 0; #endif /* SMART_MESH */ pAd->ChannelList[index+i].MaxTxPwr = 20; } index += num; os_free_mem(NULL, pChannelList); os_free_mem(NULL, pChannelListFlag); } } pAd->ChannelListNum = index; DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n", pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum)); #ifdef RT_CFG80211_SUPPORT for (i=0;i<pAd->ChannelListNum;i++) { CFG80211OS_ChanInfoInit( pAd->pCfg80211_CB, i, pAd->ChannelList[i].Channel, pAd->ChannelList[i].MaxTxPwr, WMODE_CAP_N(pAd->CommonCfg.PhyMode), (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_20)); } #endif /* RT_CFG80211_SUPPORT */ #ifdef DBG for (i=0;i<pAd->ChannelListNum;i++) { DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, Flags = %x\n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2, pAd->ChannelList[i].Flags)); } #endif }
/* ======================================================================== Routine Description: Apply new regulatory rule. Arguments: pAdCB - WLAN control block pointer pWiphy - Wireless hardware description pAlpha2 - Regulation domain (2B) Return Value: NONE Note: Can only be called when interface is up. For general mac80211 device, it will be set to new power by Ops->config() In rt2x00/, the settings is done in rt2x00lib_config(). ======================================================================== */ VOID CFG80211_RegRuleApply( IN VOID *pAdCB, IN VOID *pWiphy, IN UCHAR *pAlpha2) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB; VOID *pBand24G, *pBand5G; UINT32 IdBand, IdChan, IdPwr; UINT32 ChanNum, ChanId, Power, RecId, DfsType; BOOLEAN FlgIsRadar; ULONG IrqFlags; #ifdef DFS_SUPPORT RADAR_DETECT_STRUCT *pRadarDetect; #endif /* DFS_SUPPORT */ CFG80211DBG(RT_DEBUG_ERROR, ("crda> CFG80211_RegRuleApply ==>\n")); /* init */ pBand24G = NULL; pBand5G = NULL; if (pAd == NULL) return; RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); /* zero first */ NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER)); /* 2.4GHZ & 5GHz */ RecId = 0; #ifdef DFS_SUPPORT pRadarDetect = &pAd->CommonCfg.RadarDetect; #endif /* DFS_SUPPORT */ /* find the DfsType */ DfsType = CE; pBand24G = NULL; pBand5G = NULL; if (CFG80211OS_BandInfoGet(CFG80211CB, pWiphy, &pBand24G, &pBand5G) == FALSE) return; #ifdef AUTO_CH_SELECT_ENHANCE #ifdef EXT_BUILD_CHANNEL_LIST if ((pAlpha2[0] != '0') && (pAlpha2[1] != '0')) { UINT32 IdReg; if (pBand5G != NULL) { for(IdReg=0; ; IdReg++) { if (ChRegion[IdReg].CountReg[0] == 0x00) break; /* End of if */ if ((pAlpha2[0] == ChRegion[IdReg].CountReg[0]) && (pAlpha2[1] == ChRegion[IdReg].CountReg[1])) { if (pAd->CommonCfg.DfsType != MAX_RD_REGION) DfsType = pAd->CommonCfg.DfsType; else DfsType = ChRegion[IdReg].DfsType; CFG80211DBG(RT_DEBUG_ERROR, ("crda> find region %c%c, DFS Type %d\n", pAlpha2[0], pAlpha2[1], DfsType)); break; } /* End of if */ } /* End of for */ } /* End of if */ } /* End of if */ #endif /* EXT_BUILD_CHANNEL_LIST */ #endif /* AUTO_CH_SELECT_ENHANCE */ for(IdBand=0; IdBand<2; IdBand++) { if (((IdBand == 0) && (pBand24G == NULL)) || ((IdBand == 1) && (pBand5G == NULL))) { continue; } /* End of if */ if (IdBand == 0) { CFG80211DBG(RT_DEBUG_ERROR, ("crda> reset chan/power for 2.4GHz\n")); } else { CFG80211DBG(RT_DEBUG_ERROR, ("crda> reset chan/power for 5GHz\n")); } /* End of if */ ChanNum = CFG80211OS_ChanNumGet(CFG80211CB, pWiphy, IdBand); for(IdChan=0; IdChan<ChanNum; IdChan++) { if (CFG80211OS_ChanInfoGet(CFG80211CB, pWiphy, IdBand, IdChan, &ChanId, &Power, &FlgIsRadar) == FALSE) { /* the channel is not allowed in the regulatory domain */ /* get next channel information */ continue; } if (!WMODE_CAP_2G(pAd->CommonCfg.PhyMode)) { /* 5G-only mode */ if (ChanId <= CFG80211_NUM_OF_CHAN_2GHZ) continue; } if (!WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) { /* 2.4G-only mode */ if (ChanId > CFG80211_NUM_OF_CHAN_2GHZ) continue; } for(IdPwr=0; IdPwr<MAX_NUM_OF_CHANNELS; IdPwr++) { if (ChanId == pAd->TxPower[IdPwr].Channel) { /* init the channel info. */ NdisMoveMemory(&pAd->ChannelList[RecId], &pAd->TxPower[IdPwr], sizeof(CHANNEL_TX_POWER)); /* keep channel number */ pAd->ChannelList[RecId].Channel = ChanId; /* keep maximum tranmission power */ pAd->ChannelList[RecId].MaxTxPwr = Power; /* keep DFS flag */ if (FlgIsRadar == TRUE) pAd->ChannelList[RecId].DfsReq = TRUE; else pAd->ChannelList[RecId].DfsReq = FALSE; /* End of if */ /* keep DFS type */ pAd->ChannelList[RecId].RegulatoryDomain = DfsType; /* re-set DFS info. */ pAd->CommonCfg.RDDurRegion = DfsType; CFG80211DBG(RT_DEBUG_ERROR, ("Chan %03d:\tpower %d dBm, " "DFS %d, DFS Type %d\n", ChanId, Power, ((FlgIsRadar == TRUE)?1:0), DfsType)); /* change to record next channel info. */ RecId ++; break; } /* End of if */ } /* End of for */ } /* End of for */ } /* End of for */ pAd->ChannelListNum = RecId; RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); CFG80211DBG(RT_DEBUG_ERROR, ("crda> Number of channels = %d\n", RecId)); } /* End of CFG80211_RegRuleApply */
/* ========================================================================== Description: Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type, and 3) PHY-mode user selected. The outcome is used by driver when doing site survey. IRQL = PASSIVE_LEVEL IRQL = DISPATCH_LEVEL ========================================================================== */ VOID BuildChannelList( IN PRTMP_ADAPTER pAd) { UCHAR i, j, index=0, num=0; PCH_DESC pChDesc = NULL; BOOLEAN bRegionFound = FALSE; PUCHAR pChannelList; PUCHAR pChannelListFlag; NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER)); /* if not 11a-only mode, channel list starts from 2.4Ghz band*/ if (!WMODE_5G_ONLY(pAd->CommonCfg.PhyMode)) { for (i = 0; i < Country_Region_GroupNum_2GHZ; i++) { if ((pAd->CommonCfg.CountryRegion & 0x7f) == Country_Region_ChDesc_2GHZ[i].RegionIndex) { pChDesc = Country_Region_ChDesc_2GHZ[i].pChDesc; num = TotalChNum(pChDesc); bRegionFound = TRUE; break; } } if (!bRegionFound) { DBGPRINT(RT_DEBUG_ERROR,("CountryRegion=%d not support", pAd->CommonCfg.CountryRegion)); return; } if (num > 0) { os_alloc_mem(NULL, (UCHAR **)&pChannelList, num * sizeof(UCHAR)); if (!pChannelList) { DBGPRINT(RT_DEBUG_ERROR,("%s:Allocate memory for ChannelList failed\n", __FUNCTION__)); return; } os_alloc_mem(NULL, (UCHAR **)&pChannelListFlag, num * sizeof(UCHAR)); if (!pChannelListFlag) { DBGPRINT(RT_DEBUG_ERROR,("%s:Allocate memory for ChannelListFlag failed\n", __FUNCTION__)); os_free_mem(NULL, pChannelList); return; } for (i = 0; i < num; i++) { pChannelList[i] = GetChannel_2GHZ(pChDesc, i); pChannelListFlag[i] = GetChannelFlag(pChDesc, i); } for (i = 0; i < num; i++) { for (j = 0; j < MAX_NUM_OF_CHANNELS; j++) { if (pChannelList[i] == pAd->TxPower[j].Channel) NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER)); pAd->ChannelList[index + i].Flags = pChannelListFlag[i]; } #ifdef DOT11_N_SUPPORT if (N_ChannelGroupCheck(pAd, pAd->ChannelList[index + i].Channel)) pAd->ChannelList[index + i].Flags |= CHANNEL_40M_CAP; #endif /* DOT11_N_SUPPORT */ pAd->ChannelList[index+i].MaxTxPwr = 20; } index += num; os_free_mem(NULL, pChannelList); os_free_mem(NULL, pChannelListFlag); } bRegionFound = FALSE; num = 0; } if (WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) { for (i = 0; i < Country_Region_GroupNum_5GHZ; i++) { if ((pAd->CommonCfg.CountryRegionForABand & 0x7f) == Country_Region_ChDesc_5GHZ[i].RegionIndex) { pChDesc = Country_Region_ChDesc_5GHZ[i].pChDesc; num = TotalChNum(pChDesc); bRegionFound = TRUE; break; } } if (!bRegionFound) { DBGPRINT(RT_DEBUG_ERROR,("CountryRegionABand=%d not support", pAd->CommonCfg.CountryRegionForABand)); return; } if (num > 0) { UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}; os_alloc_mem(NULL, (UCHAR **)&pChannelList, num * sizeof(UCHAR)); if (!pChannelList) { DBGPRINT(RT_DEBUG_ERROR,("%s:Allocate memory for ChannelList failed\n", __FUNCTION__)); return; } os_alloc_mem(NULL, (UCHAR **)&pChannelListFlag, num * sizeof(UCHAR)); if (!pChannelListFlag) { DBGPRINT(RT_DEBUG_ERROR,("%s:Allocate memory for ChannelListFlag failed\n", __FUNCTION__)); os_free_mem(NULL, pChannelList); return; } for (i = 0; i < num; i++) { pChannelList[i] = GetChannel_5GHZ(pChDesc, i); pChannelListFlag[i] = GetChannelFlag(pChDesc, i); } for (i=0; i<num; i++) { for (j=0; j<MAX_NUM_OF_CHANNELS; j++) { if (pChannelList[i] == pAd->TxPower[j].Channel) NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER)); pAd->ChannelList[index + i].Flags = pChannelListFlag[i]; } #ifdef DOT11_N_SUPPORT if (N_ChannelGroupCheck(pAd, pAd->ChannelList[index + i].Channel)) pAd->ChannelList[index + i].Flags |= CHANNEL_40M_CAP; #endif /* DOT11_N_SUPPORT */ for (j=0; j<15; j++) { if (pChannelList[i] == RadarCh[j]) pAd->ChannelList[index+i].DfsReq = TRUE; } pAd->ChannelList[index+i].MaxTxPwr = 20; } index += num; os_free_mem(NULL, pChannelList); os_free_mem(NULL, pChannelListFlag); } } pAd->ChannelListNum = index; DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n", pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum)); #ifdef RT_CFG80211_SUPPORT for (i=0;i<pAd->ChannelListNum;i++) { CFG80211OS_ChanInfoInit( pAd->pCfg80211_CB, i, pAd->ChannelList[i].Channel, pAd->ChannelList[i].MaxTxPwr, WMODE_CAP_N(pAd->CommonCfg.PhyMode), (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_20)); } #endif /* RT_CFG80211_SUPPORT */ #ifdef DBG for (i=0;i<pAd->ChannelListNum;i++) { DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, Flags = %x\n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2, pAd->ChannelList[i].Flags)); } #endif }