linux/drivers/staging/rt2860/common/cmm_sync.c
<<
>>
Prefs
   1/*
   2 *************************************************************************
   3 * Ralink Tech Inc.
   4 * 5F., No.36, Taiyuan St., Jhubei City,
   5 * Hsinchu County 302,
   6 * Taiwan, R.O.C.
   7 *
   8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
   9 *
  10 * This program is free software; you can redistribute it and/or modify  *
  11 * it under the terms of the GNU General Public License as published by  *
  12 * the Free Software Foundation; either version 2 of the License, or     *
  13 * (at your option) any later version.                                   *
  14 *                                                                       *
  15 * This program is distributed in the hope that it will be useful,       *
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  18 * GNU General Public License for more details.                          *
  19 *                                                                       *
  20 * You should have received a copy of the GNU General Public License     *
  21 * along with this program; if not, write to the                         *
  22 * Free Software Foundation, Inc.,                                       *
  23 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  24 *                                                                       *
  25 *************************************************************************
  26
  27        Module Name:
  28        sync.c
  29
  30        Abstract:
  31
  32        Revision History:
  33        Who                     When                    What
  34        --------        ----------              ----------------------------------------------
  35        John Chang      2004-09-01      modified for rt2561/2661
  36*/
  37#include "../rt_config.h"
  38
  39// 2.4 Ghz channel plan index in the TxPower arrays.
  40#define BG_BAND_REGION_0_START  0                       // 1,2,3,4,5,6,7,8,9,10,11
  41#define BG_BAND_REGION_0_SIZE   11
  42#define BG_BAND_REGION_1_START  0                       // 1,2,3,4,5,6,7,8,9,10,11,12,13
  43#define BG_BAND_REGION_1_SIZE   13
  44#define BG_BAND_REGION_2_START  9                       // 10,11
  45#define BG_BAND_REGION_2_SIZE   2
  46#define BG_BAND_REGION_3_START  9                       // 10,11,12,13
  47#define BG_BAND_REGION_3_SIZE   4
  48#define BG_BAND_REGION_4_START  13                      // 14
  49#define BG_BAND_REGION_4_SIZE   1
  50#define BG_BAND_REGION_5_START  0                       // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
  51#define BG_BAND_REGION_5_SIZE   14
  52#define BG_BAND_REGION_6_START  2                       // 3,4,5,6,7,8,9
  53#define BG_BAND_REGION_6_SIZE   7
  54#define BG_BAND_REGION_7_START  4                       // 5,6,7,8,9,10,11,12,13
  55#define BG_BAND_REGION_7_SIZE   9
  56#define BG_BAND_REGION_31_START 0                       // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
  57#define BG_BAND_REGION_31_SIZE  14
  58
  59// 5 Ghz channel plan index in the TxPower arrays.
  60UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
  61UCHAR 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};
  62UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
  63UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
  64UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
  65UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
  66UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
  67UCHAR 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};
  68UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
  69UCHAR 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};
  70UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
  71UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
  72
  73//BaSizeArray follows the 802.11n definition as MaxRxFactor.  2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
  74UCHAR BaSizeArray[4] = {8,16,32,64};
  75
  76/*
  77        ==========================================================================
  78        Description:
  79                Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
  80                and 3) PHY-mode user selected.
  81                The outcome is used by driver when doing site survey.
  82
  83        IRQL = PASSIVE_LEVEL
  84        IRQL = DISPATCH_LEVEL
  85
  86        ==========================================================================
  87 */
  88VOID BuildChannelList(
  89        IN PRTMP_ADAPTER pAd)
  90{
  91        UCHAR i, j, index=0, num=0;
  92        PUCHAR  pChannelList = NULL;
  93
  94        NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
  95
  96        // if not 11a-only mode, channel list starts from 2.4Ghz band
  97        if ((pAd->CommonCfg.PhyMode != PHY_11A)
  98                && (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
  99        )
 100        {
 101                switch (pAd->CommonCfg.CountryRegion  & 0x7f)
 102                {
 103                        case REGION_0_BG_BAND:  // 1 -11
 104                                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
 105                                index += BG_BAND_REGION_0_SIZE;
 106                                break;
 107                        case REGION_1_BG_BAND:  // 1 - 13
 108                                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
 109                                index += BG_BAND_REGION_1_SIZE;
 110                                break;
 111                        case REGION_2_BG_BAND:  // 10 - 11
 112                                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
 113                                index += BG_BAND_REGION_2_SIZE;
 114                                break;
 115                        case REGION_3_BG_BAND:  // 10 - 13
 116                                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
 117                                index += BG_BAND_REGION_3_SIZE;
 118                                break;
 119                        case REGION_4_BG_BAND:  // 14
 120                                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
 121                                index += BG_BAND_REGION_4_SIZE;
 122                                break;
 123                        case REGION_5_BG_BAND:  // 1 - 14
 124                                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
 125                                index += BG_BAND_REGION_5_SIZE;
 126                                break;
 127                        case REGION_6_BG_BAND:  // 3 - 9
 128                                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
 129                                index += BG_BAND_REGION_6_SIZE;
 130                                break;
 131                        case REGION_7_BG_BAND:  // 5 - 13
 132                                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_7_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_7_SIZE);
 133                                index += BG_BAND_REGION_7_SIZE;
 134                                break;
 135                        case REGION_31_BG_BAND: // 1 - 14
 136                                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_31_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_31_SIZE);
 137                                index += BG_BAND_REGION_31_SIZE;
 138                                break;
 139                        default:            // Error. should never happen
 140                                break;
 141                }
 142                for (i=0; i<index; i++)
 143                        pAd->ChannelList[i].MaxTxPwr = 20;
 144        }
 145
 146        if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
 147                || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
 148                || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
 149        )
 150        {
 151                switch (pAd->CommonCfg.CountryRegionForABand & 0x7f)
 152                {
 153                        case REGION_0_A_BAND:
 154                                num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
 155                                pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
 156                                break;
 157                        case REGION_1_A_BAND:
 158                                num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
 159                                pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
 160                                break;
 161                        case REGION_2_A_BAND:
 162                                num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
 163                                pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
 164                                break;
 165                        case REGION_3_A_BAND:
 166                                num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
 167                                pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
 168                                break;
 169                        case REGION_4_A_BAND:
 170                                num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
 171                                pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
 172                                break;
 173                        case REGION_5_A_BAND:
 174                                num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
 175                                pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
 176                                break;
 177                        case REGION_6_A_BAND:
 178                                num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
 179                                pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
 180                                break;
 181                        case REGION_7_A_BAND:
 182                                num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
 183                                pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
 184                                break;
 185                        case REGION_8_A_BAND:
 186                                num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
 187                                pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
 188                                break;
 189                        case REGION_9_A_BAND:
 190                                num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
 191                                pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
 192                                break;
 193
 194                        case REGION_10_A_BAND:
 195                                num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
 196                                pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
 197                                break;
 198
 199                        case REGION_11_A_BAND:
 200                                num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
 201                                pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
 202                                break;
 203
 204                        default:            // Error. should never happen
 205                                DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
 206                                break;
 207                }
 208
 209                if (num != 0)
 210                {
 211                        UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
 212                        for (i=0; i<num; i++)
 213                        {
 214                                for (j=0; j<MAX_NUM_OF_CHANNELS; j++)
 215                                {
 216                                        if (pChannelList[i] == pAd->TxPower[j].Channel)
 217                                                NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER));
 218                                        }
 219                                for (j=0; j<15; j++)
 220                                {
 221                                        if (pChannelList[i] == RadarCh[j])
 222                                                pAd->ChannelList[index+i].DfsReq = TRUE;
 223                                }
 224                                pAd->ChannelList[index+i].MaxTxPwr = 20;
 225                        }
 226                        index += num;
 227                }
 228        }
 229
 230        pAd->ChannelListNum = index;
 231        DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
 232                pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
 233#ifdef DBG
 234        for (i=0;i<pAd->ChannelListNum;i++)
 235        {
 236                DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2));
 237        }
 238#endif
 239}
 240
 241/*
 242        ==========================================================================
 243        Description:
 244                This routine return the first channel number according to the country
 245                code selection and RF IC selection (signal band or dual band). It is called
 246                whenever driver need to start a site survey of all supported channels.
 247        Return:
 248                ch - the first channel number of current country code setting
 249
 250        IRQL = PASSIVE_LEVEL
 251
 252        ==========================================================================
 253 */
 254UCHAR FirstChannel(
 255        IN PRTMP_ADAPTER pAd)
 256{
 257        return pAd->ChannelList[0].Channel;
 258}
 259
 260/*
 261        ==========================================================================
 262        Description:
 263                This routine returns the next channel number. This routine is called
 264                during driver need to start a site survey of all supported channels.
 265        Return:
 266                next_channel - the next channel number valid in current country code setting.
 267        Note:
 268                return 0 if no more next channel
 269        ==========================================================================
 270 */
 271UCHAR NextChannel(
 272        IN PRTMP_ADAPTER pAd,
 273        IN UCHAR channel)
 274{
 275        int i;
 276        UCHAR next_channel = 0;
 277
 278        for (i = 0; i < (pAd->ChannelListNum - 1); i++)
 279                if (channel == pAd->ChannelList[i].Channel)
 280                {
 281                        next_channel = pAd->ChannelList[i+1].Channel;
 282                        break;
 283        }
 284        return next_channel;
 285}
 286
 287/*
 288        ==========================================================================
 289        Description:
 290                This routine is for Cisco Compatible Extensions 2.X
 291                Spec31. AP Control of Client Transmit Power
 292        Return:
 293                None
 294        Note:
 295           Required by Aironet dBm(mW)
 296                   0dBm(1mW),   1dBm(5mW), 13dBm(20mW), 15dBm(30mW),
 297                  17dBm(50mw), 20dBm(100mW)
 298
 299           We supported
 300                   3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%),
 301                  14dBm(75%),   15dBm(100%)
 302
 303                The client station's actual transmit power shall be within +/- 5dB of
 304                the minimum value or next lower value.
 305        ==========================================================================
 306 */
 307VOID ChangeToCellPowerLimit(
 308        IN PRTMP_ADAPTER pAd,
 309        IN UCHAR         AironetCellPowerLimit)
 310{
 311        //valud 0xFF means that hasn't found power limit information
 312        //from the AP's Beacon/Probe response.
 313        if (AironetCellPowerLimit == 0xFF)
 314                return;
 315
 316        if (AironetCellPowerLimit < 6) //Used Lowest Power Percentage.
 317                pAd->CommonCfg.TxPowerPercentage = 6;
 318        else if (AironetCellPowerLimit < 9)
 319                pAd->CommonCfg.TxPowerPercentage = 10;
 320        else if (AironetCellPowerLimit < 12)
 321                pAd->CommonCfg.TxPowerPercentage = 25;
 322        else if (AironetCellPowerLimit < 14)
 323                pAd->CommonCfg.TxPowerPercentage = 50;
 324        else if (AironetCellPowerLimit < 15)
 325                pAd->CommonCfg.TxPowerPercentage = 75;
 326        else
 327                pAd->CommonCfg.TxPowerPercentage = 100; //else used maximum
 328
 329        if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
 330                pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
 331
 332}
 333
 334CHAR    ConvertToRssi(
 335        IN PRTMP_ADAPTER pAd,
 336        IN      CHAR                    Rssi,
 337        IN  UCHAR   RssiNumber)
 338{
 339        UCHAR   RssiOffset, LNAGain;
 340
 341        // Rssi equals to zero should be an invalid value
 342        if (Rssi == 0)
 343                return -99;
 344
 345        LNAGain = GET_LNA_GAIN(pAd);
 346    if (pAd->LatchRfRegs.Channel > 14)
 347    {
 348        if (RssiNumber == 0)
 349                        RssiOffset = pAd->ARssiOffset0;
 350                else if (RssiNumber == 1)
 351                        RssiOffset = pAd->ARssiOffset1;
 352                else
 353                        RssiOffset = pAd->ARssiOffset2;
 354    }
 355    else
 356    {
 357        if (RssiNumber == 0)
 358                        RssiOffset = pAd->BGRssiOffset0;
 359                else if (RssiNumber == 1)
 360                        RssiOffset = pAd->BGRssiOffset1;
 361                else
 362                        RssiOffset = pAd->BGRssiOffset2;
 363    }
 364
 365    return (-12 - RssiOffset - LNAGain - Rssi);
 366}
 367
 368/*
 369        ==========================================================================
 370        Description:
 371                Scan next channel
 372        ==========================================================================
 373 */
 374VOID ScanNextChannel(
 375        IN PRTMP_ADAPTER pAd)
 376{
 377        HEADER_802_11   Hdr80211;
 378        PUCHAR          pOutBuffer = NULL;
 379        NDIS_STATUS     NStatus;
 380        ULONG           FrameLen = 0;
 381        UCHAR           SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
 382        USHORT          Status;
 383        PHEADER_802_11  pHdr80211;
 384        UINT                    ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
 385
 386        if (MONITOR_ON(pAd))
 387                return;
 388
 389        if (pAd->MlmeAux.Channel == 0)
 390        {
 391                if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
 392                        && (INFRA_ON(pAd)
 393                                || (pAd->OpMode == OPMODE_AP))
 394                        )
 395                {
 396                        AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
 397                        AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
 398                        RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
 399                        BBPValue &= (~0x18);
 400                        BBPValue |= 0x10;
 401                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
 402                        DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
 403                }
 404                else
 405                {
 406                        AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
 407                        AsicLockChannel(pAd, pAd->CommonCfg.Channel);
 408                        DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
 409                }
 410
 411                {
 412                        //
 413                        // To prevent data lost.
 414                        // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
 415                        // Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done
 416                        //
 417                        if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
 418                        {
 419                                NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
 420                                if (NStatus     == NDIS_STATUS_SUCCESS)
 421                                {
 422                                        pHdr80211 = (PHEADER_802_11) pOutBuffer;
 423                                        MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
 424                                        pHdr80211->Duration = 0;
 425                                        pHdr80211->FC.Type = BTYPE_DATA;
 426                                        pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
 427
 428                                        // Send using priority queue
 429                                        MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
 430                                        DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n"));
 431                                        MlmeFreeMemory(pAd, pOutBuffer);
 432                                        RTMPusecDelay(5000);
 433                                }
 434                        }
 435
 436                        pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 437                        Status = MLME_SUCCESS;
 438                        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
 439                }
 440
 441                RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
 442        }
 443#ifdef RT2870
 444        else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
 445        {
 446                pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 447                MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
 448        }
 449#endif // RT2870 //
 450        else
 451        {
 452                {
 453                // BBP and RF are not accessible in PS mode, we has to wake them up first
 454                if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
 455#ifdef RT2860
 456                                AsicForceWakeup(pAd, FROM_TX);
 457#endif
 458#ifdef RT2870
 459                        AsicForceWakeup(pAd, TRUE);
 460#endif
 461                        // leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
 462                        if (pAd->StaCfg.Psm == PWR_SAVE)
 463                                MlmeSetPsmBit(pAd, PWR_ACTIVE);
 464                }
 465
 466                AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
 467                AsicLockChannel(pAd, pAd->MlmeAux.Channel);
 468
 469                {
 470                        if (pAd->MlmeAux.Channel > 14)
 471                        {
 472                                if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
 473                                {
 474                                        ScanType = SCAN_PASSIVE;
 475                                        ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
 476                                }
 477                        }
 478                }
 479
 480                //Global country domain(ch1-11:active scan, ch12-14 passive scan)
 481                if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND))
 482                {
 483                        ScanType = SCAN_PASSIVE;
 484                }
 485
 486                // We need to shorten active scan time in order for WZC connect issue
 487                // Chnage the channel scan time for CISCO stuff based on its IAPP announcement
 488                if (ScanType == FAST_SCAN_ACTIVE)
 489                        RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
 490                else if (((ScanType == SCAN_CISCO_ACTIVE) ||
 491                                (ScanType == SCAN_CISCO_PASSIVE) ||
 492                                (ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
 493                                (ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
 494                {
 495                        if (pAd->StaCfg.CCXScanTime < 25)
 496                                RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
 497                        else
 498                                RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
 499                }
 500                else // must be SCAN_PASSIVE or SCAN_ACTIVE
 501                {
 502                        if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
 503                                || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
 504                        )
 505                        {
 506                                if (pAd->MlmeAux.Channel > 14)
 507                                        RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
 508                                else
 509                                RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
 510                        }
 511                        else
 512                                RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
 513                }
 514
 515                if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ||
 516                        (ScanType == SCAN_CISCO_ACTIVE))
 517                {
 518                        NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
 519                        if (NStatus != NDIS_STATUS_SUCCESS)
 520                        {
 521                                DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
 522
 523                                {
 524                                        pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 525                                        Status = MLME_FAIL_NO_RESOURCE;
 526                                        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
 527                                }
 528
 529                                return;
 530                        }
 531
 532                        // There is no need to send broadcast probe request if active scan is in effect.
 533                        if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
 534                                )
 535                                SsidLen = pAd->MlmeAux.SsidLen;
 536                        else
 537                                SsidLen = 0;
 538
 539                        MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
 540                        MakeOutgoingFrame(pOutBuffer,               &FrameLen,
 541                                                          sizeof(HEADER_802_11),    &Hdr80211,
 542                                                          1,                        &SsidIe,
 543                                                          1,                        &SsidLen,
 544                                                          SsidLen,                              pAd->MlmeAux.Ssid,
 545                                                          1,                        &SupRateIe,
 546                                                          1,                        &pAd->CommonCfg.SupRateLen,
 547                                                          pAd->CommonCfg.SupRateLen,  pAd->CommonCfg.SupRate,
 548                                                          END_OF_ARGS);
 549
 550                        if (pAd->CommonCfg.ExtRateLen)
 551                        {
 552                                ULONG Tmp;
 553                                MakeOutgoingFrame(pOutBuffer + FrameLen,            &Tmp,
 554                                                                  1,                                &ExtRateIe,
 555                                                                  1,                                &pAd->CommonCfg.ExtRateLen,
 556                                                                  pAd->CommonCfg.ExtRateLen,          pAd->CommonCfg.ExtRate,
 557                                                                  END_OF_ARGS);
 558                                FrameLen += Tmp;
 559                        }
 560
 561                        if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
 562                        {
 563                                ULONG   Tmp;
 564                                UCHAR   HtLen;
 565                                UCHAR   BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
 566
 567                                if (pAd->bBroadComHT == TRUE)
 568                                {
 569                                        HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
 570
 571                                        MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
 572                                                                        1,                                &WpaIe,
 573                                                                        1,                                &HtLen,
 574                                                                        4,                                &BROADCOM[0],
 575                                                                        pAd->MlmeAux.HtCapabilityLen,     &pAd->MlmeAux.HtCapability,
 576                                                                        END_OF_ARGS);
 577                                }
 578                                else
 579                                {
 580                                        HtLen = pAd->MlmeAux.HtCapabilityLen;
 581
 582                                        MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
 583                                                                        1,                                &HtCapIe,
 584                                                                        1,                                &HtLen,
 585                                                                        HtLen,                            &pAd->CommonCfg.HtCapability,
 586                                                                        END_OF_ARGS);
 587                                }
 588                                FrameLen += Tmp;
 589                        }
 590
 591                        MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 592                        MlmeFreeMemory(pAd, pOutBuffer);
 593                }
 594
 595                // For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
 596
 597                pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
 598        }
 599}
 600
 601VOID MgtProbReqMacHeaderInit(
 602        IN      PRTMP_ADAPTER   pAd,
 603        IN OUT PHEADER_802_11 pHdr80211,
 604        IN UCHAR SubType,
 605        IN UCHAR ToDs,
 606        IN PUCHAR pDA,
 607        IN PUCHAR pBssid)
 608{
 609        NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
 610
 611        pHdr80211->FC.Type = BTYPE_MGMT;
 612        pHdr80211->FC.SubType = SubType;
 613        if (SubType == SUBTYPE_ACK)
 614                pHdr80211->FC.Type = BTYPE_CNTL;
 615        pHdr80211->FC.ToDs = ToDs;
 616        COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
 617        COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
 618        COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
 619}
 620
 621
 622