• 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 #ifdef RT2870
467 #ifdef CONFIG_STA_SUPPORT
468 	else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
469 	{
470 		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
471 		MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
472 	}
473 #endif // CONFIG_STA_SUPPORT //
474 #endif // RT2870 //
475 	else
476 	{
477 #ifdef CONFIG_STA_SUPPORT
478 		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
479 		{
480 		// BBP and RF are not accessible in PS mode, we has to wake them up first
481 		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
482 			AsicForceWakeup(pAd, TRUE);
483 
484 			// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
485 			if (pAd->StaCfg.Psm == PWR_SAVE)
486 				MlmeSetPsmBit(pAd, PWR_ACTIVE);
487 		}
488 #endif // CONFIG_STA_SUPPORT //
489 
490 		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
491 		AsicLockChannel(pAd, pAd->MlmeAux.Channel);
492 
493 #ifdef CONFIG_STA_SUPPORT
494 		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
495 		{
496 			if (pAd->MlmeAux.Channel > 14)
497 			{
498 				if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
499 				{
500 					ScanType = SCAN_PASSIVE;
501 					ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
502 				}
503 			}
504 
505 #ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
506 			// carrier detection
507 			if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
508 			{
509 				ScanType = SCAN_PASSIVE;
510 				ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
511 			}
512 #endif // CARRIER_DETECTION_SUPPORT //
513 		}
514 
515 #endif // CONFIG_STA_SUPPORT //
516 
517 		//Global country domain(ch1-11:active scan, ch12-14 passive scan)
518 		if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND))
519 		{
520 			ScanType = SCAN_PASSIVE;
521 		}
522 
523 		// We need to shorten active scan time in order for WZC connect issue
524 		// Chnage the channel scan time for CISCO stuff based on its IAPP announcement
525 		if (ScanType == FAST_SCAN_ACTIVE)
526 			RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
527 #ifdef CONFIG_STA_SUPPORT
528 		else if (((ScanType == SCAN_CISCO_ACTIVE) ||
529 				(ScanType == SCAN_CISCO_PASSIVE) ||
530 				(ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
531 				(ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
532 		{
533 			if (pAd->StaCfg.CCXScanTime < 25)
534 				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
535 			else
536 				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
537 		}
538 #endif // CONFIG_STA_SUPPORT //
539 		else // must be SCAN_PASSIVE or SCAN_ACTIVE
540 		{
541 			if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
542 #ifdef DOT11_N_SUPPORT
543 				|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
544 #endif // DOT11_N_SUPPORT //
545 			)
546 			{
547 				if (pAd->MlmeAux.Channel > 14)
548 					RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
549 				else
550 				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
551 			}
552 			else
553 				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
554 		}
555 
556 		if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ||
557 			(ScanType == SCAN_CISCO_ACTIVE))
558 		{
559 			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
560 			if (NStatus != NDIS_STATUS_SUCCESS)
561 			{
562 				DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
563 #ifdef CONFIG_STA_SUPPORT
564 				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
565 				{
566 					pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
567 					Status = MLME_FAIL_NO_RESOURCE;
568 					MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
569 				}
570 #endif // CONFIG_STA_SUPPORT //
571 
572 				return;
573 			}
574 
575 			// There is no need to send broadcast probe request if active scan is in effect.
576 			if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
577 				)
578 				SsidLen = pAd->MlmeAux.SsidLen;
579 			else
580 				SsidLen = 0;
581 
582 			MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
583 			MakeOutgoingFrame(pOutBuffer,               &FrameLen,
584 							  sizeof(HEADER_802_11),    &Hdr80211,
585 							  1,                        &SsidIe,
586 							  1,                        &SsidLen,
587 							  SsidLen,			        pAd->MlmeAux.Ssid,
588 							  1,                        &SupRateIe,
589 							  1,                        &pAd->CommonCfg.SupRateLen,
590 							  pAd->CommonCfg.SupRateLen,  pAd->CommonCfg.SupRate,
591 							  END_OF_ARGS);
592 
593 			if (pAd->CommonCfg.ExtRateLen)
594 			{
595 				ULONG Tmp;
596 				MakeOutgoingFrame(pOutBuffer + FrameLen,            &Tmp,
597 								  1,                                &ExtRateIe,
598 								  1,                                &pAd->CommonCfg.ExtRateLen,
599 								  pAd->CommonCfg.ExtRateLen,          pAd->CommonCfg.ExtRate,
600 								  END_OF_ARGS);
601 				FrameLen += Tmp;
602 			}
603 
604 #ifdef DOT11_N_SUPPORT
605 			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
606 			{
607 				ULONG	Tmp;
608 				UCHAR	HtLen;
609 				UCHAR	BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
610 #ifdef RT_BIG_ENDIAN
611 				HT_CAPABILITY_IE HtCapabilityTmp;
612 #endif
613 				if (pAd->bBroadComHT == TRUE)
614 				{
615 					HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
616 #ifdef RT_BIG_ENDIAN
617 					NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
618 					*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
619 					*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
620 
621 					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
622 									1,                                &WpaIe,
623 									1,                                &HtLen,
624 									4,                                &BROADCOM[0],
625 									pAd->MlmeAux.HtCapabilityLen,     &HtCapabilityTmp,
626 									END_OF_ARGS);
627 #else
628 					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
629 									1,                                &WpaIe,
630 									1,                                &HtLen,
631 									4,                                &BROADCOM[0],
632 									pAd->MlmeAux.HtCapabilityLen,     &pAd->MlmeAux.HtCapability,
633 									END_OF_ARGS);
634 #endif // RT_BIG_ENDIAN //
635 				}
636 				else
637 				{
638 					HtLen = pAd->MlmeAux.HtCapabilityLen;
639 #ifdef RT_BIG_ENDIAN
640 					NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE);
641 					*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
642 					*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
643 
644 					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
645 									1,                                &HtCapIe,
646 									1,                                &HtLen,
647 									HtLen,                            &HtCapabilityTmp,
648 									END_OF_ARGS);
649 #else
650 					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
651 									1,                                &HtCapIe,
652 									1,                                &HtLen,
653 									HtLen,                            &pAd->CommonCfg.HtCapability,
654 									END_OF_ARGS);
655 #endif // RT_BIG_ENDIAN //
656 				}
657 				FrameLen += Tmp;
658 
659 #ifdef DOT11N_DRAFT3
660 				if (pAd->CommonCfg.BACapability.field.b2040CoexistScanSup == 1)
661 				{
662 					ULONG		Tmp;
663 					HtLen = 1;
664 					MakeOutgoingFrame(pOutBuffer + FrameLen,            &Tmp,
665 									  1,					&ExtHtCapIe,
666 									  1,					&HtLen,
667 									  1,          			&pAd->CommonCfg.BSSCoexist2040.word,
668 									  END_OF_ARGS);
669 
670 					FrameLen += Tmp;
671 				}
672 #endif // DOT11N_DRAFT3 //
673 			}
674 #endif // DOT11_N_SUPPORT //
675 
676 
677 			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
678 			MlmeFreeMemory(pAd, pOutBuffer);
679 		}
680 
681 		// For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
682 
683 #ifdef CONFIG_STA_SUPPORT
684 		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
685 			pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
686 #endif // CONFIG_STA_SUPPORT //
687 
688 	}
689 }
690 
MgtProbReqMacHeaderInit(IN PRTMP_ADAPTER pAd,IN OUT PHEADER_802_11 pHdr80211,IN UCHAR SubType,IN UCHAR ToDs,IN PUCHAR pDA,IN PUCHAR pBssid)691 VOID MgtProbReqMacHeaderInit(
692 	IN	PRTMP_ADAPTER	pAd,
693 	IN OUT PHEADER_802_11 pHdr80211,
694 	IN UCHAR SubType,
695 	IN UCHAR ToDs,
696 	IN PUCHAR pDA,
697 	IN PUCHAR pBssid)
698 {
699 	NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
700 
701 	pHdr80211->FC.Type = BTYPE_MGMT;
702 	pHdr80211->FC.SubType = SubType;
703 	if (SubType == SUBTYPE_ACK)
704 		pHdr80211->FC.Type = BTYPE_CNTL;
705 	pHdr80211->FC.ToDs = ToDs;
706 	COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
707 	COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
708 	COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
709 }
710 
711 
712