blob: f84194da47bce9e5b93f58c4deb7050c0fff73b8 [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:
cmm_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. */
u8 A_BAND_REGION_0_CHANNEL_LIST[] =
{ 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 };
u8 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 };
u8 A_BAND_REGION_2_CHANNEL_LIST[] = { 36, 40, 44, 48, 52, 56, 60, 64 };
u8 A_BAND_REGION_3_CHANNEL_LIST[] = { 52, 56, 60, 64, 149, 153, 157, 161 };
u8 A_BAND_REGION_4_CHANNEL_LIST[] = { 149, 153, 157, 161, 165 };
u8 A_BAND_REGION_5_CHANNEL_LIST[] = { 149, 153, 157, 161 };
u8 A_BAND_REGION_6_CHANNEL_LIST[] = { 36, 40, 44, 48 };
u8 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, 169, 173 };
u8 A_BAND_REGION_8_CHANNEL_LIST[] = { 52, 56, 60, 64 };
u8 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 };
u8 A_BAND_REGION_10_CHANNEL_LIST[] =
{ 36, 40, 44, 48, 149, 153, 157, 161, 165 };
u8 A_BAND_REGION_11_CHANNEL_LIST[] =
{ 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153,
157, 161 };
u8 A_BAND_REGION_12_CHANNEL_LIST[] =
{ 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
132, 136, 140 };
u8 A_BAND_REGION_13_CHANNEL_LIST[] =
{ 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
149, 153, 157, 161 };
u8 A_BAND_REGION_14_CHANNEL_LIST[] =
{ 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
153, 157, 161, 165 };
u8 A_BAND_REGION_15_CHANNEL_LIST[] = { 149, 153, 157, 161, 165, 169, 173 };
/*BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8. */
u8 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(struct rt_rtmp_adapter *pAd)
{
u8 i, j, index = 0, num = 0;
u8 *pChannelList = NULL;
NdisZeroMemory(pAd->ChannelList,
MAX_NUM_OF_CHANNELS * sizeof(struct rt_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(struct rt_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(struct rt_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(struct rt_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(struct rt_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(struct rt_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(struct rt_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(struct rt_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(struct rt_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(struct rt_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(u8);
pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
break;
case REGION_1_A_BAND:
num =
sizeof(A_BAND_REGION_1_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
break;
case REGION_2_A_BAND:
num =
sizeof(A_BAND_REGION_2_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
break;
case REGION_3_A_BAND:
num =
sizeof(A_BAND_REGION_3_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
break;
case REGION_4_A_BAND:
num =
sizeof(A_BAND_REGION_4_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
break;
case REGION_5_A_BAND:
num =
sizeof(A_BAND_REGION_5_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
break;
case REGION_6_A_BAND:
num =
sizeof(A_BAND_REGION_6_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
break;
case REGION_7_A_BAND:
num =
sizeof(A_BAND_REGION_7_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
break;
case REGION_8_A_BAND:
num =
sizeof(A_BAND_REGION_8_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
break;
case REGION_9_A_BAND:
num =
sizeof(A_BAND_REGION_9_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
break;
case REGION_10_A_BAND:
num =
sizeof(A_BAND_REGION_10_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
break;
case REGION_11_A_BAND:
num =
sizeof(A_BAND_REGION_11_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
break;
case REGION_12_A_BAND:
num =
sizeof(A_BAND_REGION_12_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_12_CHANNEL_LIST;
break;
case REGION_13_A_BAND:
num =
sizeof(A_BAND_REGION_13_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_13_CHANNEL_LIST;
break;
case REGION_14_A_BAND:
num =
sizeof(A_BAND_REGION_14_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_14_CHANNEL_LIST;
break;
case REGION_15_A_BAND:
num =
sizeof(A_BAND_REGION_15_CHANNEL_LIST) /
sizeof(u8);
pChannelList = A_BAND_REGION_15_CHANNEL_LIST;
break;
default: /* Error. should never happen */
DBGPRINT(RT_DEBUG_WARN,
("countryregion=%d not support",
pAd->CommonCfg.CountryRegionForABand));
break;
}
if (num != 0) {
u8 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
(struct rt_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
==========================================================================
*/
u8 FirstChannel(struct rt_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
==========================================================================
*/
u8 NextChannel(struct rt_rtmp_adapter *pAd, u8 channel)
{
int i;
u8 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(struct rt_rtmp_adapter *pAd,
u8 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(struct rt_rtmp_adapter *pAd, char Rssi, u8 RssiNumber)
{
u8 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(struct rt_rtmp_adapter *pAd)
{
struct rt_header_802_11 Hdr80211;
u8 *pOutBuffer = NULL;
int NStatus;
unsigned long FrameLen = 0;
u8 SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
u16 Status;
struct rt_header_802_11 * pHdr80211;
u32 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,
(void *)& pOutBuffer);
if (NStatus == NDIS_STATUS_SUCCESS) {
pHdr80211 = (struct rt_header_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
(struct rt_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 RTMP_MAC_USB
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 /* RTMP_MAC_USB // */
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))
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, 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 /* 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)
) {
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(struct rt_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) {
unsigned long 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) {
unsigned long Tmp;
u8 HtLen;
u8 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(struct rt_rtmp_adapter *pAd,
struct rt_header_802_11 * pHdr80211,
u8 SubType,
u8 ToDs, u8 *pDA, u8 *pBssid)
{
NdisZeroMemory(pHdr80211, sizeof(struct rt_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);
}