Linux-libre 2.6.32.54-gnu1
[librecmc/linux-libre.git] / drivers / staging / rt2860 / common / cmm_sync.c
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.
60 UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
61 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};
62 UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
63 UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
64 UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
65 UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
66 UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
67 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};
68 UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
69 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};
70 UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
71 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};
72
73 //BaSizeArray follows the 802.11n definition as MaxRxFactor.  2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
74 UCHAR 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  */
88 VOID 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  */
254 UCHAR 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  */
271 UCHAR 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  */
307 VOID 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
334 CHAR    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  */
374 VOID 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
601 VOID 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