Merge git://git.kernel.org/pub/scm/linux/kernel/git/joern/logfs
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / rt2860 / common / cmm_sync.c
CommitLineData
91980990
GKH
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:
ca97b838 28 cmm_sync.c
91980990
GKH
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
ec278fa2
BZ
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 */
91980990 41#define BG_BAND_REGION_0_SIZE 11
ec278fa2 42#define BG_BAND_REGION_1_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13 */
91980990 43#define BG_BAND_REGION_1_SIZE 13
ec278fa2 44#define BG_BAND_REGION_2_START 9 /* 10,11 */
91980990 45#define BG_BAND_REGION_2_SIZE 2
ec278fa2 46#define BG_BAND_REGION_3_START 9 /* 10,11,12,13 */
91980990 47#define BG_BAND_REGION_3_SIZE 4
ec278fa2 48#define BG_BAND_REGION_4_START 13 /* 14 */
91980990 49#define BG_BAND_REGION_4_SIZE 1
ec278fa2 50#define BG_BAND_REGION_5_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13,14 */
91980990 51#define BG_BAND_REGION_5_SIZE 14
ec278fa2 52#define BG_BAND_REGION_6_START 2 /* 3,4,5,6,7,8,9 */
91980990 53#define BG_BAND_REGION_6_SIZE 7
ec278fa2 54#define BG_BAND_REGION_7_START 4 /* 5,6,7,8,9,10,11,12,13 */
91980990 55#define BG_BAND_REGION_7_SIZE 9
ec278fa2 56#define BG_BAND_REGION_31_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13,14 */
91980990
GKH
57#define BG_BAND_REGION_31_SIZE 14
58
ec278fa2 59/* 5 Ghz channel plan index in the TxPower arrays. */
51126deb 60u8 A_BAND_REGION_0_CHANNEL_LIST[] =
96b3c83d 61 { 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 };
51126deb 62u8 A_BAND_REGION_1_CHANNEL_LIST[] =
96b3c83d
BZ
63 { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
64132, 136, 140 };
51126deb
BZ
65u8 A_BAND_REGION_2_CHANNEL_LIST[] = { 36, 40, 44, 48, 52, 56, 60, 64 };
66u8 A_BAND_REGION_3_CHANNEL_LIST[] = { 52, 56, 60, 64, 149, 153, 157, 161 };
67u8 A_BAND_REGION_4_CHANNEL_LIST[] = { 149, 153, 157, 161, 165 };
68u8 A_BAND_REGION_5_CHANNEL_LIST[] = { 149, 153, 157, 161 };
69u8 A_BAND_REGION_6_CHANNEL_LIST[] = { 36, 40, 44, 48 };
70u8 A_BAND_REGION_7_CHANNEL_LIST[] =
96b3c83d
BZ
71 { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
72132, 136, 140, 149, 153, 157, 161, 165, 169, 173 };
51126deb
BZ
73u8 A_BAND_REGION_8_CHANNEL_LIST[] = { 52, 56, 60, 64 };
74u8 A_BAND_REGION_9_CHANNEL_LIST[] =
96b3c83d
BZ
75 { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140,
76149, 153, 157, 161, 165 };
51126deb 77u8 A_BAND_REGION_10_CHANNEL_LIST[] =
96b3c83d 78 { 36, 40, 44, 48, 149, 153, 157, 161, 165 };
51126deb 79u8 A_BAND_REGION_11_CHANNEL_LIST[] =
96b3c83d
BZ
80 { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153,
81157, 161 };
51126deb 82u8 A_BAND_REGION_12_CHANNEL_LIST[] =
96b3c83d
BZ
83 { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
84132, 136, 140 };
51126deb 85u8 A_BAND_REGION_13_CHANNEL_LIST[] =
96b3c83d
BZ
86 { 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
87149, 153, 157, 161 };
51126deb 88u8 A_BAND_REGION_14_CHANNEL_LIST[] =
96b3c83d
BZ
89 { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
90153, 157, 161, 165 };
51126deb 91u8 A_BAND_REGION_15_CHANNEL_LIST[] = { 149, 153, 157, 161, 165, 169, 173 };
91980990 92
ec278fa2 93/*BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8. */
51126deb 94u8 BaSizeArray[4] = { 8, 16, 32, 64 };
91980990
GKH
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 */
62eb734b 108void BuildChannelList(struct rt_rtmp_adapter *pAd)
91980990 109{
51126deb
BZ
110 u8 i, j, index = 0, num = 0;
111 u8 *pChannelList = NULL;
91980990 112
96b3c83d 113 NdisZeroMemory(pAd->ChannelList,
62eb734b 114 MAX_NUM_OF_CHANNELS * sizeof(struct rt_channel_tx_power));
91980990 115
ec278fa2 116 /* if not 11a-only mode, channel list starts from 2.4Ghz band */
91980990 117 if ((pAd->CommonCfg.PhyMode != PHY_11A)
96b3c83d
BZ
118 && (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED)
119 && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
120 ) {
121 switch (pAd->CommonCfg.CountryRegion & 0x7f) {
ec278fa2 122 case REGION_0_BG_BAND: /* 1 -11 */
96b3c83d
BZ
123 NdisMoveMemory(&pAd->ChannelList[index],
124 &pAd->TxPower[BG_BAND_REGION_0_START],
62eb734b 125 sizeof(struct rt_channel_tx_power) *
96b3c83d
BZ
126 BG_BAND_REGION_0_SIZE);
127 index += BG_BAND_REGION_0_SIZE;
128 break;
ec278fa2 129 case REGION_1_BG_BAND: /* 1 - 13 */
96b3c83d
BZ
130 NdisMoveMemory(&pAd->ChannelList[index],
131 &pAd->TxPower[BG_BAND_REGION_1_START],
62eb734b 132 sizeof(struct rt_channel_tx_power) *
96b3c83d
BZ
133 BG_BAND_REGION_1_SIZE);
134 index += BG_BAND_REGION_1_SIZE;
135 break;
ec278fa2 136 case REGION_2_BG_BAND: /* 10 - 11 */
96b3c83d
BZ
137 NdisMoveMemory(&pAd->ChannelList[index],
138 &pAd->TxPower[BG_BAND_REGION_2_START],
62eb734b 139 sizeof(struct rt_channel_tx_power) *
96b3c83d
BZ
140 BG_BAND_REGION_2_SIZE);
141 index += BG_BAND_REGION_2_SIZE;
142 break;
ec278fa2 143 case REGION_3_BG_BAND: /* 10 - 13 */
96b3c83d
BZ
144 NdisMoveMemory(&pAd->ChannelList[index],
145 &pAd->TxPower[BG_BAND_REGION_3_START],
62eb734b 146 sizeof(struct rt_channel_tx_power) *
96b3c83d
BZ
147 BG_BAND_REGION_3_SIZE);
148 index += BG_BAND_REGION_3_SIZE;
149 break;
ec278fa2 150 case REGION_4_BG_BAND: /* 14 */
96b3c83d
BZ
151 NdisMoveMemory(&pAd->ChannelList[index],
152 &pAd->TxPower[BG_BAND_REGION_4_START],
62eb734b 153 sizeof(struct rt_channel_tx_power) *
96b3c83d
BZ
154 BG_BAND_REGION_4_SIZE);
155 index += BG_BAND_REGION_4_SIZE;
156 break;
ec278fa2 157 case REGION_5_BG_BAND: /* 1 - 14 */
96b3c83d
BZ
158 NdisMoveMemory(&pAd->ChannelList[index],
159 &pAd->TxPower[BG_BAND_REGION_5_START],
62eb734b 160 sizeof(struct rt_channel_tx_power) *
96b3c83d
BZ
161 BG_BAND_REGION_5_SIZE);
162 index += BG_BAND_REGION_5_SIZE;
163 break;
ec278fa2 164 case REGION_6_BG_BAND: /* 3 - 9 */
96b3c83d
BZ
165 NdisMoveMemory(&pAd->ChannelList[index],
166 &pAd->TxPower[BG_BAND_REGION_6_START],
62eb734b 167 sizeof(struct rt_channel_tx_power) *
96b3c83d
BZ
168 BG_BAND_REGION_6_SIZE);
169 index += BG_BAND_REGION_6_SIZE;
170 break;
ec278fa2 171 case REGION_7_BG_BAND: /* 5 - 13 */
96b3c83d
BZ
172 NdisMoveMemory(&pAd->ChannelList[index],
173 &pAd->TxPower[BG_BAND_REGION_7_START],
62eb734b 174 sizeof(struct rt_channel_tx_power) *
96b3c83d
BZ
175 BG_BAND_REGION_7_SIZE);
176 index += BG_BAND_REGION_7_SIZE;
177 break;
ec278fa2 178 case REGION_31_BG_BAND: /* 1 - 14 */
96b3c83d
BZ
179 NdisMoveMemory(&pAd->ChannelList[index],
180 &pAd->TxPower[BG_BAND_REGION_31_START],
62eb734b 181 sizeof(struct rt_channel_tx_power) *
96b3c83d
BZ
182 BG_BAND_REGION_31_SIZE);
183 index += BG_BAND_REGION_31_SIZE;
184 break;
ec278fa2 185 default: /* Error. should never happen */
96b3c83d 186 break;
91980990 187 }
96b3c83d 188 for (i = 0; i < index; i++)
91980990
GKH
189 pAd->ChannelList[i].MaxTxPwr = 20;
190 }
191
96b3c83d
BZ
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) /
51126deb 203 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 209 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 215 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 221 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 227 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 233 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 239 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 245 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 251 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 257 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 264 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 271 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 277 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 283 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 289 sizeof(u8);
96b3c83d
BZ
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) /
51126deb 295 sizeof(u8);
96b3c83d
BZ
296 pChannelList = A_BAND_REGION_15_CHANNEL_LIST;
297 break;
ec278fa2 298 default: /* Error. should never happen */
96b3c83d
BZ
299 DBGPRINT(RT_DEBUG_WARN,
300 ("countryregion=%d not support",
301 pAd->CommonCfg.CountryRegionForABand));
302 break;
91980990
GKH
303 }
304
96b3c83d 305 if (num != 0) {
51126deb 306 u8 RadarCh[15] =
96b3c83d
BZ
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
62eb734b 318 (struct rt_channel_tx_power));
96b3c83d
BZ
319 }
320 for (j = 0; j < 15; j++) {
91980990 321 if (pChannelList[i] == RadarCh[j])
96b3c83d
BZ
322 pAd->ChannelList[index +
323 i].DfsReq =
324 TRUE;
91980990 325 }
96b3c83d 326 pAd->ChannelList[index + i].MaxTxPwr = 20;
91980990
GKH
327 }
328 index += num;
329 }
330 }
331
332 pAd->ChannelListNum = index;
96b3c83d
BZ
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));
91980990 338#ifdef DBG
96b3c83d
BZ
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));
91980990
GKH
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 */
62eb734b 362u8 FirstChannel(struct rt_rtmp_adapter *pAd)
91980990
GKH
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 */
62eb734b 378u8 NextChannel(struct rt_rtmp_adapter *pAd, u8 channel)
91980990
GKH
379{
380 int i;
51126deb 381 u8 next_channel = 0;
91980990
GKH
382
383 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
96b3c83d
BZ
384 if (channel == pAd->ChannelList[i].Channel) {
385 next_channel = pAd->ChannelList[i + 1].Channel;
91980990 386 break;
96b3c83d 387 }
91980990
GKH
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 */
62eb734b 411void ChangeToCellPowerLimit(struct rt_rtmp_adapter *pAd,
51126deb 412 u8 AironetCellPowerLimit)
91980990 413{
ec278fa2
BZ
414 /*valud 0xFF means that hasn't found power limit information */
415 /*from the AP's Beacon/Probe response. */
91980990
GKH
416 if (AironetCellPowerLimit == 0xFF)
417 return;
418
ec278fa2 419 if (AironetCellPowerLimit < 6) /*Used Lowest Power Percentage. */
91980990
GKH
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
ec278fa2 430 pAd->CommonCfg.TxPowerPercentage = 100; /*else used maximum */
91980990
GKH
431
432 if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
96b3c83d
BZ
433 pAd->CommonCfg.TxPowerPercentage =
434 pAd->CommonCfg.TxPowerDefault;
91980990
GKH
435
436}
437
62eb734b 438char ConvertToRssi(struct rt_rtmp_adapter *pAd, char Rssi, u8 RssiNumber)
91980990 439{
51126deb 440 u8 RssiOffset, LNAGain;
91980990 441
ec278fa2 442 /* Rssi equals to zero should be an invalid value */
91980990
GKH
443 if (Rssi == 0)
444 return -99;
445
446 LNAGain = GET_LNA_GAIN(pAd);
96b3c83d
BZ
447 if (pAd->LatchRfRegs.Channel > 14) {
448 if (RssiNumber == 0)
91980990
GKH
449 RssiOffset = pAd->ARssiOffset0;
450 else if (RssiNumber == 1)
451 RssiOffset = pAd->ARssiOffset1;
452 else
453 RssiOffset = pAd->ARssiOffset2;
96b3c83d
BZ
454 } else {
455 if (RssiNumber == 0)
91980990
GKH
456 RssiOffset = pAd->BGRssiOffset0;
457 else if (RssiNumber == 1)
458 RssiOffset = pAd->BGRssiOffset1;
459 else
460 RssiOffset = pAd->BGRssiOffset2;
96b3c83d 461 }
91980990 462
96b3c83d 463 return (-12 - RssiOffset - LNAGain - Rssi);
91980990
GKH
464}
465
466/*
467 ==========================================================================
468 Description:
469 Scan next channel
470 ==========================================================================
471 */
62eb734b 472void ScanNextChannel(struct rt_rtmp_adapter *pAd)
91980990 473{
62eb734b 474 struct rt_header_802_11 Hdr80211;
51126deb
BZ
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;
62eb734b 480 struct rt_header_802_11 * pHdr80211;
51126deb 481 u32 ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
91980990 482
ca97b838 483 {
96b3c83d
BZ
484 if (MONITOR_ON(pAd))
485 return;
ca97b838
BZ
486 }
487
96b3c83d 488 if (pAd->MlmeAux.Channel == 0) {
91980990 489 if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
96b3c83d
BZ
490 && (INFRA_ON(pAd)
491 || (pAd->OpMode == OPMODE_AP))
492 ) {
493 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel,
494 FALSE);
91980990
GKH
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);
96b3c83d
BZ
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 {
91980990
GKH
505 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
506 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
96b3c83d
BZ
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));
91980990
GKH
510 }
511
91980990 512 {
ec278fa2
BZ
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 /* */
96b3c83d
BZ
518 if (OPSTATUS_TEST_FLAG
519 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
520 && (INFRA_ON(pAd))) {
521 NStatus =
522 MlmeAllocateMemory(pAd,
51126deb 523 (void *)& pOutBuffer);
96b3c83d 524 if (NStatus == NDIS_STATUS_SUCCESS) {
62eb734b 525 pHdr80211 = (struct rt_header_802_11 *) pOutBuffer;
96b3c83d
BZ
526 MgtMacHeaderInit(pAd, pHdr80211,
527 SUBTYPE_NULL_FUNC, 1,
528 pAd->CommonCfg.Bssid,
529 pAd->CommonCfg.Bssid);
91980990
GKH
530 pHdr80211->Duration = 0;
531 pHdr80211->FC.Type = BTYPE_DATA;
96b3c83d
BZ
532 pHdr80211->FC.PwrMgmt =
533 (pAd->StaCfg.Psm == PWR_SAVE);
91980990 534
ec278fa2 535 /* Send using priority queue */
96b3c83d
BZ
536 MiniportMMRequest(pAd, 0, pOutBuffer,
537 sizeof
62eb734b 538 (struct rt_header_802_11));
96b3c83d
BZ
539 DBGPRINT(RT_DEBUG_TRACE,
540 ("MlmeScanReqAction -- Send PSM Data frame\n"));
91980990
GKH
541 MlmeFreeMemory(pAd, pOutBuffer);
542 RTMPusecDelay(5000);
543 }
544 }
545
546 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
547 Status = MLME_SUCCESS;
96b3c83d
BZ
548 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF,
549 2, &Status);
91980990 550 }
91980990
GKH
551
552 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
553 }
ca97b838 554#ifdef RTMP_MAC_USB
96b3c83d
BZ
555 else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
556 && (pAd->OpMode == OPMODE_STA)) {
59fe2d89
BZ
557 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
558 MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
559 }
ec278fa2 560#endif /* RTMP_MAC_USB // */
96b3c83d 561 else {
91980990 562 {
ec278fa2 563 /* BBP and RF are not accessible in PS mode, we has to wake them up first */
96b3c83d
BZ
564 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
565 AsicForceWakeup(pAd, TRUE);
ca97b838 566
ec278fa2 567 /* leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON */
91980990 568 if (pAd->StaCfg.Psm == PWR_SAVE)
ca97b838 569 RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
91980990 570 }
91980990
GKH
571
572 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
573 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
574
91980990 575 {
96b3c83d
BZ
576 if (pAd->MlmeAux.Channel > 14) {
577 if ((pAd->CommonCfg.bIEEE80211H == 1)
578 && RadarChannelCheck(pAd,
579 pAd->MlmeAux.
580 Channel)) {
91980990
GKH
581 ScanType = SCAN_PASSIVE;
582 ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
583 }
584 }
91980990 585 }
91980990 586
ec278fa2 587 /*Global country domain(ch1-11:active scan, ch12-14 passive scan) */
96b3c83d
BZ
588 if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12)
589 && ((pAd->CommonCfg.CountryRegion & 0x7f) ==
590 REGION_31_BG_BAND)) {
91980990
GKH
591 ScanType = SCAN_PASSIVE;
592 }
ec278fa2
BZ
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 */
91980990 595 if (ScanType == FAST_SCAN_ACTIVE)
96b3c83d
BZ
596 RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
597 FAST_ACTIVE_SCAN_TIME);
ec278fa2 598 else /* must be SCAN_PASSIVE or SCAN_ACTIVE */
91980990
GKH
599 {
600 if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
96b3c83d
BZ
601 || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)
602 || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
603 ) {
91980990 604 if (pAd->MlmeAux.Channel > 14)
96b3c83d
BZ
605 RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
606 ScanTimeIn5gChannel);
91980990 607 else
96b3c83d
BZ
608 RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
609 MIN_CHANNEL_TIME);
610 } else
611 RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
612 MAX_CHANNEL_TIME);
91980990
GKH
613 }
614
ca97b838 615 if ((ScanType == SCAN_ACTIVE)
96b3c83d
BZ
616 || (ScanType == FAST_SCAN_ACTIVE)
617 ) {
ec278fa2 618 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
96b3c83d
BZ
619 if (NStatus != NDIS_STATUS_SUCCESS) {
620 DBGPRINT(RT_DEBUG_TRACE,
621 ("SYNC - ScanNextChannel() allocate memory fail\n"));
6a28a69a 622
91980990 623 {
96b3c83d
BZ
624 pAd->Mlme.SyncMachine.CurrState =
625 SYNC_IDLE;
91980990 626 Status = MLME_FAIL_NO_RESOURCE;
96b3c83d
BZ
627 MlmeEnqueue(pAd,
628 MLME_CNTL_STATE_MACHINE,
629 MT2_SCAN_CONF, 2, &Status);
91980990 630 }
91980990
GKH
631
632 return;
633 }
ec278fa2 634 /* There is no need to send broadcast probe request if active scan is in effect. */
96b3c83d
BZ
635 if ((ScanType == SCAN_ACTIVE)
636 || (ScanType == FAST_SCAN_ACTIVE)
637 )
91980990
GKH
638 SsidLen = pAd->MlmeAux.SsidLen;
639 else
640 SsidLen = 0;
641
96b3c83d
BZ
642 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
643 BROADCAST_ADDR, BROADCAST_ADDR);
644 MakeOutgoingFrame(pOutBuffer, &FrameLen,
62eb734b 645 sizeof(struct rt_header_802_11), &Hdr80211, 1,
96b3c83d
BZ
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) {
51126deb 653 unsigned long Tmp;
96b3c83d
BZ
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);
91980990
GKH
660 FrameLen += Tmp;
661 }
662
96b3c83d 663 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
51126deb
BZ
664 unsigned long Tmp;
665 u8 HtLen;
666 u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
96b3c83d
BZ
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 {
91980990 682 HtLen = pAd->MlmeAux.HtCapabilityLen;
91980990 683
96b3c83d
BZ
684 MakeOutgoingFrame(pOutBuffer + FrameLen,
685 &Tmp, 1, &HtCapIe, 1,
686 &HtLen, HtLen,
687 &pAd->CommonCfg.
688 HtCapability,
689 END_OF_ARGS);
91980990
GKH
690 }
691 FrameLen += Tmp;
91980990 692 }
91980990
GKH
693
694 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
695 MlmeFreeMemory(pAd, pOutBuffer);
696 }
ec278fa2 697 /* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse */
91980990 698
5a911fd6 699 pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
91980990
GKH
700 }
701}
702
62eb734b
BZ
703void MgtProbReqMacHeaderInit(struct rt_rtmp_adapter *pAd,
704 struct rt_header_802_11 * pHdr80211,
51126deb
BZ
705 u8 SubType,
706 u8 ToDs, u8 *pDA, u8 *pBssid)
91980990 707{
62eb734b 708 NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
91980990
GKH
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}