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 	Jan Lee			2006-08-01      	modified for rt2860 for 802.11n
37 	Justin P. Mattock	11/07/2010		Fix typos
38 */
39 #include "../rt_config.h"
40 
41 #define ADHOC_ENTRY_BEACON_LOST_TIME	(2*OS_HZ)	/* 2 sec */
42 
43 /*
44 	==========================================================================
45 	Description:
46 		The sync state machine,
47 	Parameters:
48 		Sm - pointer to the state machine
49 	Note:
50 		the state machine looks like the following
51 
52 	==========================================================================
53  */
SyncStateMachineInit(struct rt_rtmp_adapter * pAd,struct rt_state_machine * Sm,OUT STATE_MACHINE_FUNC Trans[])54 void SyncStateMachineInit(struct rt_rtmp_adapter *pAd,
55 			  struct rt_state_machine *Sm, OUT STATE_MACHINE_FUNC Trans[])
56 {
57 	StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG,
58 			 (STATE_MACHINE_FUNC) Drop, SYNC_IDLE,
59 			 SYNC_MACHINE_BASE);
60 
61 	/* column 1 */
62 	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ,
63 			      (STATE_MACHINE_FUNC) MlmeScanReqAction);
64 	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ,
65 			      (STATE_MACHINE_FUNC) MlmeJoinReqAction);
66 	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ,
67 			      (STATE_MACHINE_FUNC) MlmeStartReqAction);
68 	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON,
69 			      (STATE_MACHINE_FUNC) PeerBeacon);
70 	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ,
71 			      (STATE_MACHINE_FUNC) PeerProbeReqAction);
72 
73 	/*column 2 */
74 	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ,
75 			      (STATE_MACHINE_FUNC) InvalidStateWhenScan);
76 	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ,
77 			      (STATE_MACHINE_FUNC) InvalidStateWhenJoin);
78 	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ,
79 			      (STATE_MACHINE_FUNC) InvalidStateWhenStart);
80 	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON,
81 			      (STATE_MACHINE_FUNC) PeerBeaconAtJoinAction);
82 	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT,
83 			      (STATE_MACHINE_FUNC) BeaconTimeoutAtJoinAction);
84 
85 	/* column 3 */
86 	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ,
87 			      (STATE_MACHINE_FUNC) InvalidStateWhenScan);
88 	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ,
89 			      (STATE_MACHINE_FUNC) InvalidStateWhenJoin);
90 	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ,
91 			      (STATE_MACHINE_FUNC) InvalidStateWhenStart);
92 	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON,
93 			      (STATE_MACHINE_FUNC) PeerBeaconAtScanAction);
94 	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP,
95 			      (STATE_MACHINE_FUNC) PeerBeaconAtScanAction);
96 	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT,
97 			      (STATE_MACHINE_FUNC) ScanTimeoutAction);
98 
99 	/* timer init */
100 	RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer,
101 		      GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
102 	RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer,
103 		      GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
104 }
105 
106 /*
107 	==========================================================================
108 	Description:
109 		Beacon timeout handler, executed in timer thread
110 
111 	IRQL = DISPATCH_LEVEL
112 
113 	==========================================================================
114  */
BeaconTimeout(void * SystemSpecific1,void * FunctionContext,void * SystemSpecific2,void * SystemSpecific3)115 void BeaconTimeout(void *SystemSpecific1,
116 		   void *FunctionContext,
117 		   void *SystemSpecific2, void *SystemSpecific3)
118 {
119 	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
120 
121 	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeout\n"));
122 
123 	/* Do nothing if the driver is starting halt state. */
124 	/* This might happen when timer already been fired before cancel timer with mlmehalt */
125 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
126 		return;
127 
128 	if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
129 	    ) {
130 		u8 BBPValue = 0;
131 		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
132 		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
133 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
134 		BBPValue &= (~0x18);
135 		BBPValue |= 0x10;
136 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
137 		DBGPRINT(RT_DEBUG_TRACE,
138 			 ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",
139 			  pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
140 	}
141 
142 	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
143 	RTMP_MLME_HANDLER(pAd);
144 }
145 
146 /*
147 	==========================================================================
148 	Description:
149 		Scan timeout handler, executed in timer thread
150 
151 	IRQL = DISPATCH_LEVEL
152 
153 	==========================================================================
154  */
ScanTimeout(void * SystemSpecific1,void * FunctionContext,void * SystemSpecific2,void * SystemSpecific3)155 void ScanTimeout(void *SystemSpecific1,
156 		 void *FunctionContext,
157 		 void *SystemSpecific2, void *SystemSpecific3)
158 {
159 	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
160 
161 	/* Do nothing if the driver is starting halt state. */
162 	/* This might happen when timer already been fired before cancel timer with mlmehalt */
163 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
164 		return;
165 
166 	if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL)) {
167 		RTMP_MLME_HANDLER(pAd);
168 	} else {
169 		/* To prevent SyncMachine.CurrState is SCAN_LISTEN forever. */
170 		pAd->MlmeAux.Channel = 0;
171 		ScanNextChannel(pAd);
172 		if (pAd->CommonCfg.bWirelessEvent) {
173 			RTMPSendWirelessEvent(pAd,
174 					      IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG,
175 					      pAd->MacTab.Content[BSSID_WCID].
176 					      Addr, BSS0, 0);
177 		}
178 	}
179 }
180 
181 /*
182 	==========================================================================
183 	Description:
184 		MLME SCAN req state machine procedure
185 	==========================================================================
186  */
MlmeScanReqAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)187 void MlmeScanReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
188 {
189 	u8 Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
190 	BOOLEAN TimerCancelled;
191 	unsigned long Now;
192 	u16 Status;
193 	struct rt_header_802_11 * pHdr80211;
194 	u8 *pOutBuffer = NULL;
195 	int NStatus;
196 
197 	/* Check the total scan tries for one single OID command */
198 	/* If this is the CCX 2.0 Case, skip that! */
199 	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
200 		DBGPRINT(RT_DEBUG_TRACE,
201 			 ("SYNC - MlmeScanReqAction before Startup\n"));
202 		return;
203 	}
204 	/* Increase the scan retry counters. */
205 	pAd->StaCfg.ScanCnt++;
206 
207 #ifdef RTMP_MAC_PCI
208 	if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
209 	    (IDLE_ON(pAd)) &&
210 	    (pAd->StaCfg.bRadio == TRUE) &&
211 	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
212 		if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) {
213 			AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00,
214 					     0x02);
215 			AsicCheckCommanOk(pAd, PowerWakeCID);
216 			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
217 			DBGPRINT(RT_DEBUG_TRACE,
218 				 ("PSM - Issue Wake up command \n"));
219 		} else {
220 			RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
221 		}
222 	}
223 #endif /* RTMP_MAC_PCI // */
224 
225 	/* first check the parameter sanity */
226 	if (MlmeScanReqSanity(pAd,
227 			      Elem->Msg,
228 			      Elem->MsgLen,
229 			      &BssType, (char *)Ssid, &SsidLen, &ScanType)) {
230 
231 		/* Check for channel load and noise hist request */
232 		/* Suspend MSDU only at scan request, not the last two mentioned */
233 		/* Suspend MSDU transmission here */
234 		RTMPSuspendMsduTransmission(pAd);
235 
236 		/* */
237 		/* To prevent data loss. */
238 		/* Send a NULL data with turned PSM bit on to current associated AP before SCAN progress. */
239 		/* And should send a NULL data with turned PSM bit off to AP, when scan progress done */
240 		/* */
241 		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
242 		    && (INFRA_ON(pAd))) {
243 			NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);
244 			if (NStatus == NDIS_STATUS_SUCCESS) {
245 				pHdr80211 = (struct rt_header_802_11 *) pOutBuffer;
246 				MgtMacHeaderInit(pAd, pHdr80211,
247 						 SUBTYPE_NULL_FUNC, 1,
248 						 pAd->CommonCfg.Bssid,
249 						 pAd->CommonCfg.Bssid);
250 				pHdr80211->Duration = 0;
251 				pHdr80211->FC.Type = BTYPE_DATA;
252 				pHdr80211->FC.PwrMgmt = PWR_SAVE;
253 
254 				/* Send using priority queue */
255 				MiniportMMRequest(pAd, 0, pOutBuffer,
256 						  sizeof(struct rt_header_802_11));
257 				DBGPRINT(RT_DEBUG_TRACE,
258 					 ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
259 				MlmeFreeMemory(pAd, pOutBuffer);
260 				RTMPusecDelay(5000);
261 			}
262 		}
263 
264 		NdisGetSystemUpTime(&Now);
265 		pAd->StaCfg.LastScanTime = Now;
266 		/* reset all the timers */
267 		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
268 		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
269 
270 		/* record desired BSS parameters */
271 		pAd->MlmeAux.BssType = BssType;
272 		pAd->MlmeAux.ScanType = ScanType;
273 		pAd->MlmeAux.SsidLen = SsidLen;
274 		NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
275 		NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
276 
277 		/* start from the first channel */
278 		pAd->MlmeAux.Channel = FirstChannel(pAd);
279 
280 		/* Let BBP register at 20MHz to do scan */
281 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
282 		BBPValue &= (~0x18);
283 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
284 		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
285 		ScanNextChannel(pAd);
286 	} else {
287 		DBGPRINT_ERR("SYNC - MlmeScanReqAction() sanity check fail\n");
288 		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
289 		Status = MLME_INVALID_FORMAT;
290 		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2,
291 			    &Status);
292 	}
293 }
294 
295 /*
296 	==========================================================================
297 	Description:
298 		MLME JOIN req state machine procedure
299 	==========================================================================
300  */
MlmeJoinReqAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)301 void MlmeJoinReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
302 {
303 	u8 BBPValue = 0;
304 	struct rt_bss_entry *pBss;
305 	BOOLEAN TimerCancelled;
306 	struct rt_header_802_11 Hdr80211;
307 	int NStatus;
308 	unsigned long FrameLen = 0;
309 	u8 *pOutBuffer = NULL;
310 	u8 *pSupRate = NULL;
311 	u8 SupRateLen;
312 	u8 *pExtRate = NULL;
313 	u8 ExtRateLen;
314 	u8 ASupRate[] = { 0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C };
315 	u8 ASupRateLen = sizeof(ASupRate) / sizeof(u8);
316 	struct rt_mlme_join_req *pInfo = (struct rt_mlme_join_req *)(Elem->Msg);
317 
318 	DBGPRINT(RT_DEBUG_TRACE,
319 		 ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
320 
321 #ifdef RTMP_MAC_PCI
322 	if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
323 	    (IDLE_ON(pAd)) &&
324 	    (pAd->StaCfg.bRadio == TRUE) &&
325 	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
326 		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
327 	}
328 #endif /* RTMP_MAC_PCI // */
329 
330 	/* reset all the timers */
331 	RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
332 	RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
333 
334 	pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
335 
336 	/* record the desired SSID & BSSID we're waiting for */
337 	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
338 
339 	/* If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again. */
340 	if (pBss->Hidden == 0) {
341 		RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
342 		NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
343 		pAd->MlmeAux.SsidLen = pBss->SsidLen;
344 	}
345 
346 	pAd->MlmeAux.BssType = pBss->BssType;
347 	pAd->MlmeAux.Channel = pBss->Channel;
348 	pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
349 
350 	/* Let BBP register at 20MHz to do scan */
351 	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
352 	BBPValue &= (~0x18);
353 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
354 
355 	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
356 
357 	/* switch channel and waiting for beacon timer */
358 	AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
359 	AsicLockChannel(pAd, pAd->MlmeAux.Channel);
360 	RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
361 
362 	do {
363 		if (((pAd->CommonCfg.bIEEE80211H == 1) &&
364 		     (pAd->MlmeAux.Channel > 14) &&
365 		     RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
366 		    ) {
367 			/* */
368 			/* We can't send any Probe request frame to meet 802.11h. */
369 			/* */
370 			if (pBss->Hidden == 0)
371 				break;
372 		}
373 		/* */
374 		/* send probe request */
375 		/* */
376 		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
377 		if (NStatus == NDIS_STATUS_SUCCESS) {
378 			if (pAd->MlmeAux.Channel <= 14) {
379 				pSupRate = pAd->CommonCfg.SupRate;
380 				SupRateLen = pAd->CommonCfg.SupRateLen;
381 				pExtRate = pAd->CommonCfg.ExtRate;
382 				ExtRateLen = pAd->CommonCfg.ExtRateLen;
383 			} else {
384 				/* */
385 				/* Overwrite Support Rate, CCK rate are not allowed */
386 				/* */
387 				pSupRate = ASupRate;
388 				SupRateLen = ASupRateLen;
389 				ExtRateLen = 0;
390 			}
391 
392 			if (pAd->MlmeAux.BssType == BSS_INFRA)
393 				MgtMacHeaderInit(pAd, &Hdr80211,
394 						 SUBTYPE_PROBE_REQ, 0,
395 						 pAd->MlmeAux.Bssid,
396 						 pAd->MlmeAux.Bssid);
397 			else
398 				MgtMacHeaderInit(pAd, &Hdr80211,
399 						 SUBTYPE_PROBE_REQ, 0,
400 						 BROADCAST_ADDR,
401 						 BROADCAST_ADDR);
402 
403 			MakeOutgoingFrame(pOutBuffer, &FrameLen,
404 					  sizeof(struct rt_header_802_11), &Hdr80211,
405 					  1, &SsidIe,
406 					  1, &pAd->MlmeAux.SsidLen,
407 					  pAd->MlmeAux.SsidLen,
408 					  pAd->MlmeAux.Ssid, 1, &SupRateIe, 1,
409 					  &SupRateLen, SupRateLen, pSupRate,
410 					  END_OF_ARGS);
411 
412 			if (ExtRateLen) {
413 				unsigned long Tmp;
414 				MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
415 						  1, &ExtRateIe,
416 						  1, &ExtRateLen,
417 						  ExtRateLen, pExtRate,
418 						  END_OF_ARGS);
419 				FrameLen += Tmp;
420 			}
421 
422 			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
423 			MlmeFreeMemory(pAd, pOutBuffer);
424 		}
425 	} while (FALSE);
426 
427 	DBGPRINT(RT_DEBUG_TRACE,
428 		("SYNC - Switch to ch %d, Wait BEACON from %pM\n",
429 			pBss->Channel, pBss->Bssid));
430 
431 	pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
432 }
433 
434 /*
435 	==========================================================================
436 	Description:
437 		MLME START Request state machine procedure, starting an IBSS
438 	==========================================================================
439  */
MlmeStartReqAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)440 void MlmeStartReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
441 {
442 	u8 Ssid[MAX_LEN_OF_SSID], SsidLen;
443 	BOOLEAN TimerCancelled;
444 
445 	/* New for WPA security suites */
446 	u8 VarIE[MAX_VIE_LEN];	/* Total VIE length = MAX_VIE_LEN - -5 */
447 	struct rt_ndis_802_11_variable_ies *pVIE = NULL;
448 	LARGE_INTEGER TimeStamp;
449 	BOOLEAN Privacy;
450 	u16 Status;
451 
452 	/* Init Variable IE structure */
453 	pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
454 	pVIE->Length = 0;
455 	TimeStamp.u.LowPart = 0;
456 	TimeStamp.u.HighPart = 0;
457 
458 	if (MlmeStartReqSanity
459 	    (pAd, Elem->Msg, Elem->MsgLen, (char *)Ssid, &SsidLen)) {
460 		/* reset all the timers */
461 		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
462 		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
463 
464 		/* */
465 		/* Start a new IBSS. All IBSS parameters are decided now.... */
466 		/* */
467 		DBGPRINT(RT_DEBUG_TRACE,
468 			 ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
469 		pAd->MlmeAux.BssType = BSS_ADHOC;
470 		NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
471 		pAd->MlmeAux.SsidLen = SsidLen;
472 
473 		/* generate a radom number as BSSID */
474 		MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
475 		DBGPRINT(RT_DEBUG_TRACE,
476 			 ("MlmeStartReqAction - generate a radom number as BSSID \n"));
477 
478 		Privacy =
479 		    (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
480 		    || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
481 		    || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
482 		pAd->MlmeAux.CapabilityInfo =
483 		    CAP_GENERATE(0, 1, Privacy,
484 				 (pAd->CommonCfg.TxPreamble ==
485 				  Rt802_11PreambleShort), 1, 0);
486 		pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
487 		pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin;
488 		pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
489 
490 		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
491 		pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
492 
493 		pAd->MlmeAux.SupRateLen = pAd->CommonCfg.SupRateLen;
494 		NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate,
495 			       MAX_LEN_OF_SUPPORTED_RATES);
496 		RTMPCheckRates(pAd, pAd->MlmeAux.SupRate,
497 			       &pAd->MlmeAux.SupRateLen);
498 		pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
499 		NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate,
500 			       MAX_LEN_OF_SUPPORTED_RATES);
501 		RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate,
502 			       &pAd->MlmeAux.ExtRateLen);
503 
504 		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
505 			RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy,
506 				       &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0],
507 				       &pAd->MlmeAux.HtCapability,
508 				       &pAd->MlmeAux.AddHtInfo);
509 			pAd->MlmeAux.HtCapabilityLen = sizeof(struct rt_ht_capability_ie);
510 			/* Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here. */
511 			DBGPRINT(RT_DEBUG_TRACE,
512 				 ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
513 		} else {
514 			pAd->MlmeAux.HtCapabilityLen = 0;
515 			pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
516 			NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.
517 				       MCSSet[0], 16);
518 		}
519 		/* temporarily not support QOS in IBSS */
520 		NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(struct rt_edca_parm));
521 		NdisZeroMemory(&pAd->MlmeAux.APQbssLoad,
522 			       sizeof(struct rt_qbss_load_parm));
523 		NdisZeroMemory(&pAd->MlmeAux.APQosCapability,
524 			       sizeof(struct rt_qos_capability_parm));
525 
526 		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
527 		AsicLockChannel(pAd, pAd->MlmeAux.Channel);
528 
529 		DBGPRINT(RT_DEBUG_TRACE,
530 			 ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
531 			  pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen,
532 			  pAd->MlmeAux.ExtRateLen));
533 
534 		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
535 		Status = MLME_SUCCESS;
536 		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2,
537 			    &Status);
538 	} else {
539 		DBGPRINT_ERR("SYNC - MlmeStartReqAction() sanity check fail.\n");
540 		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
541 		Status = MLME_INVALID_FORMAT;
542 		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2,
543 			    &Status);
544 	}
545 }
546 
547 /*
548 	==========================================================================
549 	Description:
550 		peer sends beacon back when scanning
551 	==========================================================================
552  */
PeerBeaconAtScanAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)553 void PeerBeaconAtScanAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
554 {
555 	u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
556 	u8 Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
557 	    SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
558 	struct rt_cf_parm CfParm;
559 	u16 BeaconPeriod, AtimWin, CapabilityInfo;
560 	struct rt_frame_802_11 * pFrame;
561 	LARGE_INTEGER TimeStamp;
562 	u8 Erp;
563 	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
564 	    ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
565 	u8 SupRateLen, ExtRateLen;
566 	u16 LenVIE;
567 	u8 CkipFlag;
568 	u8 AironetCellPowerLimit;
569 	struct rt_edca_parm EdcaParm;
570 	struct rt_qbss_load_parm QbssLoad;
571 	struct rt_qos_capability_parm QosCapability;
572 	unsigned long RalinkIe;
573 	u8 VarIE[MAX_VIE_LEN];	/* Total VIE length = MAX_VIE_LEN - -5 */
574 	struct rt_ndis_802_11_variable_ies *pVIE = NULL;
575 	struct rt_ht_capability_ie HtCapability;
576 	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
577 	u8 HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
578 	u8 AddHtInfoLen;
579 	u8 NewExtChannelOffset = 0xff;
580 
581 	/* NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00); */
582 	pFrame = (struct rt_frame_802_11 *) Elem->Msg;
583 	/* Init Variable IE structure */
584 	pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
585 	pVIE->Length = 0;
586 
587 	RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
588 	RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
589 
590 	if (PeerBeaconAndProbeRspSanity(pAd,
591 					Elem->Msg,
592 					Elem->MsgLen,
593 					Elem->Channel,
594 					Addr2,
595 					Bssid,
596 					(char *)Ssid,
597 					&SsidLen,
598 					&BssType,
599 					&BeaconPeriod,
600 					&Channel,
601 					&NewChannel,
602 					&TimeStamp,
603 					&CfParm,
604 					&AtimWin,
605 					&CapabilityInfo,
606 					&Erp,
607 					&DtimCount,
608 					&DtimPeriod,
609 					&BcastFlag,
610 					&MessageToMe,
611 					SupRate,
612 					&SupRateLen,
613 					ExtRate,
614 					&ExtRateLen,
615 					&CkipFlag,
616 					&AironetCellPowerLimit,
617 					&EdcaParm,
618 					&QbssLoad,
619 					&QosCapability,
620 					&RalinkIe,
621 					&HtCapabilityLen,
622 					&PreNHtCapabilityLen,
623 					&HtCapability,
624 					&AddHtInfoLen,
625 					&AddHtInfo,
626 					&NewExtChannelOffset, &LenVIE, pVIE)) {
627 		unsigned long Idx;
628 		char Rssi = 0;
629 
630 		Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
631 		if (Idx != BSS_NOT_FOUND)
632 			Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
633 
634 		Rssi =
635 		    RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
636 				ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
637 				ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
638 
639 		if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
640 			HtCapabilityLen = SIZE_HT_CAP_IE;
641 
642 		Idx =
643 		    BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (char *)Ssid,
644 				     SsidLen, BssType, BeaconPeriod, &CfParm,
645 				     AtimWin, CapabilityInfo, SupRate,
646 				     SupRateLen, ExtRate, ExtRateLen,
647 				     &HtCapability, &AddHtInfo, HtCapabilityLen,
648 				     AddHtInfoLen, NewExtChannelOffset, Channel,
649 				     Rssi, TimeStamp, CkipFlag, &EdcaParm,
650 				     &QosCapability, &QbssLoad, LenVIE, pVIE);
651 
652 		if (Idx != BSS_NOT_FOUND) {
653 			NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF,
654 				       &Elem->Msg[24], 4);
655 			NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0],
656 				       &Elem->TimeStamp.u.LowPart, 4);
657 			NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4],
658 				       &Elem->TimeStamp.u.LowPart, 4);
659 		}
660 
661 	}
662 	/* sanity check fail, ignored */
663 }
664 
665 /*
666 	==========================================================================
667 	Description:
668 		When waiting joining the (I)BSS, beacon received from external
669 	==========================================================================
670  */
PeerBeaconAtJoinAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)671 void PeerBeaconAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
672 {
673 	u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
674 	u8 Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
675 	    DtimCount, DtimPeriod, BcastFlag, NewChannel;
676 	LARGE_INTEGER TimeStamp;
677 	u16 BeaconPeriod, AtimWin, CapabilityInfo;
678 	struct rt_cf_parm Cf;
679 	BOOLEAN TimerCancelled;
680 	u8 Erp;
681 	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
682 	    ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
683 	u8 SupRateLen, ExtRateLen;
684 	u8 CkipFlag;
685 	u16 LenVIE;
686 	u8 AironetCellPowerLimit;
687 	struct rt_edca_parm EdcaParm;
688 	struct rt_qbss_load_parm QbssLoad;
689 	struct rt_qos_capability_parm QosCapability;
690 	u16 Status;
691 	u8 VarIE[MAX_VIE_LEN];	/* Total VIE length = MAX_VIE_LEN - -5 */
692 	struct rt_ndis_802_11_variable_ies *pVIE = NULL;
693 	unsigned long RalinkIe;
694 	unsigned long Idx;
695 	struct rt_ht_capability_ie HtCapability;
696 	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
697 	u8 HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
698 	u8 AddHtInfoLen;
699 	u8 NewExtChannelOffset = 0xff;
700 	u8 CentralChannel;
701 	BOOLEAN bAllowNrate = FALSE;
702 
703 	/* Init Variable IE structure */
704 	pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
705 	pVIE->Length = 0;
706 	RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
707 	RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
708 
709 	if (PeerBeaconAndProbeRspSanity(pAd,
710 					Elem->Msg,
711 					Elem->MsgLen,
712 					Elem->Channel,
713 					Addr2,
714 					Bssid,
715 					(char *)Ssid,
716 					&SsidLen,
717 					&BssType,
718 					&BeaconPeriod,
719 					&Channel,
720 					&NewChannel,
721 					&TimeStamp,
722 					&Cf,
723 					&AtimWin,
724 					&CapabilityInfo,
725 					&Erp,
726 					&DtimCount,
727 					&DtimPeriod,
728 					&BcastFlag,
729 					&MessageToMe,
730 					SupRate,
731 					&SupRateLen,
732 					ExtRate,
733 					&ExtRateLen,
734 					&CkipFlag,
735 					&AironetCellPowerLimit,
736 					&EdcaParm,
737 					&QbssLoad,
738 					&QosCapability,
739 					&RalinkIe,
740 					&HtCapabilityLen,
741 					&PreNHtCapabilityLen,
742 					&HtCapability,
743 					&AddHtInfoLen,
744 					&AddHtInfo,
745 					&NewExtChannelOffset, &LenVIE, pVIE)) {
746 		/* Disqualify 11b only adhoc when we are in 11g only adhoc mode */
747 		if ((BssType == BSS_ADHOC)
748 		    && (pAd->CommonCfg.PhyMode == PHY_11G)
749 		    && ((SupRateLen + ExtRateLen) < 12))
750 			return;
751 
752 		/* BEACON from desired BSS/IBSS found. We should be able to decide most */
753 		/* BSS parameters here. */
754 		/* Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATION? */
755 		/*    Do we need to recover back all parameters belonging to previous BSS? */
756 		/* A. Should be not. There's no back-door recover to previous AP. It still needs */
757 		/*    a new JOIN-AUTH-ASSOC sequence. */
758 		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid)) {
759 			DBGPRINT(RT_DEBUG_TRACE,
760 				 ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n",
761 				  Channel));
762 			RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,
763 					&TimerCancelled);
764 
765 			/* Update RSSI to prevent No signal display when cards first initialized */
766 			pAd->StaCfg.RssiSample.LastRssi0 =
767 			    ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
768 			pAd->StaCfg.RssiSample.LastRssi1 =
769 			    ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
770 			pAd->StaCfg.RssiSample.LastRssi2 =
771 			    ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
772 			pAd->StaCfg.RssiSample.AvgRssi0 =
773 			    pAd->StaCfg.RssiSample.LastRssi0;
774 			pAd->StaCfg.RssiSample.AvgRssi0X8 =
775 			    pAd->StaCfg.RssiSample.AvgRssi0 << 3;
776 			pAd->StaCfg.RssiSample.AvgRssi1 =
777 			    pAd->StaCfg.RssiSample.LastRssi1;
778 			pAd->StaCfg.RssiSample.AvgRssi1X8 =
779 			    pAd->StaCfg.RssiSample.AvgRssi1 << 3;
780 			pAd->StaCfg.RssiSample.AvgRssi2 =
781 			    pAd->StaCfg.RssiSample.LastRssi2;
782 			pAd->StaCfg.RssiSample.AvgRssi2X8 =
783 			    pAd->StaCfg.RssiSample.AvgRssi2 << 3;
784 
785 			/* */
786 			/* We need to check if SSID only set to any, then we can record the current SSID. */
787 			/* Otherwise will cause hidden SSID association failed. */
788 			/* */
789 			if (pAd->MlmeAux.SsidLen == 0) {
790 				NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid,
791 					       SsidLen);
792 				pAd->MlmeAux.SsidLen = SsidLen;
793 			} else {
794 				Idx =
795 				    BssSsidTableSearch(&pAd->ScanTab, Bssid,
796 						       pAd->MlmeAux.Ssid,
797 						       pAd->MlmeAux.SsidLen,
798 						       Channel);
799 
800 				if (Idx == BSS_NOT_FOUND) {
801 					char Rssi = 0;
802 					Rssi =
803 					    RTMPMaxRssi(pAd,
804 							ConvertToRssi(pAd,
805 								      Elem->
806 								      Rssi0,
807 								      RSSI_0),
808 							ConvertToRssi(pAd,
809 								      Elem->
810 								      Rssi1,
811 								      RSSI_1),
812 							ConvertToRssi(pAd,
813 								      Elem->
814 								      Rssi2,
815 								      RSSI_2));
816 					Idx =
817 					    BssTableSetEntry(pAd, &pAd->ScanTab,
818 							     Bssid,
819 							     (char *) Ssid,
820 							     SsidLen, BssType,
821 							     BeaconPeriod, &Cf,
822 							     AtimWin,
823 							     CapabilityInfo,
824 							     SupRate,
825 							     SupRateLen,
826 							     ExtRate,
827 							     ExtRateLen,
828 							     &HtCapability,
829 							     &AddHtInfo,
830 							     HtCapabilityLen,
831 							     AddHtInfoLen,
832 							     NewExtChannelOffset,
833 							     Channel, Rssi,
834 							     TimeStamp,
835 							     CkipFlag,
836 							     &EdcaParm,
837 							     &QosCapability,
838 							     &QbssLoad, LenVIE,
839 							     pVIE);
840 					if (Idx != BSS_NOT_FOUND) {
841 						NdisMoveMemory(pAd->ScanTab.
842 							       BssEntry[Idx].
843 							       PTSF,
844 							       &Elem->Msg[24],
845 							       4);
846 						NdisMoveMemory(&pAd->ScanTab.
847 							       BssEntry[Idx].
848 							       TTSF[0],
849 							       &Elem->TimeStamp.
850 							       u.LowPart, 4);
851 						NdisMoveMemory(&pAd->ScanTab.
852 							       BssEntry[Idx].
853 							       TTSF[4],
854 							       &Elem->TimeStamp.
855 							       u.LowPart, 4);
856 						CapabilityInfo =
857 						    pAd->ScanTab.BssEntry[Idx].
858 						    CapabilityInfo;
859 					}
860 				} else {
861 					/* */
862 					/* Multiple SSID case, used correct CapabilityInfo */
863 					/* */
864 					CapabilityInfo =
865 					    pAd->ScanTab.BssEntry[Idx].
866 					    CapabilityInfo;
867 				}
868 			}
869 			NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
870 			pAd->MlmeAux.CapabilityInfo =
871 			    CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
872 			pAd->MlmeAux.BssType = BssType;
873 			pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
874 			pAd->MlmeAux.Channel = Channel;
875 			pAd->MlmeAux.AtimWin = AtimWin;
876 			pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
877 			pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
878 			pAd->MlmeAux.APRalinkIe = RalinkIe;
879 
880 			/* Copy AP's supported rate to MlmeAux for creating association request */
881 			/* Also filter out not supported rate */
882 			pAd->MlmeAux.SupRateLen = SupRateLen;
883 			NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate,
884 				       SupRateLen);
885 			RTMPCheckRates(pAd, pAd->MlmeAux.SupRate,
886 				       &pAd->MlmeAux.SupRateLen);
887 			pAd->MlmeAux.ExtRateLen = ExtRateLen;
888 			NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate,
889 				       ExtRateLen);
890 			RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate,
891 				       &pAd->MlmeAux.ExtRateLen);
892 
893 			NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet,
894 				       16);
895 
896 			if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled)
897 			     && (pAd->StaCfg.WepStatus !=
898 				 Ndis802_11Encryption2Enabled))
899 			    || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) {
900 				bAllowNrate = TRUE;
901 			}
902 
903 			pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
904 			pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
905 
906 			RTMPZeroMemory(&pAd->MlmeAux.HtCapability,
907 				       SIZE_HT_CAP_IE);
908 			/* filter out un-supported ht rates */
909 			if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
910 			    && ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
911 				&& (bAllowNrate))) {
912 				RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo,
913 					       &AddHtInfo, SIZE_ADD_HT_INFO_IE);
914 
915 				/* StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability */
916 				NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.
917 					       MCSSet, HtCapability.MCSSet, 16);
918 				pAd->MlmeAux.NewExtChannelOffset =
919 				    NewExtChannelOffset;
920 				pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
921 				pAd->StaActive.SupportedPhyInfo.bHtEnable =
922 				    TRUE;
923 				if (PreNHtCapabilityLen > 0)
924 					pAd->StaActive.SupportedPhyInfo.
925 					    bPreNHt = TRUE;
926 				RTMPCheckHt(pAd, BSSID_WCID, &HtCapability,
927 					    &AddHtInfo);
928 				/* Copy AP Parameter to StaActive.  This is also in LinkUp. */
929 				DBGPRINT(RT_DEBUG_TRACE,
930 					 ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
931 					  pAd->StaActive.SupportedHtPhy.
932 					  MpduDensity,
933 					  pAd->StaActive.SupportedHtPhy.
934 					  MaxRAmpduFactor,
935 					  HtCapability.HtCapInfo.ChannelWidth));
936 
937 				if (AddHtInfoLen > 0) {
938 					CentralChannel = AddHtInfo.ControlChan;
939 					/* Check again the Bandwidth capability of this AP. */
940 					if ((AddHtInfo.ControlChan > 2)
941 					    && (AddHtInfo.AddHtInfo.
942 						ExtChanOffset == EXTCHA_BELOW)
943 					    && (HtCapability.HtCapInfo.
944 						ChannelWidth == BW_40)) {
945 						CentralChannel =
946 						    AddHtInfo.ControlChan - 2;
947 					} else
948 					    if ((AddHtInfo.AddHtInfo.
949 						 ExtChanOffset == EXTCHA_ABOVE)
950 						&& (HtCapability.HtCapInfo.
951 						    ChannelWidth == BW_40)) {
952 						CentralChannel =
953 						    AddHtInfo.ControlChan + 2;
954 					}
955 					/* Check Error . */
956 					if (pAd->MlmeAux.CentralChannel !=
957 					    CentralChannel)
958 						DBGPRINT(RT_DEBUG_ERROR,
959 							 ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n",
960 							  CentralChannel,
961 							  AddHtInfo.ControlChan,
962 							  pAd->MlmeAux.
963 							  CentralChannel));
964 
965 					DBGPRINT(RT_DEBUG_TRACE,
966 						 ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d,  .\n",
967 						  CentralChannel,
968 						  AddHtInfo.ControlChan));
969 
970 				}
971 
972 			} else {
973 				/* To prevent error, let legacy AP must have same CentralChannel and Channel. */
974 				if ((HtCapabilityLen == 0)
975 				    && (PreNHtCapabilityLen == 0))
976 					pAd->MlmeAux.CentralChannel =
977 					    pAd->MlmeAux.Channel;
978 
979 				pAd->StaActive.SupportedPhyInfo.bHtEnable =
980 				    FALSE;
981 				pAd->MlmeAux.NewExtChannelOffset = 0xff;
982 				RTMPZeroMemory(&pAd->MlmeAux.HtCapability,
983 					       SIZE_HT_CAP_IE);
984 				pAd->MlmeAux.HtCapabilityLen = 0;
985 				RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo,
986 					       SIZE_ADD_HT_INFO_IE);
987 			}
988 
989 			RTMPUpdateMlmeRate(pAd);
990 
991 			/* copy QOS related information */
992 			if ((pAd->CommonCfg.bWmmCapable)
993 			    || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
994 			    ) {
995 				NdisMoveMemory(&pAd->MlmeAux.APEdcaParm,
996 					       &EdcaParm, sizeof(struct rt_edca_parm));
997 				NdisMoveMemory(&pAd->MlmeAux.APQbssLoad,
998 					       &QbssLoad,
999 					       sizeof(struct rt_qbss_load_parm));
1000 				NdisMoveMemory(&pAd->MlmeAux.APQosCapability,
1001 					       &QosCapability,
1002 					       sizeof(struct rt_qos_capability_parm));
1003 			} else {
1004 				NdisZeroMemory(&pAd->MlmeAux.APEdcaParm,
1005 					       sizeof(struct rt_edca_parm));
1006 				NdisZeroMemory(&pAd->MlmeAux.APQbssLoad,
1007 					       sizeof(struct rt_qbss_load_parm));
1008 				NdisZeroMemory(&pAd->MlmeAux.APQosCapability,
1009 					       sizeof(struct rt_qos_capability_parm));
1010 			}
1011 
1012 			DBGPRINT(RT_DEBUG_TRACE,
1013 				 ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
1014 				  pAd->MlmeAux.SupRateLen,
1015 				  pAd->MlmeAux.ExtRateLen));
1016 
1017 			if (AironetCellPowerLimit != 0xFF) {
1018 				/*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */
1019 				ChangeToCellPowerLimit(pAd,
1020 						       AironetCellPowerLimit);
1021 			} else	/*Used the default TX Power Percentage. */
1022 				pAd->CommonCfg.TxPowerPercentage =
1023 				    pAd->CommonCfg.TxPowerDefault;
1024 
1025 			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1026 			Status = MLME_SUCCESS;
1027 			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF,
1028 				    2, &Status);
1029 		}
1030 		/* not to me BEACON, ignored */
1031 	}
1032 	/* sanity check fail, ignore this frame */
1033 }
1034 
1035 /*
1036 	==========================================================================
1037 	Description:
1038 		receive BEACON from peer
1039 
1040 	IRQL = DISPATCH_LEVEL
1041 
1042 	==========================================================================
1043  */
PeerBeacon(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)1044 void PeerBeacon(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1045 {
1046 	u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
1047 	char Ssid[MAX_LEN_OF_SSID];
1048 	struct rt_cf_parm CfParm;
1049 	u8 SsidLen, MessageToMe = 0, BssType, Channel, NewChannel, index = 0;
1050 	u8 DtimCount = 0, DtimPeriod = 0, BcastFlag = 0;
1051 	u16 CapabilityInfo, AtimWin, BeaconPeriod;
1052 	LARGE_INTEGER TimeStamp;
1053 	u16 TbttNumToNextWakeUp;
1054 	u8 Erp;
1055 	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
1056 	    ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1057 	u8 SupRateLen, ExtRateLen;
1058 	u8 CkipFlag;
1059 	u16 LenVIE;
1060 	u8 AironetCellPowerLimit;
1061 	struct rt_edca_parm EdcaParm;
1062 	struct rt_qbss_load_parm QbssLoad;
1063 	struct rt_qos_capability_parm QosCapability;
1064 	unsigned long RalinkIe;
1065 	/* New for WPA security suites */
1066 	u8 VarIE[MAX_VIE_LEN];	/* Total VIE length = MAX_VIE_LEN - -5 */
1067 	struct rt_ndis_802_11_variable_ies *pVIE = NULL;
1068 	struct rt_ht_capability_ie HtCapability;
1069 	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
1070 	u8 HtCapabilityLen, PreNHtCapabilityLen;
1071 	u8 AddHtInfoLen;
1072 	u8 NewExtChannelOffset = 0xff;
1073 
1074 	if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
1075 	    ))
1076 		return;
1077 
1078 	/* Init Variable IE structure */
1079 	pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
1080 	pVIE->Length = 0;
1081 	RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
1082 	RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
1083 
1084 	if (PeerBeaconAndProbeRspSanity(pAd,
1085 					Elem->Msg,
1086 					Elem->MsgLen,
1087 					Elem->Channel,
1088 					Addr2,
1089 					Bssid,
1090 					Ssid,
1091 					&SsidLen,
1092 					&BssType,
1093 					&BeaconPeriod,
1094 					&Channel,
1095 					&NewChannel,
1096 					&TimeStamp,
1097 					&CfParm,
1098 					&AtimWin,
1099 					&CapabilityInfo,
1100 					&Erp,
1101 					&DtimCount,
1102 					&DtimPeriod,
1103 					&BcastFlag,
1104 					&MessageToMe,
1105 					SupRate,
1106 					&SupRateLen,
1107 					ExtRate,
1108 					&ExtRateLen,
1109 					&CkipFlag,
1110 					&AironetCellPowerLimit,
1111 					&EdcaParm,
1112 					&QbssLoad,
1113 					&QosCapability,
1114 					&RalinkIe,
1115 					&HtCapabilityLen,
1116 					&PreNHtCapabilityLen,
1117 					&HtCapability,
1118 					&AddHtInfoLen,
1119 					&AddHtInfo,
1120 					&NewExtChannelOffset, &LenVIE, pVIE)) {
1121 		BOOLEAN is_my_bssid, is_my_ssid;
1122 		unsigned long Bssidx, Now;
1123 		struct rt_bss_entry *pBss;
1124 		char RealRssi =
1125 		    RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
1126 				ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
1127 				ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1128 
1129 		is_my_bssid =
1130 		    MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid) ? TRUE : FALSE;
1131 		is_my_ssid =
1132 		    SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid,
1133 			       pAd->CommonCfg.SsidLen) ? TRUE : FALSE;
1134 
1135 		/* ignore BEACON not for my SSID */
1136 		if ((!is_my_ssid) && (!is_my_bssid))
1137 			return;
1138 
1139 		/* It means STA waits disassoc completely from this AP, ignores this beacon. */
1140 		if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
1141 			return;
1142 
1143 		/* Copy Control channel for this BSSID. */
1144 		if (AddHtInfoLen != 0)
1145 			Channel = AddHtInfo.ControlChan;
1146 
1147 		if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
1148 			HtCapabilityLen = SIZE_HT_CAP_IE;
1149 
1150 		/* */
1151 		/* Housekeeping "SsidBssTab" table for later-on ROAMing usage. */
1152 		/* */
1153 		Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1154 		if (Bssidx == BSS_NOT_FOUND) {
1155 			/* discover new AP of this network, create BSS entry */
1156 			Bssidx =
1157 			    BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid,
1158 					     SsidLen, BssType, BeaconPeriod,
1159 					     &CfParm, AtimWin, CapabilityInfo,
1160 					     SupRate, SupRateLen, ExtRate,
1161 					     ExtRateLen, &HtCapability,
1162 					     &AddHtInfo, HtCapabilityLen,
1163 					     AddHtInfoLen, NewExtChannelOffset,
1164 					     Channel, RealRssi, TimeStamp,
1165 					     CkipFlag, &EdcaParm,
1166 					     &QosCapability, &QbssLoad, LenVIE,
1167 					     pVIE);
1168 			if (Bssidx == BSS_NOT_FOUND)	/* return if BSS table full */
1169 				return;
1170 
1171 			NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF,
1172 				       &Elem->Msg[24], 4);
1173 			NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0],
1174 				       &Elem->TimeStamp.u.LowPart, 4);
1175 			NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4],
1176 				       &Elem->TimeStamp.u.LowPart, 4);
1177 
1178 		}
1179 
1180 		if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0)
1181 		    && (Channel != NewChannel)) {
1182 			/* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */
1183 			/* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */
1184 			AsicSwitchChannel(pAd, 1, FALSE);
1185 			AsicLockChannel(pAd, 1);
1186 			LinkDown(pAd, FALSE);
1187 			MlmeQueueInit(&pAd->Mlme.Queue);
1188 			BssTableInit(&pAd->ScanTab);
1189 			RTMPusecDelay(1000000);	/* use delay to prevent STA do reassoc */
1190 
1191 			/* channel sanity check */
1192 			for (index = 0; index < pAd->ChannelListNum; index++) {
1193 				if (pAd->ChannelList[index].Channel ==
1194 				    NewChannel) {
1195 					pAd->ScanTab.BssEntry[Bssidx].Channel =
1196 					    NewChannel;
1197 					pAd->CommonCfg.Channel = NewChannel;
1198 					AsicSwitchChannel(pAd,
1199 							  pAd->CommonCfg.
1200 							  Channel, FALSE);
1201 					AsicLockChannel(pAd,
1202 							pAd->CommonCfg.Channel);
1203 					DBGPRINT(RT_DEBUG_TRACE,
1204 						 ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n",
1205 						  NewChannel));
1206 					break;
1207 				}
1208 			}
1209 
1210 			if (index >= pAd->ChannelListNum) {
1211 				DBGPRINT_ERR("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum);
1212 			}
1213 		}
1214 		/* if the ssid matched & bssid unmatched, we should select the bssid with large value. */
1215 		/* This might happened when two STA start at the same time */
1216 		if ((!is_my_bssid) && ADHOC_ON(pAd)) {
1217 			int i;
1218 
1219 			/* Add the safeguard against the mismatch of adhoc wep status */
1220 			if (pAd->StaCfg.WepStatus !=
1221 			    pAd->ScanTab.BssEntry[Bssidx].WepStatus) {
1222 				return;
1223 			}
1224 			/* collapse into the ADHOC network which has bigger BSSID value. */
1225 			for (i = 0; i < 6; i++) {
1226 				if (Bssid[i] > pAd->CommonCfg.Bssid[i]) {
1227 					DBGPRINT(RT_DEBUG_TRACE,
1228 						("SYNC - merge to the IBSS "
1229 							"with bigger BSSID="
1230 							"%pM\n", Bssid));
1231 					AsicDisableSync(pAd);
1232 					COPY_MAC_ADDR(pAd->CommonCfg.Bssid,
1233 						      Bssid);
1234 					AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1235 					MakeIbssBeacon(pAd);	/* re-build BEACON frame */
1236 					AsicEnableIbssSync(pAd);	/* copy BEACON frame to on-chip memory */
1237 					is_my_bssid = TRUE;
1238 					break;
1239 				} else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
1240 					break;
1241 			}
1242 		}
1243 
1244 		NdisGetSystemUpTime(&Now);
1245 		pBss = &pAd->ScanTab.BssEntry[Bssidx];
1246 		pBss->Rssi = RealRssi;	/* lastest RSSI */
1247 		pBss->LastBeaconRxTime = Now;	/* last RX timestamp */
1248 
1249 		/* */
1250 		/* BEACON from my BSSID - either IBSS or INFRA network */
1251 		/* */
1252 		if (is_my_bssid) {
1253 			struct rt_rxwi RxWI;
1254 
1255 			pAd->StaCfg.DtimCount = DtimCount;
1256 			pAd->StaCfg.DtimPeriod = DtimPeriod;
1257 			pAd->StaCfg.LastBeaconRxTime = Now;
1258 
1259 			RxWI.RSSI0 = Elem->Rssi0;
1260 			RxWI.RSSI1 = Elem->Rssi1;
1261 			RxWI.RSSI2 = Elem->Rssi2;
1262 
1263 			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
1264 			if (AironetCellPowerLimit != 0xFF) {
1265 				/* */
1266 				/* We get the Cisco (ccx) "TxPower Limit" required */
1267 				/* Changed to appropriate TxPower Limit for Ciso Compatible Extensions */
1268 				/* */
1269 				ChangeToCellPowerLimit(pAd,
1270 						       AironetCellPowerLimit);
1271 			} else {
1272 				/* */
1273 				/* AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist. */
1274 				/* Used the default TX Power Percentage, that set from UI. */
1275 				/* */
1276 				pAd->CommonCfg.TxPowerPercentage =
1277 				    pAd->CommonCfg.TxPowerDefault;
1278 			}
1279 
1280 			if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo))) {
1281 				u8 MaxSupportedRateIn500Kbps = 0;
1282 				u8 idx;
1283 				struct rt_mac_table_entry *pEntry;
1284 
1285 				/* supported rates array may not be sorted. sort it and find the maximum rate */
1286 				for (idx = 0; idx < SupRateLen; idx++) {
1287 					if (MaxSupportedRateIn500Kbps <
1288 					    (SupRate[idx] & 0x7f))
1289 						MaxSupportedRateIn500Kbps =
1290 						    SupRate[idx] & 0x7f;
1291 				}
1292 
1293 				for (idx = 0; idx < ExtRateLen; idx++) {
1294 					if (MaxSupportedRateIn500Kbps <
1295 					    (ExtRate[idx] & 0x7f))
1296 						MaxSupportedRateIn500Kbps =
1297 						    ExtRate[idx] & 0x7f;
1298 				}
1299 
1300 				/* look up the existing table */
1301 				pEntry = MacTableLookup(pAd, Addr2);
1302 
1303 				/* Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon. */
1304 				/* To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station. */
1305 				if ((ADHOC_ON(pAd)
1306 				     && (Elem->Wcid == RESERVED_WCID))
1307 				    || (pEntry
1308 					&&
1309 					((pEntry->LastBeaconRxTime +
1310 					  ADHOC_ENTRY_BEACON_LOST_TIME) <
1311 					 Now))) {
1312 					if (pEntry == NULL)
1313 						/* Another adhoc joining, add to our MAC table. */
1314 						pEntry =
1315 						    MacTableInsertEntry(pAd,
1316 									Addr2,
1317 									BSS0,
1318 									FALSE);
1319 
1320 					if (StaAddMacTableEntry(pAd,
1321 								pEntry,
1322 								MaxSupportedRateIn500Kbps,
1323 								&HtCapability,
1324 								HtCapabilityLen,
1325 								&AddHtInfo,
1326 								AddHtInfoLen,
1327 								CapabilityInfo)
1328 					    == FALSE) {
1329 						DBGPRINT(RT_DEBUG_TRACE,
1330 							 ("ADHOC - Add Entry failed.\n"));
1331 						return;
1332 					}
1333 
1334 					if (pEntry &&
1335 					    (Elem->Wcid == RESERVED_WCID)) {
1336 						idx = pAd->StaCfg.DefaultKeyId;
1337 						RTMP_STA_SECURITY_INFO_ADD(pAd,
1338 									   BSS0,
1339 									   idx,
1340 									   pEntry);
1341 					}
1342 				}
1343 
1344 				if (pEntry && pEntry->ValidAsCLI)
1345 					pEntry->LastBeaconRxTime = Now;
1346 
1347 				/* At least another peer in this IBSS, declare MediaState as CONNECTED */
1348 				if (!OPSTATUS_TEST_FLAG
1349 				    (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
1350 					OPSTATUS_SET_FLAG(pAd,
1351 							  fOP_STATUS_MEDIA_STATE_CONNECTED);
1352 
1353 					pAd->IndicateMediaState =
1354 					    NdisMediaStateConnected;
1355 					RTMP_IndicateMediaState(pAd);
1356 					pAd->ExtraInfo = GENERAL_LINK_UP;
1357 					AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1358 
1359 					/* 2003/03/12 - john */
1360 					/* Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that */
1361 					/* "site survey" result should always include the current connected network. */
1362 					/* */
1363 					Bssidx =
1364 					    BssTableSearch(&pAd->ScanTab, Bssid,
1365 							   Channel);
1366 					if (Bssidx == BSS_NOT_FOUND) {
1367 						Bssidx =
1368 						    BssTableSetEntry(pAd,
1369 								     &pAd->
1370 								     ScanTab,
1371 								     Bssid,
1372 								     Ssid,
1373 								     SsidLen,
1374 								     BssType,
1375 								     BeaconPeriod,
1376 								     &CfParm,
1377 								     AtimWin,
1378 								     CapabilityInfo,
1379 								     SupRate,
1380 								     SupRateLen,
1381 								     ExtRate,
1382 								     ExtRateLen,
1383 								     &HtCapability,
1384 								     &AddHtInfo,
1385 								     HtCapabilityLen,
1386 								     AddHtInfoLen,
1387 								     NewExtChannelOffset,
1388 								     Channel,
1389 								     RealRssi,
1390 								     TimeStamp,
1391 								     0,
1392 								     &EdcaParm,
1393 								     &QosCapability,
1394 								     &QbssLoad,
1395 								     LenVIE,
1396 								     pVIE);
1397 					}
1398 					DBGPRINT(RT_DEBUG_TRACE,
1399 						 ("ADHOC  fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1400 				}
1401 			}
1402 
1403 			if (INFRA_ON(pAd)) {
1404 				BOOLEAN bUseShortSlot, bUseBGProtection;
1405 
1406 				/* decide to use/change to - */
1407 				/*      1. long slot (20 us) or short slot (9 us) time */
1408 				/*      2. turn on/off RTS/CTS and/or CTS-to-self protection */
1409 				/*      3. short preamble */
1410 
1411 				/*bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo); */
1412 				bUseShortSlot =
1413 				    CAP_IS_SHORT_SLOT(CapabilityInfo);
1414 				if (bUseShortSlot !=
1415 				    OPSTATUS_TEST_FLAG(pAd,
1416 						       fOP_STATUS_SHORT_SLOT_INUSED))
1417 					AsicSetSlotTime(pAd, bUseShortSlot);
1418 
1419 				bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) ||	/* always use */
1420 				    ((pAd->CommonCfg.UseBGProtection == 0)
1421 				     && ERP_IS_USE_PROTECTION(Erp));
1422 
1423 				if (pAd->CommonCfg.Channel > 14)	/* always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP */
1424 					bUseBGProtection = FALSE;
1425 
1426 				if (bUseBGProtection !=
1427 				    OPSTATUS_TEST_FLAG(pAd,
1428 						       fOP_STATUS_BG_PROTECTION_INUSED))
1429 				{
1430 					if (bUseBGProtection) {
1431 						OPSTATUS_SET_FLAG(pAd,
1432 								  fOP_STATUS_BG_PROTECTION_INUSED);
1433 						AsicUpdateProtect(pAd,
1434 								  pAd->MlmeAux.
1435 								  AddHtInfo.
1436 								  AddHtInfo2.
1437 								  OperaionMode,
1438 								  (OFDMSETPROTECT
1439 								   |
1440 								   CCKSETPROTECT
1441 								   |
1442 								   ALLN_SETPROTECT),
1443 								  FALSE,
1444 								  (pAd->MlmeAux.
1445 								   AddHtInfo.
1446 								   AddHtInfo2.
1447 								   NonGfPresent
1448 								   == 1));
1449 					} else {
1450 						OPSTATUS_CLEAR_FLAG(pAd,
1451 								    fOP_STATUS_BG_PROTECTION_INUSED);
1452 						AsicUpdateProtect(pAd,
1453 								  pAd->MlmeAux.
1454 								  AddHtInfo.
1455 								  AddHtInfo2.
1456 								  OperaionMode,
1457 								  (OFDMSETPROTECT
1458 								   |
1459 								   CCKSETPROTECT
1460 								   |
1461 								   ALLN_SETPROTECT),
1462 								  TRUE,
1463 								  (pAd->MlmeAux.
1464 								   AddHtInfo.
1465 								   AddHtInfo2.
1466 								   NonGfPresent
1467 								   == 1));
1468 					}
1469 
1470 					DBGPRINT(RT_DEBUG_WARN,
1471 						 ("SYNC - AP changed B/G protection to %d\n",
1472 						  bUseBGProtection));
1473 				}
1474 				/* check Ht protection mode. and adhere to the Non-GF device indication by AP. */
1475 				if ((AddHtInfoLen != 0) &&
1476 				    ((AddHtInfo.AddHtInfo2.OperaionMode !=
1477 				      pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1478 				      OperaionMode)
1479 				     || (AddHtInfo.AddHtInfo2.NonGfPresent !=
1480 					 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1481 					 NonGfPresent))) {
1482 					pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1483 					    NonGfPresent =
1484 					    AddHtInfo.AddHtInfo2.NonGfPresent;
1485 					pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1486 					    OperaionMode =
1487 					    AddHtInfo.AddHtInfo2.OperaionMode;
1488 					if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1489 					    NonGfPresent == 1) {
1490 						AsicUpdateProtect(pAd,
1491 								  pAd->MlmeAux.
1492 								  AddHtInfo.
1493 								  AddHtInfo2.
1494 								  OperaionMode,
1495 								  ALLN_SETPROTECT,
1496 								  FALSE, TRUE);
1497 					} else
1498 						AsicUpdateProtect(pAd,
1499 								  pAd->MlmeAux.
1500 								  AddHtInfo.
1501 								  AddHtInfo2.
1502 								  OperaionMode,
1503 								  ALLN_SETPROTECT,
1504 								  FALSE, FALSE);
1505 
1506 					DBGPRINT(RT_DEBUG_TRACE,
1507 						 ("SYNC - AP changed N OperaionMode to %d\n",
1508 						  pAd->MlmeAux.AddHtInfo.
1509 						  AddHtInfo2.OperaionMode));
1510 				}
1511 
1512 				if (OPSTATUS_TEST_FLAG
1513 				    (pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED)
1514 				    && ERP_IS_USE_BARKER_PREAMBLE(Erp)) {
1515 					MlmeSetTxPreamble(pAd,
1516 							  Rt802_11PreambleLong);
1517 					DBGPRINT(RT_DEBUG_TRACE,
1518 						 ("SYNC - AP forced to use long preamble\n"));
1519 				}
1520 
1521 				if (OPSTATUS_TEST_FLAG
1522 				    (pAd, fOP_STATUS_WMM_INUSED)
1523 				    && (EdcaParm.bValid == TRUE)
1524 				    && (EdcaParm.EdcaUpdateCount !=
1525 					pAd->CommonCfg.APEdcaParm.
1526 					EdcaUpdateCount)) {
1527 					DBGPRINT(RT_DEBUG_TRACE,
1528 						 ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1529 						  pAd->CommonCfg.APEdcaParm.
1530 						  EdcaUpdateCount,
1531 						  EdcaParm.EdcaUpdateCount));
1532 					AsicSetEdcaParm(pAd, &EdcaParm);
1533 				}
1534 				/* copy QOS related information */
1535 				NdisMoveMemory(&pAd->CommonCfg.APQbssLoad,
1536 					       &QbssLoad,
1537 					       sizeof(struct rt_qbss_load_parm));
1538 				NdisMoveMemory(&pAd->CommonCfg.APQosCapability,
1539 					       &QosCapability,
1540 					       sizeof(struct rt_qos_capability_parm));
1541 			}
1542 			/* only INFRASTRUCTURE mode support power-saving feature */
1543 			if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE))
1544 			    || (pAd->CommonCfg.bAPSDForcePowerSave)) {
1545 				u8 FreeNumber;
1546 				/*  1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL */
1547 				/*  2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE */
1548 				/*  3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE */
1549 				/*  4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE */
1550 				/*  5. otherwise, put PHY back to sleep to save battery. */
1551 				if (MessageToMe) {
1552 #ifdef RTMP_MAC_PCI
1553 					if (OPSTATUS_TEST_FLAG
1554 					    (pAd, fOP_STATUS_PCIE_DEVICE)) {
1555 						/* Restore to correct BBP R3 value */
1556 						if (pAd->Antenna.field.RxPath >
1557 						    1)
1558 							RTMP_BBP_IO_WRITE8_BY_REG_ID
1559 							    (pAd, BBP_R3,
1560 							     pAd->StaCfg.BBPR3);
1561 						/* Turn clk to 80Mhz. */
1562 					}
1563 #endif /* RTMP_MAC_PCI // */
1564 					if (pAd->CommonCfg.bAPSDCapable
1565 					    && pAd->CommonCfg.APEdcaParm.
1566 					    bAPSDCapable
1567 					    && pAd->CommonCfg.bAPSDAC_BE
1568 					    && pAd->CommonCfg.bAPSDAC_BK
1569 					    && pAd->CommonCfg.bAPSDAC_VI
1570 					    && pAd->CommonCfg.bAPSDAC_VO) {
1571 						pAd->CommonCfg.
1572 						    bNeedSendTriggerFrame =
1573 						    TRUE;
1574 					} else
1575 						RTMP_PS_POLL_ENQUEUE(pAd);
1576 				} else if (BcastFlag && (DtimCount == 0)
1577 					   && OPSTATUS_TEST_FLAG(pAd,
1578 								 fOP_STATUS_RECEIVE_DTIM))
1579 				{
1580 #ifdef RTMP_MAC_PCI
1581 					if (OPSTATUS_TEST_FLAG
1582 					    (pAd, fOP_STATUS_PCIE_DEVICE)) {
1583 						if (pAd->Antenna.field.RxPath >
1584 						    1)
1585 							RTMP_BBP_IO_WRITE8_BY_REG_ID
1586 							    (pAd, BBP_R3,
1587 							     pAd->StaCfg.BBPR3);
1588 					}
1589 #endif /* RTMP_MAC_PCI // */
1590 				} else
1591 				    if ((pAd->TxSwQueue[QID_AC_BK].Number != 0)
1592 					|| (pAd->TxSwQueue[QID_AC_BE].Number !=
1593 					    0)
1594 					|| (pAd->TxSwQueue[QID_AC_VI].Number !=
1595 					    0)
1596 					|| (pAd->TxSwQueue[QID_AC_VO].Number !=
1597 					    0)
1598 					||
1599 					(RTMPFreeTXDRequest
1600 					 (pAd, QID_AC_BK, TX_RING_SIZE - 1,
1601 					  &FreeNumber) != NDIS_STATUS_SUCCESS)
1602 					||
1603 					(RTMPFreeTXDRequest
1604 					 (pAd, QID_AC_BE, TX_RING_SIZE - 1,
1605 					  &FreeNumber) != NDIS_STATUS_SUCCESS)
1606 					||
1607 					(RTMPFreeTXDRequest
1608 					 (pAd, QID_AC_VI, TX_RING_SIZE - 1,
1609 					  &FreeNumber) != NDIS_STATUS_SUCCESS)
1610 					||
1611 					(RTMPFreeTXDRequest
1612 					 (pAd, QID_AC_VO, TX_RING_SIZE - 1,
1613 					  &FreeNumber) != NDIS_STATUS_SUCCESS)
1614 					||
1615 					(RTMPFreeTXDRequest
1616 					 (pAd, QID_MGMT, MGMT_RING_SIZE - 1,
1617 					  &FreeNumber) !=
1618 					 NDIS_STATUS_SUCCESS)) {
1619 					/* TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme */
1620 					/* can we cheat here (i.e. just check MGMT & AC_BE) for better performance? */
1621 #ifdef RTMP_MAC_PCI
1622 					if (OPSTATUS_TEST_FLAG
1623 					    (pAd, fOP_STATUS_PCIE_DEVICE)) {
1624 						if (pAd->Antenna.field.RxPath >
1625 						    1)
1626 							RTMP_BBP_IO_WRITE8_BY_REG_ID
1627 							    (pAd, BBP_R3,
1628 							     pAd->StaCfg.BBPR3);
1629 					}
1630 #endif /* RTMP_MAC_PCI // */
1631 				} else {
1632 					if ((pAd->CommonCfg.
1633 					     bACMAPSDTr[QID_AC_VO])
1634 					    || (pAd->CommonCfg.
1635 						bACMAPSDTr[QID_AC_VI])
1636 					    || (pAd->CommonCfg.
1637 						bACMAPSDTr[QID_AC_BK])
1638 					    || (pAd->CommonCfg.
1639 						bACMAPSDTr[QID_AC_BE])) {
1640 						/*
1641 						   WMM Spec v1.0 3.6.2.4,
1642 						   The WMM STA shall remain awake until it receives a
1643 						   QoS Data or Null frame addressed to it, with the
1644 						   EOSP subfield in QoS Control field set to 1.
1645 
1646 						   So we can not sleep here or we will suffer a case:
1647 
1648 						   PS Management Frame -->
1649 						   Trigger frame -->
1650 						   Beacon (TIM=0) (Beacon is closer to Trig frame) -->
1651 						   Station goes to sleep -->
1652 						   AP delivery queued UAPSD packets -->
1653 						   Station can NOT receive the reply
1654 
1655 						   Maybe we need a timeout timer to avoid that we do
1656 						   NOT receive the EOSP frame.
1657 
1658 						   We can not use More Data to check if SP is ended
1659 						   due to MaxSPLength.
1660 						 */
1661 					} else {
1662 						u16 NextDtim = DtimCount;
1663 
1664 						if (NextDtim == 0)
1665 							NextDtim = DtimPeriod;
1666 
1667 						TbttNumToNextWakeUp =
1668 						    pAd->StaCfg.
1669 						    DefaultListenCount;
1670 						if (OPSTATUS_TEST_FLAG
1671 						    (pAd,
1672 						     fOP_STATUS_RECEIVE_DTIM)
1673 						    && (TbttNumToNextWakeUp >
1674 							NextDtim))
1675 							TbttNumToNextWakeUp =
1676 							    NextDtim;
1677 
1678 						if (!OPSTATUS_TEST_FLAG
1679 						    (pAd, fOP_STATUS_DOZE)) {
1680 							/* Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode. */
1681 							pAd->
1682 							    ThisTbttNumToNextWakeUp
1683 							    =
1684 							    TbttNumToNextWakeUp;
1685 							AsicSleepThenAutoWakeup
1686 							    (pAd,
1687 							     pAd->
1688 							     ThisTbttNumToNextWakeUp);
1689 						}
1690 					}
1691 				}
1692 			}
1693 		}
1694 		/* not my BSSID, ignore it */
1695 	}
1696 	/* sanity check fail, ignore this frame */
1697 }
1698 
1699 /*
1700 	==========================================================================
1701 	Description:
1702 		Receive PROBE REQ from remote peer when operating in IBSS mode
1703 	==========================================================================
1704  */
PeerProbeReqAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)1705 void PeerProbeReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1706 {
1707 	u8 Addr2[MAC_ADDR_LEN];
1708 	char Ssid[MAX_LEN_OF_SSID];
1709 	u8 SsidLen;
1710 	u8 HtLen, AddHtLen, NewExtLen;
1711 	struct rt_header_802_11 ProbeRspHdr;
1712 	int NStatus;
1713 	u8 *pOutBuffer = NULL;
1714 	unsigned long FrameLen = 0;
1715 	LARGE_INTEGER FakeTimestamp;
1716 	u8 DsLen = 1, IbssLen = 2;
1717 	u8 LocalErpIe[3] = { IE_ERP, 1, 0 };
1718 	BOOLEAN Privacy;
1719 	u16 CapabilityInfo;
1720 	u8 RSNIe = IE_WPA;
1721 
1722 	if (!ADHOC_ON(pAd))
1723 		return;
1724 
1725 	if (PeerProbeReqSanity
1726 	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen)) {
1727 		if ((SsidLen == 0)
1728 		    || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid,
1729 				  pAd->CommonCfg.SsidLen)) {
1730 			/* allocate and send out ProbeRsp frame */
1731 			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
1732 			if (NStatus != NDIS_STATUS_SUCCESS)
1733 				return;
1734 
1735 			/*pAd->StaCfg.AtimWin = 0;  // ?????? */
1736 
1737 			Privacy =
1738 			    (pAd->StaCfg.WepStatus ==
1739 			     Ndis802_11Encryption1Enabled)
1740 			    || (pAd->StaCfg.WepStatus ==
1741 				Ndis802_11Encryption2Enabled)
1742 			    || (pAd->StaCfg.WepStatus ==
1743 				Ndis802_11Encryption3Enabled);
1744 			CapabilityInfo =
1745 			    CAP_GENERATE(0, 1, Privacy,
1746 					 (pAd->CommonCfg.TxPreamble ==
1747 					  Rt802_11PreambleShort), 0, 0);
1748 
1749 			MakeOutgoingFrame(pOutBuffer, &FrameLen,
1750 					  sizeof(struct rt_header_802_11), &ProbeRspHdr,
1751 					  TIMESTAMP_LEN, &FakeTimestamp,
1752 					  2, &pAd->CommonCfg.BeaconPeriod,
1753 					  2, &CapabilityInfo,
1754 					  1, &SsidIe,
1755 					  1, &pAd->CommonCfg.SsidLen,
1756 					  pAd->CommonCfg.SsidLen,
1757 					  pAd->CommonCfg.Ssid, 1, &SupRateIe, 1,
1758 					  &pAd->StaActive.SupRateLen,
1759 					  pAd->StaActive.SupRateLen,
1760 					  pAd->StaActive.SupRate, 1, &DsIe, 1,
1761 					  &DsLen, 1, &pAd->CommonCfg.Channel, 1,
1762 					  &IbssIe, 1, &IbssLen, 2,
1763 					  &pAd->StaActive.AtimWin, END_OF_ARGS);
1764 
1765 			if (pAd->StaActive.ExtRateLen) {
1766 				unsigned long tmp;
1767 				MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1768 						  3, LocalErpIe,
1769 						  1, &ExtRateIe,
1770 						  1, &pAd->StaActive.ExtRateLen,
1771 						  pAd->StaActive.ExtRateLen,
1772 						  &pAd->StaActive.ExtRate,
1773 						  END_OF_ARGS);
1774 				FrameLen += tmp;
1775 			}
1776 			/* If adhoc secruity is set for WPA-None, append the cipher suite IE */
1777 			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
1778 				unsigned long tmp;
1779 				MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1780 						  1, &RSNIe,
1781 						  1, &pAd->StaCfg.RSNIE_Len,
1782 						  pAd->StaCfg.RSNIE_Len,
1783 						  pAd->StaCfg.RSN_IE,
1784 						  END_OF_ARGS);
1785 				FrameLen += tmp;
1786 			}
1787 
1788 			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
1789 				unsigned long TmpLen;
1790 				u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
1791 				HtLen = sizeof(pAd->CommonCfg.HtCapability);
1792 				AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
1793 				NewExtLen = 1;
1794 				/*New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */
1795 				if (pAd->bBroadComHT == TRUE) {
1796 					MakeOutgoingFrame(pOutBuffer + FrameLen,
1797 							  &TmpLen, 1, &WpaIe, 4,
1798 							  &BROADCOM[0],
1799 							  pAd->MlmeAux.
1800 							  HtCapabilityLen,
1801 							  &pAd->MlmeAux.
1802 							  HtCapability,
1803 							  END_OF_ARGS);
1804 				} else {
1805 					MakeOutgoingFrame(pOutBuffer + FrameLen,
1806 							  &TmpLen, 1, &HtCapIe,
1807 							  1, &HtLen,
1808 							  sizeof
1809 							  (struct rt_ht_capability_ie),
1810 							  &pAd->CommonCfg.
1811 							  HtCapability, 1,
1812 							  &AddHtInfoIe, 1,
1813 							  &AddHtLen,
1814 							  sizeof
1815 							  (struct rt_add_ht_info_ie),
1816 							  &pAd->CommonCfg.
1817 							  AddHTInfo, 1,
1818 							  &NewExtChanIe, 1,
1819 							  &NewExtLen,
1820 							  sizeof
1821 							  (struct rt_new_ext_chan_ie),
1822 							  &pAd->CommonCfg.
1823 							  NewExtChanOffset,
1824 							  END_OF_ARGS);
1825 				}
1826 				FrameLen += TmpLen;
1827 			}
1828 
1829 			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1830 			MlmeFreeMemory(pAd, pOutBuffer);
1831 		}
1832 	}
1833 }
1834 
BeaconTimeoutAtJoinAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)1835 void BeaconTimeoutAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1836 {
1837 	u16 Status;
1838 	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1839 	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1840 	Status = MLME_REJ_TIMEOUT;
1841 	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1842 }
1843 
1844 /*
1845 	==========================================================================
1846 	Description:
1847 		Scan timeout procedure. basically add channel index by 1 and rescan
1848 	==========================================================================
1849  */
ScanTimeoutAction(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)1850 void ScanTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1851 {
1852 	pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
1853 
1854 	/* Only one channel scanned for CISCO beacon request */
1855 	if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
1856 	    (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
1857 	    (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
1858 	    (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
1859 		pAd->MlmeAux.Channel = 0;
1860 
1861 	/* this routine will stop if pAd->MlmeAux.Channel == 0 */
1862 	ScanNextChannel(pAd);
1863 }
1864 
1865 /*
1866 	==========================================================================
1867 	Description:
1868 	==========================================================================
1869  */
InvalidStateWhenScan(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)1870 void InvalidStateWhenScan(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1871 {
1872 	u16 Status;
1873 	DBGPRINT(RT_DEBUG_TRACE,
1874 		 ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n",
1875 		  pAd->Mlme.SyncMachine.CurrState));
1876 	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1877 	Status = MLME_STATE_MACHINE_REJECT;
1878 	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
1879 }
1880 
1881 /*
1882 	==========================================================================
1883 	Description:
1884 	==========================================================================
1885  */
InvalidStateWhenJoin(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)1886 void InvalidStateWhenJoin(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1887 {
1888 	u16 Status;
1889 	DBGPRINT(RT_DEBUG_TRACE,
1890 		 ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n",
1891 		  pAd->Mlme.SyncMachine.CurrState));
1892 	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1893 	Status = MLME_STATE_MACHINE_REJECT;
1894 	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1895 }
1896 
1897 /*
1898 	==========================================================================
1899 	Description:
1900 	==========================================================================
1901  */
InvalidStateWhenStart(struct rt_rtmp_adapter * pAd,struct rt_mlme_queue_elem * Elem)1902 void InvalidStateWhenStart(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1903 {
1904 	u16 Status;
1905 	DBGPRINT(RT_DEBUG_TRACE,
1906 		 ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n",
1907 		  pAd->Mlme.SyncMachine.CurrState));
1908 	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1909 	Status = MLME_STATE_MACHINE_REJECT;
1910 	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
1911 }
1912 
1913 /*
1914 	==========================================================================
1915 	Description:
1916 
1917 	IRQL = DISPATCH_LEVEL
1918 
1919 	==========================================================================
1920  */
EnqueuePsPoll(struct rt_rtmp_adapter * pAd)1921 void EnqueuePsPoll(struct rt_rtmp_adapter *pAd)
1922 {
1923 
1924 	if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
1925 		pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
1926 	MiniportMMRequest(pAd, 0, (u8 *)& pAd->PsPollFrame,
1927 			  sizeof(struct rt_pspoll_frame));
1928 }
1929 
1930 /*
1931 	==========================================================================
1932 	Description:
1933 	==========================================================================
1934  */
EnqueueProbeRequest(struct rt_rtmp_adapter * pAd)1935 void EnqueueProbeRequest(struct rt_rtmp_adapter *pAd)
1936 {
1937 	int NState;
1938 	u8 *pOutBuffer;
1939 	unsigned long FrameLen = 0;
1940 	struct rt_header_802_11 Hdr80211;
1941 
1942 	DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
1943 
1944 	NState = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
1945 	if (NState == NDIS_STATUS_SUCCESS) {
1946 		MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
1947 				 BROADCAST_ADDR, BROADCAST_ADDR);
1948 
1949 		/* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */
1950 		MakeOutgoingFrame(pOutBuffer, &FrameLen,
1951 				  sizeof(struct rt_header_802_11), &Hdr80211,
1952 				  1, &SsidIe,
1953 				  1, &pAd->CommonCfg.SsidLen,
1954 				  pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1955 				  1, &SupRateIe,
1956 				  1, &pAd->StaActive.SupRateLen,
1957 				  pAd->StaActive.SupRateLen,
1958 				  pAd->StaActive.SupRate, END_OF_ARGS);
1959 		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1960 		MlmeFreeMemory(pAd, pOutBuffer);
1961 	}
1962 
1963 }
1964 
ScanRunning(struct rt_rtmp_adapter * pAd)1965 BOOLEAN ScanRunning(struct rt_rtmp_adapter *pAd)
1966 {
1967 	return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;
1968 }
1969