upload tizen1.0 source
[kernel/linux-2.6.36.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         cmm_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 u8 A_BAND_REGION_0_CHANNEL_LIST[] =
61     { 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 };
62 u8 A_BAND_REGION_1_CHANNEL_LIST[] =
63     { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
64 132, 136, 140 };
65 u8 A_BAND_REGION_2_CHANNEL_LIST[] = { 36, 40, 44, 48, 52, 56, 60, 64 };
66 u8 A_BAND_REGION_3_CHANNEL_LIST[] = { 52, 56, 60, 64, 149, 153, 157, 161 };
67 u8 A_BAND_REGION_4_CHANNEL_LIST[] = { 149, 153, 157, 161, 165 };
68 u8 A_BAND_REGION_5_CHANNEL_LIST[] = { 149, 153, 157, 161 };
69 u8 A_BAND_REGION_6_CHANNEL_LIST[] = { 36, 40, 44, 48 };
70 u8 A_BAND_REGION_7_CHANNEL_LIST[] =
71     { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
72 132, 136, 140, 149, 153, 157, 161, 165, 169, 173 };
73 u8 A_BAND_REGION_8_CHANNEL_LIST[] = { 52, 56, 60, 64 };
74 u8 A_BAND_REGION_9_CHANNEL_LIST[] =
75     { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140,
76 149, 153, 157, 161, 165 };
77 u8 A_BAND_REGION_10_CHANNEL_LIST[] =
78     { 36, 40, 44, 48, 149, 153, 157, 161, 165 };
79 u8 A_BAND_REGION_11_CHANNEL_LIST[] =
80     { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153,
81 157, 161 };
82 u8 A_BAND_REGION_12_CHANNEL_LIST[] =
83     { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
84 132, 136, 140 };
85 u8 A_BAND_REGION_13_CHANNEL_LIST[] =
86     { 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
87 149, 153, 157, 161 };
88 u8 A_BAND_REGION_14_CHANNEL_LIST[] =
89     { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
90 153, 157, 161, 165 };
91 u8 A_BAND_REGION_15_CHANNEL_LIST[] = { 149, 153, 157, 161, 165, 169, 173 };
92
93 /*BaSizeArray follows the 802.11n definition as MaxRxFactor.  2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8. */
94 u8 BaSizeArray[4] = { 8, 16, 32, 64 };
95
96 /*
97         ==========================================================================
98         Description:
99                 Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
100                 and 3) PHY-mode user selected.
101                 The outcome is used by driver when doing site survey.
102
103         IRQL = PASSIVE_LEVEL
104         IRQL = DISPATCH_LEVEL
105
106         ==========================================================================
107  */
108 void BuildChannelList(struct rt_rtmp_adapter *pAd)
109 {
110         u8 i, j, index = 0, num = 0;
111         u8 *pChannelList = NULL;
112
113         NdisZeroMemory(pAd->ChannelList,
114                        MAX_NUM_OF_CHANNELS * sizeof(struct rt_channel_tx_power));
115
116         /* if not 11a-only mode, channel list starts from 2.4Ghz band */
117         if ((pAd->CommonCfg.PhyMode != PHY_11A)
118             && (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED)
119             && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
120             ) {
121                 switch (pAd->CommonCfg.CountryRegion & 0x7f) {
122                 case REGION_0_BG_BAND:  /* 1 -11 */
123                         NdisMoveMemory(&pAd->ChannelList[index],
124                                        &pAd->TxPower[BG_BAND_REGION_0_START],
125                                        sizeof(struct rt_channel_tx_power) *
126                                        BG_BAND_REGION_0_SIZE);
127                         index += BG_BAND_REGION_0_SIZE;
128                         break;
129                 case REGION_1_BG_BAND:  /* 1 - 13 */
130                         NdisMoveMemory(&pAd->ChannelList[index],
131                                        &pAd->TxPower[BG_BAND_REGION_1_START],
132                                        sizeof(struct rt_channel_tx_power) *
133                                        BG_BAND_REGION_1_SIZE);
134                         index += BG_BAND_REGION_1_SIZE;
135                         break;
136                 case REGION_2_BG_BAND:  /* 10 - 11 */
137                         NdisMoveMemory(&pAd->ChannelList[index],
138                                        &pAd->TxPower[BG_BAND_REGION_2_START],
139                                        sizeof(struct rt_channel_tx_power) *
140                                        BG_BAND_REGION_2_SIZE);
141                         index += BG_BAND_REGION_2_SIZE;
142                         break;
143                 case REGION_3_BG_BAND:  /* 10 - 13 */
144                         NdisMoveMemory(&pAd->ChannelList[index],
145                                        &pAd->TxPower[BG_BAND_REGION_3_START],
146                                        sizeof(struct rt_channel_tx_power) *
147                                        BG_BAND_REGION_3_SIZE);
148                         index += BG_BAND_REGION_3_SIZE;
149                         break;
150                 case REGION_4_BG_BAND:  /* 14 */
151                         NdisMoveMemory(&pAd->ChannelList[index],
152                                        &pAd->TxPower[BG_BAND_REGION_4_START],
153                                        sizeof(struct rt_channel_tx_power) *
154                                        BG_BAND_REGION_4_SIZE);
155                         index += BG_BAND_REGION_4_SIZE;
156                         break;
157                 case REGION_5_BG_BAND:  /* 1 - 14 */
158                         NdisMoveMemory(&pAd->ChannelList[index],
159                                        &pAd->TxPower[BG_BAND_REGION_5_START],
160                                        sizeof(struct rt_channel_tx_power) *
161                                        BG_BAND_REGION_5_SIZE);
162                         index += BG_BAND_REGION_5_SIZE;
163                         break;
164                 case REGION_6_BG_BAND:  /* 3 - 9 */
165                         NdisMoveMemory(&pAd->ChannelList[index],
166                                        &pAd->TxPower[BG_BAND_REGION_6_START],
167                                        sizeof(struct rt_channel_tx_power) *
168                                        BG_BAND_REGION_6_SIZE);
169                         index += BG_BAND_REGION_6_SIZE;
170                         break;
171                 case REGION_7_BG_BAND:  /* 5 - 13 */
172                         NdisMoveMemory(&pAd->ChannelList[index],
173                                        &pAd->TxPower[BG_BAND_REGION_7_START],
174                                        sizeof(struct rt_channel_tx_power) *
175                                        BG_BAND_REGION_7_SIZE);
176                         index += BG_BAND_REGION_7_SIZE;
177                         break;
178                 case REGION_31_BG_BAND: /* 1 - 14 */
179                         NdisMoveMemory(&pAd->ChannelList[index],
180                                        &pAd->TxPower[BG_BAND_REGION_31_START],
181                                        sizeof(struct rt_channel_tx_power) *
182                                        BG_BAND_REGION_31_SIZE);
183                         index += BG_BAND_REGION_31_SIZE;
184                         break;
185                 default:        /* Error. should never happen */
186                         break;
187                 }
188                 for (i = 0; i < index; i++)
189                         pAd->ChannelList[i].MaxTxPwr = 20;
190         }
191
192         if ((pAd->CommonCfg.PhyMode == PHY_11A)
193             || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
194             || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)
195             || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
196             || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
197             || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
198             ) {
199                 switch (pAd->CommonCfg.CountryRegionForABand & 0x7f) {
200                 case REGION_0_A_BAND:
201                         num =
202                             sizeof(A_BAND_REGION_0_CHANNEL_LIST) /
203                             sizeof(u8);
204                         pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
205                         break;
206                 case REGION_1_A_BAND:
207                         num =
208                             sizeof(A_BAND_REGION_1_CHANNEL_LIST) /
209                             sizeof(u8);
210                         pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
211                         break;
212                 case REGION_2_A_BAND:
213                         num =
214                             sizeof(A_BAND_REGION_2_CHANNEL_LIST) /
215                             sizeof(u8);
216                         pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
217                         break;
218                 case REGION_3_A_BAND:
219                         num =
220                             sizeof(A_BAND_REGION_3_CHANNEL_LIST) /
221                             sizeof(u8);
222                         pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
223                         break;
224                 case REGION_4_A_BAND:
225                         num =
226                             sizeof(A_BAND_REGION_4_CHANNEL_LIST) /
227                             sizeof(u8);
228                         pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
229                         break;
230                 case REGION_5_A_BAND:
231                         num =
232                             sizeof(A_BAND_REGION_5_CHANNEL_LIST) /
233                             sizeof(u8);
234                         pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
235                         break;
236                 case REGION_6_A_BAND:
237                         num =
238                             sizeof(A_BAND_REGION_6_CHANNEL_LIST) /
239                             sizeof(u8);
240                         pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
241                         break;
242                 case REGION_7_A_BAND:
243                         num =
244                             sizeof(A_BAND_REGION_7_CHANNEL_LIST) /
245                             sizeof(u8);
246                         pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
247                         break;
248                 case REGION_8_A_BAND:
249                         num =
250                             sizeof(A_BAND_REGION_8_CHANNEL_LIST) /
251                             sizeof(u8);
252                         pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
253                         break;
254                 case REGION_9_A_BAND:
255                         num =
256                             sizeof(A_BAND_REGION_9_CHANNEL_LIST) /
257                             sizeof(u8);
258                         pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
259                         break;
260
261                 case REGION_10_A_BAND:
262                         num =
263                             sizeof(A_BAND_REGION_10_CHANNEL_LIST) /
264                             sizeof(u8);
265                         pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
266                         break;
267
268                 case REGION_11_A_BAND:
269                         num =
270                             sizeof(A_BAND_REGION_11_CHANNEL_LIST) /
271                             sizeof(u8);
272                         pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
273                         break;
274                 case REGION_12_A_BAND:
275                         num =
276                             sizeof(A_BAND_REGION_12_CHANNEL_LIST) /
277                             sizeof(u8);
278                         pChannelList = A_BAND_REGION_12_CHANNEL_LIST;
279                         break;
280                 case REGION_13_A_BAND:
281                         num =
282                             sizeof(A_BAND_REGION_13_CHANNEL_LIST) /
283                             sizeof(u8);
284                         pChannelList = A_BAND_REGION_13_CHANNEL_LIST;
285                         break;
286                 case REGION_14_A_BAND:
287                         num =
288                             sizeof(A_BAND_REGION_14_CHANNEL_LIST) /
289                             sizeof(u8);
290                         pChannelList = A_BAND_REGION_14_CHANNEL_LIST;
291                         break;
292                 case REGION_15_A_BAND:
293                         num =
294                             sizeof(A_BAND_REGION_15_CHANNEL_LIST) /
295                             sizeof(u8);
296                         pChannelList = A_BAND_REGION_15_CHANNEL_LIST;
297                         break;
298                 default:        /* Error. should never happen */
299                         DBGPRINT(RT_DEBUG_WARN,
300                                  ("countryregion=%d not support",
301                                   pAd->CommonCfg.CountryRegionForABand));
302                         break;
303                 }
304
305                 if (num != 0) {
306                         u8 RadarCh[15] =
307                             { 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124,
308                     128, 132, 136, 140 };
309                         for (i = 0; i < num; i++) {
310                                 for (j = 0; j < MAX_NUM_OF_CHANNELS; j++) {
311                                         if (pChannelList[i] ==
312                                             pAd->TxPower[j].Channel)
313                                                 NdisMoveMemory(&pAd->
314                                                                ChannelList[index
315                                                                            + i],
316                                                                &pAd->TxPower[j],
317                                                                sizeof
318                                                                (struct rt_channel_tx_power));
319                                 }
320                                 for (j = 0; j < 15; j++) {
321                                         if (pChannelList[i] == RadarCh[j])
322                                                 pAd->ChannelList[index +
323                                                                  i].DfsReq =
324                                                     TRUE;
325                                 }
326                                 pAd->ChannelList[index + i].MaxTxPwr = 20;
327                         }
328                         index += num;
329                 }
330         }
331
332         pAd->ChannelListNum = index;
333         DBGPRINT(RT_DEBUG_TRACE,
334                  ("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
335                   pAd->CommonCfg.CountryRegion,
336                   pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType,
337                   pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
338 #ifdef DBG
339         for (i = 0; i < pAd->ChannelListNum; i++) {
340                 DBGPRINT_RAW(RT_DEBUG_TRACE,
341                              ("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ",
342                               pAd->ChannelList[i].Channel,
343                               pAd->ChannelList[i].Power,
344                               pAd->ChannelList[i].Power2));
345         }
346 #endif
347 }
348
349 /*
350         ==========================================================================
351         Description:
352                 This routine return the first channel number according to the country
353                 code selection and RF IC selection (signal band or dual band). It is called
354                 whenever driver need to start a site survey of all supported channels.
355         Return:
356                 ch - the first channel number of current country code setting
357
358         IRQL = PASSIVE_LEVEL
359
360         ==========================================================================
361  */
362 u8 FirstChannel(struct rt_rtmp_adapter *pAd)
363 {
364         return pAd->ChannelList[0].Channel;
365 }
366
367 /*
368         ==========================================================================
369         Description:
370                 This routine returns the next channel number. This routine is called
371                 during driver need to start a site survey of all supported channels.
372         Return:
373                 next_channel - the next channel number valid in current country code setting.
374         Note:
375                 return 0 if no more next channel
376         ==========================================================================
377  */
378 u8 NextChannel(struct rt_rtmp_adapter *pAd, u8 channel)
379 {
380         int i;
381         u8 next_channel = 0;
382
383         for (i = 0; i < (pAd->ChannelListNum - 1); i++)
384                 if (channel == pAd->ChannelList[i].Channel) {
385                         next_channel = pAd->ChannelList[i + 1].Channel;
386                         break;
387                 }
388         return next_channel;
389 }
390
391 /*
392         ==========================================================================
393         Description:
394                 This routine is for Cisco Compatible Extensions 2.X
395                 Spec31. AP Control of Client Transmit Power
396         Return:
397                 None
398         Note:
399            Required by Aironet dBm(mW)
400                    0dBm(1mW),   1dBm(5mW), 13dBm(20mW), 15dBm(30mW),
401                   17dBm(50mw), 20dBm(100mW)
402
403            We supported
404                    3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%),
405                   14dBm(75%),   15dBm(100%)
406
407                 The client station's actual transmit power shall be within +/- 5dB of
408                 the minimum value or next lower value.
409         ==========================================================================
410  */
411 void ChangeToCellPowerLimit(struct rt_rtmp_adapter *pAd,
412                             u8 AironetCellPowerLimit)
413 {
414         /*valud 0xFF means that hasn't found power limit information */
415         /*from the AP's Beacon/Probe response. */
416         if (AironetCellPowerLimit == 0xFF)
417                 return;
418
419         if (AironetCellPowerLimit < 6)  /*Used Lowest Power Percentage. */
420                 pAd->CommonCfg.TxPowerPercentage = 6;
421         else if (AironetCellPowerLimit < 9)
422                 pAd->CommonCfg.TxPowerPercentage = 10;
423         else if (AironetCellPowerLimit < 12)
424                 pAd->CommonCfg.TxPowerPercentage = 25;
425         else if (AironetCellPowerLimit < 14)
426                 pAd->CommonCfg.TxPowerPercentage = 50;
427         else if (AironetCellPowerLimit < 15)
428                 pAd->CommonCfg.TxPowerPercentage = 75;
429         else
430                 pAd->CommonCfg.TxPowerPercentage = 100; /*else used maximum */
431
432         if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
433                 pAd->CommonCfg.TxPowerPercentage =
434                     pAd->CommonCfg.TxPowerDefault;
435
436 }
437
438 char ConvertToRssi(struct rt_rtmp_adapter *pAd, char Rssi, u8 RssiNumber)
439 {
440         u8 RssiOffset, LNAGain;
441
442         /* Rssi equals to zero should be an invalid value */
443         if (Rssi == 0)
444                 return -99;
445
446         LNAGain = GET_LNA_GAIN(pAd);
447         if (pAd->LatchRfRegs.Channel > 14) {
448                 if (RssiNumber == 0)
449                         RssiOffset = pAd->ARssiOffset0;
450                 else if (RssiNumber == 1)
451                         RssiOffset = pAd->ARssiOffset1;
452                 else
453                         RssiOffset = pAd->ARssiOffset2;
454         } else {
455                 if (RssiNumber == 0)
456                         RssiOffset = pAd->BGRssiOffset0;
457                 else if (RssiNumber == 1)
458                         RssiOffset = pAd->BGRssiOffset1;
459                 else
460                         RssiOffset = pAd->BGRssiOffset2;
461         }
462
463         return (-12 - RssiOffset - LNAGain - Rssi);
464 }
465
466 /*
467         ==========================================================================
468         Description:
469                 Scan next channel
470         ==========================================================================
471  */
472 void ScanNextChannel(struct rt_rtmp_adapter *pAd)
473 {
474         struct rt_header_802_11 Hdr80211;
475         u8 *pOutBuffer = NULL;
476         int NStatus;
477         unsigned long FrameLen = 0;
478         u8 SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
479         u16 Status;
480         struct rt_header_802_11 * pHdr80211;
481         u32 ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
482
483         {
484                 if (MONITOR_ON(pAd))
485                         return;
486         }
487
488         if (pAd->MlmeAux.Channel == 0) {
489                 if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
490                     && (INFRA_ON(pAd)
491                         || (pAd->OpMode == OPMODE_AP))
492                     ) {
493                         AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel,
494                                           FALSE);
495                         AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
496                         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
497                         BBPValue &= (~0x18);
498                         BBPValue |= 0x10;
499                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
500                         DBGPRINT(RT_DEBUG_TRACE,
501                                  ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",
502                                   pAd->CommonCfg.CentralChannel,
503                                   pAd->ScanTab.BssNr));
504                 } else {
505                         AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
506                         AsicLockChannel(pAd, pAd->CommonCfg.Channel);
507                         DBGPRINT(RT_DEBUG_TRACE,
508                                  ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",
509                                   pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
510                 }
511
512                 {
513                         /* */
514                         /* To prevent data lost. */
515                         /* Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. */
516                         /* Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done */
517                         /* */
518                         if (OPSTATUS_TEST_FLAG
519                             (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
520                             && (INFRA_ON(pAd))) {
521                                 NStatus =
522                                     MlmeAllocateMemory(pAd,
523                                                        (void *)& pOutBuffer);
524                                 if (NStatus == NDIS_STATUS_SUCCESS) {
525                                         pHdr80211 = (struct rt_header_802_11 *) pOutBuffer;
526                                         MgtMacHeaderInit(pAd, pHdr80211,
527                                                          SUBTYPE_NULL_FUNC, 1,
528                                                          pAd->CommonCfg.Bssid,
529                                                          pAd->CommonCfg.Bssid);
530                                         pHdr80211->Duration = 0;
531                                         pHdr80211->FC.Type = BTYPE_DATA;
532                                         pHdr80211->FC.PwrMgmt =
533                                             (pAd->StaCfg.Psm == PWR_SAVE);
534
535                                         /* Send using priority queue */
536                                         MiniportMMRequest(pAd, 0, pOutBuffer,
537                                                           sizeof
538                                                           (struct rt_header_802_11));
539                                         DBGPRINT(RT_DEBUG_TRACE,
540                                                  ("MlmeScanReqAction -- Send PSM Data frame\n"));
541                                         MlmeFreeMemory(pAd, pOutBuffer);
542                                         RTMPusecDelay(5000);
543                                 }
544                         }
545
546                         pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
547                         Status = MLME_SUCCESS;
548                         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF,
549                                     2, &Status);
550                 }
551
552                 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
553         }
554 #ifdef RTMP_MAC_USB
555         else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
556                  && (pAd->OpMode == OPMODE_STA)) {
557                 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
558                 MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
559         }
560 #endif /* RTMP_MAC_USB // */
561         else {
562                 {
563                         /* BBP and RF are not accessible in PS mode, we has to wake them up first */
564                         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
565                                 AsicForceWakeup(pAd, TRUE);
566
567                         /* leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON */
568                         if (pAd->StaCfg.Psm == PWR_SAVE)
569                                 RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
570                 }
571
572                 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
573                 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
574
575                 {
576                         if (pAd->MlmeAux.Channel > 14) {
577                                 if ((pAd->CommonCfg.bIEEE80211H == 1)
578                                     && RadarChannelCheck(pAd,
579                                                          pAd->MlmeAux.
580                                                          Channel)) {
581                                         ScanType = SCAN_PASSIVE;
582                                         ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
583                                 }
584                         }
585                 }
586
587                 /*Global country domain(ch1-11:active scan, ch12-14 passive scan) */
588                 if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12)
589                     && ((pAd->CommonCfg.CountryRegion & 0x7f) ==
590                         REGION_31_BG_BAND)) {
591                         ScanType = SCAN_PASSIVE;
592                 }
593                 /* We need to shorten active scan time in order for WZC connect issue */
594                 /* Chnage the channel scan time for CISCO stuff based on its IAPP announcement */
595                 if (ScanType == FAST_SCAN_ACTIVE)
596                         RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
597                                      FAST_ACTIVE_SCAN_TIME);
598                 else            /* must be SCAN_PASSIVE or SCAN_ACTIVE */
599                 {
600                         if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
601                             || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)
602                             || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
603                             ) {
604                                 if (pAd->MlmeAux.Channel > 14)
605                                         RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
606                                                      ScanTimeIn5gChannel);
607                                 else
608                                         RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
609                                                      MIN_CHANNEL_TIME);
610                         } else
611                                 RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
612                                              MAX_CHANNEL_TIME);
613                 }
614
615                 if ((ScanType == SCAN_ACTIVE)
616                     || (ScanType == FAST_SCAN_ACTIVE)
617                     ) {
618                         NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
619                         if (NStatus != NDIS_STATUS_SUCCESS) {
620                                 DBGPRINT(RT_DEBUG_TRACE,
621                                          ("SYNC - ScanNextChannel() allocate memory fail\n"));
622
623                                 {
624                                         pAd->Mlme.SyncMachine.CurrState =
625                                             SYNC_IDLE;
626                                         Status = MLME_FAIL_NO_RESOURCE;
627                                         MlmeEnqueue(pAd,
628                                                     MLME_CNTL_STATE_MACHINE,
629                                                     MT2_SCAN_CONF, 2, &Status);
630                                 }
631
632                                 return;
633                         }
634                         /* There is no need to send broadcast probe request if active scan is in effect. */
635                         if ((ScanType == SCAN_ACTIVE)
636                             || (ScanType == FAST_SCAN_ACTIVE)
637                             )
638                                 SsidLen = pAd->MlmeAux.SsidLen;
639                         else
640                                 SsidLen = 0;
641
642                         MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
643                                          BROADCAST_ADDR, BROADCAST_ADDR);
644                         MakeOutgoingFrame(pOutBuffer, &FrameLen,
645                                           sizeof(struct rt_header_802_11), &Hdr80211, 1,
646                                           &SsidIe, 1, &SsidLen, SsidLen,
647                                           pAd->MlmeAux.Ssid, 1, &SupRateIe, 1,
648                                           &pAd->CommonCfg.SupRateLen,
649                                           pAd->CommonCfg.SupRateLen,
650                                           pAd->CommonCfg.SupRate, END_OF_ARGS);
651
652                         if (pAd->CommonCfg.ExtRateLen) {
653                                 unsigned long Tmp;
654                                 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
655                                                   1, &ExtRateIe,
656                                                   1, &pAd->CommonCfg.ExtRateLen,
657                                                   pAd->CommonCfg.ExtRateLen,
658                                                   pAd->CommonCfg.ExtRate,
659                                                   END_OF_ARGS);
660                                 FrameLen += Tmp;
661                         }
662
663                         if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
664                                 unsigned long Tmp;
665                                 u8 HtLen;
666                                 u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
667
668                                 if (pAd->bBroadComHT == TRUE) {
669                                         HtLen =
670                                             pAd->MlmeAux.HtCapabilityLen + 4;
671
672                                         MakeOutgoingFrame(pOutBuffer + FrameLen,
673                                                           &Tmp, 1, &WpaIe, 1,
674                                                           &HtLen, 4,
675                                                           &BROADCOM[0],
676                                                           pAd->MlmeAux.
677                                                           HtCapabilityLen,
678                                                           &pAd->MlmeAux.
679                                                           HtCapability,
680                                                           END_OF_ARGS);
681                                 } else {
682                                         HtLen = pAd->MlmeAux.HtCapabilityLen;
683
684                                         MakeOutgoingFrame(pOutBuffer + FrameLen,
685                                                           &Tmp, 1, &HtCapIe, 1,
686                                                           &HtLen, HtLen,
687                                                           &pAd->CommonCfg.
688                                                           HtCapability,
689                                                           END_OF_ARGS);
690                                 }
691                                 FrameLen += Tmp;
692                         }
693
694                         MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
695                         MlmeFreeMemory(pAd, pOutBuffer);
696                 }
697                 /* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse */
698
699                 pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
700         }
701 }
702
703 void MgtProbReqMacHeaderInit(struct rt_rtmp_adapter *pAd,
704                              struct rt_header_802_11 * pHdr80211,
705                              u8 SubType,
706                              u8 ToDs, u8 *pDA, u8 *pBssid)
707 {
708         NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
709
710         pHdr80211->FC.Type = BTYPE_MGMT;
711         pHdr80211->FC.SubType = SubType;
712         if (SubType == SUBTYPE_ACK)
713                 pHdr80211->FC.Type = BTYPE_CNTL;
714         pHdr80211->FC.ToDs = ToDs;
715         COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
716         COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
717         COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
718 }