• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/rt2860/common/
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. */
60u8 A_BAND_REGION_0_CHANNEL_LIST[] =
61    { 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 };
62u8 A_BAND_REGION_1_CHANNEL_LIST[] =
63    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
64132, 136, 140 };
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[] =
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 };
73u8 A_BAND_REGION_8_CHANNEL_LIST[] = { 52, 56, 60, 64 };
74u8 A_BAND_REGION_9_CHANNEL_LIST[] =
75    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140,
76149, 153, 157, 161, 165 };
77u8 A_BAND_REGION_10_CHANNEL_LIST[] =
78    { 36, 40, 44, 48, 149, 153, 157, 161, 165 };
79u8 A_BAND_REGION_11_CHANNEL_LIST[] =
80    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153,
81157, 161 };
82u8 A_BAND_REGION_12_CHANNEL_LIST[] =
83    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
84132, 136, 140 };
85u8 A_BAND_REGION_13_CHANNEL_LIST[] =
86    { 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
87149, 153, 157, 161 };
88u8 A_BAND_REGION_14_CHANNEL_LIST[] =
89    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
90153, 157, 161, 165 };
91u8 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. */
94u8 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 */
108void 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 */
362u8 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 */
378u8 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 */
411void 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
438char 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 */
472void 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
703void 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