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"
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(
57 OUT STATE_MACHINE_FUNC Trans[])
59 StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE);
62 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction);
63 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction);
64 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction);
65 StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon);
66 StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction);
69 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
70 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
71 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
72 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction);
73 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction);
76 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
77 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
78 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
79 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
80 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
81 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction);
84 RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
85 RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
89 ==========================================================================
91 Beacon timeout handler, executed in timer thread
95 ==========================================================================
98 IN PVOID SystemSpecific1,
99 IN PVOID FunctionContext,
100 IN PVOID SystemSpecific2,
101 IN PVOID SystemSpecific3)
103 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
105 DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n"));
107 // Do nothing if the driver is starting halt state.
108 // This might happen when timer already been fired before cancel timer with mlmehalt
109 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
112 if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
116 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
117 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
118 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
121 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
122 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
125 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
126 RTMP_MLME_HANDLER(pAd);
130 ==========================================================================
132 Scan timeout handler, executed in timer thread
134 IRQL = DISPATCH_LEVEL
136 ==========================================================================
139 IN PVOID SystemSpecific1,
140 IN PVOID FunctionContext,
141 IN PVOID SystemSpecific2,
142 IN PVOID SystemSpecific3)
144 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
147 // Do nothing if the driver is starting halt state.
148 // This might happen when timer already been fired before cancel timer with mlmehalt
149 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
152 if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL))
154 RTMP_MLME_HANDLER(pAd);
158 // To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
159 pAd->MlmeAux.Channel = 0;
160 ScanNextChannel(pAd);
161 if (pAd->CommonCfg.bWirelessEvent)
163 RTMPSendWirelessEvent(pAd, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
169 ==========================================================================
171 MLME SCAN req state machine procedure
172 ==========================================================================
174 VOID MlmeScanReqAction(
175 IN PRTMP_ADAPTER pAd,
176 IN MLME_QUEUE_ELEM *Elem)
178 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
179 BOOLEAN TimerCancelled;
182 PHEADER_802_11 pHdr80211;
183 PUCHAR pOutBuffer = NULL;
186 // Check the total scan tries for one single OID command
187 // If this is the CCX 2.0 Case, skip that!
188 if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
190 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n"));
194 // Increase the scan retry counters.
195 pAd->StaCfg.ScanCnt++;
198 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
200 (pAd->StaCfg.bRadio == TRUE) &&
201 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
203 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
205 #endif // RTMP_MAC_PCI //
207 // first check the parameter sanity
208 if (MlmeScanReqSanity(pAd,
217 // Check for channel load and noise hist request
218 // Suspend MSDU only at scan request, not the last two mentioned
219 // Suspend MSDU transmission here
220 RTMPSuspendMsduTransmission(pAd);
223 // To prevent data lost.
224 // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
225 // And should send an NULL data with turned PSM bit off to AP, when scan progress done
227 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
229 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
230 if (NStatus == NDIS_STATUS_SUCCESS)
232 pHdr80211 = (PHEADER_802_11) pOutBuffer;
233 MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
234 pHdr80211->Duration = 0;
235 pHdr80211->FC.Type = BTYPE_DATA;
236 pHdr80211->FC.PwrMgmt = PWR_SAVE;
238 // Send using priority queue
239 MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
240 DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
241 MlmeFreeMemory(pAd, pOutBuffer);
246 NdisGetSystemUpTime(&Now);
247 pAd->StaCfg.LastScanTime = Now;
248 // reset all the timers
249 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
250 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
252 // record desired BSS parameters
253 pAd->MlmeAux.BssType = BssType;
254 pAd->MlmeAux.ScanType = ScanType;
255 pAd->MlmeAux.SsidLen = SsidLen;
256 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
257 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
259 // start from the first channel
260 pAd->MlmeAux.Channel = FirstChannel(pAd);
262 // Let BBP register at 20MHz to do scan
263 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
265 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
266 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
267 ScanNextChannel(pAd);
271 DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
272 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
273 Status = MLME_INVALID_FORMAT;
274 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
279 ==========================================================================
281 MLME JOIN req state machine procedure
282 ==========================================================================
284 VOID MlmeJoinReqAction(
285 IN PRTMP_ADAPTER pAd,
286 IN MLME_QUEUE_ELEM *Elem)
290 BOOLEAN TimerCancelled;
291 HEADER_802_11 Hdr80211;
294 PUCHAR pOutBuffer = NULL;
295 PUCHAR pSupRate = NULL;
297 PUCHAR pExtRate = NULL;
299 UCHAR ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
300 UCHAR ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR);
301 MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg);
303 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
306 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
308 (pAd->StaCfg.bRadio == TRUE) &&
309 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
311 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
313 #endif // RTMP_MAC_PCI //
315 // reset all the timers
316 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
317 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
319 pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
321 // record the desired SSID & BSSID we're waiting for
322 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
324 // If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
325 if (pBss->Hidden == 0)
327 RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
328 NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
329 pAd->MlmeAux.SsidLen = pBss->SsidLen;
332 pAd->MlmeAux.BssType = pBss->BssType;
333 pAd->MlmeAux.Channel = pBss->Channel;
334 pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
337 // Let BBP register at 20MHz to do scan
338 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
340 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
342 pAd->CommonCfg.BBPCurrentBW = BW_20;
344 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
346 // switch channel and waiting for beacon timer
347 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
348 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
349 RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
353 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
354 (pAd->MlmeAux.Channel > 14) &&
355 RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
359 // We can't send any Probe request frame to meet 802.11h.
361 if (pBss->Hidden == 0)
366 // send probe request
368 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
369 if (NStatus == NDIS_STATUS_SUCCESS)
371 if (pAd->MlmeAux.Channel <= 14)
373 pSupRate = pAd->CommonCfg.SupRate;
374 SupRateLen = pAd->CommonCfg.SupRateLen;
375 pExtRate = pAd->CommonCfg.ExtRate;
376 ExtRateLen = pAd->CommonCfg.ExtRateLen;
381 // Overwrite Support Rate, CCK rate are not allowed
384 SupRateLen = ASupRateLen;
388 if (pAd->MlmeAux.BssType == BSS_INFRA)
389 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, pAd->MlmeAux.Bssid);
391 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
393 MakeOutgoingFrame(pOutBuffer, &FrameLen,
394 sizeof(HEADER_802_11), &Hdr80211,
396 1, &pAd->MlmeAux.SsidLen,
397 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
400 SupRateLen, pSupRate,
406 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
409 ExtRateLen, pExtRate,
415 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
416 MlmeFreeMemory(pAd, pOutBuffer);
420 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
421 pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
423 pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
427 ==========================================================================
429 MLME START Request state machine procedure, starting an IBSS
430 ==========================================================================
432 VOID MlmeStartReqAction(
433 IN PRTMP_ADAPTER pAd,
434 IN MLME_QUEUE_ELEM *Elem)
436 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen;
437 BOOLEAN TimerCancelled;
439 // New for WPA security suites
440 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
441 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
442 LARGE_INTEGER TimeStamp;
446 // Init Variable IE structure
447 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
449 TimeStamp.u.LowPart = 0;
450 TimeStamp.u.HighPart = 0;
452 if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, (PCHAR)Ssid, &SsidLen))
454 // reset all the timers
455 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
456 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
459 // Start a new IBSS. All IBSS parameters are decided now....
461 DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
462 pAd->MlmeAux.BssType = BSS_ADHOC;
463 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
464 pAd->MlmeAux.SsidLen = SsidLen;
466 // generate a radom number as BSSID
467 MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
468 DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
470 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
471 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
472 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
473 pAd->MlmeAux.CapabilityInfo = CAP_GENERATE(0,1,Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 1, 0);
474 pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
475 pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin;
476 pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
478 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
479 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
481 pAd->MlmeAux.SupRateLen= pAd->CommonCfg.SupRateLen;
482 NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
483 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
484 pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
485 NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
486 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
488 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
490 RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
491 pAd->MlmeAux.HtCapabilityLen = sizeof(HT_CAPABILITY_IE);
492 // Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
493 DBGPRINT(RT_DEBUG_TRACE, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
497 pAd->MlmeAux.HtCapabilityLen = 0;
498 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
499 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
501 // temporarily not support QOS in IBSS
502 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
503 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
504 NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
506 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
507 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
509 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
510 pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
512 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
513 Status = MLME_SUCCESS;
514 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
518 DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
519 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
520 Status = MLME_INVALID_FORMAT;
521 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
526 ==========================================================================
528 peer sends beacon back when scanning
529 ==========================================================================
531 VOID PeerBeaconAtScanAction(
532 IN PRTMP_ADAPTER pAd,
533 IN MLME_QUEUE_ELEM *Elem)
535 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
536 UCHAR Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
537 SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
539 USHORT BeaconPeriod, AtimWin, CapabilityInfo;
540 PFRAME_802_11 pFrame;
541 LARGE_INTEGER TimeStamp;
543 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
544 UCHAR SupRateLen, ExtRateLen;
547 UCHAR AironetCellPowerLimit;
549 QBSS_LOAD_PARM QbssLoad;
550 QOS_CAPABILITY_PARM QosCapability;
552 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
553 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
554 HT_CAPABILITY_IE HtCapability;
555 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
556 UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
558 UCHAR NewExtChannelOffset = 0xff;
561 // NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00);
562 pFrame = (PFRAME_802_11) Elem->Msg;
563 // Init Variable IE structure
564 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
567 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
568 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
570 if (PeerBeaconAndProbeRspSanity(pAd,
596 &AironetCellPowerLimit,
602 &PreNHtCapabilityLen,
606 &NewExtChannelOffset,
613 Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
614 if (Idx != BSS_NOT_FOUND)
615 Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
617 Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
619 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
620 HtCapabilityLen = SIZE_HT_CAP_IE;
622 Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (PCHAR)Ssid, SsidLen, BssType, BeaconPeriod,
623 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
624 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
625 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
627 if (Idx != BSS_NOT_FOUND)
629 NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
630 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
631 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
635 // sanity check fail, ignored
639 ==========================================================================
641 When waiting joining the (I)BSS, beacon received from external
642 ==========================================================================
644 VOID PeerBeaconAtJoinAction(
645 IN PRTMP_ADAPTER pAd,
646 IN MLME_QUEUE_ELEM *Elem)
648 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
649 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
650 DtimCount, DtimPeriod, BcastFlag, NewChannel;
651 LARGE_INTEGER TimeStamp;
652 USHORT BeaconPeriod, AtimWin, CapabilityInfo;
654 BOOLEAN TimerCancelled;
656 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
657 UCHAR SupRateLen, ExtRateLen;
660 UCHAR AironetCellPowerLimit;
662 QBSS_LOAD_PARM QbssLoad;
663 QOS_CAPABILITY_PARM QosCapability;
665 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
666 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
669 HT_CAPABILITY_IE HtCapability;
670 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
671 UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
673 UCHAR NewExtChannelOffset = 0xff;
674 UCHAR CentralChannel;
675 BOOLEAN bAllowNrate = FALSE;
677 // Init Variable IE structure
678 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
680 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
681 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
684 if (PeerBeaconAndProbeRspSanity(pAd,
710 &AironetCellPowerLimit,
716 &PreNHtCapabilityLen,
720 &NewExtChannelOffset,
724 // Disqualify 11b only adhoc when we are in 11g only adhoc mode
725 if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12))
728 // BEACON from desired BSS/IBSS found. We should be able to decide most
729 // BSS parameters here.
730 // Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
731 // Do we need to receover back all parameters belonging to previous BSS?
732 // A. Should be not. There's no back-door recover to previous AP. It still need
733 // a new JOIN-AUTH-ASSOC sequence.
734 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid))
736 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel));
737 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
739 // Update RSSI to prevent No signal display when cards first initialized
740 pAd->StaCfg.RssiSample.LastRssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
741 pAd->StaCfg.RssiSample.LastRssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
742 pAd->StaCfg.RssiSample.LastRssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
743 pAd->StaCfg.RssiSample.AvgRssi0 = pAd->StaCfg.RssiSample.LastRssi0;
744 pAd->StaCfg.RssiSample.AvgRssi0X8 = pAd->StaCfg.RssiSample.AvgRssi0 << 3;
745 pAd->StaCfg.RssiSample.AvgRssi1 = pAd->StaCfg.RssiSample.LastRssi1;
746 pAd->StaCfg.RssiSample.AvgRssi1X8 = pAd->StaCfg.RssiSample.AvgRssi1 << 3;
747 pAd->StaCfg.RssiSample.AvgRssi2 = pAd->StaCfg.RssiSample.LastRssi2;
748 pAd->StaCfg.RssiSample.AvgRssi2X8 = pAd->StaCfg.RssiSample.AvgRssi2 << 3;
751 // We need to check if SSID only set to any, then we can record the current SSID.
752 // Otherwise will cause hidden SSID association failed.
754 if (pAd->MlmeAux.SsidLen == 0)
756 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
757 pAd->MlmeAux.SsidLen = SsidLen;
761 Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel);
763 if (Idx == BSS_NOT_FOUND)
766 Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
767 Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (CHAR *) Ssid, SsidLen, BssType, BeaconPeriod,
768 &Cf, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
769 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
770 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
771 if (Idx != BSS_NOT_FOUND)
773 NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
774 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
775 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
776 CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
782 // Multiple SSID case, used correct CapabilityInfo
784 CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
787 NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
788 pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
789 pAd->MlmeAux.BssType = BssType;
790 pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
791 pAd->MlmeAux.Channel = Channel;
792 pAd->MlmeAux.AtimWin = AtimWin;
793 pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
794 pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
795 pAd->MlmeAux.APRalinkIe = RalinkIe;
797 // Copy AP's supported rate to MlmeAux for creating assoication request
798 // Also filter out not supported rate
799 pAd->MlmeAux.SupRateLen = SupRateLen;
800 NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
801 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
802 pAd->MlmeAux.ExtRateLen = ExtRateLen;
803 NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
804 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
806 NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16);
809 if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled) && (pAd->StaCfg.WepStatus != Ndis802_11Encryption2Enabled))
810 || (pAd->CommonCfg.HT_DisallowTKIP == FALSE))
815 pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
816 pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
818 RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
819 // filter out un-supported ht rates
820 if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) &&
821 ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (bAllowNrate)))
823 RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE);
825 // StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
826 NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
827 pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
828 pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
829 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
830 if (PreNHtCapabilityLen > 0)
831 pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE;
832 RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo);
833 // Copy AP Parameter to StaActive. This is also in LinkUp.
834 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
835 pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth));
837 if (AddHtInfoLen > 0)
839 CentralChannel = AddHtInfo.ControlChan;
840 // Check again the Bandwidth capability of this AP.
841 if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
843 CentralChannel = AddHtInfo.ControlChan - 2;
845 else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
847 CentralChannel = AddHtInfo.ControlChan + 2;
851 if (pAd->MlmeAux.CentralChannel != CentralChannel)
852 DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel));
854 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, AddHtInfo.ControlChan));
861 // To prevent error, let legacy AP must have same CentralChannel and Channel.
862 if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0))
863 pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel;
865 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
866 pAd->MlmeAux.NewExtChannelOffset = 0xff;
867 RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
868 pAd->MlmeAux.HtCapabilityLen = 0;
869 RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
872 RTMPUpdateMlmeRate(pAd);
874 // copy QOS related information
875 if ((pAd->CommonCfg.bWmmCapable)
876 || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
879 NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM));
880 NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
881 NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
885 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
886 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
887 NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
890 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
891 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
893 if (AironetCellPowerLimit != 0xFF)
895 //We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
896 ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
898 else //Used the default TX Power Percentage.
899 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
901 InitChannelRelatedValue(pAd);
903 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
904 Status = MLME_SUCCESS;
905 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
907 // not to me BEACON, ignored
909 // sanity check fail, ignore this frame
913 ==========================================================================
915 receive BEACON from peer
917 IRQL = DISPATCH_LEVEL
919 ==========================================================================
922 IN PRTMP_ADAPTER pAd,
923 IN MLME_QUEUE_ELEM *Elem)
925 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
926 CHAR Ssid[MAX_LEN_OF_SSID];
928 UCHAR SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0;
929 UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0;
930 USHORT CapabilityInfo, AtimWin, BeaconPeriod;
931 LARGE_INTEGER TimeStamp;
932 USHORT TbttNumToNextWakeUp;
934 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
935 UCHAR SupRateLen, ExtRateLen;
938 UCHAR AironetCellPowerLimit;
940 QBSS_LOAD_PARM QbssLoad;
941 QOS_CAPABILITY_PARM QosCapability;
943 // New for WPA security suites
944 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
945 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
946 HT_CAPABILITY_IE HtCapability;
947 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
948 UCHAR HtCapabilityLen, PreNHtCapabilityLen;
950 UCHAR NewExtChannelOffset = 0xff;
952 if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
956 // Init Variable IE structure
957 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
959 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
960 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
962 if (PeerBeaconAndProbeRspSanity(pAd,
988 &AironetCellPowerLimit,
994 &PreNHtCapabilityLen,
998 &NewExtChannelOffset,
1002 BOOLEAN is_my_bssid, is_my_ssid;
1005 CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1007 is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE;
1008 is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE;
1011 // ignore BEACON not for my SSID
1012 if ((! is_my_ssid) && (! is_my_bssid))
1015 // It means STA waits disassoc completely from this AP, ignores this beacon.
1016 if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
1019 // Copy Control channel for this BSSID.
1020 if (AddHtInfoLen != 0)
1021 Channel = AddHtInfo.ControlChan;
1023 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
1024 HtCapabilityLen = SIZE_HT_CAP_IE;
1027 // Housekeeping "SsidBssTab" table for later-on ROAMing usage.
1029 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1030 if (Bssidx == BSS_NOT_FOUND)
1032 // discover new AP of this network, create BSS entry
1033 Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
1034 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,
1035 &HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel,
1036 RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability,
1037 &QbssLoad, LenVIE, pVIE);
1038 if (Bssidx == BSS_NOT_FOUND) // return if BSS table full
1041 NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4);
1042 NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
1043 NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
1049 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
1051 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1052 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1053 AsicSwitchChannel(pAd, 1, FALSE);
1054 AsicLockChannel(pAd, 1);
1055 LinkDown(pAd, FALSE);
1056 MlmeQueueInit(&pAd->Mlme.Queue);
1057 BssTableInit(&pAd->ScanTab);
1058 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1060 // channel sanity check
1061 for (index = 0 ; index < pAd->ChannelListNum; index++)
1063 if (pAd->ChannelList[index].Channel == NewChannel)
1065 pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
1066 pAd->CommonCfg.Channel = NewChannel;
1067 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1068 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1069 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
1074 if (index >= pAd->ChannelListNum)
1076 DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
1080 // if the ssid matched & bssid unmatched, we should select the bssid with large value.
1081 // This might happened when two STA start at the same time
1082 if ((! is_my_bssid) && ADHOC_ON(pAd))
1086 // Add the safeguard against the mismatch of adhoc wep status
1087 if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
1092 // collapse into the ADHOC network which has bigger BSSID value.
1093 for (i = 0; i < 6; i++)
1095 if (Bssid[i] > pAd->CommonCfg.Bssid[i])
1097 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
1098 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
1099 AsicDisableSync(pAd);
1100 COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid);
1101 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1102 MakeIbssBeacon(pAd); // re-build BEACON frame
1103 AsicEnableIbssSync(pAd); // copy BEACON frame to on-chip memory
1107 else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
1113 NdisGetSystemUpTime(&Now);
1114 pBss = &pAd->ScanTab.BssEntry[Bssidx];
1115 pBss->Rssi = RealRssi; // lastest RSSI
1116 pBss->LastBeaconRxTime = Now; // last RX timestamp
1119 // BEACON from my BSSID - either IBSS or INFRA network
1125 pAd->StaCfg.DtimCount = DtimCount;
1126 pAd->StaCfg.DtimPeriod = DtimPeriod;
1127 pAd->StaCfg.LastBeaconRxTime = Now;
1130 RxWI.RSSI0 = Elem->Rssi0;
1131 RxWI.RSSI1 = Elem->Rssi1;
1132 RxWI.RSSI2 = Elem->Rssi2;
1134 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
1135 if (AironetCellPowerLimit != 0xFF)
1138 // We get the Cisco (ccx) "TxPower Limit" required
1139 // Changed to appropriate TxPower Limit for Ciso Compatible Extensions
1141 ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
1146 // AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
1147 // Used the default TX Power Percentage, that set from UI.
1149 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
1152 if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
1154 UCHAR MaxSupportedRateIn500Kbps = 0;
1156 MAC_TABLE_ENTRY *pEntry;
1158 // supported rates array may not be sorted. sort it and find the maximum rate
1159 for (idx=0; idx<SupRateLen; idx++)
1161 if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
1162 MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
1165 for (idx=0; idx<ExtRateLen; idx++)
1167 if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
1168 MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
1171 // look up the existing table
1172 pEntry = MacTableLookup(pAd, Addr2);
1174 // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
1175 // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
1176 if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) ||
1177 (pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now)))
1180 // Another adhoc joining, add to our MAC table.
1181 pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
1183 if (StaAddMacTableEntry(pAd,
1185 MaxSupportedRateIn500Kbps,
1190 CapabilityInfo) == FALSE)
1192 DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n"));
1197 (Elem->Wcid == RESERVED_WCID))
1199 idx = pAd->StaCfg.DefaultKeyId;
1200 RTMP_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
1204 if (pEntry && pEntry->ValidAsCLI)
1205 pEntry->LastBeaconRxTime = Now;
1207 // At least another peer in this IBSS, declare MediaState as CONNECTED
1208 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1210 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1212 pAd->IndicateMediaState = NdisMediaStateConnected;
1213 RTMP_IndicateMediaState(pAd);
1214 pAd->ExtraInfo = GENERAL_LINK_UP;
1215 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1217 // 2003/03/12 - john
1218 // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
1219 // "site survey" result should always include the current connected network.
1221 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1222 if (Bssidx == BSS_NOT_FOUND)
1224 Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
1225 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
1226 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
1227 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
1229 DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1235 BOOLEAN bUseShortSlot, bUseBGProtection;
1237 // decide to use/change to -
1238 // 1. long slot (20 us) or short slot (9 us) time
1239 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1240 // 3. short preamble
1242 //bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
1243 bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo);
1244 if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
1245 AsicSetSlotTime(pAd, bUseShortSlot);
1247 bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || // always use
1248 ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp));
1250 if (pAd->CommonCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
1251 bUseBGProtection = FALSE;
1253 if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
1255 if (bUseBGProtection)
1257 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1258 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
1262 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1263 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
1266 DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection));
1269 // check Ht protection mode. and adhere to the Non-GF device indication by AP.
1270 if ((AddHtInfoLen != 0) &&
1271 ((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) ||
1272 (AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent)))
1274 pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent;
1275 pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode;
1276 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1278 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1281 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1283 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode));
1286 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) &&
1287 ERP_IS_USE_BARKER_PREAMBLE(Erp))
1289 MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
1290 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n"));
1293 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
1294 (EdcaParm.bValid == TRUE) &&
1295 (EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount))
1297 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1298 pAd->CommonCfg.APEdcaParm.EdcaUpdateCount,
1299 EdcaParm.EdcaUpdateCount));
1300 AsicSetEdcaParm(pAd, &EdcaParm);
1303 // copy QOS related information
1304 NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
1305 NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
1308 // only INFRASTRUCTURE mode support power-saving feature
1309 if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave))
1312 // 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
1313 // 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
1314 // 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
1315 // 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
1316 // 5. otherwise, put PHY back to sleep to save battery.
1320 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1322 // Restore to correct BBP R3 value
1323 if (pAd->Antenna.field.RxPath > 1)
1324 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
1325 // Turn clk to 80Mhz.
1327 #endif // RTMP_MAC_PCI //
1328 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
1329 pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
1331 pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
1334 RTMP_PS_POLL_ENQUEUE(pAd);
1336 else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
1339 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1341 if (pAd->Antenna.field.RxPath > 1)
1342 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
1344 #endif // RTMP_MAC_PCI //
1346 else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) ||
1347 (pAd->TxSwQueue[QID_AC_BE].Number != 0) ||
1348 (pAd->TxSwQueue[QID_AC_VI].Number != 0) ||
1349 (pAd->TxSwQueue[QID_AC_VO].Number != 0) ||
1350 (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1351 (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1352 (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1353 (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1354 (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS))
1356 // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
1357 // can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
1359 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1361 if (pAd->Antenna.field.RxPath > 1)
1362 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
1364 #endif // RTMP_MAC_PCI //
1368 if ((pAd->CommonCfg.bACMAPSDTr[QID_AC_VO]) ||
1369 (pAd->CommonCfg.bACMAPSDTr[QID_AC_VI]) ||
1370 (pAd->CommonCfg.bACMAPSDTr[QID_AC_BK]) ||
1371 (pAd->CommonCfg.bACMAPSDTr[QID_AC_BE]))
1374 WMM Spec v1.0 3.6.2.4,
1375 The WMM STA shall remain awake until it receives a
1376 QoS Data or Null frame addressed to it, with the
1377 EOSP subfield in QoS Control field set to 1.
1379 So we can not sleep here or we will suffer a case:
1381 PS Management Frame -->
1383 Beacon (TIM=0) (Beacon is closer to Trig frame) -->
1384 Station goes to sleep -->
1385 AP delivery queued UAPSD packets -->
1386 Station can NOT receive the reply
1388 Maybe we need a timeout timer to avoid that we do
1389 NOT receive the EOSP frame.
1391 We can not use More Data to check if SP is ended
1397 USHORT NextDtim = DtimCount;
1400 NextDtim = DtimPeriod;
1402 TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
1403 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
1404 TbttNumToNextWakeUp = NextDtim;
1406 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1408 // Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode.
1409 pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp;
1410 AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp);
1416 // not my BSSID, ignore it
1418 // sanity check fail, ignore this frame
1422 ==========================================================================
1424 Receive PROBE REQ from remote peer when operating in IBSS mode
1425 ==========================================================================
1427 VOID PeerProbeReqAction(
1428 IN PRTMP_ADAPTER pAd,
1429 IN MLME_QUEUE_ELEM *Elem)
1431 UCHAR Addr2[MAC_ADDR_LEN];
1432 CHAR Ssid[MAX_LEN_OF_SSID];
1434 UCHAR HtLen, AddHtLen, NewExtLen;
1435 HEADER_802_11 ProbeRspHdr;
1436 NDIS_STATUS NStatus;
1437 PUCHAR pOutBuffer = NULL;
1439 LARGE_INTEGER FakeTimestamp;
1440 UCHAR DsLen = 1, IbssLen = 2;
1441 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0};
1443 USHORT CapabilityInfo;
1444 UCHAR RSNIe = IE_WPA;
1446 if (! ADHOC_ON(pAd))
1449 if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
1451 if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
1453 // allocate and send out ProbeRsp frame
1454 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1455 if (NStatus != NDIS_STATUS_SUCCESS)
1458 //pAd->StaCfg.AtimWin = 0; // ??????
1460 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
1461 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
1462 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
1463 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
1465 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1466 sizeof(HEADER_802_11), &ProbeRspHdr,
1467 TIMESTAMP_LEN, &FakeTimestamp,
1468 2, &pAd->CommonCfg.BeaconPeriod,
1471 1, &pAd->CommonCfg.SsidLen,
1472 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1474 1, &pAd->StaActive.SupRateLen,
1475 pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
1478 1, &pAd->CommonCfg.Channel,
1481 2, &pAd->StaActive.AtimWin,
1484 if (pAd->StaActive.ExtRateLen)
1487 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1490 1, &pAd->StaActive.ExtRateLen,
1491 pAd->StaActive.ExtRateLen, &pAd->StaActive.ExtRate,
1496 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1497 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1500 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1502 1, &pAd->StaCfg.RSNIE_Len,
1503 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
1508 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1511 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
1512 HtLen = sizeof(pAd->CommonCfg.HtCapability);
1513 AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
1515 //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
1516 if (pAd->bBroadComHT == TRUE)
1518 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
1521 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
1526 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
1529 sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability,
1532 sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo,
1535 sizeof(NEW_EXT_CHAN_IE), &pAd->CommonCfg.NewExtChanOffset,
1541 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1542 MlmeFreeMemory(pAd, pOutBuffer);
1547 VOID BeaconTimeoutAtJoinAction(
1548 IN PRTMP_ADAPTER pAd,
1549 IN MLME_QUEUE_ELEM *Elem)
1552 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1553 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1554 Status = MLME_REJ_TIMEOUT;
1555 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1559 ==========================================================================
1561 Scan timeout procedure. basically add channel index by 1 and rescan
1562 ==========================================================================
1564 VOID ScanTimeoutAction(
1565 IN PRTMP_ADAPTER pAd,
1566 IN MLME_QUEUE_ELEM *Elem)
1568 pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
1570 // Only one channel scanned for CISCO beacon request
1571 if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
1572 (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
1573 (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
1574 (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
1575 pAd->MlmeAux.Channel = 0;
1577 // this routine will stop if pAd->MlmeAux.Channel == 0
1578 ScanNextChannel(pAd);
1582 ==========================================================================
1584 ==========================================================================
1586 VOID InvalidStateWhenScan(
1587 IN PRTMP_ADAPTER pAd,
1588 IN MLME_QUEUE_ELEM *Elem)
1591 DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1592 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1593 Status = MLME_STATE_MACHINE_REJECT;
1594 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
1598 ==========================================================================
1600 ==========================================================================
1602 VOID InvalidStateWhenJoin(
1603 IN PRTMP_ADAPTER pAd,
1604 IN MLME_QUEUE_ELEM *Elem)
1607 DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1608 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1609 Status = MLME_STATE_MACHINE_REJECT;
1610 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1614 ==========================================================================
1616 ==========================================================================
1618 VOID InvalidStateWhenStart(
1619 IN PRTMP_ADAPTER pAd,
1620 IN MLME_QUEUE_ELEM *Elem)
1623 DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1624 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1625 Status = MLME_STATE_MACHINE_REJECT;
1626 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
1630 ==========================================================================
1633 IRQL = DISPATCH_LEVEL
1635 ==========================================================================
1638 IN PRTMP_ADAPTER pAd)
1642 if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
1643 pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
1644 MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
1649 ==========================================================================
1651 ==========================================================================
1653 VOID EnqueueProbeRequest(
1654 IN PRTMP_ADAPTER pAd)
1659 HEADER_802_11 Hdr80211;
1661 DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
1663 NState = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1664 if (NState == NDIS_STATUS_SUCCESS)
1666 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
1668 // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
1669 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1670 sizeof(HEADER_802_11), &Hdr80211,
1672 1, &pAd->CommonCfg.SsidLen,
1673 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1675 1, &pAd->StaActive.SupRateLen,
1676 pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
1678 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1679 MlmeFreeMemory(pAd, pOutBuffer);
1684 BOOLEAN ScanRunning(
1685 IN PRTMP_ADAPTER pAd)
1687 return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;