2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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. *
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. *
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. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 modified for rt2561/2661
36 Jan Lee 2006-08-01 modified for rt2860 for 802.11n
38 #include "../rt_config.h"
40 #define ADHOC_ENTRY_BEACON_LOST_TIME (2*OS_HZ) // 2 sec
43 ==========================================================================
45 The sync state machine,
47 Sm - pointer to the state machine
49 the state machine looks like the following
51 ==========================================================================
53 VOID SyncStateMachineInit(
56 OUT STATE_MACHINE_FUNC Trans[])
58 StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE);
61 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction);
62 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction);
63 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction);
64 StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon);
65 StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction);
68 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
69 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
70 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
71 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction);
72 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction);
75 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
76 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
77 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
78 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
79 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
80 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction);
83 RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
84 RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
88 ==========================================================================
90 Beacon timeout handler, executed in timer thread
94 ==========================================================================
97 IN PVOID SystemSpecific1,
98 IN PVOID FunctionContext,
99 IN PVOID SystemSpecific2,
100 IN PVOID SystemSpecific3)
102 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
104 DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n"));
106 // Do nothing if the driver is starting halt state.
107 // This might happen when timer already been fired before cancel timer with mlmehalt
108 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
111 #ifdef DOT11_N_SUPPORT
112 if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
116 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
117 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
118 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
121 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
122 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
124 #endif // DOT11_N_SUPPORT //
126 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
127 RT28XX_MLME_HANDLER(pAd);
131 ==========================================================================
133 Scan timeout handler, executed in timer thread
135 IRQL = DISPATCH_LEVEL
137 ==========================================================================
140 IN PVOID SystemSpecific1,
141 IN PVOID FunctionContext,
142 IN PVOID SystemSpecific2,
143 IN PVOID SystemSpecific3)
145 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
148 // Do nothing if the driver is starting halt state.
149 // This might happen when timer already been fired before cancel timer with mlmehalt
150 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
153 if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL))
155 RT28XX_MLME_HANDLER(pAd);
159 // To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
160 pAd->MlmeAux.Channel = 0;
161 ScanNextChannel(pAd);
162 if (pAd->CommonCfg.bWirelessEvent)
164 RTMPSendWirelessEvent(pAd, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
170 ==========================================================================
172 MLME SCAN req state machine procedure
173 ==========================================================================
175 VOID MlmeScanReqAction(
176 IN PRTMP_ADAPTER pAd,
177 IN MLME_QUEUE_ELEM *Elem)
179 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
180 BOOLEAN TimerCancelled;
183 PHEADER_802_11 pHdr80211;
184 PUCHAR pOutBuffer = NULL;
187 // Check the total scan tries for one single OID command
188 // If this is the CCX 2.0 Case, skip that!
189 if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
191 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n"));
195 // Increase the scan retry counters.
196 pAd->StaCfg.ScanCnt++;
199 // first check the parameter sanity
200 if (MlmeScanReqSanity(pAd,
209 // Check for channel load and noise hist request
210 // Suspend MSDU only at scan request, not the last two mentioned
211 if ((ScanType == SCAN_CISCO_NOISE) || (ScanType == SCAN_CISCO_CHANNEL_LOAD))
213 if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
214 RTMPSuspendMsduTransmission(pAd); // Suspend MSDU transmission here
218 // Suspend MSDU transmission here
219 RTMPSuspendMsduTransmission(pAd);
223 // To prevent data lost.
224 // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
225 // And should send an NULL data with turned PSM bit off to AP, when scan progress done
227 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
229 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
230 if (NStatus == NDIS_STATUS_SUCCESS)
232 pHdr80211 = (PHEADER_802_11) pOutBuffer;
233 MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
234 pHdr80211->Duration = 0;
235 pHdr80211->FC.Type = BTYPE_DATA;
236 pHdr80211->FC.PwrMgmt = PWR_SAVE;
238 // Send using priority queue
239 MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
240 DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
241 MlmeFreeMemory(pAd, pOutBuffer);
246 NdisGetSystemUpTime(&Now);
247 pAd->StaCfg.LastScanTime = Now;
248 // reset all the timers
249 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
250 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
252 // record desired BSS parameters
253 pAd->MlmeAux.BssType = BssType;
254 pAd->MlmeAux.ScanType = ScanType;
255 pAd->MlmeAux.SsidLen = SsidLen;
256 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
257 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
259 // start from the first channel
260 pAd->MlmeAux.Channel = FirstChannel(pAd);
262 // Change the scan channel when dealing with CCX beacon report
263 if ((ScanType == SCAN_CISCO_PASSIVE) || (ScanType == SCAN_CISCO_ACTIVE) ||
264 (ScanType == SCAN_CISCO_CHANNEL_LOAD) || (ScanType == SCAN_CISCO_NOISE))
265 pAd->MlmeAux.Channel = pAd->StaCfg.CCXScanChannel;
267 // Let BBP register at 20MHz to do scan
268 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
270 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
271 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
272 ScanNextChannel(pAd);
276 DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
277 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
278 Status = MLME_INVALID_FORMAT;
279 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
284 ==========================================================================
286 MLME JOIN req state machine procedure
287 ==========================================================================
289 VOID MlmeJoinReqAction(
290 IN PRTMP_ADAPTER pAd,
291 IN MLME_QUEUE_ELEM *Elem)
295 BOOLEAN TimerCancelled;
296 HEADER_802_11 Hdr80211;
299 PUCHAR pOutBuffer = NULL;
300 PUCHAR pSupRate = NULL;
302 PUCHAR pExtRate = NULL;
304 UCHAR ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
305 UCHAR ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR);
306 MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg);
308 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
311 // reset all the timers
312 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
313 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
315 pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
317 // record the desired SSID & BSSID we're waiting for
318 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
320 // If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
321 if (pBss->Hidden == 0)
323 NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
324 pAd->MlmeAux.SsidLen = pBss->SsidLen;
327 pAd->MlmeAux.BssType = pBss->BssType;
328 pAd->MlmeAux.Channel = pBss->Channel;
329 pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
331 #ifdef EXT_BUILD_CHANNEL_LIST
332 // Country IE of the AP will be evaluated and will be used.
333 if ((pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None) &&
334 (pBss->bHasCountryIE == TRUE))
336 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pBss->CountryString[0], 2);
337 if (pBss->CountryString[2] == 'I')
338 pAd->CommonCfg.Geography = IDOR;
339 else if (pBss->CountryString[2] == 'O')
340 pAd->CommonCfg.Geography = ODOR;
342 pAd->CommonCfg.Geography = BOTH;
343 BuildChannelListEx(pAd);
345 #endif // EXT_BUILD_CHANNEL_LIST //
347 // Let BBP register at 20MHz to do scan
348 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
350 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
351 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
353 // switch channel and waiting for beacon timer
354 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
355 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
356 RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
360 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
361 (pAd->MlmeAux.Channel > 14) &&
362 RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
366 // We can't send any Probe request frame to meet 802.11h.
368 if (pBss->Hidden == 0)
373 // send probe request
375 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
376 if (NStatus == NDIS_STATUS_SUCCESS)
378 if (pAd->MlmeAux.Channel <= 14)
380 pSupRate = pAd->CommonCfg.SupRate;
381 SupRateLen = pAd->CommonCfg.SupRateLen;
382 pExtRate = pAd->CommonCfg.ExtRate;
383 ExtRateLen = pAd->CommonCfg.ExtRateLen;
388 // Overwrite Support Rate, CCK rate are not allowed
391 SupRateLen = ASupRateLen;
395 if (pAd->MlmeAux.BssType == BSS_INFRA)
396 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, pAd->MlmeAux.Bssid);
398 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
400 MakeOutgoingFrame(pOutBuffer, &FrameLen,
401 sizeof(HEADER_802_11), &Hdr80211,
403 1, &pAd->MlmeAux.SsidLen,
404 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
407 SupRateLen, pSupRate,
413 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
416 ExtRateLen, pExtRate,
422 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
423 MlmeFreeMemory(pAd, pOutBuffer);
427 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
428 pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
430 pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
434 ==========================================================================
436 MLME START Request state machine procedure, starting an IBSS
437 ==========================================================================
439 VOID MlmeStartReqAction(
440 IN PRTMP_ADAPTER pAd,
441 IN MLME_QUEUE_ELEM *Elem)
443 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen;
444 BOOLEAN TimerCancelled;
446 // New for WPA security suites
447 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
448 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
449 LARGE_INTEGER TimeStamp;
453 // Init Variable IE structure
454 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
456 TimeStamp.u.LowPart = 0;
457 TimeStamp.u.HighPart = 0;
459 if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, Ssid, &SsidLen))
461 // reset all the timers
462 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
463 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
466 // Start a new IBSS. All IBSS parameters are decided now....
468 DBGPRINT(RT_DEBUG_TRACE, ("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;
473 // generate a radom number as BSSID
474 MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
475 DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
477 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
478 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
479 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
480 pAd->MlmeAux.CapabilityInfo = CAP_GENERATE(0,1,Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 1, 0);
481 pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
482 pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin;
483 pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
485 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
486 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
488 pAd->MlmeAux.SupRateLen= pAd->CommonCfg.SupRateLen;
489 NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
490 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
491 pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
492 NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
493 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
494 #ifdef DOT11_N_SUPPORT
495 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
497 RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
498 pAd->MlmeAux.HtCapabilityLen = sizeof(HT_CAPABILITY_IE);
499 // Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
500 DBGPRINT(RT_DEBUG_TRACE, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
503 #endif // DOT11_N_SUPPORT //
505 pAd->MlmeAux.HtCapabilityLen = 0;
506 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
508 // temporarily not support QOS in IBSS
509 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
510 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
511 NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
513 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
514 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
516 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
517 pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
519 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
520 Status = MLME_SUCCESS;
521 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
525 DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
526 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
527 Status = MLME_INVALID_FORMAT;
528 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
533 ==========================================================================
535 peer sends beacon back when scanning
536 ==========================================================================
538 VOID PeerBeaconAtScanAction(
539 IN PRTMP_ADAPTER pAd,
540 IN MLME_QUEUE_ELEM *Elem)
542 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
543 UCHAR Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
544 SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
546 USHORT BeaconPeriod, AtimWin, CapabilityInfo;
547 PFRAME_802_11 pFrame;
548 LARGE_INTEGER TimeStamp;
550 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
551 UCHAR SupRateLen, ExtRateLen;
554 UCHAR AironetCellPowerLimit;
556 QBSS_LOAD_PARM QbssLoad;
557 QOS_CAPABILITY_PARM QosCapability;
559 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
560 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
561 HT_CAPABILITY_IE HtCapability;
562 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
563 UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
565 UCHAR NewExtChannelOffset = 0xff;
568 // NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00);
569 pFrame = (PFRAME_802_11) Elem->Msg;
570 // Init Variable IE structure
571 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
573 #ifdef DOT11_N_SUPPORT
574 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
575 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
576 #endif // DOT11_N_SUPPORT //
578 if (PeerBeaconAndProbeRspSanity(pAd,
604 &AironetCellPowerLimit,
610 &PreNHtCapabilityLen,
614 &NewExtChannelOffset,
621 Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
622 if (Idx != BSS_NOT_FOUND)
623 Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
625 Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
628 #ifdef DOT11_N_SUPPORT
629 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
630 HtCapabilityLen = SIZE_HT_CAP_IE;
631 #endif // DOT11_N_SUPPORT //
632 if ((pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) && (Channel == pAd->StaCfg.CCXScanChannel))
634 Idx = BssTableSetEntry(pAd, &pAd->StaCfg.CCXBssTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
635 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen,ExtRate, ExtRateLen, &HtCapability,
636 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
637 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
638 if (Idx != BSS_NOT_FOUND)
640 NdisMoveMemory(pAd->StaCfg.CCXBssTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
641 NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
642 NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
643 if (pAd->StaCfg.CCXReqType == MSRN_TYPE_BEACON_REQ)
644 AironetAddBeaconReport(pAd, Idx, Elem);
649 Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
650 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
651 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
652 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
653 #ifdef DOT11_N_SUPPORT
655 if (pAd->ChannelList[pAd->CommonCfg.ChannelListIdx].bEffectedChannel == TRUE)
658 PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &RegClass);
659 TriEventTableSetEntry(pAd, &pAd->CommonCfg.TriggerEventTab, Bssid, &HtCapability, HtCapabilityLen, RegClass, Channel);
661 #endif // DOT11N_DRAFT3 //
662 #endif // DOT11_N_SUPPORT //
663 if (Idx != BSS_NOT_FOUND)
665 NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
666 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
667 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
671 // sanity check fail, ignored
675 ==========================================================================
677 When waiting joining the (I)BSS, beacon received from external
678 ==========================================================================
680 VOID PeerBeaconAtJoinAction(
681 IN PRTMP_ADAPTER pAd,
682 IN MLME_QUEUE_ELEM *Elem)
684 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
685 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
686 DtimCount, DtimPeriod, BcastFlag, NewChannel;
687 LARGE_INTEGER TimeStamp;
688 USHORT BeaconPeriod, AtimWin, CapabilityInfo;
690 BOOLEAN TimerCancelled;
692 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
693 UCHAR SupRateLen, ExtRateLen;
696 UCHAR AironetCellPowerLimit;
698 QBSS_LOAD_PARM QbssLoad;
699 QOS_CAPABILITY_PARM QosCapability;
701 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
702 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
705 HT_CAPABILITY_IE HtCapability;
706 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
707 UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
709 UCHAR NewExtChannelOffset = 0xff;
710 #ifdef DOT11_N_SUPPORT
711 UCHAR CentralChannel;
712 #endif // DOT11_N_SUPPORT //
714 // Init Variable IE structure
715 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
717 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
718 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
721 if (PeerBeaconAndProbeRspSanity(pAd,
747 &AironetCellPowerLimit,
753 &PreNHtCapabilityLen,
757 &NewExtChannelOffset,
761 // Disqualify 11b only adhoc when we are in 11g only adhoc mode
762 if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12))
765 // BEACON from desired BSS/IBSS found. We should be able to decide most
766 // BSS parameters here.
767 // Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
768 // Do we need to receover back all parameters belonging to previous BSS?
769 // A. Should be not. There's no back-door recover to previous AP. It still need
770 // a new JOIN-AUTH-ASSOC sequence.
771 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid))
773 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel));
774 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
776 // Update RSSI to prevent No signal display when cards first initialized
777 pAd->StaCfg.RssiSample.LastRssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
778 pAd->StaCfg.RssiSample.LastRssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
779 pAd->StaCfg.RssiSample.LastRssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
780 pAd->StaCfg.RssiSample.AvgRssi0 = pAd->StaCfg.RssiSample.LastRssi0;
781 pAd->StaCfg.RssiSample.AvgRssi0X8 = pAd->StaCfg.RssiSample.AvgRssi0 << 3;
782 pAd->StaCfg.RssiSample.AvgRssi1 = pAd->StaCfg.RssiSample.LastRssi1;
783 pAd->StaCfg.RssiSample.AvgRssi1X8 = pAd->StaCfg.RssiSample.AvgRssi1 << 3;
784 pAd->StaCfg.RssiSample.AvgRssi2 = pAd->StaCfg.RssiSample.LastRssi2;
785 pAd->StaCfg.RssiSample.AvgRssi2X8 = pAd->StaCfg.RssiSample.AvgRssi2 << 3;
788 // We need to check if SSID only set to any, then we can record the current SSID.
789 // Otherwise will cause hidden SSID association failed.
791 if (pAd->MlmeAux.SsidLen == 0)
793 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
794 pAd->MlmeAux.SsidLen = SsidLen;
798 Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel);
800 if (Idx != BSS_NOT_FOUND)
803 // Multiple SSID case, used correct CapabilityInfo
805 CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
808 NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
809 pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
810 pAd->MlmeAux.BssType = BssType;
811 pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
812 pAd->MlmeAux.Channel = Channel;
813 pAd->MlmeAux.AtimWin = AtimWin;
814 pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
815 pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
816 pAd->MlmeAux.APRalinkIe = RalinkIe;
818 // Copy AP's supported rate to MlmeAux for creating assoication request
819 // Also filter out not supported rate
820 pAd->MlmeAux.SupRateLen = SupRateLen;
821 NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
822 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
823 pAd->MlmeAux.ExtRateLen = ExtRateLen;
824 NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
825 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
827 NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16);
828 #ifdef DOT11_N_SUPPORT
829 pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
830 pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
832 // filter out un-supported ht rates
833 if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
835 RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
836 RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE);
838 // StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
839 NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
840 pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
841 pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
842 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
843 if (PreNHtCapabilityLen > 0)
844 pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE;
845 RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo);
846 // Copy AP Parameter to StaActive. This is also in LinkUp.
847 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
848 pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth));
850 if (AddHtInfoLen > 0)
852 CentralChannel = AddHtInfo.ControlChan;
853 // Check again the Bandwidth capability of this AP.
854 if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
856 CentralChannel = AddHtInfo.ControlChan - 2;
858 else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
860 CentralChannel = AddHtInfo.ControlChan + 2;
864 if (pAd->MlmeAux.CentralChannel != CentralChannel)
865 DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel));
867 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, AddHtInfo.ControlChan));
873 #endif // DOT11_N_SUPPORT //
875 // To prevent error, let legacy AP must have same CentralChannel and Channel.
876 if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0))
877 pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel;
879 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
880 RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
881 RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
884 RTMPUpdateMlmeRate(pAd);
886 // copy QOS related information
887 if ((pAd->CommonCfg.bWmmCapable)
888 #ifdef DOT11_N_SUPPORT
889 || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
890 #endif // DOT11_N_SUPPORT //
893 NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM));
894 NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
895 NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
899 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
900 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
901 NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
904 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
905 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
909 pAd->StaCfg.CkipFlag = CkipFlag;
911 // Keep TimeStamp for Re-Association used.
912 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
913 pAd->StaCfg.CCKMBeaconAtJoinTimeStamp = TimeStamp;
914 #endif // LEAP_SUPPORT //
916 if (AironetCellPowerLimit != 0xFF)
918 //We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
919 ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
921 else //Used the default TX Power Percentage.
922 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
924 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
925 Status = MLME_SUCCESS;
926 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
928 // not to me BEACON, ignored
930 // sanity check fail, ignore this frame
934 ==========================================================================
936 receive BEACON from peer
938 IRQL = DISPATCH_LEVEL
940 ==========================================================================
943 IN PRTMP_ADAPTER pAd,
944 IN MLME_QUEUE_ELEM *Elem)
946 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
947 CHAR Ssid[MAX_LEN_OF_SSID];
949 UCHAR SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0;
950 UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0;
951 USHORT CapabilityInfo, AtimWin, BeaconPeriod;
952 LARGE_INTEGER TimeStamp;
953 USHORT TbttNumToNextWakeUp;
955 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
956 UCHAR SupRateLen, ExtRateLen;
959 UCHAR AironetCellPowerLimit;
961 QBSS_LOAD_PARM QbssLoad;
962 QOS_CAPABILITY_PARM QosCapability;
964 // New for WPA security suites
965 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
966 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
967 HT_CAPABILITY_IE HtCapability;
968 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
969 UCHAR HtCapabilityLen, PreNHtCapabilityLen;
971 UCHAR NewExtChannelOffset = 0xff;
973 if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
977 // Init Variable IE structure
978 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
980 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
981 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
983 if (PeerBeaconAndProbeRspSanity(pAd,
1009 &AironetCellPowerLimit,
1015 &PreNHtCapabilityLen,
1019 &NewExtChannelOffset,
1023 BOOLEAN is_my_bssid, is_my_ssid;
1026 CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1028 is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE;
1029 is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE;
1032 // ignore BEACON not for my SSID
1033 if ((! is_my_ssid) && (! is_my_bssid))
1036 // It means STA waits disassoc completely from this AP, ignores this beacon.
1037 if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
1040 #ifdef DOT11_N_SUPPORT
1041 // Copy Control channel for this BSSID.
1042 if (AddHtInfoLen != 0)
1043 Channel = AddHtInfo.ControlChan;
1045 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
1046 HtCapabilityLen = SIZE_HT_CAP_IE;
1047 #endif // DOT11_N_SUPPORT //
1050 // Housekeeping "SsidBssTab" table for later-on ROAMing usage.
1052 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1053 if (Bssidx == BSS_NOT_FOUND)
1055 // discover new AP of this network, create BSS entry
1056 Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
1057 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,
1058 &HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel,
1059 RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability,
1060 &QbssLoad, LenVIE, pVIE);
1061 if (Bssidx == BSS_NOT_FOUND) // return if BSS table full
1064 NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4);
1065 NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
1066 NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
1072 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
1074 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1075 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1076 AsicSwitchChannel(pAd, 1, FALSE);
1077 AsicLockChannel(pAd, 1);
1078 LinkDown(pAd, FALSE);
1079 MlmeQueueInit(&pAd->Mlme.Queue);
1080 BssTableInit(&pAd->ScanTab);
1081 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1083 // channel sanity check
1084 for (index = 0 ; index < pAd->ChannelListNum; index++)
1086 if (pAd->ChannelList[index].Channel == NewChannel)
1088 pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
1089 pAd->CommonCfg.Channel = NewChannel;
1090 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1091 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1092 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
1097 if (index >= pAd->ChannelListNum)
1099 DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
1103 // if the ssid matched & bssid unmatched, we should select the bssid with large value.
1104 // This might happened when two STA start at the same time
1105 if ((! is_my_bssid) && ADHOC_ON(pAd))
1109 // Add the safeguard against the mismatch of adhoc wep status
1110 if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
1115 // collapse into the ADHOC network which has bigger BSSID value.
1116 for (i = 0; i < 6; i++)
1118 if (Bssid[i] > pAd->CommonCfg.Bssid[i])
1120 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
1121 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
1122 AsicDisableSync(pAd);
1123 COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid);
1124 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1125 MakeIbssBeacon(pAd); // re-build BEACON frame
1126 AsicEnableIbssSync(pAd); // copy BEACON frame to on-chip memory
1130 else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
1136 NdisGetSystemUpTime(&Now);
1137 pBss = &pAd->ScanTab.BssEntry[Bssidx];
1138 pBss->Rssi = RealRssi; // lastest RSSI
1139 pBss->LastBeaconRxTime = Now; // last RX timestamp
1142 // BEACON from my BSSID - either IBSS or INFRA network
1148 pAd->StaCfg.DtimCount = DtimCount;
1149 pAd->StaCfg.DtimPeriod = DtimPeriod;
1150 pAd->StaCfg.LastBeaconRxTime = Now;
1153 RxWI.RSSI0 = Elem->Rssi0;
1154 RxWI.RSSI1 = Elem->Rssi1;
1155 RxWI.RSSI2 = Elem->Rssi2;
1157 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
1158 if (AironetCellPowerLimit != 0xFF)
1161 // We get the Cisco (ccx) "TxPower Limit" required
1162 // Changed to appropriate TxPower Limit for Ciso Compatible Extensions
1164 ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
1169 // AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
1170 // Used the default TX Power Percentage, that set from UI.
1172 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
1175 if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
1177 UCHAR MaxSupportedRateIn500Kbps = 0;
1179 MAC_TABLE_ENTRY *pEntry;
1181 // supported rates array may not be sorted. sort it and find the maximum rate
1182 for (idx=0; idx<SupRateLen; idx++)
1184 if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
1185 MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
1188 for (idx=0; idx<ExtRateLen; idx++)
1190 if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
1191 MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
1194 // look up the existing table
1195 pEntry = MacTableLookup(pAd, Addr2);
1197 // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
1198 // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
1199 if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) ||
1200 (pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now)))
1203 // Another adhoc joining, add to our MAC table.
1204 pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
1206 if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo) == FALSE)
1208 DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n"));
1213 (Elem->Wcid == RESERVED_WCID))
1215 idx = pAd->StaCfg.DefaultKeyId;
1216 RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
1220 if (pEntry && pEntry->ValidAsCLI)
1221 pEntry->LastBeaconRxTime = Now;
1223 // At least another peer in this IBSS, declare MediaState as CONNECTED
1224 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1226 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1228 pAd->IndicateMediaState = NdisMediaStateConnected;
1229 RTMP_IndicateMediaState(pAd);
1230 pAd->ExtraInfo = GENERAL_LINK_UP;
1231 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1233 // 2003/03/12 - john
1234 // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
1235 // "site survey" result should always include the current connected network.
1237 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1238 if (Bssidx == BSS_NOT_FOUND)
1240 Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
1241 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
1242 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
1243 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
1245 DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1251 BOOLEAN bUseShortSlot, bUseBGProtection;
1253 // decide to use/change to -
1254 // 1. long slot (20 us) or short slot (9 us) time
1255 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1256 // 3. short preamble
1258 //bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
1259 bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo);
1260 if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
1261 AsicSetSlotTime(pAd, bUseShortSlot);
1263 bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || // always use
1264 ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp));
1266 if (pAd->CommonCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
1267 bUseBGProtection = FALSE;
1269 if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
1271 if (bUseBGProtection)
1273 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1274 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
1278 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1279 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
1282 DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection));
1285 #ifdef DOT11_N_SUPPORT
1286 // check Ht protection mode. and adhere to the Non-GF device indication by AP.
1287 if ((AddHtInfoLen != 0) &&
1288 ((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) ||
1289 (AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent)))
1291 pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent;
1292 pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode;
1293 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1295 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1298 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1300 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode));
1302 #endif // DOT11_N_SUPPORT //
1304 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) &&
1305 ERP_IS_USE_BARKER_PREAMBLE(Erp))
1307 MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
1308 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n"));
1311 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
1312 (EdcaParm.bValid == TRUE) &&
1313 (EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount))
1315 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1316 pAd->CommonCfg.APEdcaParm.EdcaUpdateCount,
1317 EdcaParm.EdcaUpdateCount));
1318 AsicSetEdcaParm(pAd, &EdcaParm);
1321 // copy QOS related information
1322 NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
1323 NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
1326 // only INFRASTRUCTURE mode support power-saving feature
1327 if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave))
1330 // 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
1331 // 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
1332 // 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
1333 // 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
1334 // 5. otherwise, put PHY back to sleep to save battery.
1337 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
1338 pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
1340 pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
1343 RT28XX_PS_POLL_ENQUEUE(pAd);
1345 else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
1348 else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) ||
1349 (pAd->TxSwQueue[QID_AC_BE].Number != 0) ||
1350 (pAd->TxSwQueue[QID_AC_VI].Number != 0) ||
1351 (pAd->TxSwQueue[QID_AC_VO].Number != 0) ||
1352 (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1353 (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1354 (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1355 (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1356 (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS))
1358 // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
1359 // can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
1363 USHORT NextDtim = DtimCount;
1366 NextDtim = DtimPeriod;
1368 TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
1369 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
1370 TbttNumToNextWakeUp = NextDtim;
1372 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1374 AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
1379 // not my BSSID, ignore it
1381 // sanity check fail, ignore this frame
1385 ==========================================================================
1387 Receive PROBE REQ from remote peer when operating in IBSS mode
1388 ==========================================================================
1390 VOID PeerProbeReqAction(
1391 IN PRTMP_ADAPTER pAd,
1392 IN MLME_QUEUE_ELEM *Elem)
1394 UCHAR Addr2[MAC_ADDR_LEN];
1395 CHAR Ssid[MAX_LEN_OF_SSID];
1397 #ifdef DOT11_N_SUPPORT
1398 UCHAR HtLen, AddHtLen, NewExtLen;
1399 #endif // DOT11_N_SUPPORT //
1400 HEADER_802_11 ProbeRspHdr;
1401 NDIS_STATUS NStatus;
1402 PUCHAR pOutBuffer = NULL;
1404 LARGE_INTEGER FakeTimestamp;
1405 UCHAR DsLen = 1, IbssLen = 2;
1406 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0};
1408 USHORT CapabilityInfo;
1409 UCHAR RSNIe = IE_WPA;
1411 if (! ADHOC_ON(pAd))
1414 if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
1416 if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
1418 // allocate and send out ProbeRsp frame
1419 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1420 if (NStatus != NDIS_STATUS_SUCCESS)
1423 //pAd->StaCfg.AtimWin = 0; // ??????
1425 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
1426 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
1427 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
1428 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
1430 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1431 sizeof(HEADER_802_11), &ProbeRspHdr,
1432 TIMESTAMP_LEN, &FakeTimestamp,
1433 2, &pAd->CommonCfg.BeaconPeriod,
1436 1, &pAd->CommonCfg.SsidLen,
1437 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1439 1, &pAd->StaActive.SupRateLen,
1440 pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
1443 1, &pAd->CommonCfg.Channel,
1446 2, &pAd->StaActive.AtimWin,
1449 if (pAd->StaActive.ExtRateLen)
1452 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1455 1, &pAd->StaActive.ExtRateLen,
1456 pAd->StaActive.ExtRateLen, &pAd->StaActive.ExtRate,
1461 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1462 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1465 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1467 1, &pAd->StaCfg.RSNIE_Len,
1468 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
1472 #ifdef DOT11_N_SUPPORT
1473 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1476 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
1477 HtLen = sizeof(pAd->CommonCfg.HtCapability);
1478 AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
1480 //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
1481 if (pAd->bBroadComHT == TRUE)
1483 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
1486 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
1491 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
1494 sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability,
1497 sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo,
1500 sizeof(NEW_EXT_CHAN_IE), &pAd->CommonCfg.NewExtChanOffset,
1505 #endif // DOT11_N_SUPPORT //
1506 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1507 MlmeFreeMemory(pAd, pOutBuffer);
1512 VOID BeaconTimeoutAtJoinAction(
1513 IN PRTMP_ADAPTER pAd,
1514 IN MLME_QUEUE_ELEM *Elem)
1517 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1518 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1519 Status = MLME_REJ_TIMEOUT;
1520 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1524 ==========================================================================
1526 Scan timeout procedure. basically add channel index by 1 and rescan
1527 ==========================================================================
1529 VOID ScanTimeoutAction(
1530 IN PRTMP_ADAPTER pAd,
1531 IN MLME_QUEUE_ELEM *Elem)
1533 pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
1535 // Only one channel scanned for CISCO beacon request
1536 if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
1537 (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
1538 (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
1539 (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
1540 pAd->MlmeAux.Channel = 0;
1542 // this routine will stop if pAd->MlmeAux.Channel == 0
1543 ScanNextChannel(pAd);
1547 ==========================================================================
1549 ==========================================================================
1551 VOID InvalidStateWhenScan(
1552 IN PRTMP_ADAPTER pAd,
1553 IN MLME_QUEUE_ELEM *Elem)
1556 DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1557 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1558 Status = MLME_STATE_MACHINE_REJECT;
1559 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
1563 ==========================================================================
1565 ==========================================================================
1567 VOID InvalidStateWhenJoin(
1568 IN PRTMP_ADAPTER pAd,
1569 IN MLME_QUEUE_ELEM *Elem)
1572 DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1573 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1574 Status = MLME_STATE_MACHINE_REJECT;
1575 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1579 ==========================================================================
1581 ==========================================================================
1583 VOID InvalidStateWhenStart(
1584 IN PRTMP_ADAPTER pAd,
1585 IN MLME_QUEUE_ELEM *Elem)
1588 DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1589 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1590 Status = MLME_STATE_MACHINE_REJECT;
1591 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
1595 ==========================================================================
1598 IRQL = DISPATCH_LEVEL
1600 ==========================================================================
1603 IN PRTMP_ADAPTER pAd)
1605 if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
1606 pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
1607 MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
1612 ==========================================================================
1614 ==========================================================================
1616 VOID EnqueueProbeRequest(
1617 IN PRTMP_ADAPTER pAd)
1622 HEADER_802_11 Hdr80211;
1624 DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
1626 NState = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1627 if (NState == NDIS_STATUS_SUCCESS)
1629 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
1631 // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
1632 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1633 sizeof(HEADER_802_11), &Hdr80211,
1635 1, &pAd->CommonCfg.SsidLen,
1636 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1638 1, &pAd->StaActive.SupRateLen,
1639 pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
1641 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1642 MlmeFreeMemory(pAd, pOutBuffer);
1647 #ifdef DOT11_N_SUPPORT
1648 #ifdef DOT11N_DRAFT3
1649 VOID BuildEffectedChannelList(
1650 IN PRTMP_ADAPTER pAd)
1654 UCHAR UpperChannel = 0, LowerChannel = 0;
1656 RTMPZeroMemory(EChannel, 11);
1658 // Find upper channel and lower channel.
1659 if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
1661 UpperChannel = pAd->CommonCfg.Channel;
1662 LowerChannel = pAd->CommonCfg.CentralChannel;
1664 else if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
1666 UpperChannel = pAd->CommonCfg.CentralChannel;
1667 LowerChannel = pAd->CommonCfg.Channel;
1674 // Record channels that is below lower channel..
1675 if (LowerChannel > 1)
1677 EChannel[0] = LowerChannel - 1;
1679 if (LowerChannel > 2)
1681 EChannel[1] = LowerChannel - 2;
1683 if (LowerChannel > 3)
1685 EChannel[2] = LowerChannel - 3;
1690 // Record channels that is between lower channel and upper channel.
1691 for (k = LowerChannel;k < UpperChannel;k++)
1696 // Record channels that is above upper channel..
1697 if (LowerChannel < 11)
1699 EChannel[i] = UpperChannel + 1;
1701 if (LowerChannel < 10)
1703 EChannel[i] = LowerChannel + 2;
1705 if (LowerChannel < 9)
1707 EChannel[i] = LowerChannel + 3;
1713 for (j = 0;j < i;j++)
1715 for (k = 0;k < pAd->ChannelListNum;k++)
1717 if (pAd->ChannelList[k].Channel == EChannel[j])
1719 pAd->ChannelList[k].bEffectedChannel = TRUE;
1720 DBGPRINT(RT_DEBUG_TRACE,(" EffectedChannel( =%d)\n", EChannel[j]));
1726 #endif // DOT11N_DRAFT3 //
1727 #endif // DOT11_N_SUPPORT //
1729 BOOLEAN ScanRunning(
1730 IN PRTMP_ADAPTER pAd)
1732 return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;