/* ========================================================================== 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 }
/* ========================================================================== 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 }