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(struct rt_rtmp_adapter *pAd,
54 struct rt_state_machine *Sm, OUT STATE_MACHINE_FUNC Trans[])
56 StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG,
57 (STATE_MACHINE_FUNC) Drop, SYNC_IDLE,
61 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ,
62 (STATE_MACHINE_FUNC) MlmeScanReqAction);
63 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ,
64 (STATE_MACHINE_FUNC) MlmeJoinReqAction);
65 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ,
66 (STATE_MACHINE_FUNC) MlmeStartReqAction);
67 StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON,
68 (STATE_MACHINE_FUNC) PeerBeacon);
69 StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ,
70 (STATE_MACHINE_FUNC) PeerProbeReqAction);
73 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ,
74 (STATE_MACHINE_FUNC) InvalidStateWhenScan);
75 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ,
76 (STATE_MACHINE_FUNC) InvalidStateWhenJoin);
77 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ,
78 (STATE_MACHINE_FUNC) InvalidStateWhenStart);
79 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON,
80 (STATE_MACHINE_FUNC) PeerBeaconAtJoinAction);
81 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT,
82 (STATE_MACHINE_FUNC) BeaconTimeoutAtJoinAction);
85 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ,
86 (STATE_MACHINE_FUNC) InvalidStateWhenScan);
87 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ,
88 (STATE_MACHINE_FUNC) InvalidStateWhenJoin);
89 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ,
90 (STATE_MACHINE_FUNC) InvalidStateWhenStart);
91 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON,
92 (STATE_MACHINE_FUNC) PeerBeaconAtScanAction);
93 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP,
94 (STATE_MACHINE_FUNC) PeerBeaconAtScanAction);
95 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT,
96 (STATE_MACHINE_FUNC) ScanTimeoutAction);
99 RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer,
100 GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
101 RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer,
102 GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
106 ==========================================================================
108 Beacon timeout handler, executed in timer thread
110 IRQL = DISPATCH_LEVEL
112 ==========================================================================
114 void BeaconTimeout(void *SystemSpecific1,
115 void *FunctionContext,
116 void *SystemSpecific2, void *SystemSpecific3)
118 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
120 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeout\n"));
122 /* Do nothing if the driver is starting halt state. */
123 /* This might happen when timer already been fired before cancel timer with mlmehalt */
124 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
127 if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
130 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
131 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
132 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
135 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
136 DBGPRINT(RT_DEBUG_TRACE,
137 ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",
138 pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
141 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
142 RTMP_MLME_HANDLER(pAd);
146 ==========================================================================
148 Scan timeout handler, executed in timer thread
150 IRQL = DISPATCH_LEVEL
152 ==========================================================================
154 void ScanTimeout(void *SystemSpecific1,
155 void *FunctionContext,
156 void *SystemSpecific2, void *SystemSpecific3)
158 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
160 /* Do nothing if the driver is starting halt state. */
161 /* This might happen when timer already been fired before cancel timer with mlmehalt */
162 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
165 if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL)) {
166 RTMP_MLME_HANDLER(pAd);
168 /* To prevent SyncMachine.CurrState is SCAN_LISTEN forever. */
169 pAd->MlmeAux.Channel = 0;
170 ScanNextChannel(pAd);
171 if (pAd->CommonCfg.bWirelessEvent) {
172 RTMPSendWirelessEvent(pAd,
173 IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG,
174 pAd->MacTab.Content[BSSID_WCID].
181 ==========================================================================
183 MLME SCAN req state machine procedure
184 ==========================================================================
186 void MlmeScanReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
188 u8 Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
189 BOOLEAN TimerCancelled;
192 struct rt_header_802_11 * pHdr80211;
193 u8 *pOutBuffer = NULL;
196 /* Check the total scan tries for one single OID command */
197 /* If this is the CCX 2.0 Case, skip that! */
198 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
199 DBGPRINT(RT_DEBUG_TRACE,
200 ("SYNC - MlmeScanReqAction before Startup\n"));
203 /* Increase the scan retry counters. */
204 pAd->StaCfg.ScanCnt++;
207 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
209 (pAd->StaCfg.bRadio == TRUE) &&
210 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
211 if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) {
212 AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00,
214 AsicCheckCommanOk(pAd, PowerWakeCID);
215 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
216 DBGPRINT(RT_DEBUG_TRACE,
217 ("PSM - Issue Wake up command \n"));
219 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
222 #endif /* RTMP_MAC_PCI // */
224 /* first check the parameter sanity */
225 if (MlmeScanReqSanity(pAd,
228 &BssType, (char *)Ssid, &SsidLen, &ScanType)) {
230 /* Check for channel load and noise hist request */
231 /* Suspend MSDU only at scan request, not the last two mentioned */
232 /* Suspend MSDU transmission here */
233 RTMPSuspendMsduTransmission(pAd);
236 /* To prevent data lost. */
237 /* Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. */
238 /* And should send an NULL data with turned PSM bit off to AP, when scan progress done */
240 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
241 && (INFRA_ON(pAd))) {
242 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);
243 if (NStatus == NDIS_STATUS_SUCCESS) {
244 pHdr80211 = (struct rt_header_802_11 *) pOutBuffer;
245 MgtMacHeaderInit(pAd, pHdr80211,
246 SUBTYPE_NULL_FUNC, 1,
247 pAd->CommonCfg.Bssid,
248 pAd->CommonCfg.Bssid);
249 pHdr80211->Duration = 0;
250 pHdr80211->FC.Type = BTYPE_DATA;
251 pHdr80211->FC.PwrMgmt = PWR_SAVE;
253 /* Send using priority queue */
254 MiniportMMRequest(pAd, 0, pOutBuffer,
255 sizeof(struct rt_header_802_11));
256 DBGPRINT(RT_DEBUG_TRACE,
257 ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
258 MlmeFreeMemory(pAd, pOutBuffer);
263 NdisGetSystemUpTime(&Now);
264 pAd->StaCfg.LastScanTime = Now;
265 /* reset all the timers */
266 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
267 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
269 /* record desired BSS parameters */
270 pAd->MlmeAux.BssType = BssType;
271 pAd->MlmeAux.ScanType = ScanType;
272 pAd->MlmeAux.SsidLen = SsidLen;
273 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
274 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
276 /* start from the first channel */
277 pAd->MlmeAux.Channel = FirstChannel(pAd);
279 /* Let BBP register at 20MHz to do scan */
280 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
282 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
283 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
284 ScanNextChannel(pAd);
286 DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
287 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
288 Status = MLME_INVALID_FORMAT;
289 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2,
295 ==========================================================================
297 MLME JOIN req state machine procedure
298 ==========================================================================
300 void MlmeJoinReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
303 struct rt_bss_entry *pBss;
304 BOOLEAN TimerCancelled;
305 struct rt_header_802_11 Hdr80211;
307 unsigned long FrameLen = 0;
308 u8 *pOutBuffer = NULL;
313 u8 ASupRate[] = { 0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C };
314 u8 ASupRateLen = sizeof(ASupRate) / sizeof(u8);
315 struct rt_mlme_join_req *pInfo = (struct rt_mlme_join_req *)(Elem->Msg);
317 DBGPRINT(RT_DEBUG_TRACE,
318 ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
321 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
323 (pAd->StaCfg.bRadio == TRUE) &&
324 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
325 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
327 #endif /* RTMP_MAC_PCI // */
329 /* reset all the timers */
330 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
331 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
333 pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
335 /* record the desired SSID & BSSID we're waiting for */
336 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
338 /* If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again. */
339 if (pBss->Hidden == 0) {
340 RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
341 NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
342 pAd->MlmeAux.SsidLen = pBss->SsidLen;
345 pAd->MlmeAux.BssType = pBss->BssType;
346 pAd->MlmeAux.Channel = pBss->Channel;
347 pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
349 /* Let BBP register at 20MHz to do scan */
350 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
352 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
354 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
356 /* switch channel and waiting for beacon timer */
357 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
358 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
359 RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
362 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
363 (pAd->MlmeAux.Channel > 14) &&
364 RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
367 /* We can't send any Probe request frame to meet 802.11h. */
369 if (pBss->Hidden == 0)
373 /* send probe request */
375 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
376 if (NStatus == NDIS_STATUS_SUCCESS) {
377 if (pAd->MlmeAux.Channel <= 14) {
378 pSupRate = pAd->CommonCfg.SupRate;
379 SupRateLen = pAd->CommonCfg.SupRateLen;
380 pExtRate = pAd->CommonCfg.ExtRate;
381 ExtRateLen = pAd->CommonCfg.ExtRateLen;
384 /* Overwrite Support Rate, CCK rate are not allowed */
387 SupRateLen = ASupRateLen;
391 if (pAd->MlmeAux.BssType == BSS_INFRA)
392 MgtMacHeaderInit(pAd, &Hdr80211,
393 SUBTYPE_PROBE_REQ, 0,
397 MgtMacHeaderInit(pAd, &Hdr80211,
398 SUBTYPE_PROBE_REQ, 0,
402 MakeOutgoingFrame(pOutBuffer, &FrameLen,
403 sizeof(struct rt_header_802_11), &Hdr80211,
405 1, &pAd->MlmeAux.SsidLen,
406 pAd->MlmeAux.SsidLen,
407 pAd->MlmeAux.Ssid, 1, &SupRateIe, 1,
408 &SupRateLen, SupRateLen, pSupRate,
413 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
416 ExtRateLen, pExtRate,
421 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
422 MlmeFreeMemory(pAd, pOutBuffer);
426 DBGPRINT(RT_DEBUG_TRACE,
427 ("SYNC - Switch to ch %d, Wait BEACON from %pM\n",
428 pBss->Channel, pBss->Bssid));
430 pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
434 ==========================================================================
436 MLME START Request state machine procedure, starting an IBSS
437 ==========================================================================
439 void MlmeStartReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
441 u8 Ssid[MAX_LEN_OF_SSID], SsidLen;
442 BOOLEAN TimerCancelled;
444 /* New for WPA security suites */
445 u8 VarIE[MAX_VIE_LEN]; /* Total VIE length = MAX_VIE_LEN - -5 */
446 struct rt_ndis_802_11_variable_ies *pVIE = NULL;
447 LARGE_INTEGER TimeStamp;
451 /* Init Variable IE structure */
452 pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
454 TimeStamp.u.LowPart = 0;
455 TimeStamp.u.HighPart = 0;
457 if (MlmeStartReqSanity
458 (pAd, Elem->Msg, Elem->MsgLen, (char *)Ssid, &SsidLen)) {
459 /* reset all the timers */
460 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
461 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
464 /* Start a new IBSS. All IBSS parameters are decided now.... */
466 DBGPRINT(RT_DEBUG_TRACE,
467 ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
468 pAd->MlmeAux.BssType = BSS_ADHOC;
469 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
470 pAd->MlmeAux.SsidLen = SsidLen;
472 /* generate a radom number as BSSID */
473 MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
474 DBGPRINT(RT_DEBUG_TRACE,
475 ("MlmeStartReqAction - generate a radom number as BSSID \n"));
478 (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
479 || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
480 || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
481 pAd->MlmeAux.CapabilityInfo =
482 CAP_GENERATE(0, 1, Privacy,
483 (pAd->CommonCfg.TxPreamble ==
484 Rt802_11PreambleShort), 1, 0);
485 pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
486 pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin;
487 pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
489 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
490 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
492 pAd->MlmeAux.SupRateLen = pAd->CommonCfg.SupRateLen;
493 NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate,
494 MAX_LEN_OF_SUPPORTED_RATES);
495 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate,
496 &pAd->MlmeAux.SupRateLen);
497 pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
498 NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate,
499 MAX_LEN_OF_SUPPORTED_RATES);
500 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate,
501 &pAd->MlmeAux.ExtRateLen);
503 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
504 RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy,
505 &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0],
506 &pAd->MlmeAux.HtCapability,
507 &pAd->MlmeAux.AddHtInfo);
508 pAd->MlmeAux.HtCapabilityLen = sizeof(struct rt_ht_capability_ie);
509 /* Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here. */
510 DBGPRINT(RT_DEBUG_TRACE,
511 ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
513 pAd->MlmeAux.HtCapabilityLen = 0;
514 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
515 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.
518 /* temporarily not support QOS in IBSS */
519 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(struct rt_edca_parm));
520 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad,
521 sizeof(struct rt_qbss_load_parm));
522 NdisZeroMemory(&pAd->MlmeAux.APQosCapability,
523 sizeof(struct rt_qos_capability_parm));
525 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
526 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
528 DBGPRINT(RT_DEBUG_TRACE,
529 ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
530 pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen,
531 pAd->MlmeAux.ExtRateLen));
533 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
534 Status = MLME_SUCCESS;
535 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2,
538 DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
539 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
540 Status = MLME_INVALID_FORMAT;
541 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2,
547 ==========================================================================
549 peer sends beacon back when scanning
550 ==========================================================================
552 void PeerBeaconAtScanAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
554 u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
555 u8 Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
556 SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
557 struct rt_cf_parm CfParm;
558 u16 BeaconPeriod, AtimWin, CapabilityInfo;
559 struct rt_frame_802_11 * pFrame;
560 LARGE_INTEGER TimeStamp;
562 u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
563 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
564 u8 SupRateLen, ExtRateLen;
567 u8 AironetCellPowerLimit;
568 struct rt_edca_parm EdcaParm;
569 struct rt_qbss_load_parm QbssLoad;
570 struct rt_qos_capability_parm QosCapability;
571 unsigned long RalinkIe;
572 u8 VarIE[MAX_VIE_LEN]; /* Total VIE length = MAX_VIE_LEN - -5 */
573 struct rt_ndis_802_11_variable_ies *pVIE = NULL;
574 struct rt_ht_capability_ie HtCapability;
575 struct rt_add_ht_info_ie AddHtInfo; /* AP might use this additional ht info IE */
576 u8 HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
578 u8 NewExtChannelOffset = 0xff;
580 /* NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00); */
581 pFrame = (struct rt_frame_802_11 *) Elem->Msg;
582 /* Init Variable IE structure */
583 pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
586 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
587 RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
589 if (PeerBeaconAndProbeRspSanity(pAd,
615 &AironetCellPowerLimit,
621 &PreNHtCapabilityLen,
625 &NewExtChannelOffset, &LenVIE, pVIE)) {
629 Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
630 if (Idx != BSS_NOT_FOUND)
631 Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
634 RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
635 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
636 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
638 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
639 HtCapabilityLen = SIZE_HT_CAP_IE;
642 BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (char *)Ssid,
643 SsidLen, BssType, BeaconPeriod, &CfParm,
644 AtimWin, CapabilityInfo, SupRate,
645 SupRateLen, ExtRate, ExtRateLen,
646 &HtCapability, &AddHtInfo, HtCapabilityLen,
647 AddHtInfoLen, NewExtChannelOffset, Channel,
648 Rssi, TimeStamp, CkipFlag, &EdcaParm,
649 &QosCapability, &QbssLoad, LenVIE, pVIE);
651 if (Idx != BSS_NOT_FOUND) {
652 NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF,
654 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0],
655 &Elem->TimeStamp.u.LowPart, 4);
656 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4],
657 &Elem->TimeStamp.u.LowPart, 4);
661 /* sanity check fail, ignored */
665 ==========================================================================
667 When waiting joining the (I)BSS, beacon received from external
668 ==========================================================================
670 void PeerBeaconAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
672 u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
673 u8 Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
674 DtimCount, DtimPeriod, BcastFlag, NewChannel;
675 LARGE_INTEGER TimeStamp;
676 u16 BeaconPeriod, AtimWin, CapabilityInfo;
677 struct rt_cf_parm Cf;
678 BOOLEAN TimerCancelled;
680 u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
681 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
682 u8 SupRateLen, ExtRateLen;
685 u8 AironetCellPowerLimit;
686 struct rt_edca_parm EdcaParm;
687 struct rt_qbss_load_parm QbssLoad;
688 struct rt_qos_capability_parm QosCapability;
690 u8 VarIE[MAX_VIE_LEN]; /* Total VIE length = MAX_VIE_LEN - -5 */
691 struct rt_ndis_802_11_variable_ies *pVIE = NULL;
692 unsigned long RalinkIe;
694 struct rt_ht_capability_ie HtCapability;
695 struct rt_add_ht_info_ie AddHtInfo; /* AP might use this additional ht info IE */
696 u8 HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
698 u8 NewExtChannelOffset = 0xff;
700 BOOLEAN bAllowNrate = FALSE;
702 /* Init Variable IE structure */
703 pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
705 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
706 RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
708 if (PeerBeaconAndProbeRspSanity(pAd,
734 &AironetCellPowerLimit,
740 &PreNHtCapabilityLen,
744 &NewExtChannelOffset, &LenVIE, pVIE)) {
745 /* Disqualify 11b only adhoc when we are in 11g only adhoc mode */
746 if ((BssType == BSS_ADHOC)
747 && (pAd->CommonCfg.PhyMode == PHY_11G)
748 && ((SupRateLen + ExtRateLen) < 12))
751 /* BEACON from desired BSS/IBSS found. We should be able to decide most */
752 /* BSS parameters here. */
753 /* Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? */
754 /* Do we need to receover back all parameters belonging to previous BSS? */
755 /* A. Should be not. There's no back-door recover to previous AP. It still need */
756 /* a new JOIN-AUTH-ASSOC sequence. */
757 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid)) {
758 DBGPRINT(RT_DEBUG_TRACE,
759 ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n",
761 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,
764 /* Update RSSI to prevent No signal display when cards first initialized */
765 pAd->StaCfg.RssiSample.LastRssi0 =
766 ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
767 pAd->StaCfg.RssiSample.LastRssi1 =
768 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
769 pAd->StaCfg.RssiSample.LastRssi2 =
770 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
771 pAd->StaCfg.RssiSample.AvgRssi0 =
772 pAd->StaCfg.RssiSample.LastRssi0;
773 pAd->StaCfg.RssiSample.AvgRssi0X8 =
774 pAd->StaCfg.RssiSample.AvgRssi0 << 3;
775 pAd->StaCfg.RssiSample.AvgRssi1 =
776 pAd->StaCfg.RssiSample.LastRssi1;
777 pAd->StaCfg.RssiSample.AvgRssi1X8 =
778 pAd->StaCfg.RssiSample.AvgRssi1 << 3;
779 pAd->StaCfg.RssiSample.AvgRssi2 =
780 pAd->StaCfg.RssiSample.LastRssi2;
781 pAd->StaCfg.RssiSample.AvgRssi2X8 =
782 pAd->StaCfg.RssiSample.AvgRssi2 << 3;
785 /* We need to check if SSID only set to any, then we can record the current SSID. */
786 /* Otherwise will cause hidden SSID association failed. */
788 if (pAd->MlmeAux.SsidLen == 0) {
789 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid,
791 pAd->MlmeAux.SsidLen = SsidLen;
794 BssSsidTableSearch(&pAd->ScanTab, Bssid,
796 pAd->MlmeAux.SsidLen,
799 if (Idx == BSS_NOT_FOUND) {
816 BssTableSetEntry(pAd, &pAd->ScanTab,
839 if (Idx != BSS_NOT_FOUND) {
840 NdisMoveMemory(pAd->ScanTab.
845 NdisMoveMemory(&pAd->ScanTab.
850 NdisMoveMemory(&pAd->ScanTab.
856 pAd->ScanTab.BssEntry[Idx].
861 /* Multiple SSID case, used correct CapabilityInfo */
864 pAd->ScanTab.BssEntry[Idx].
868 NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
869 pAd->MlmeAux.CapabilityInfo =
870 CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
871 pAd->MlmeAux.BssType = BssType;
872 pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
873 pAd->MlmeAux.Channel = Channel;
874 pAd->MlmeAux.AtimWin = AtimWin;
875 pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
876 pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
877 pAd->MlmeAux.APRalinkIe = RalinkIe;
879 /* Copy AP's supported rate to MlmeAux for creating assoication request */
880 /* Also filter out not supported rate */
881 pAd->MlmeAux.SupRateLen = SupRateLen;
882 NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate,
884 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate,
885 &pAd->MlmeAux.SupRateLen);
886 pAd->MlmeAux.ExtRateLen = ExtRateLen;
887 NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate,
889 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate,
890 &pAd->MlmeAux.ExtRateLen);
892 NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet,
895 if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled)
896 && (pAd->StaCfg.WepStatus !=
897 Ndis802_11Encryption2Enabled))
898 || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) {
902 pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
903 pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
905 RTMPZeroMemory(&pAd->MlmeAux.HtCapability,
907 /* filter out un-supported ht rates */
908 if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
909 && ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
911 RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo,
912 &AddHtInfo, SIZE_ADD_HT_INFO_IE);
914 /* StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability */
915 NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.
916 MCSSet, HtCapability.MCSSet, 16);
917 pAd->MlmeAux.NewExtChannelOffset =
919 pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
920 pAd->StaActive.SupportedPhyInfo.bHtEnable =
922 if (PreNHtCapabilityLen > 0)
923 pAd->StaActive.SupportedPhyInfo.
925 RTMPCheckHt(pAd, BSSID_WCID, &HtCapability,
927 /* Copy AP Parameter to StaActive. This is also in LinkUp. */
928 DBGPRINT(RT_DEBUG_TRACE,
929 ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
930 pAd->StaActive.SupportedHtPhy.
932 pAd->StaActive.SupportedHtPhy.
934 HtCapability.HtCapInfo.ChannelWidth));
936 if (AddHtInfoLen > 0) {
937 CentralChannel = AddHtInfo.ControlChan;
938 /* Check again the Bandwidth capability of this AP. */
939 if ((AddHtInfo.ControlChan > 2)
940 && (AddHtInfo.AddHtInfo.
941 ExtChanOffset == EXTCHA_BELOW)
942 && (HtCapability.HtCapInfo.
943 ChannelWidth == BW_40)) {
945 AddHtInfo.ControlChan - 2;
947 if ((AddHtInfo.AddHtInfo.
948 ExtChanOffset == EXTCHA_ABOVE)
949 && (HtCapability.HtCapInfo.
950 ChannelWidth == BW_40)) {
952 AddHtInfo.ControlChan + 2;
955 if (pAd->MlmeAux.CentralChannel !=
957 DBGPRINT(RT_DEBUG_ERROR,
958 ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n",
960 AddHtInfo.ControlChan,
964 DBGPRINT(RT_DEBUG_TRACE,
965 ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n",
967 AddHtInfo.ControlChan));
972 /* To prevent error, let legacy AP must have same CentralChannel and Channel. */
973 if ((HtCapabilityLen == 0)
974 && (PreNHtCapabilityLen == 0))
975 pAd->MlmeAux.CentralChannel =
976 pAd->MlmeAux.Channel;
978 pAd->StaActive.SupportedPhyInfo.bHtEnable =
980 pAd->MlmeAux.NewExtChannelOffset = 0xff;
981 RTMPZeroMemory(&pAd->MlmeAux.HtCapability,
983 pAd->MlmeAux.HtCapabilityLen = 0;
984 RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo,
985 SIZE_ADD_HT_INFO_IE);
988 RTMPUpdateMlmeRate(pAd);
990 /* copy QOS related information */
991 if ((pAd->CommonCfg.bWmmCapable)
992 || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
994 NdisMoveMemory(&pAd->MlmeAux.APEdcaParm,
995 &EdcaParm, sizeof(struct rt_edca_parm));
996 NdisMoveMemory(&pAd->MlmeAux.APQbssLoad,
998 sizeof(struct rt_qbss_load_parm));
999 NdisMoveMemory(&pAd->MlmeAux.APQosCapability,
1001 sizeof(struct rt_qos_capability_parm));
1003 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm,
1004 sizeof(struct rt_edca_parm));
1005 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad,
1006 sizeof(struct rt_qbss_load_parm));
1007 NdisZeroMemory(&pAd->MlmeAux.APQosCapability,
1008 sizeof(struct rt_qos_capability_parm));
1011 DBGPRINT(RT_DEBUG_TRACE,
1012 ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
1013 pAd->MlmeAux.SupRateLen,
1014 pAd->MlmeAux.ExtRateLen));
1016 if (AironetCellPowerLimit != 0xFF) {
1017 /*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */
1018 ChangeToCellPowerLimit(pAd,
1019 AironetCellPowerLimit);
1020 } else /*Used the default TX Power Percentage. */
1021 pAd->CommonCfg.TxPowerPercentage =
1022 pAd->CommonCfg.TxPowerDefault;
1024 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1025 Status = MLME_SUCCESS;
1026 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF,
1029 /* not to me BEACON, ignored */
1031 /* sanity check fail, ignore this frame */
1035 ==========================================================================
1037 receive BEACON from peer
1039 IRQL = DISPATCH_LEVEL
1041 ==========================================================================
1043 void PeerBeacon(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1045 u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
1046 char Ssid[MAX_LEN_OF_SSID];
1047 struct rt_cf_parm CfParm;
1048 u8 SsidLen, MessageToMe = 0, BssType, Channel, NewChannel, index = 0;
1049 u8 DtimCount = 0, DtimPeriod = 0, BcastFlag = 0;
1050 u16 CapabilityInfo, AtimWin, BeaconPeriod;
1051 LARGE_INTEGER TimeStamp;
1052 u16 TbttNumToNextWakeUp;
1054 u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
1055 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1056 u8 SupRateLen, ExtRateLen;
1059 u8 AironetCellPowerLimit;
1060 struct rt_edca_parm EdcaParm;
1061 struct rt_qbss_load_parm QbssLoad;
1062 struct rt_qos_capability_parm QosCapability;
1063 unsigned long RalinkIe;
1064 /* New for WPA security suites */
1065 u8 VarIE[MAX_VIE_LEN]; /* Total VIE length = MAX_VIE_LEN - -5 */
1066 struct rt_ndis_802_11_variable_ies *pVIE = NULL;
1067 struct rt_ht_capability_ie HtCapability;
1068 struct rt_add_ht_info_ie AddHtInfo; /* AP might use this additional ht info IE */
1069 u8 HtCapabilityLen, PreNHtCapabilityLen;
1071 u8 NewExtChannelOffset = 0xff;
1073 if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
1077 /* Init Variable IE structure */
1078 pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
1080 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
1081 RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
1083 if (PeerBeaconAndProbeRspSanity(pAd,
1109 &AironetCellPowerLimit,
1115 &PreNHtCapabilityLen,
1119 &NewExtChannelOffset, &LenVIE, pVIE)) {
1120 BOOLEAN is_my_bssid, is_my_ssid;
1121 unsigned long Bssidx, Now;
1122 struct rt_bss_entry *pBss;
1124 RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
1125 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
1126 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1129 MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid) ? TRUE : FALSE;
1131 SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid,
1132 pAd->CommonCfg.SsidLen) ? TRUE : FALSE;
1134 /* ignore BEACON not for my SSID */
1135 if ((!is_my_ssid) && (!is_my_bssid))
1138 /* It means STA waits disassoc completely from this AP, ignores this beacon. */
1139 if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
1142 /* Copy Control channel for this BSSID. */
1143 if (AddHtInfoLen != 0)
1144 Channel = AddHtInfo.ControlChan;
1146 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
1147 HtCapabilityLen = SIZE_HT_CAP_IE;
1150 /* Housekeeping "SsidBssTab" table for later-on ROAMing usage. */
1152 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1153 if (Bssidx == BSS_NOT_FOUND) {
1154 /* discover new AP of this network, create BSS entry */
1156 BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid,
1157 SsidLen, BssType, BeaconPeriod,
1158 &CfParm, AtimWin, CapabilityInfo,
1159 SupRate, SupRateLen, ExtRate,
1160 ExtRateLen, &HtCapability,
1161 &AddHtInfo, HtCapabilityLen,
1162 AddHtInfoLen, NewExtChannelOffset,
1163 Channel, RealRssi, TimeStamp,
1164 CkipFlag, &EdcaParm,
1165 &QosCapability, &QbssLoad, LenVIE,
1167 if (Bssidx == BSS_NOT_FOUND) /* return if BSS table full */
1170 NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF,
1172 NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0],
1173 &Elem->TimeStamp.u.LowPart, 4);
1174 NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4],
1175 &Elem->TimeStamp.u.LowPart, 4);
1179 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0)
1180 && (Channel != NewChannel)) {
1181 /* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */
1182 /* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */
1183 AsicSwitchChannel(pAd, 1, FALSE);
1184 AsicLockChannel(pAd, 1);
1185 LinkDown(pAd, FALSE);
1186 MlmeQueueInit(&pAd->Mlme.Queue);
1187 BssTableInit(&pAd->ScanTab);
1188 RTMPusecDelay(1000000); /* use delay to prevent STA do reassoc */
1190 /* channel sanity check */
1191 for (index = 0; index < pAd->ChannelListNum; index++) {
1192 if (pAd->ChannelList[index].Channel ==
1194 pAd->ScanTab.BssEntry[Bssidx].Channel =
1196 pAd->CommonCfg.Channel = NewChannel;
1197 AsicSwitchChannel(pAd,
1200 AsicLockChannel(pAd,
1201 pAd->CommonCfg.Channel);
1202 DBGPRINT(RT_DEBUG_TRACE,
1203 ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n",
1209 if (index >= pAd->ChannelListNum) {
1210 DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
1213 /* if the ssid matched & bssid unmatched, we should select the bssid with large value. */
1214 /* This might happened when two STA start at the same time */
1215 if ((!is_my_bssid) && ADHOC_ON(pAd)) {
1218 /* Add the safeguard against the mismatch of adhoc wep status */
1219 if (pAd->StaCfg.WepStatus !=
1220 pAd->ScanTab.BssEntry[Bssidx].WepStatus) {
1223 /* collapse into the ADHOC network which has bigger BSSID value. */
1224 for (i = 0; i < 6; i++) {
1225 if (Bssid[i] > pAd->CommonCfg.Bssid[i]) {
1226 DBGPRINT(RT_DEBUG_TRACE,
1227 ("SYNC - merge to the IBSS "
1228 "with bigger BSSID="
1230 AsicDisableSync(pAd);
1231 COPY_MAC_ADDR(pAd->CommonCfg.Bssid,
1233 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1234 MakeIbssBeacon(pAd); /* re-build BEACON frame */
1235 AsicEnableIbssSync(pAd); /* copy BEACON frame to on-chip memory */
1238 } else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
1243 NdisGetSystemUpTime(&Now);
1244 pBss = &pAd->ScanTab.BssEntry[Bssidx];
1245 pBss->Rssi = RealRssi; /* lastest RSSI */
1246 pBss->LastBeaconRxTime = Now; /* last RX timestamp */
1249 /* BEACON from my BSSID - either IBSS or INFRA network */
1252 struct rt_rxwi RxWI;
1254 pAd->StaCfg.DtimCount = DtimCount;
1255 pAd->StaCfg.DtimPeriod = DtimPeriod;
1256 pAd->StaCfg.LastBeaconRxTime = Now;
1258 RxWI.RSSI0 = Elem->Rssi0;
1259 RxWI.RSSI1 = Elem->Rssi1;
1260 RxWI.RSSI2 = Elem->Rssi2;
1262 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
1263 if (AironetCellPowerLimit != 0xFF) {
1265 /* We get the Cisco (ccx) "TxPower Limit" required */
1266 /* Changed to appropriate TxPower Limit for Ciso Compatible Extensions */
1268 ChangeToCellPowerLimit(pAd,
1269 AironetCellPowerLimit);
1272 /* AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist. */
1273 /* Used the default TX Power Percentage, that set from UI. */
1275 pAd->CommonCfg.TxPowerPercentage =
1276 pAd->CommonCfg.TxPowerDefault;
1279 if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo))) {
1280 u8 MaxSupportedRateIn500Kbps = 0;
1282 struct rt_mac_table_entry *pEntry;
1284 /* supported rates array may not be sorted. sort it and find the maximum rate */
1285 for (idx = 0; idx < SupRateLen; idx++) {
1286 if (MaxSupportedRateIn500Kbps <
1287 (SupRate[idx] & 0x7f))
1288 MaxSupportedRateIn500Kbps =
1289 SupRate[idx] & 0x7f;
1292 for (idx = 0; idx < ExtRateLen; idx++) {
1293 if (MaxSupportedRateIn500Kbps <
1294 (ExtRate[idx] & 0x7f))
1295 MaxSupportedRateIn500Kbps =
1296 ExtRate[idx] & 0x7f;
1299 /* look up the existing table */
1300 pEntry = MacTableLookup(pAd, Addr2);
1302 /* Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon. */
1303 /* To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station. */
1305 && (Elem->Wcid == RESERVED_WCID))
1308 ((pEntry->LastBeaconRxTime +
1309 ADHOC_ENTRY_BEACON_LOST_TIME) <
1312 /* Another adhoc joining, add to our MAC table. */
1314 MacTableInsertEntry(pAd,
1319 if (StaAddMacTableEntry(pAd,
1321 MaxSupportedRateIn500Kbps,
1328 DBGPRINT(RT_DEBUG_TRACE,
1329 ("ADHOC - Add Entry failed.\n"));
1334 (Elem->Wcid == RESERVED_WCID)) {
1335 idx = pAd->StaCfg.DefaultKeyId;
1336 RTMP_STA_SECURITY_INFO_ADD(pAd,
1343 if (pEntry && pEntry->ValidAsCLI)
1344 pEntry->LastBeaconRxTime = Now;
1346 /* At least another peer in this IBSS, declare MediaState as CONNECTED */
1347 if (!OPSTATUS_TEST_FLAG
1348 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
1349 OPSTATUS_SET_FLAG(pAd,
1350 fOP_STATUS_MEDIA_STATE_CONNECTED);
1352 pAd->IndicateMediaState =
1353 NdisMediaStateConnected;
1354 RTMP_IndicateMediaState(pAd);
1355 pAd->ExtraInfo = GENERAL_LINK_UP;
1356 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1358 /* 2003/03/12 - john */
1359 /* Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that */
1360 /* "site survey" result should always include the current connected network. */
1363 BssTableSearch(&pAd->ScanTab, Bssid,
1365 if (Bssidx == BSS_NOT_FOUND) {
1367 BssTableSetEntry(pAd,
1386 NewExtChannelOffset,
1397 DBGPRINT(RT_DEBUG_TRACE,
1398 ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1402 if (INFRA_ON(pAd)) {
1403 BOOLEAN bUseShortSlot, bUseBGProtection;
1405 /* decide to use/change to - */
1406 /* 1. long slot (20 us) or short slot (9 us) time */
1407 /* 2. turn on/off RTS/CTS and/or CTS-to-self protection */
1408 /* 3. short preamble */
1410 /*bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo); */
1412 CAP_IS_SHORT_SLOT(CapabilityInfo);
1413 if (bUseShortSlot !=
1414 OPSTATUS_TEST_FLAG(pAd,
1415 fOP_STATUS_SHORT_SLOT_INUSED))
1416 AsicSetSlotTime(pAd, bUseShortSlot);
1418 bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || /* always use */
1419 ((pAd->CommonCfg.UseBGProtection == 0)
1420 && ERP_IS_USE_PROTECTION(Erp));
1422 if (pAd->CommonCfg.Channel > 14) /* always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP */
1423 bUseBGProtection = FALSE;
1425 if (bUseBGProtection !=
1426 OPSTATUS_TEST_FLAG(pAd,
1427 fOP_STATUS_BG_PROTECTION_INUSED))
1429 if (bUseBGProtection) {
1430 OPSTATUS_SET_FLAG(pAd,
1431 fOP_STATUS_BG_PROTECTION_INUSED);
1432 AsicUpdateProtect(pAd,
1449 OPSTATUS_CLEAR_FLAG(pAd,
1450 fOP_STATUS_BG_PROTECTION_INUSED);
1451 AsicUpdateProtect(pAd,
1469 DBGPRINT(RT_DEBUG_WARN,
1470 ("SYNC - AP changed B/G protection to %d\n",
1473 /* check Ht protection mode. and adhere to the Non-GF device indication by AP. */
1474 if ((AddHtInfoLen != 0) &&
1475 ((AddHtInfo.AddHtInfo2.OperaionMode !=
1476 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1478 || (AddHtInfo.AddHtInfo2.NonGfPresent !=
1479 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1481 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1483 AddHtInfo.AddHtInfo2.NonGfPresent;
1484 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1486 AddHtInfo.AddHtInfo2.OperaionMode;
1487 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1488 NonGfPresent == 1) {
1489 AsicUpdateProtect(pAd,
1497 AsicUpdateProtect(pAd,
1505 DBGPRINT(RT_DEBUG_TRACE,
1506 ("SYNC - AP changed N OperaionMode to %d\n",
1507 pAd->MlmeAux.AddHtInfo.
1508 AddHtInfo2.OperaionMode));
1511 if (OPSTATUS_TEST_FLAG
1512 (pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED)
1513 && ERP_IS_USE_BARKER_PREAMBLE(Erp)) {
1514 MlmeSetTxPreamble(pAd,
1515 Rt802_11PreambleLong);
1516 DBGPRINT(RT_DEBUG_TRACE,
1517 ("SYNC - AP forced to use long preamble\n"));
1520 if (OPSTATUS_TEST_FLAG
1521 (pAd, fOP_STATUS_WMM_INUSED)
1522 && (EdcaParm.bValid == TRUE)
1523 && (EdcaParm.EdcaUpdateCount !=
1524 pAd->CommonCfg.APEdcaParm.
1526 DBGPRINT(RT_DEBUG_TRACE,
1527 ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1528 pAd->CommonCfg.APEdcaParm.
1530 EdcaParm.EdcaUpdateCount));
1531 AsicSetEdcaParm(pAd, &EdcaParm);
1533 /* copy QOS related information */
1534 NdisMoveMemory(&pAd->CommonCfg.APQbssLoad,
1536 sizeof(struct rt_qbss_load_parm));
1537 NdisMoveMemory(&pAd->CommonCfg.APQosCapability,
1539 sizeof(struct rt_qos_capability_parm));
1541 /* only INFRASTRUCTURE mode support power-saving feature */
1542 if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE))
1543 || (pAd->CommonCfg.bAPSDForcePowerSave)) {
1545 /* 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL */
1546 /* 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE */
1547 /* 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE */
1548 /* 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE */
1549 /* 5. otherwise, put PHY back to sleep to save battery. */
1552 if (OPSTATUS_TEST_FLAG
1553 (pAd, fOP_STATUS_PCIE_DEVICE)) {
1554 /* Restore to correct BBP R3 value */
1555 if (pAd->Antenna.field.RxPath >
1557 RTMP_BBP_IO_WRITE8_BY_REG_ID
1560 /* Turn clk to 80Mhz. */
1562 #endif /* RTMP_MAC_PCI // */
1563 if (pAd->CommonCfg.bAPSDCapable
1564 && pAd->CommonCfg.APEdcaParm.
1566 && pAd->CommonCfg.bAPSDAC_BE
1567 && pAd->CommonCfg.bAPSDAC_BK
1568 && pAd->CommonCfg.bAPSDAC_VI
1569 && pAd->CommonCfg.bAPSDAC_VO) {
1571 bNeedSendTriggerFrame =
1574 RTMP_PS_POLL_ENQUEUE(pAd);
1575 } else if (BcastFlag && (DtimCount == 0)
1576 && OPSTATUS_TEST_FLAG(pAd,
1577 fOP_STATUS_RECEIVE_DTIM))
1580 if (OPSTATUS_TEST_FLAG
1581 (pAd, fOP_STATUS_PCIE_DEVICE)) {
1582 if (pAd->Antenna.field.RxPath >
1584 RTMP_BBP_IO_WRITE8_BY_REG_ID
1588 #endif /* RTMP_MAC_PCI // */
1590 if ((pAd->TxSwQueue[QID_AC_BK].Number != 0)
1591 || (pAd->TxSwQueue[QID_AC_BE].Number !=
1593 || (pAd->TxSwQueue[QID_AC_VI].Number !=
1595 || (pAd->TxSwQueue[QID_AC_VO].Number !=
1599 (pAd, QID_AC_BK, TX_RING_SIZE - 1,
1600 &FreeNumber) != NDIS_STATUS_SUCCESS)
1603 (pAd, QID_AC_BE, TX_RING_SIZE - 1,
1604 &FreeNumber) != NDIS_STATUS_SUCCESS)
1607 (pAd, QID_AC_VI, TX_RING_SIZE - 1,
1608 &FreeNumber) != NDIS_STATUS_SUCCESS)
1611 (pAd, QID_AC_VO, TX_RING_SIZE - 1,
1612 &FreeNumber) != NDIS_STATUS_SUCCESS)
1615 (pAd, QID_MGMT, MGMT_RING_SIZE - 1,
1617 NDIS_STATUS_SUCCESS)) {
1618 /* TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme */
1619 /* can we cheat here (i.e. just check MGMT & AC_BE) for better performance? */
1621 if (OPSTATUS_TEST_FLAG
1622 (pAd, fOP_STATUS_PCIE_DEVICE)) {
1623 if (pAd->Antenna.field.RxPath >
1625 RTMP_BBP_IO_WRITE8_BY_REG_ID
1629 #endif /* RTMP_MAC_PCI // */
1631 if ((pAd->CommonCfg.
1632 bACMAPSDTr[QID_AC_VO])
1634 bACMAPSDTr[QID_AC_VI])
1636 bACMAPSDTr[QID_AC_BK])
1638 bACMAPSDTr[QID_AC_BE])) {
1640 WMM Spec v1.0 3.6.2.4,
1641 The WMM STA shall remain awake until it receives a
1642 QoS Data or Null frame addressed to it, with the
1643 EOSP subfield in QoS Control field set to 1.
1645 So we can not sleep here or we will suffer a case:
1647 PS Management Frame -->
1649 Beacon (TIM=0) (Beacon is closer to Trig frame) -->
1650 Station goes to sleep -->
1651 AP delivery queued UAPSD packets -->
1652 Station can NOT receive the reply
1654 Maybe we need a timeout timer to avoid that we do
1655 NOT receive the EOSP frame.
1657 We can not use More Data to check if SP is ended
1661 u16 NextDtim = DtimCount;
1664 NextDtim = DtimPeriod;
1666 TbttNumToNextWakeUp =
1669 if (OPSTATUS_TEST_FLAG
1671 fOP_STATUS_RECEIVE_DTIM)
1672 && (TbttNumToNextWakeUp >
1674 TbttNumToNextWakeUp =
1677 if (!OPSTATUS_TEST_FLAG
1678 (pAd, fOP_STATUS_DOZE)) {
1679 /* Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode. */
1681 ThisTbttNumToNextWakeUp
1683 TbttNumToNextWakeUp;
1684 AsicSleepThenAutoWakeup
1687 ThisTbttNumToNextWakeUp);
1693 /* not my BSSID, ignore it */
1695 /* sanity check fail, ignore this frame */
1699 ==========================================================================
1701 Receive PROBE REQ from remote peer when operating in IBSS mode
1702 ==========================================================================
1704 void PeerProbeReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1706 u8 Addr2[MAC_ADDR_LEN];
1707 char Ssid[MAX_LEN_OF_SSID];
1709 u8 HtLen, AddHtLen, NewExtLen;
1710 struct rt_header_802_11 ProbeRspHdr;
1712 u8 *pOutBuffer = NULL;
1713 unsigned long FrameLen = 0;
1714 LARGE_INTEGER FakeTimestamp;
1715 u8 DsLen = 1, IbssLen = 2;
1716 u8 LocalErpIe[3] = { IE_ERP, 1, 0 };
1724 if (PeerProbeReqSanity
1725 (pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen)) {
1727 || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid,
1728 pAd->CommonCfg.SsidLen)) {
1729 /* allocate and send out ProbeRsp frame */
1730 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
1731 if (NStatus != NDIS_STATUS_SUCCESS)
1734 /*pAd->StaCfg.AtimWin = 0; // ?????? */
1737 (pAd->StaCfg.WepStatus ==
1738 Ndis802_11Encryption1Enabled)
1739 || (pAd->StaCfg.WepStatus ==
1740 Ndis802_11Encryption2Enabled)
1741 || (pAd->StaCfg.WepStatus ==
1742 Ndis802_11Encryption3Enabled);
1744 CAP_GENERATE(0, 1, Privacy,
1745 (pAd->CommonCfg.TxPreamble ==
1746 Rt802_11PreambleShort), 0, 0);
1748 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1749 sizeof(struct rt_header_802_11), &ProbeRspHdr,
1750 TIMESTAMP_LEN, &FakeTimestamp,
1751 2, &pAd->CommonCfg.BeaconPeriod,
1754 1, &pAd->CommonCfg.SsidLen,
1755 pAd->CommonCfg.SsidLen,
1756 pAd->CommonCfg.Ssid, 1, &SupRateIe, 1,
1757 &pAd->StaActive.SupRateLen,
1758 pAd->StaActive.SupRateLen,
1759 pAd->StaActive.SupRate, 1, &DsIe, 1,
1760 &DsLen, 1, &pAd->CommonCfg.Channel, 1,
1761 &IbssIe, 1, &IbssLen, 2,
1762 &pAd->StaActive.AtimWin, END_OF_ARGS);
1764 if (pAd->StaActive.ExtRateLen) {
1766 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1769 1, &pAd->StaActive.ExtRateLen,
1770 pAd->StaActive.ExtRateLen,
1771 &pAd->StaActive.ExtRate,
1775 /* If adhoc secruity is set for WPA-None, append the cipher suite IE */
1776 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
1778 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1780 1, &pAd->StaCfg.RSNIE_Len,
1781 pAd->StaCfg.RSNIE_Len,
1787 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
1788 unsigned long TmpLen;
1789 u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
1790 HtLen = sizeof(pAd->CommonCfg.HtCapability);
1791 AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
1793 /*New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */
1794 if (pAd->bBroadComHT == TRUE) {
1795 MakeOutgoingFrame(pOutBuffer + FrameLen,
1796 &TmpLen, 1, &WpaIe, 4,
1804 MakeOutgoingFrame(pOutBuffer + FrameLen,
1805 &TmpLen, 1, &HtCapIe,
1808 (struct rt_ht_capability_ie),
1814 (struct rt_add_ht_info_ie),
1820 (struct rt_new_ext_chan_ie),
1828 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1829 MlmeFreeMemory(pAd, pOutBuffer);
1834 void BeaconTimeoutAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1837 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1838 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1839 Status = MLME_REJ_TIMEOUT;
1840 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1844 ==========================================================================
1846 Scan timeout procedure. basically add channel index by 1 and rescan
1847 ==========================================================================
1849 void ScanTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1851 pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
1853 /* Only one channel scanned for CISCO beacon request */
1854 if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
1855 (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
1856 (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
1857 (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
1858 pAd->MlmeAux.Channel = 0;
1860 /* this routine will stop if pAd->MlmeAux.Channel == 0 */
1861 ScanNextChannel(pAd);
1865 ==========================================================================
1867 ==========================================================================
1869 void InvalidStateWhenScan(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1872 DBGPRINT(RT_DEBUG_TRACE,
1873 ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n",
1874 pAd->Mlme.SyncMachine.CurrState));
1875 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1876 Status = MLME_STATE_MACHINE_REJECT;
1877 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
1881 ==========================================================================
1883 ==========================================================================
1885 void InvalidStateWhenJoin(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1888 DBGPRINT(RT_DEBUG_TRACE,
1889 ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n",
1890 pAd->Mlme.SyncMachine.CurrState));
1891 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1892 Status = MLME_STATE_MACHINE_REJECT;
1893 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1897 ==========================================================================
1899 ==========================================================================
1901 void InvalidStateWhenStart(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1904 DBGPRINT(RT_DEBUG_TRACE,
1905 ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n",
1906 pAd->Mlme.SyncMachine.CurrState));
1907 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1908 Status = MLME_STATE_MACHINE_REJECT;
1909 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
1913 ==========================================================================
1916 IRQL = DISPATCH_LEVEL
1918 ==========================================================================
1920 void EnqueuePsPoll(struct rt_rtmp_adapter *pAd)
1923 if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
1924 pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
1925 MiniportMMRequest(pAd, 0, (u8 *)& pAd->PsPollFrame,
1926 sizeof(struct rt_pspoll_frame));
1930 ==========================================================================
1932 ==========================================================================
1934 void EnqueueProbeRequest(struct rt_rtmp_adapter *pAd)
1938 unsigned long FrameLen = 0;
1939 struct rt_header_802_11 Hdr80211;
1941 DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
1943 NState = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
1944 if (NState == NDIS_STATUS_SUCCESS) {
1945 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
1946 BROADCAST_ADDR, BROADCAST_ADDR);
1948 /* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */
1949 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1950 sizeof(struct rt_header_802_11), &Hdr80211,
1952 1, &pAd->CommonCfg.SsidLen,
1953 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1955 1, &pAd->StaActive.SupRateLen,
1956 pAd->StaActive.SupRateLen,
1957 pAd->StaActive.SupRate, END_OF_ARGS);
1958 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1959 MlmeFreeMemory(pAd, pOutBuffer);
1964 BOOLEAN ScanRunning(struct rt_rtmp_adapter *pAd)
1966 return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;