blob: a6e1b6ddfe57ef669d88019a036d9922a846b27d [file] [log] [blame]
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
sync.c
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
John Chang 2004-09-01 modified for rt2561/2661
*/
#include "../rt_config.h"
// 2.4 Ghz channel plan index in the TxPower arrays.
#define BG_BAND_REGION_0_START 0 // 1,2,3,4,5,6,7,8,9,10,11
#define BG_BAND_REGION_0_SIZE 11
#define BG_BAND_REGION_1_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13
#define BG_BAND_REGION_1_SIZE 13
#define BG_BAND_REGION_2_START 9 // 10,11
#define BG_BAND_REGION_2_SIZE 2
#define BG_BAND_REGION_3_START 9 // 10,11,12,13
#define BG_BAND_REGION_3_SIZE 4
#define BG_BAND_REGION_4_START 13 // 14
#define BG_BAND_REGION_4_SIZE 1
#define BG_BAND_REGION_5_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
#define BG_BAND_REGION_5_SIZE 14
#define BG_BAND_REGION_6_START 2 // 3,4,5,6,7,8,9
#define BG_BAND_REGION_6_SIZE 7
#define BG_BAND_REGION_7_START 4 // 5,6,7,8,9,10,11,12,13
#define BG_BAND_REGION_7_SIZE 9
#define BG_BAND_REGION_31_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
#define BG_BAND_REGION_31_SIZE 14
// 5 Ghz channel plan index in the TxPower arrays.
UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_1_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
//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};
/*
==========================================================================
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;
PUCHAR pChannelList = NULL;
NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
// if not 11a-only mode, channel list starts from 2.4Ghz band
if ((pAd->CommonCfg.PhyMode != PHY_11A)
&& (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
)
{
switch (pAd->CommonCfg.CountryRegion & 0x7f)
{
case REGION_0_BG_BAND: // 1 -11
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
index += BG_BAND_REGION_0_SIZE;
break;
case REGION_1_BG_BAND: // 1 - 13
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
index += BG_BAND_REGION_1_SIZE;
break;
case REGION_2_BG_BAND: // 10 - 11
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
index += BG_BAND_REGION_2_SIZE;
break;
case REGION_3_BG_BAND: // 10 - 13
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
index += BG_BAND_REGION_3_SIZE;
break;
case REGION_4_BG_BAND: // 14
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
index += BG_BAND_REGION_4_SIZE;
break;
case REGION_5_BG_BAND: // 1 - 14
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
index += BG_BAND_REGION_5_SIZE;
break;
case REGION_6_BG_BAND: // 3 - 9
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
index += BG_BAND_REGION_6_SIZE;
break;
case REGION_7_BG_BAND: // 5 - 13
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_7_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_7_SIZE);
index += BG_BAND_REGION_7_SIZE;
break;
case REGION_31_BG_BAND: // 1 - 14
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_31_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_31_SIZE);
index += BG_BAND_REGION_31_SIZE;
break;
default: // Error. should never happen
break;
}
for (i=0; i<index; i++)
pAd->ChannelList[i].MaxTxPwr = 20;
}
if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
|| (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
)
{
switch (pAd->CommonCfg.CountryRegionForABand & 0x7f)
{
case REGION_0_A_BAND:
num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
break;
case REGION_1_A_BAND:
num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
break;
case REGION_2_A_BAND:
num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
break;
case REGION_3_A_BAND:
num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
break;
case REGION_4_A_BAND:
num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
break;
case REGION_5_A_BAND:
num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
break;
case REGION_6_A_BAND:
num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
break;
case REGION_7_A_BAND:
num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
break;
case REGION_8_A_BAND:
num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
break;
case REGION_9_A_BAND:
num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
break;
case REGION_10_A_BAND:
num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
break;
case REGION_11_A_BAND:
num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
break;
default: // Error. should never happen
DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
break;
}
if (num != 0)
{
UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
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));
}
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;
}
}
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 DBG
for (i=0;i<pAd->ChannelListNum;i++)
{
DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2));
}
#endif
}
/*
==========================================================================
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(
IN PRTMP_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(
IN PRTMP_ADAPTER pAd,
IN UCHAR channel)
{
int i;
UCHAR next_channel = 0;
for (i = 0; i < (pAd->ChannelListNum - 1); i++)
if (channel == pAd->ChannelList[i].Channel)
{
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(
IN PRTMP_ADAPTER pAd,
IN 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(
IN PRTMP_ADAPTER pAd,
IN CHAR Rssi,
IN UCHAR RssiNumber)
{
UCHAR RssiOffset, LNAGain;
// Rssi equals to zero should be an invalid value
if (Rssi == 0)
return -99;
LNAGain = GET_LNA_GAIN(pAd);
if (pAd->LatchRfRegs.Channel > 14)
{
if (RssiNumber == 0)
RssiOffset = pAd->ARssiOffset0;
else if (RssiNumber == 1)
RssiOffset = pAd->ARssiOffset1;
else
RssiOffset = pAd->ARssiOffset2;
}
else
{
if (RssiNumber == 0)
RssiOffset = pAd->BGRssiOffset0;
else if (RssiNumber == 1)
RssiOffset = pAd->BGRssiOffset1;
else
RssiOffset = pAd->BGRssiOffset2;
}
return (-12 - RssiOffset - LNAGain - Rssi);
}
/*
==========================================================================
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;
USHORT Status;
PHEADER_802_11 pHdr80211;
UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
if (MONITOR_ON(pAd))
return;
if (pAd->MlmeAux.Channel == 0)
{
if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
&& (INFRA_ON(pAd)
|| (pAd->OpMode == OPMODE_AP))
)
{
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));
}
{
//
// 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)))
{
NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
if (NStatus == NDIS_STATUS_SUCCESS)
{
pHdr80211 = (PHEADER_802_11) pOutBuffer;
MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
pHdr80211->Duration = 0;
pHdr80211->FC.Type = BTYPE_DATA;
pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
// Send using priority queue
MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n"));
MlmeFreeMemory(pAd, pOutBuffer);
RTMPusecDelay(5000);
}
}
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
Status = MLME_SUCCESS;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
}
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
}
#ifdef RT2870
else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
{
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
}
#endif // RT2870 //
else
{
{
// BBP and RF are not accessible in PS mode, we has to wake them up first
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
#ifdef RT2860
AsicForceWakeup(pAd, FROM_TX);
#endif
#ifdef RT2870
AsicForceWakeup(pAd, TRUE);
#endif
// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
if (pAd->StaCfg.Psm == PWR_SAVE)
MlmeSetPsmBit(pAd, PWR_ACTIVE);
}
AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
AsicLockChannel(pAd, pAd->MlmeAux.Channel);
{
if (pAd->MlmeAux.Channel > 14)
{
if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
{
ScanType = SCAN_PASSIVE;
ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
}
}
}
//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))
{
ScanType = SCAN_PASSIVE;
}
// 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)
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
else if (((ScanType == SCAN_CISCO_ACTIVE) ||
(ScanType == SCAN_CISCO_PASSIVE) ||
(ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
(ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
{
if (pAd->StaCfg.CCXScanTime < 25)
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
else
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
}
else // must be SCAN_PASSIVE or SCAN_ACTIVE
{
if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
)
{
if (pAd->MlmeAux.Channel > 14)
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
else
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
}
else
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
}
if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ||
(ScanType == SCAN_CISCO_ACTIVE))
{
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
if (NStatus != NDIS_STATUS_SUCCESS)
{
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
{
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
Status = MLME_FAIL_NO_RESOURCE;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
}
return;
}
// There is no need to send broadcast probe request if active scan is in effect.
if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
)
SsidLen = pAd->MlmeAux.SsidLen;
else
SsidLen = 0;
MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(HEADER_802_11), &Hdr80211,
1, &SsidIe,
1, &SsidLen,
SsidLen, pAd->MlmeAux.Ssid,
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;
}
if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
{
ULONG Tmp;
UCHAR HtLen;
UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
if (pAd->bBroadComHT == TRUE)
{
HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
1, &WpaIe,
1, &HtLen,
4, &BROADCOM[0],
pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
END_OF_ARGS);
}
else
{
HtLen = pAd->MlmeAux.HtCapabilityLen;
MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
1, &HtCapIe,
1, &HtLen,
HtLen, &pAd->CommonCfg.HtCapability,
END_OF_ARGS);
}
FrameLen += Tmp;
}
MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
MlmeFreeMemory(pAd, pOutBuffer);
}
// For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
}
}
VOID MgtProbReqMacHeaderInit(
IN PRTMP_ADAPTER pAd,
IN OUT PHEADER_802_11 pHdr80211,
IN UCHAR SubType,
IN UCHAR ToDs,
IN PUCHAR pDA,
IN PUCHAR pBssid)
{
NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
pHdr80211->FC.Type = BTYPE_MGMT;
pHdr80211->FC.SubType = SubType;
if (SubType == SUBTYPE_ACK)
pHdr80211->FC.Type = BTYPE_CNTL;
pHdr80211->FC.ToDs = ToDs;
COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
}