/*
 *************************************************************************
 * 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);
}
