/* *************************************************************************** * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, Taiwan, R.O.C. * (c) Copyright 2002, Ralink Technology, Inc. * * All rights reserved. Ralink's source code is an unpublished work and the * use of a copyright notice does not imply otherwise. This source code * contains confidential trade secret material of Ralink Tech. Any attemp * or participation in deciphering, decoding, reverse engineering or in any * way altering the source code is stricitly prohibited, unless the prior * written consent of Ralink Technology, Inc. is obtained. *************************************************************************** Module Name: cmm_sync.c Abstract: Revision History: Who When What -------- ---------- ---------------------------------------------- John Chang 2004-09-01 modified for rt2561/2661 */ #include "rt_config.h" /*BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.*/ UCHAR BaSizeArray[4] = {8,16,32,64}; extern COUNTRY_REGION_CH_DESC Country_Region_ChDesc_2GHZ[]; extern UINT16 const Country_Region_GroupNum_2GHZ; extern COUNTRY_REGION_CH_DESC Country_Region_ChDesc_5GHZ[]; extern UINT16 const Country_Region_GroupNum_5GHZ; /* ========================================================================== 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; UINT16 index = 0, num = 0; PCH_DESC pChDesc = NULL; BOOLEAN bRegionFound = FALSE; PUCHAR pChannelList = NULL; PUCHAR pChannelListFlag = NULL; #ifdef CFG80211_BUILD_CHANNEL_LIST PCH_DESC pChDesc2G = NULL, pChDesc5G = NULL; #endif /* CFG80211_BUILD_CHANNEL_LIST */ 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_CAP_2G(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; #ifdef CFG80211_BUILD_CHANNEL_LIST pChDesc2G = pChDesc; #endif /* CFG80211_BUILD_CHANNEL_LIST */ 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]; // TODO: shiang-7603, NdisMoveMemory may replace the pAd->ChannelList[index+i].Channel as other values! pAd->ChannelList[index+i].Channel = pChannelList[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; #ifdef CFG80211_BUILD_CHANNEL_LIST pChDesc5G = pChDesc; #endif /* CFG80211_BUILD_CHANNEL_LIST */ 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}; #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; iTxPower[j].Channel) NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER)); pAd->ChannelList[index + i].Flags = pChannelListFlag[i]; // TODO: shiang-7603, NdisMoveMemory may replace the pAd->ChannelList[index+i].Channel as other values! pAd->ChannelList[index+i].Channel = pChannelList[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<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 = (UCHAR)index; DBGPRINT(RT_DEBUG_TRACE,("CountryCode(2.4G/5G)=%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; iChannelListNum; 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)); } #ifdef CFG80211_BUILD_CHANNEL_LIST if (CFG80211OS_UpdateRegRuleByRegionIdx( pAd->pCfg80211_CB, pChDesc2G, pChDesc5G ) != 0) { DBGPRINT(RT_DEBUG_ERROR,("Update RegRule failed!\n")); } #endif /* CFG80211_BUILD_CHANNEL_LIST */ #endif /* RT_CFG80211_SUPPORT */ #ifdef DBG DBGPRINT(RT_DEBUG_TRACE, ("SupportedChannelList:\n")); for (i=0; iChannelListNum; i++) { DBGPRINT_RAW(RT_DEBUG_TRACE,("\tChannel # %d: Pwr0/1 = %d/%d, Flags = %x\n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2, pAd->ChannelList[i].Flags)); } #endif } #ifdef P2P_CHANNEL_LIST_SEPARATE VOID P2PBuildChannelList( IN PRTMP_ADAPTER pAd) { UCHAR i, index=0, num=0; PCH_DESC pChDesc = NULL; BOOLEAN bRegionFound = FALSE; PCFG80211_CTRL pCfg80211_Ctrl = &pAd->cfg80211_ctrl; NdisZeroMemory(pCfg80211_Ctrl->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER)); /* if not 11a-only mode, channel list starts from 2.4Ghz band*/ if (WMODE_CAP_2G(pAd->CommonCfg.PhyMode)) { for (i = 0; i < Country_Region_GroupNum_2GHZ; i++) { if ((pCfg80211_Ctrl->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,("%s::P2PCountryRegion=%d not support", __FUNCTION__, pCfg80211_Ctrl->CountryRegion)); return; } if (num > 0) { for (i = 0; i < num; i++) { pCfg80211_Ctrl->ChannelList[i].Channel = GetChannel_2GHZ(pChDesc, i); pCfg80211_Ctrl->ChannelList[i].Flags = GetChannelFlag(pChDesc, i); } index += num; } num = 0; } if (WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) { for (i = 0; i < Country_Region_GroupNum_5GHZ; i++) { if ((pCfg80211_Ctrl->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,("%s::P2PCountryRegionForABand=%d not support", __FUNCTION__, pCfg80211_Ctrl->CountryRegionForABand)); return; } if (num > 0) { for (i = 0; i < num; i++) { pCfg80211_Ctrl->ChannelList[index + i].Channel = GetChannel_5GHZ(pChDesc, i); pCfg80211_Ctrl->ChannelList[index + i].Flags = GetChannelFlag(pChDesc, i); } index += num; } } pCfg80211_Ctrl->ChannelListNum = index; DBGPRINT(RT_DEBUG_TRACE, ("%s::Channel list nubmer = %d\n", __FUNCTION__, pCfg80211_Ctrl->ChannelListNum)); } #endif /* P2P_CHANNEL_LIST_SEPARATE */ /* ========================================================================== Description: This routine return the first channel number according to the country code selection and RF IC selection (signal band or dual band). It is called whenever driver need to start a site survey of all supported channels. Return: ch - the first channel number of current country code setting IRQL = PASSIVE_LEVEL ========================================================================== */ UCHAR FirstChannel(RTMP_ADAPTER *pAd) { return pAd->ChannelList[0].Channel; } /* ========================================================================== Description: This routine returns the next channel number. This routine is called during driver need to start a site survey of all supported channels. Return: next_channel - the next channel number valid in current country code setting. Note: return 0 if no more next channel ========================================================================== */ UCHAR NextChannel(RTMP_ADAPTER *pAd, UCHAR channel) { int i; UCHAR next_channel = 0; #ifdef P2P_SUPPORT UCHAR CurrentChannel = channel; if (pAd->ScanCtrl.ScanType == SCAN_P2P_SEARCH) { if (IS_P2P_LISTEN(pAd)) { DBGPRINT(RT_DEBUG_ERROR, ("Error !! P2P Discovery state machine has change to Listen state during scanning !\n")); return next_channel; } for (i = 0; i < (pAd->P2pCfg.P2pProprietary.ListenChanelCount - 1); i++) { if (CurrentChannel == pAd->P2pCfg.P2pProprietary.ListenChanel[i]) next_channel = pAd->P2pCfg.P2pProprietary.ListenChanel[i+1]; } P2P_INC_CHA_INDEX(pAd->P2pCfg.P2pProprietary.ListenChanelIndex, pAd->P2pCfg.P2pProprietary.ListenChanelCount); if (next_channel == CurrentChannel) { DBGPRINT(RT_DEBUG_INFO, ("SYNC - next_channel equals to CurrentChannel= %d\n", next_channel)); DBGPRINT(RT_DEBUG_INFO, ("SYNC - ListenChannel List : %d %d %d\n", pAd->P2pCfg.P2pProprietary.ListenChanel[0], pAd->P2pCfg.P2pProprietary.ListenChanel[1], pAd->P2pCfg.P2pProprietary.ListenChanel[2])); next_channel = 0; } #if 0 if (!INFRA_ON(pAd) && (next_channel == 0)) pAd->CommonCfg.Channel = pAd->P2pCfg.ListenChannel; #endif DBGPRINT(RT_DEBUG_INFO, ("SYNC - P2P Scan return channel = %d. Listen Channel = %d.\n", next_channel, pAd->CommonCfg.Channel)); return next_channel; } #endif /* P2P_SUPPORT */ #ifdef P2P_CHANNEL_LIST_SEPARATE PCFG80211_CTRL pCfg80211_Ctrl = &pAd->cfg80211_ctrl; #endif /* P2P_CHANNEL_LIST_SEPARATE */ #ifdef P2P_CHANNEL_LIST_SEPARATE if ((pAd->ScanCtrl.ScanType == SCAN_P2P)) { for (i = 0; i < (pCfg80211_Ctrl->ChannelListNum - 1); i++) { if (channel == pCfg80211_Ctrl->ChannelList[i].Channel) { next_channel = pCfg80211_Ctrl->ChannelList[i+1].Channel; return next_channel; } } } #endif /* P2P_CHANNEL_LIST_SEPARATE */ for (i = 0; i < (pAd->ChannelListNum - 1); i++) { if (channel == pAd->ChannelList[i].Channel) { #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* Only scan effected channel if this is a SCAN_2040_BSS_COEXIST*/ /* 2009 PF#2: Nee to handle the second channel of AP fall into affected channel range.*/ if ((pAd->ScanCtrl.ScanType == SCAN_2040_BSS_COEXIST) && (pAd->ChannelList[i+1].Channel >14)) { channel = pAd->ChannelList[i+1].Channel; continue; } else #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ { /* Record this channel's idx in ChannelList array.*/ next_channel = pAd->ChannelList[i+1].Channel; break; } } } return next_channel; } /* ========================================================================== Description: This routine is for Cisco Compatible Extensions 2.X Spec31. AP Control of Client Transmit Power Return: None Note: Required by Aironet dBm(mW) 0dBm(1mW), 1dBm(5mW), 13dBm(20mW), 15dBm(30mW), 17dBm(50mw), 20dBm(100mW) We supported 3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%), 14dBm(75%), 15dBm(100%) The client station's actual transmit power shall be within +/- 5dB of the minimum value or next lower value. ========================================================================== */ VOID ChangeToCellPowerLimit(RTMP_ADAPTER *pAd, UCHAR AironetCellPowerLimit) { /* valud 0xFF means that hasn't found power limit information from the AP's Beacon/Probe response */ if (AironetCellPowerLimit == 0xFF) return; if (AironetCellPowerLimit < 6) /*Used Lowest Power Percentage.*/ pAd->CommonCfg.TxPowerPercentage = 6; else if (AironetCellPowerLimit < 9) pAd->CommonCfg.TxPowerPercentage = 10; else if (AironetCellPowerLimit < 12) pAd->CommonCfg.TxPowerPercentage = 25; else if (AironetCellPowerLimit < 14) pAd->CommonCfg.TxPowerPercentage = 50; else if (AironetCellPowerLimit < 15) pAd->CommonCfg.TxPowerPercentage = 75; else pAd->CommonCfg.TxPowerPercentage = 100; /*else used maximum*/ if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault) pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; } CHAR ConvertToRssi(RTMP_ADAPTER *pAd, struct raw_rssi_info *rssi_info, UCHAR rssi_idx) { UCHAR RssiOffset, LNAGain; CHAR BaseVal; CHAR rssi; /* Rssi equals to zero or rssi_idx larger than 3 should be an invalid value*/ if (rssi_idx >= 3) return -99; rssi = rssi_info->raw_rssi[rssi_idx]; if (rssi == 0) return -99; LNAGain = pAd->hw_cfg.lan_gain; if (pAd->LatchRfRegs.Channel > 14) RssiOffset = pAd->ARssiOffset[rssi_idx]; else RssiOffset = pAd->BGRssiOffset[rssi_idx]; BaseVal = -12; #ifdef RT6352 if (IS_RT6352(pAd)) BaseVal = -2; #endif /* RT6352 */ #if defined (MT7603) || defined (MT7628) if (IS_MT7603(pAd) || IS_MT7628(pAd)) return (rssi + (CHAR)RssiOffset - (CHAR)LNAGain); #endif #ifdef RT65xx /* Recommended by CSD team about MT76x0: SW/QA owners should read the "external-LNA gain" and "RSSI OFFSET" content in EEPROM as "SIGNED". 2.4G : RSSI_report = RSSI_bpp + EEPROM_0x46[15:8 or 7:0] - EEPROM_0x44[7:0] 5G : RSSI_report = RSSI_bbp + EEPROM_0x4A[15:8 or 7:0] - EEPROM_0x44 or 0x48 or 0x4c[15:8] */ if (IS_MT76x0(pAd)) return (rssi + (CHAR)RssiOffset - (CHAR)LNAGain); if (IS_MT76x2(pAd)) { if (pAd->LatchRfRegs.Channel > 14) return (rssi + pAd->ARssiOffset[rssi_idx] - (CHAR)LNAGain); else return (rssi + pAd->BGRssiOffset[rssi_idx] - (CHAR)LNAGain); } if (IS_RT8592(pAd)) return (rssi - LNAGain - RssiOffset); #endif /* RT65xx */ #ifdef MT7601 // TODO: shiang-usw, fix me for AntSel and BW for MT7601!!! if (IS_MT7601(pAd)) { CHAR LNA, RSSI; CHAR *LNATable; UCHAR AntSel = rssi_info->raw_rssi[1]; /* Antenna ID */ UCHAR BW = rssi_info->raw_rssi[2]; /* BW */ /* CHAR MainBW40LNA[] = { 1, 18, 35 }; CHAR MainBW20LNA[] = { 1, 18, 36 }; CHAR AuxBW40LNA[] = { 1, 23, 42 }; CHAR AuxBW20LNA[] = { 1, 23, 42 }; */ CHAR MainBW40LNA[] = { 0, 16, 34 }; CHAR MainBW20LNA[] = { -2, 15, 33 }; CHAR AuxBW40LNA[] = { -2, 16, 34 }; CHAR AuxBW20LNA[] = { -2, 15, 33 }; LNA = (rssi >> 6) & 0x3; RSSI = rssi & 0x3F; if ( (AntSel >> 7) == 0 ) { if (BW == BW_40) LNATable = MainBW40LNA; else LNATable = MainBW20LNA; } else { if (BW == BW_40) LNATable = AuxBW40LNA; else LNATable = AuxBW20LNA; } if ( LNA == 3 ) LNA = LNATable[2]; else if ( LNA == 2 ) LNA = LNATable[1]; else LNA = LNATable[0]; return ( 8 - LNA - RSSI - LNAGain - RssiOffset ); } else #endif /* MT7601 */ return (BaseVal - RssiOffset - LNAGain - rssi); } CHAR ConvertToSnr(RTMP_ADAPTER *pAd, UCHAR Snr) { if (pAd->chipCap.SnrFormula == SNR_FORMULA2) return (Snr * 3 + 8) >> 4; else if (pAd->chipCap.SnrFormula == SNR_FORMULA3) return (Snr * 3 / 16 ); /* * 0.1881 */ else return (Snr - 16); /*return ((0xeb - Snr) * 3) / 16 ; */ } #ifdef WIDI_SUPPORT #ifdef CONFIG_STA_SUPPORT /* ========================================================================== Description: SendProbeRequest ========================================================================== */ VOID WidiSendProbeRequest( IN PRTMP_ADAPTER pAd, IN UCHAR * destMac, IN UCHAR ssidLen, IN CHAR * ssidStr, IN UCHAR * deviceName, IN UCHAR * primaryDeviceType, IN UCHAR * vendExt, IN USHORT vendExtLen, IN UCHAR channel) { HEADER_802_11 Hdr80211; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; UCHAR SsidLen = 0, ScanType = pAd->MlmeAux.ScanType; UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME; pAd->StaCfg.bSendingProbe = 1; IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (MONITOR_ON(pAd)) return; } IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { /* 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); } AsicSwitchChannel(pAd, channel, FALSE); AsicLockChannel(pAd, channel); IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (pAd->MlmeAux.Channel > 14) { if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel)) { ScanType = SCAN_PASSIVE; ScanTimeIn5gChannel = MIN_CHANNEL_TIME; } } #ifdef CARRIER_DETECTION_SUPPORT /* Roger sync Carrier */ /* carrier detection */ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE) { ScanType = SCAN_PASSIVE; ScanTimeIn5gChannel = MIN_CHANNEL_TIME; } #endif /* CARRIER_DETECTION_SUPPORT */ } /* Global country domain(ch1-11:active scan, ch12-14 passive scan) */ if (((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND)) || (CHAN_PropertyCheck(pAd, pAd->MlmeAux.Channel, CHANNEL_PASSIVE_SCAN) == TRUE)) { ScanType = SCAN_PASSIVE; } NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /* Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR, ("%s():allocate memory fail\n", __FUNCTION__)); pAd->StaCfg.bSendingProbe = 0; return; } MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, destMac, pAd->CurrentAddress, destMac); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &Hdr80211, 1, &SsidIe, 1, &SsidLen, ssidLen, ssidStr, 1, &SupRateIe, 1, &pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRate, END_OF_ARGS); if (pAd->CommonCfg.ExtRateLen) { ULONG Tmp; MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += Tmp; } #ifdef WSC_STA_SUPPORT if (pAd->OpMode == OPMODE_STA) { /* Append WSC information in probe request if WSC state is running */ if ((pAd->StaCfg.WscControl.WscEnProbeReqIE) && (pAd->StaCfg.WscControl.WscConfMode != WSC_DISABLE)) /* && (pAd->StaCfg.WscControl.bWscTrigger == TRUE)) */ { UCHAR *pWscBuf = NULL, WscIeLen = 0; ULONG WscTmpLen = 0; if (os_alloc_mem(pAd, (UCHAR **)&pWscBuf, 512) == NDIS_STATUS_SUCCESS) { NdisZeroMemory(pWscBuf, 512); WscMakeProbeReqIEWithVendorExt(pAd, deviceName, primaryDeviceType, vendExt, vendExtLen, pWscBuf, &WscIeLen); /* DBGPRINT(RT_DEBUG_ERROR, ("Created WPS IE for Probe Request; Len = %d\n", WscIeLen)); */ MakeOutgoingFrame(pOutBuffer + FrameLen, &WscTmpLen, WscIeLen, pWscBuf, END_OF_ARGS); FrameLen += WscTmpLen; os_free_mem(NULL, pWscBuf); } else DBGPRINT(RT_DEBUG_WARN, ("%s:: WscBuf Allocate failed!\n", __FUNCTION__)); } } #endif /* WSC_STA_SUPPORT */ /* DBGPRINT(RT_DEBUG_ERROR, ("Really Sending out Probe Request\n")); */ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); #if 0 //fix toggle scan IF_DEV_CONFIG_OPMODE_ON_STA(pAd) pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN; #endif pAd->StaCfg.bSendingProbe = 0; } #endif /* CONFIG_STA_SUPPORT */ #endif /* WIDI_SUPPORT */ #ifdef CONFIG_AP_SUPPORT #ifdef DOT11_N_SUPPORT extern int DetectOverlappingPeriodicRound; VOID Handle_BSS_Width_Trigger_Events(RTMP_ADAPTER *pAd) { ULONG Now32; #ifdef DOT11N_DRAFT3 if (pAd->CommonCfg.bBssCoexEnable == FALSE) return; #endif /* DOT11N_DRAFT3 */ if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (pAd->CommonCfg.Channel <=14)) { DBGPRINT(RT_DEBUG_TRACE, ("Rcv BSS Width Trigger Event: 40Mhz --> 20Mhz \n")); NdisGetSystemUpTime(&Now32); pAd->CommonCfg.LastRcvBSSWidthTriggerEventsTime = Now32; pAd->CommonCfg.bRcvBSSWidthTriggerEvents = TRUE; pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0; pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0; DetectOverlappingPeriodicRound = 31; } } #endif /* DOT11_N_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */