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