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 */
BuildChannelList(struct rt_rtmp_adapter * pAd)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 */
FirstChannel(struct rt_rtmp_adapter * pAd)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 */
NextChannel(struct rt_rtmp_adapter * pAd,u8 channel)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 */
ChangeToCellPowerLimit(struct rt_rtmp_adapter * pAd,u8 AironetCellPowerLimit)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
ConvertToRssi(struct rt_rtmp_adapter * pAd,char Rssi,u8 RssiNumber)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 */
ScanNextChannel(struct rt_rtmp_adapter * pAd)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 response */
698
699 pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
700 }
701 }
702
MgtProbReqMacHeaderInit(struct rt_rtmp_adapter * pAd,struct rt_header_802_11 * pHdr80211,u8 SubType,u8 ToDs,u8 * pDA,u8 * pBssid)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 }
719