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
37 Justin P. Mattock 11/07/2010 Fix typos
39 #include "../rt_config.h"
41 #define ADHOC_ENTRY_BEACON_LOST_TIME (2*OS_HZ) /* 2 sec */
44 ==========================================================================
46 The sync state machine,
48 Sm - pointer to the state machine
50 the state machine looks like the following
52 ==========================================================================
54 void SyncStateMachineInit(struct rt_rtmp_adapter *pAd,
55 struct rt_state_machine *Sm, OUT STATE_MACHINE_FUNC Trans[])
57 StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG,
58 (STATE_MACHINE_FUNC) Drop, SYNC_IDLE,
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);
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);
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);
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);
107 ==========================================================================
109 Beacon timeout handler, executed in timer thread
111 IRQL = DISPATCH_LEVEL
113 ==========================================================================
115 void BeaconTimeout(void *SystemSpecific1,
116 void *FunctionContext,
117 void *SystemSpecific2, void *SystemSpecific3)
119 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
121 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeout\n"));
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))
128 if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
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);
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));
142 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
143 RTMP_MLME_HANDLER(pAd);
147 ==========================================================================
149 Scan timeout handler, executed in timer thread
151 IRQL = DISPATCH_LEVEL
153 ==========================================================================
155 void ScanTimeout(void *SystemSpecific1,
156 void *FunctionContext,
157 void *SystemSpecific2, void *SystemSpecific3)
159 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
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))
166 if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL)) {
167 RTMP_MLME_HANDLER(pAd);
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].
182 ==========================================================================
184 MLME SCAN req state machine procedure
185 ==========================================================================
187 void MlmeScanReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
189 u8 Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
190 BOOLEAN TimerCancelled;
193 struct rt_header_802_11 * pHdr80211;
194 u8 *pOutBuffer = NULL;
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"));
204 /* Increase the scan retry counters. */
205 pAd->StaCfg.ScanCnt++;
208 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
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,
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"));
220 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
223 #endif /* RTMP_MAC_PCI // */
225 /* first check the parameter sanity */
226 if (MlmeScanReqSanity(pAd,
229 &BssType, (char *)Ssid, &SsidLen, &ScanType)) {
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);
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 */
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;
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);
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);
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);
277 /* start from the first channel */
278 pAd->MlmeAux.Channel = FirstChannel(pAd);
280 /* Let BBP register at 20MHz to do scan */
281 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
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);
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,
296 ==========================================================================
298 MLME JOIN req state machine procedure
299 ==========================================================================
301 void MlmeJoinReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
304 struct rt_bss_entry *pBss;
305 BOOLEAN TimerCancelled;
306 struct rt_header_802_11 Hdr80211;
308 unsigned long FrameLen = 0;
309 u8 *pOutBuffer = NULL;
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);
318 DBGPRINT(RT_DEBUG_TRACE,
319 ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
322 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
324 (pAd->StaCfg.bRadio == TRUE) &&
325 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
326 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
328 #endif /* RTMP_MAC_PCI // */
330 /* reset all the timers */
331 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
332 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
334 pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
336 /* record the desired SSID & BSSID we're waiting for */
337 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
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;
346 pAd->MlmeAux.BssType = pBss->BssType;
347 pAd->MlmeAux.Channel = pBss->Channel;
348 pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
350 /* Let BBP register at 20MHz to do scan */
351 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
353 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
355 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
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);
363 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
364 (pAd->MlmeAux.Channel > 14) &&
365 RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
368 /* We can't send any Probe request frame to meet 802.11h. */
370 if (pBss->Hidden == 0)
374 /* send probe request */
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;
385 /* Overwrite Support Rate, CCK rate are not allowed */
388 SupRateLen = ASupRateLen;
392 if (pAd->MlmeAux.BssType == BSS_INFRA)
393 MgtMacHeaderInit(pAd, &Hdr80211,
394 SUBTYPE_PROBE_REQ, 0,
398 MgtMacHeaderInit(pAd, &Hdr80211,
399 SUBTYPE_PROBE_REQ, 0,
403 MakeOutgoingFrame(pOutBuffer, &FrameLen,
404 sizeof(struct rt_header_802_11), &Hdr80211,
406 1, &pAd->MlmeAux.SsidLen,
407 pAd->MlmeAux.SsidLen,
408 pAd->MlmeAux.Ssid, 1, &SupRateIe, 1,
409 &SupRateLen, SupRateLen, pSupRate,
414 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
417 ExtRateLen, pExtRate,
422 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
423 MlmeFreeMemory(pAd, pOutBuffer);
427 DBGPRINT(RT_DEBUG_TRACE,
428 ("SYNC - Switch to ch %d, Wait BEACON from %pM\n",
429 pBss->Channel, pBss->Bssid));
431 pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
435 ==========================================================================
437 MLME START Request state machine procedure, starting an IBSS
438 ==========================================================================
440 void MlmeStartReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
442 u8 Ssid[MAX_LEN_OF_SSID], SsidLen;
443 BOOLEAN TimerCancelled;
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;
452 /* Init Variable IE structure */
453 pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
455 TimeStamp.u.LowPart = 0;
456 TimeStamp.u.HighPart = 0;
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);
465 /* Start a new IBSS. All IBSS parameters are decided now.... */
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;
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"));
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;
490 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
491 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
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);
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"));
514 pAd->MlmeAux.HtCapabilityLen = 0;
515 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
516 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.
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));
526 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
527 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
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));
534 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
535 Status = MLME_SUCCESS;
536 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2,
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,
548 ==========================================================================
550 peer sends beacon back when scanning
551 ==========================================================================
553 void PeerBeaconAtScanAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
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;
563 u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
564 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
565 u8 SupRateLen, ExtRateLen;
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;
579 u8 NewExtChannelOffset = 0xff;
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;
587 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
588 RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
590 if (PeerBeaconAndProbeRspSanity(pAd,
616 &AironetCellPowerLimit,
622 &PreNHtCapabilityLen,
626 &NewExtChannelOffset, &LenVIE, pVIE)) {
630 Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
631 if (Idx != BSS_NOT_FOUND)
632 Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
635 RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
636 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
637 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
639 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
640 HtCapabilityLen = SIZE_HT_CAP_IE;
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);
652 if (Idx != BSS_NOT_FOUND) {
653 NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF,
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);
662 /* sanity check fail, ignored */
666 ==========================================================================
668 When waiting joining the (I)BSS, beacon received from external
669 ==========================================================================
671 void PeerBeaconAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
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;
681 u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
682 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
683 u8 SupRateLen, ExtRateLen;
686 u8 AironetCellPowerLimit;
687 struct rt_edca_parm EdcaParm;
688 struct rt_qbss_load_parm QbssLoad;
689 struct rt_qos_capability_parm QosCapability;
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;
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;
699 u8 NewExtChannelOffset = 0xff;
701 BOOLEAN bAllowNrate = FALSE;
703 /* Init Variable IE structure */
704 pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
706 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
707 RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
709 if (PeerBeaconAndProbeRspSanity(pAd,
735 &AironetCellPowerLimit,
741 &PreNHtCapabilityLen,
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))
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",
762 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,
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;
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. */
789 if (pAd->MlmeAux.SsidLen == 0) {
790 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid,
792 pAd->MlmeAux.SsidLen = SsidLen;
795 BssSsidTableSearch(&pAd->ScanTab, Bssid,
797 pAd->MlmeAux.SsidLen,
800 if (Idx == BSS_NOT_FOUND) {
817 BssTableSetEntry(pAd, &pAd->ScanTab,
840 if (Idx != BSS_NOT_FOUND) {
841 NdisMoveMemory(pAd->ScanTab.
846 NdisMoveMemory(&pAd->ScanTab.
851 NdisMoveMemory(&pAd->ScanTab.
857 pAd->ScanTab.BssEntry[Idx].
862 /* Multiple SSID case, used correct CapabilityInfo */
865 pAd->ScanTab.BssEntry[Idx].
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;
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,
885 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate,
886 &pAd->MlmeAux.SupRateLen);
887 pAd->MlmeAux.ExtRateLen = ExtRateLen;
888 NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate,
890 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate,
891 &pAd->MlmeAux.ExtRateLen);
893 NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet,
896 if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled)
897 && (pAd->StaCfg.WepStatus !=
898 Ndis802_11Encryption2Enabled))
899 || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) {
903 pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
904 pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
906 RTMPZeroMemory(&pAd->MlmeAux.HtCapability,
908 /* filter out un-supported ht rates */
909 if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
910 && ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
912 RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo,
913 &AddHtInfo, SIZE_ADD_HT_INFO_IE);
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 =
920 pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
921 pAd->StaActive.SupportedPhyInfo.bHtEnable =
923 if (PreNHtCapabilityLen > 0)
924 pAd->StaActive.SupportedPhyInfo.
926 RTMPCheckHt(pAd, BSSID_WCID, &HtCapability,
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.
933 pAd->StaActive.SupportedHtPhy.
935 HtCapability.HtCapInfo.ChannelWidth));
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)) {
946 AddHtInfo.ControlChan - 2;
948 if ((AddHtInfo.AddHtInfo.
949 ExtChanOffset == EXTCHA_ABOVE)
950 && (HtCapability.HtCapInfo.
951 ChannelWidth == BW_40)) {
953 AddHtInfo.ControlChan + 2;
956 if (pAd->MlmeAux.CentralChannel !=
958 DBGPRINT(RT_DEBUG_ERROR,
959 ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n",
961 AddHtInfo.ControlChan,
965 DBGPRINT(RT_DEBUG_TRACE,
966 ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n",
968 AddHtInfo.ControlChan));
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;
979 pAd->StaActive.SupportedPhyInfo.bHtEnable =
981 pAd->MlmeAux.NewExtChannelOffset = 0xff;
982 RTMPZeroMemory(&pAd->MlmeAux.HtCapability,
984 pAd->MlmeAux.HtCapabilityLen = 0;
985 RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo,
986 SIZE_ADD_HT_INFO_IE);
989 RTMPUpdateMlmeRate(pAd);
991 /* copy QOS related information */
992 if ((pAd->CommonCfg.bWmmCapable)
993 || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
995 NdisMoveMemory(&pAd->MlmeAux.APEdcaParm,
996 &EdcaParm, sizeof(struct rt_edca_parm));
997 NdisMoveMemory(&pAd->MlmeAux.APQbssLoad,
999 sizeof(struct rt_qbss_load_parm));
1000 NdisMoveMemory(&pAd->MlmeAux.APQosCapability,
1002 sizeof(struct rt_qos_capability_parm));
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));
1012 DBGPRINT(RT_DEBUG_TRACE,
1013 ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
1014 pAd->MlmeAux.SupRateLen,
1015 pAd->MlmeAux.ExtRateLen));
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;
1025 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1026 Status = MLME_SUCCESS;
1027 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF,
1030 /* not to me BEACON, ignored */
1032 /* sanity check fail, ignore this frame */
1036 ==========================================================================
1038 receive BEACON from peer
1040 IRQL = DISPATCH_LEVEL
1042 ==========================================================================
1044 void PeerBeacon(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
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;
1055 u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
1056 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1057 u8 SupRateLen, ExtRateLen;
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;
1072 u8 NewExtChannelOffset = 0xff;
1074 if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
1078 /* Init Variable IE structure */
1079 pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
1081 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
1082 RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
1084 if (PeerBeaconAndProbeRspSanity(pAd,
1110 &AironetCellPowerLimit,
1116 &PreNHtCapabilityLen,
1120 &NewExtChannelOffset, &LenVIE, pVIE)) {
1121 BOOLEAN is_my_bssid, is_my_ssid;
1122 unsigned long Bssidx, Now;
1123 struct rt_bss_entry *pBss;
1125 RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
1126 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
1127 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1130 MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid) ? TRUE : FALSE;
1132 SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid,
1133 pAd->CommonCfg.SsidLen) ? TRUE : FALSE;
1135 /* ignore BEACON not for my SSID */
1136 if ((!is_my_ssid) && (!is_my_bssid))
1139 /* It means STA waits disassoc completely from this AP, ignores this beacon. */
1140 if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
1143 /* Copy Control channel for this BSSID. */
1144 if (AddHtInfoLen != 0)
1145 Channel = AddHtInfo.ControlChan;
1147 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
1148 HtCapabilityLen = SIZE_HT_CAP_IE;
1151 /* Housekeeping "SsidBssTab" table for later-on ROAMing usage. */
1153 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1154 if (Bssidx == BSS_NOT_FOUND) {
1155 /* discover new AP of this network, create BSS entry */
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,
1168 if (Bssidx == BSS_NOT_FOUND) /* return if BSS table full */
1171 NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF,
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);
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 */
1191 /* channel sanity check */
1192 for (index = 0; index < pAd->ChannelListNum; index++) {
1193 if (pAd->ChannelList[index].Channel ==
1195 pAd->ScanTab.BssEntry[Bssidx].Channel =
1197 pAd->CommonCfg.Channel = NewChannel;
1198 AsicSwitchChannel(pAd,
1201 AsicLockChannel(pAd,
1202 pAd->CommonCfg.Channel);
1203 DBGPRINT(RT_DEBUG_TRACE,
1204 ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n",
1210 if (index >= pAd->ChannelListNum) {
1211 DBGPRINT_ERR("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum);
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)) {
1219 /* Add the safeguard against the mismatch of adhoc wep status */
1220 if (pAd->StaCfg.WepStatus !=
1221 pAd->ScanTab.BssEntry[Bssidx].WepStatus) {
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="
1231 AsicDisableSync(pAd);
1232 COPY_MAC_ADDR(pAd->CommonCfg.Bssid,
1234 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1235 MakeIbssBeacon(pAd); /* re-build BEACON frame */
1236 AsicEnableIbssSync(pAd); /* copy BEACON frame to on-chip memory */
1239 } else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
1244 NdisGetSystemUpTime(&Now);
1245 pBss = &pAd->ScanTab.BssEntry[Bssidx];
1246 pBss->Rssi = RealRssi; /* lastest RSSI */
1247 pBss->LastBeaconRxTime = Now; /* last RX timestamp */
1250 /* BEACON from my BSSID - either IBSS or INFRA network */
1253 struct rt_rxwi RxWI;
1255 pAd->StaCfg.DtimCount = DtimCount;
1256 pAd->StaCfg.DtimPeriod = DtimPeriod;
1257 pAd->StaCfg.LastBeaconRxTime = Now;
1259 RxWI.RSSI0 = Elem->Rssi0;
1260 RxWI.RSSI1 = Elem->Rssi1;
1261 RxWI.RSSI2 = Elem->Rssi2;
1263 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
1264 if (AironetCellPowerLimit != 0xFF) {
1266 /* We get the Cisco (ccx) "TxPower Limit" required */
1267 /* Changed to appropriate TxPower Limit for Ciso Compatible Extensions */
1269 ChangeToCellPowerLimit(pAd,
1270 AironetCellPowerLimit);
1273 /* AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist. */
1274 /* Used the default TX Power Percentage, that set from UI. */
1276 pAd->CommonCfg.TxPowerPercentage =
1277 pAd->CommonCfg.TxPowerDefault;
1280 if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo))) {
1281 u8 MaxSupportedRateIn500Kbps = 0;
1283 struct rt_mac_table_entry *pEntry;
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;
1293 for (idx = 0; idx < ExtRateLen; idx++) {
1294 if (MaxSupportedRateIn500Kbps <
1295 (ExtRate[idx] & 0x7f))
1296 MaxSupportedRateIn500Kbps =
1297 ExtRate[idx] & 0x7f;
1300 /* look up the existing table */
1301 pEntry = MacTableLookup(pAd, Addr2);
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. */
1306 && (Elem->Wcid == RESERVED_WCID))
1309 ((pEntry->LastBeaconRxTime +
1310 ADHOC_ENTRY_BEACON_LOST_TIME) <
1313 /* Another adhoc joining, add to our MAC table. */
1315 MacTableInsertEntry(pAd,
1320 if (StaAddMacTableEntry(pAd,
1322 MaxSupportedRateIn500Kbps,
1329 DBGPRINT(RT_DEBUG_TRACE,
1330 ("ADHOC - Add Entry failed.\n"));
1335 (Elem->Wcid == RESERVED_WCID)) {
1336 idx = pAd->StaCfg.DefaultKeyId;
1337 RTMP_STA_SECURITY_INFO_ADD(pAd,
1344 if (pEntry && pEntry->ValidAsCLI)
1345 pEntry->LastBeaconRxTime = Now;
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);
1353 pAd->IndicateMediaState =
1354 NdisMediaStateConnected;
1355 RTMP_IndicateMediaState(pAd);
1356 pAd->ExtraInfo = GENERAL_LINK_UP;
1357 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
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. */
1364 BssTableSearch(&pAd->ScanTab, Bssid,
1366 if (Bssidx == BSS_NOT_FOUND) {
1368 BssTableSetEntry(pAd,
1387 NewExtChannelOffset,
1398 DBGPRINT(RT_DEBUG_TRACE,
1399 ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1403 if (INFRA_ON(pAd)) {
1404 BOOLEAN bUseShortSlot, bUseBGProtection;
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 */
1411 /*bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo); */
1413 CAP_IS_SHORT_SLOT(CapabilityInfo);
1414 if (bUseShortSlot !=
1415 OPSTATUS_TEST_FLAG(pAd,
1416 fOP_STATUS_SHORT_SLOT_INUSED))
1417 AsicSetSlotTime(pAd, bUseShortSlot);
1419 bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || /* always use */
1420 ((pAd->CommonCfg.UseBGProtection == 0)
1421 && ERP_IS_USE_PROTECTION(Erp));
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;
1426 if (bUseBGProtection !=
1427 OPSTATUS_TEST_FLAG(pAd,
1428 fOP_STATUS_BG_PROTECTION_INUSED))
1430 if (bUseBGProtection) {
1431 OPSTATUS_SET_FLAG(pAd,
1432 fOP_STATUS_BG_PROTECTION_INUSED);
1433 AsicUpdateProtect(pAd,
1450 OPSTATUS_CLEAR_FLAG(pAd,
1451 fOP_STATUS_BG_PROTECTION_INUSED);
1452 AsicUpdateProtect(pAd,
1470 DBGPRINT(RT_DEBUG_WARN,
1471 ("SYNC - AP changed B/G protection to %d\n",
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.
1479 || (AddHtInfo.AddHtInfo2.NonGfPresent !=
1480 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1482 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1484 AddHtInfo.AddHtInfo2.NonGfPresent;
1485 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1487 AddHtInfo.AddHtInfo2.OperaionMode;
1488 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1489 NonGfPresent == 1) {
1490 AsicUpdateProtect(pAd,
1498 AsicUpdateProtect(pAd,
1506 DBGPRINT(RT_DEBUG_TRACE,
1507 ("SYNC - AP changed N OperaionMode to %d\n",
1508 pAd->MlmeAux.AddHtInfo.
1509 AddHtInfo2.OperaionMode));
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"));
1521 if (OPSTATUS_TEST_FLAG
1522 (pAd, fOP_STATUS_WMM_INUSED)
1523 && (EdcaParm.bValid == TRUE)
1524 && (EdcaParm.EdcaUpdateCount !=
1525 pAd->CommonCfg.APEdcaParm.
1527 DBGPRINT(RT_DEBUG_TRACE,
1528 ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1529 pAd->CommonCfg.APEdcaParm.
1531 EdcaParm.EdcaUpdateCount));
1532 AsicSetEdcaParm(pAd, &EdcaParm);
1534 /* copy QOS related information */
1535 NdisMoveMemory(&pAd->CommonCfg.APQbssLoad,
1537 sizeof(struct rt_qbss_load_parm));
1538 NdisMoveMemory(&pAd->CommonCfg.APQosCapability,
1540 sizeof(struct rt_qos_capability_parm));
1542 /* only INFRASTRUCTURE mode support power-saving feature */
1543 if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE))
1544 || (pAd->CommonCfg.bAPSDForcePowerSave)) {
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. */
1553 if (OPSTATUS_TEST_FLAG
1554 (pAd, fOP_STATUS_PCIE_DEVICE)) {
1555 /* Restore to correct BBP R3 value */
1556 if (pAd->Antenna.field.RxPath >
1558 RTMP_BBP_IO_WRITE8_BY_REG_ID
1561 /* Turn clk to 80Mhz. */
1563 #endif /* RTMP_MAC_PCI // */
1564 if (pAd->CommonCfg.bAPSDCapable
1565 && pAd->CommonCfg.APEdcaParm.
1567 && pAd->CommonCfg.bAPSDAC_BE
1568 && pAd->CommonCfg.bAPSDAC_BK
1569 && pAd->CommonCfg.bAPSDAC_VI
1570 && pAd->CommonCfg.bAPSDAC_VO) {
1572 bNeedSendTriggerFrame =
1575 RTMP_PS_POLL_ENQUEUE(pAd);
1576 } else if (BcastFlag && (DtimCount == 0)
1577 && OPSTATUS_TEST_FLAG(pAd,
1578 fOP_STATUS_RECEIVE_DTIM))
1581 if (OPSTATUS_TEST_FLAG
1582 (pAd, fOP_STATUS_PCIE_DEVICE)) {
1583 if (pAd->Antenna.field.RxPath >
1585 RTMP_BBP_IO_WRITE8_BY_REG_ID
1589 #endif /* RTMP_MAC_PCI // */
1591 if ((pAd->TxSwQueue[QID_AC_BK].Number != 0)
1592 || (pAd->TxSwQueue[QID_AC_BE].Number !=
1594 || (pAd->TxSwQueue[QID_AC_VI].Number !=
1596 || (pAd->TxSwQueue[QID_AC_VO].Number !=
1600 (pAd, QID_AC_BK, TX_RING_SIZE - 1,
1601 &FreeNumber) != NDIS_STATUS_SUCCESS)
1604 (pAd, QID_AC_BE, TX_RING_SIZE - 1,
1605 &FreeNumber) != NDIS_STATUS_SUCCESS)
1608 (pAd, QID_AC_VI, TX_RING_SIZE - 1,
1609 &FreeNumber) != NDIS_STATUS_SUCCESS)
1612 (pAd, QID_AC_VO, TX_RING_SIZE - 1,
1613 &FreeNumber) != NDIS_STATUS_SUCCESS)
1616 (pAd, QID_MGMT, MGMT_RING_SIZE - 1,
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? */
1622 if (OPSTATUS_TEST_FLAG
1623 (pAd, fOP_STATUS_PCIE_DEVICE)) {
1624 if (pAd->Antenna.field.RxPath >
1626 RTMP_BBP_IO_WRITE8_BY_REG_ID
1630 #endif /* RTMP_MAC_PCI // */
1632 if ((pAd->CommonCfg.
1633 bACMAPSDTr[QID_AC_VO])
1635 bACMAPSDTr[QID_AC_VI])
1637 bACMAPSDTr[QID_AC_BK])
1639 bACMAPSDTr[QID_AC_BE])) {
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.
1646 So we can not sleep here or we will suffer a case:
1648 PS Management 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
1655 Maybe we need a timeout timer to avoid that we do
1656 NOT receive the EOSP frame.
1658 We can not use More Data to check if SP is ended
1662 u16 NextDtim = DtimCount;
1665 NextDtim = DtimPeriod;
1667 TbttNumToNextWakeUp =
1670 if (OPSTATUS_TEST_FLAG
1672 fOP_STATUS_RECEIVE_DTIM)
1673 && (TbttNumToNextWakeUp >
1675 TbttNumToNextWakeUp =
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. */
1682 ThisTbttNumToNextWakeUp
1684 TbttNumToNextWakeUp;
1685 AsicSleepThenAutoWakeup
1688 ThisTbttNumToNextWakeUp);
1694 /* not my BSSID, ignore it */
1696 /* sanity check fail, ignore this frame */
1700 ==========================================================================
1702 Receive PROBE REQ from remote peer when operating in IBSS mode
1703 ==========================================================================
1705 void PeerProbeReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1707 u8 Addr2[MAC_ADDR_LEN];
1708 char Ssid[MAX_LEN_OF_SSID];
1710 u8 HtLen, AddHtLen, NewExtLen;
1711 struct rt_header_802_11 ProbeRspHdr;
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 };
1725 if (PeerProbeReqSanity
1726 (pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen)) {
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)
1735 /*pAd->StaCfg.AtimWin = 0; // ?????? */
1738 (pAd->StaCfg.WepStatus ==
1739 Ndis802_11Encryption1Enabled)
1740 || (pAd->StaCfg.WepStatus ==
1741 Ndis802_11Encryption2Enabled)
1742 || (pAd->StaCfg.WepStatus ==
1743 Ndis802_11Encryption3Enabled);
1745 CAP_GENERATE(0, 1, Privacy,
1746 (pAd->CommonCfg.TxPreamble ==
1747 Rt802_11PreambleShort), 0, 0);
1749 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1750 sizeof(struct rt_header_802_11), &ProbeRspHdr,
1751 TIMESTAMP_LEN, &FakeTimestamp,
1752 2, &pAd->CommonCfg.BeaconPeriod,
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);
1765 if (pAd->StaActive.ExtRateLen) {
1767 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1770 1, &pAd->StaActive.ExtRateLen,
1771 pAd->StaActive.ExtRateLen,
1772 &pAd->StaActive.ExtRate,
1776 /* If adhoc secruity is set for WPA-None, append the cipher suite IE */
1777 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
1779 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1781 1, &pAd->StaCfg.RSNIE_Len,
1782 pAd->StaCfg.RSNIE_Len,
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);
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,
1805 MakeOutgoingFrame(pOutBuffer + FrameLen,
1806 &TmpLen, 1, &HtCapIe,
1809 (struct rt_ht_capability_ie),
1815 (struct rt_add_ht_info_ie),
1821 (struct rt_new_ext_chan_ie),
1829 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1830 MlmeFreeMemory(pAd, pOutBuffer);
1835 void BeaconTimeoutAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
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);
1845 ==========================================================================
1847 Scan timeout procedure. basically add channel index by 1 and rescan
1848 ==========================================================================
1850 void ScanTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1852 pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
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;
1861 /* this routine will stop if pAd->MlmeAux.Channel == 0 */
1862 ScanNextChannel(pAd);
1866 ==========================================================================
1868 ==========================================================================
1870 void InvalidStateWhenScan(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
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);
1882 ==========================================================================
1884 ==========================================================================
1886 void InvalidStateWhenJoin(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
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);
1898 ==========================================================================
1900 ==========================================================================
1902 void InvalidStateWhenStart(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
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);
1914 ==========================================================================
1917 IRQL = DISPATCH_LEVEL
1919 ==========================================================================
1921 void EnqueuePsPoll(struct rt_rtmp_adapter *pAd)
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));
1931 ==========================================================================
1933 ==========================================================================
1935 void EnqueueProbeRequest(struct rt_rtmp_adapter *pAd)
1939 unsigned long FrameLen = 0;
1940 struct rt_header_802_11 Hdr80211;
1942 DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
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);
1949 /* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */
1950 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1951 sizeof(struct rt_header_802_11), &Hdr80211,
1953 1, &pAd->CommonCfg.SsidLen,
1954 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
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);
1965 BOOLEAN ScanRunning(struct rt_rtmp_adapter *pAd)
1967 return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;