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
39 #include "../rt_config.h"
42 #define ADHOC_ENTRY_BEACON_LOST_TIME (2*OS_HZ) // 2 sec
45 ==========================================================================
47 The sync state machine,
49 Sm - pointer to the state machine
51 the state machine looks like the following
53 ==========================================================================
55 VOID
SyncStateMachineInit(
58 OUT STATE_MACHINE_FUNC Trans
[])
60 StateMachineInit(Sm
, Trans
, MAX_SYNC_STATE
, MAX_SYNC_MSG
, (STATE_MACHINE_FUNC
)Drop
, SYNC_IDLE
, SYNC_MACHINE_BASE
);
63 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_MLME_SCAN_REQ
, (STATE_MACHINE_FUNC
)MlmeScanReqAction
);
64 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_MLME_JOIN_REQ
, (STATE_MACHINE_FUNC
)MlmeJoinReqAction
);
65 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_MLME_START_REQ
, (STATE_MACHINE_FUNC
)MlmeStartReqAction
);
66 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_PEER_BEACON
, (STATE_MACHINE_FUNC
)PeerBeacon
);
67 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_PEER_PROBE_REQ
, (STATE_MACHINE_FUNC
)PeerProbeReqAction
);
70 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_MLME_SCAN_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenScan
);
71 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_MLME_JOIN_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenJoin
);
72 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_MLME_START_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenStart
);
73 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_PEER_BEACON
, (STATE_MACHINE_FUNC
)PeerBeaconAtJoinAction
);
74 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_BEACON_TIMEOUT
, (STATE_MACHINE_FUNC
)BeaconTimeoutAtJoinAction
);
77 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_MLME_SCAN_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenScan
);
78 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_MLME_JOIN_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenJoin
);
79 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_MLME_START_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenStart
);
80 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_PEER_BEACON
, (STATE_MACHINE_FUNC
)PeerBeaconAtScanAction
);
81 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_PEER_PROBE_RSP
, (STATE_MACHINE_FUNC
)PeerBeaconAtScanAction
);
82 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_SCAN_TIMEOUT
, (STATE_MACHINE_FUNC
)ScanTimeoutAction
);
85 RTMPInitTimer(pAd
, &pAd
->MlmeAux
.BeaconTimer
, GET_TIMER_FUNCTION(BeaconTimeout
), pAd
, FALSE
);
86 RTMPInitTimer(pAd
, &pAd
->MlmeAux
.ScanTimer
, GET_TIMER_FUNCTION(ScanTimeout
), pAd
, FALSE
);
90 ==========================================================================
92 Beacon timeout handler, executed in timer thread
96 ==========================================================================
99 IN PVOID SystemSpecific1
,
100 IN PVOID FunctionContext
,
101 IN PVOID SystemSpecific2
,
102 IN PVOID SystemSpecific3
)
104 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
106 DBGPRINT(RT_DEBUG_TRACE
,("SYNC - BeaconTimeout\n"));
108 // Do nothing if the driver is starting halt state.
109 // This might happen when timer already been fired before cancel timer with mlmehalt
110 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
))
113 #ifdef DOT11_N_SUPPORT
114 if ((pAd
->CommonCfg
.BBPCurrentBW
== BW_40
)
118 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.CentralChannel
, FALSE
);
119 AsicLockChannel(pAd
, pAd
->CommonCfg
.CentralChannel
);
120 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
123 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
124 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd
->CommonCfg
.CentralChannel
, pAd
->ScanTab
.BssNr
));
126 #endif // DOT11_N_SUPPORT //
128 MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_BEACON_TIMEOUT
, 0, NULL
);
129 RTMP_MLME_HANDLER(pAd
);
133 ==========================================================================
135 Scan timeout handler, executed in timer thread
137 IRQL = DISPATCH_LEVEL
139 ==========================================================================
142 IN PVOID SystemSpecific1
,
143 IN PVOID FunctionContext
,
144 IN PVOID SystemSpecific2
,
145 IN PVOID SystemSpecific3
)
147 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
150 // Do nothing if the driver is starting halt state.
151 // This might happen when timer already been fired before cancel timer with mlmehalt
152 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
))
155 if (MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_SCAN_TIMEOUT
, 0, NULL
))
157 RTMP_MLME_HANDLER(pAd
);
161 // To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
162 pAd
->MlmeAux
.Channel
= 0;
163 ScanNextChannel(pAd
);
164 if (pAd
->CommonCfg
.bWirelessEvent
)
166 RTMPSendWirelessEvent(pAd
, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG
, pAd
->MacTab
.Content
[BSSID_WCID
].Addr
, BSS0
, 0);
172 ==========================================================================
174 MLME SCAN req state machine procedure
175 ==========================================================================
177 VOID
MlmeScanReqAction(
178 IN PRTMP_ADAPTER pAd
,
179 IN MLME_QUEUE_ELEM
*Elem
)
181 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
, ScanType
, BssType
, BBPValue
= 0;
182 BOOLEAN TimerCancelled
;
185 PHEADER_802_11 pHdr80211
;
186 PUCHAR pOutBuffer
= NULL
;
189 // Check the total scan tries for one single OID command
190 // If this is the CCX 2.0 Case, skip that!
191 if ( !RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_START_UP
))
193 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - MlmeScanReqAction before Startup\n"));
197 // Increase the scan retry counters.
198 pAd
->StaCfg
.ScanCnt
++;
201 if ((OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_PCIE_DEVICE
)) &&
203 (pAd
->StaCfg
.bRadio
== TRUE
) &&
204 (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
)))
206 if (pAd
->StaCfg
.PSControl
.field
.EnableNewPS
== FALSE
)
208 AsicSendCommandToMcu(pAd
, 0x31, PowerWakeCID
, 0x00, 0x02);
209 AsicCheckCommanOk(pAd
, PowerWakeCID
);
210 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
);
211 DBGPRINT(RT_DEBUG_TRACE
, ("PSM - Issue Wake up command \n"));
215 RT28xxPciAsicRadioOn(pAd
, GUI_IDLE_POWER_SAVE
);
218 #endif // RTMP_MAC_PCI //
220 // first check the parameter sanity
221 if (MlmeScanReqSanity(pAd
,
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
) && (INFRA_ON(pAd
)))
242 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&pOutBuffer
);
243 if (NStatus
== NDIS_STATUS_SUCCESS
)
245 pHdr80211
= (PHEADER_802_11
) pOutBuffer
;
246 MgtMacHeaderInit(pAd
, pHdr80211
, SUBTYPE_NULL_FUNC
, 1, pAd
->CommonCfg
.Bssid
, pAd
->CommonCfg
.Bssid
);
247 pHdr80211
->Duration
= 0;
248 pHdr80211
->FC
.Type
= BTYPE_DATA
;
249 pHdr80211
->FC
.PwrMgmt
= PWR_SAVE
;
251 // Send using priority queue
252 MiniportMMRequest(pAd
, 0, pOutBuffer
, sizeof(HEADER_802_11
));
253 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
254 MlmeFreeMemory(pAd
, pOutBuffer
);
259 NdisGetSystemUpTime(&Now
);
260 pAd
->StaCfg
.LastScanTime
= Now
;
261 // reset all the timers
262 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
263 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &TimerCancelled
);
265 // record desired BSS parameters
266 pAd
->MlmeAux
.BssType
= BssType
;
267 pAd
->MlmeAux
.ScanType
= ScanType
;
268 pAd
->MlmeAux
.SsidLen
= SsidLen
;
269 NdisZeroMemory(pAd
->MlmeAux
.Ssid
, MAX_LEN_OF_SSID
);
270 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, Ssid
, SsidLen
);
272 // start from the first channel
273 pAd
->MlmeAux
.Channel
= FirstChannel(pAd
);
275 // Let BBP register at 20MHz to do scan
276 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
278 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
279 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - BBP R4 to 20MHz.l\n"));
280 ScanNextChannel(pAd
);
284 DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
285 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
286 Status
= MLME_INVALID_FORMAT
;
287 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_SCAN_CONF
, 2, &Status
);
292 ==========================================================================
294 MLME JOIN req state machine procedure
295 ==========================================================================
297 VOID
MlmeJoinReqAction(
298 IN PRTMP_ADAPTER pAd
,
299 IN MLME_QUEUE_ELEM
*Elem
)
303 BOOLEAN TimerCancelled
;
304 HEADER_802_11 Hdr80211
;
307 PUCHAR pOutBuffer
= NULL
;
308 PUCHAR pSupRate
= NULL
;
310 PUCHAR pExtRate
= NULL
;
312 UCHAR ASupRate
[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
313 UCHAR ASupRateLen
= sizeof(ASupRate
)/sizeof(UCHAR
);
314 MLME_JOIN_REQ_STRUCT
*pInfo
= (MLME_JOIN_REQ_STRUCT
*)(Elem
->Msg
);
316 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo
->BssIdx
));
319 if ((OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_PCIE_DEVICE
)) &&
321 (pAd
->StaCfg
.bRadio
== TRUE
) &&
322 (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
)))
324 RT28xxPciAsicRadioOn(pAd
, GUI_IDLE_POWER_SAVE
);
326 #endif // RTMP_MAC_PCI //
328 // reset all the timers
329 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &TimerCancelled
);
330 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
332 pBss
= &pAd
->MlmeAux
.SsidBssTab
.BssEntry
[pInfo
->BssIdx
];
334 // record the desired SSID & BSSID we're waiting for
335 COPY_MAC_ADDR(pAd
->MlmeAux
.Bssid
, pBss
->Bssid
);
337 // If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
338 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 #ifdef EXT_BUILD_CHANNEL_LIST
350 // Country IE of the AP will be evaluated and will be used.
351 if ((pAd
->StaCfg
.IEEE80211dClientMode
!= Rt802_11_D_None
) &&
352 (pBss
->bHasCountryIE
== TRUE
))
354 NdisMoveMemory(&pAd
->CommonCfg
.CountryCode
[0], &pBss
->CountryString
[0], 2);
355 if (pBss
->CountryString
[2] == 'I')
356 pAd
->CommonCfg
.Geography
= IDOR
;
357 else if (pBss
->CountryString
[2] == 'O')
358 pAd
->CommonCfg
.Geography
= ODOR
;
360 pAd
->CommonCfg
.Geography
= BOTH
;
361 BuildChannelListEx(pAd
);
363 #endif // EXT_BUILD_CHANNEL_LIST //
365 // Let BBP register at 20MHz to do scan
366 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
368 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
369 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - BBP R4 to 20MHz.l\n"));
371 // switch channel and waiting for beacon timer
372 AsicSwitchChannel(pAd
, pAd
->MlmeAux
.Channel
, FALSE
);
373 AsicLockChannel(pAd
, pAd
->MlmeAux
.Channel
);
376 RTMPSetTimer(&pAd
->MlmeAux
.BeaconTimer
, JOIN_TIMEOUT
);
380 if (((pAd
->CommonCfg
.bIEEE80211H
== 1) &&
381 (pAd
->MlmeAux
.Channel
> 14) &&
382 RadarChannelCheck(pAd
, pAd
->MlmeAux
.Channel
))
383 #ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
384 || (pAd
->CommonCfg
.CarrierDetect
.Enable
== TRUE
)
385 #endif // CARRIER_DETECTION_SUPPORT //
389 // We can't send any Probe request frame to meet 802.11h.
391 if (pBss
->Hidden
== 0)
396 // send probe request
398 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
);
399 if (NStatus
== NDIS_STATUS_SUCCESS
)
401 if (pAd
->MlmeAux
.Channel
<= 14)
403 pSupRate
= pAd
->CommonCfg
.SupRate
;
404 SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
405 pExtRate
= pAd
->CommonCfg
.ExtRate
;
406 ExtRateLen
= pAd
->CommonCfg
.ExtRateLen
;
411 // Overwrite Support Rate, CCK rate are not allowed
414 SupRateLen
= ASupRateLen
;
418 if (pAd
->MlmeAux
.BssType
== BSS_INFRA
)
419 MgtMacHeaderInit(pAd
, &Hdr80211
, SUBTYPE_PROBE_REQ
, 0, pAd
->MlmeAux
.Bssid
, pAd
->MlmeAux
.Bssid
);
421 MgtMacHeaderInit(pAd
, &Hdr80211
, SUBTYPE_PROBE_REQ
, 0, BROADCAST_ADDR
, BROADCAST_ADDR
);
423 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
424 sizeof(HEADER_802_11
), &Hdr80211
,
426 1, &pAd
->MlmeAux
.SsidLen
,
427 pAd
->MlmeAux
.SsidLen
, pAd
->MlmeAux
.Ssid
,
430 SupRateLen
, pSupRate
,
436 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &Tmp
,
439 ExtRateLen
, pExtRate
,
445 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
446 MlmeFreeMemory(pAd
, pOutBuffer
);
450 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
451 pBss
->Channel
, pBss
->Bssid
[0], pBss
->Bssid
[1], pBss
->Bssid
[2], pBss
->Bssid
[3], pBss
->Bssid
[4], pBss
->Bssid
[5]));
453 pAd
->Mlme
.SyncMachine
.CurrState
= JOIN_WAIT_BEACON
;
457 ==========================================================================
459 MLME START Request state machine procedure, starting an IBSS
460 ==========================================================================
462 VOID
MlmeStartReqAction(
463 IN PRTMP_ADAPTER pAd
,
464 IN MLME_QUEUE_ELEM
*Elem
)
466 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
;
467 BOOLEAN TimerCancelled
;
469 // New for WPA security suites
470 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
471 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
472 LARGE_INTEGER TimeStamp
;
476 // Init Variable IE structure
477 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
479 TimeStamp
.u
.LowPart
= 0;
480 TimeStamp
.u
.HighPart
= 0;
482 if (MlmeStartReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, (PCHAR
)Ssid
, &SsidLen
))
484 // reset all the timers
485 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &TimerCancelled
);
486 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
489 // Start a new IBSS. All IBSS parameters are decided now....
491 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
492 pAd
->MlmeAux
.BssType
= BSS_ADHOC
;
493 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, Ssid
, SsidLen
);
494 pAd
->MlmeAux
.SsidLen
= SsidLen
;
496 // generate a radom number as BSSID
497 MacAddrRandomBssid(pAd
, pAd
->MlmeAux
.Bssid
);
498 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
500 Privacy
= (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption1Enabled
) ||
501 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) ||
502 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
);
503 pAd
->MlmeAux
.CapabilityInfo
= CAP_GENERATE(0,1,Privacy
, (pAd
->CommonCfg
.TxPreamble
== Rt802_11PreambleShort
), 1, 0);
504 pAd
->MlmeAux
.BeaconPeriod
= pAd
->CommonCfg
.BeaconPeriod
;
505 pAd
->MlmeAux
.AtimWin
= pAd
->StaCfg
.AtimWin
;
506 pAd
->MlmeAux
.Channel
= pAd
->CommonCfg
.Channel
;
508 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
;
509 pAd
->MlmeAux
.CentralChannel
= pAd
->CommonCfg
.CentralChannel
;
511 pAd
->MlmeAux
.SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
512 NdisMoveMemory(pAd
->MlmeAux
.SupRate
, pAd
->CommonCfg
.SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
513 RTMPCheckRates(pAd
, pAd
->MlmeAux
.SupRate
, &pAd
->MlmeAux
.SupRateLen
);
514 pAd
->MlmeAux
.ExtRateLen
= pAd
->CommonCfg
.ExtRateLen
;
515 NdisMoveMemory(pAd
->MlmeAux
.ExtRate
, pAd
->CommonCfg
.ExtRate
, MAX_LEN_OF_SUPPORTED_RATES
);
516 RTMPCheckRates(pAd
, pAd
->MlmeAux
.ExtRate
, &pAd
->MlmeAux
.ExtRateLen
);
517 #ifdef DOT11_N_SUPPORT
518 if (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
520 RTMPUpdateHTIE(&pAd
->CommonCfg
.DesiredHtPhy
, &pAd
->StaCfg
.DesiredHtPhyInfo
.MCSSet
[0], &pAd
->MlmeAux
.HtCapability
, &pAd
->MlmeAux
.AddHtInfo
);
521 pAd
->MlmeAux
.HtCapabilityLen
= sizeof(HT_CAPABILITY_IE
);
522 // Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
523 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
526 #endif // DOT11_N_SUPPORT //
528 pAd
->MlmeAux
.HtCapabilityLen
= 0;
529 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
530 NdisZeroMemory(&pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[0], 16);
532 // temporarily not support QOS in IBSS
533 NdisZeroMemory(&pAd
->MlmeAux
.APEdcaParm
, sizeof(EDCA_PARM
));
534 NdisZeroMemory(&pAd
->MlmeAux
.APQbssLoad
, sizeof(QBSS_LOAD_PARM
));
535 NdisZeroMemory(&pAd
->MlmeAux
.APQosCapability
, sizeof(QOS_CAPABILITY_PARM
));
537 AsicSwitchChannel(pAd
, pAd
->MlmeAux
.Channel
, FALSE
);
538 AsicLockChannel(pAd
, pAd
->MlmeAux
.Channel
);
540 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
541 pAd
->MlmeAux
.Channel
, pAd
->MlmeAux
.SupRateLen
, pAd
->MlmeAux
.ExtRateLen
));
543 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
544 Status
= MLME_SUCCESS
;
545 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_START_CONF
, 2, &Status
);
549 DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
550 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
551 Status
= MLME_INVALID_FORMAT
;
552 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_START_CONF
, 2, &Status
);
557 ==========================================================================
559 peer sends beacon back when scanning
560 ==========================================================================
562 VOID
PeerBeaconAtScanAction(
563 IN PRTMP_ADAPTER pAd
,
564 IN MLME_QUEUE_ELEM
*Elem
)
566 UCHAR Bssid
[MAC_ADDR_LEN
], Addr2
[MAC_ADDR_LEN
];
567 UCHAR Ssid
[MAX_LEN_OF_SSID
], BssType
, Channel
, NewChannel
,
568 SsidLen
, DtimCount
, DtimPeriod
, BcastFlag
, MessageToMe
;
570 USHORT BeaconPeriod
, AtimWin
, CapabilityInfo
;
571 PFRAME_802_11 pFrame
;
572 LARGE_INTEGER TimeStamp
;
574 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
575 UCHAR SupRateLen
, ExtRateLen
;
578 UCHAR AironetCellPowerLimit
;
580 QBSS_LOAD_PARM QbssLoad
;
581 QOS_CAPABILITY_PARM QosCapability
;
583 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
584 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
585 HT_CAPABILITY_IE HtCapability
;
586 ADD_HT_INFO_IE AddHtInfo
; // AP might use this additional ht info IE
587 UCHAR HtCapabilityLen
= 0, PreNHtCapabilityLen
= 0;
589 UCHAR NewExtChannelOffset
= 0xff;
592 // NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00);
593 pFrame
= (PFRAME_802_11
) Elem
->Msg
;
594 // Init Variable IE structure
595 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
597 #ifdef DOT11_N_SUPPORT
598 RTMPZeroMemory(&HtCapability
, sizeof(HtCapability
));
599 RTMPZeroMemory(&AddHtInfo
, sizeof(ADD_HT_INFO_IE
));
600 #endif // DOT11_N_SUPPORT //
602 if (PeerBeaconAndProbeRspSanity(pAd
,
628 &AironetCellPowerLimit
,
634 &PreNHtCapabilityLen
,
638 &NewExtChannelOffset
,
645 Idx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
646 if (Idx
!= BSS_NOT_FOUND
)
647 Rssi
= pAd
->ScanTab
.BssEntry
[Idx
].Rssi
;
649 Rssi
= RTMPMaxRssi(pAd
, ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
), ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
), ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
));
652 #ifdef DOT11_N_SUPPORT
653 if ((HtCapabilityLen
> 0) || (PreNHtCapabilityLen
> 0))
654 HtCapabilityLen
= SIZE_HT_CAP_IE
;
655 #endif // DOT11_N_SUPPORT //
657 Idx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, (PCHAR
)Ssid
, SsidLen
, BssType
, BeaconPeriod
,
658 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
, &HtCapability
,
659 &AddHtInfo
, HtCapabilityLen
, AddHtInfoLen
, NewExtChannelOffset
, Channel
, Rssi
, TimeStamp
, CkipFlag
,
660 &EdcaParm
, &QosCapability
, &QbssLoad
, LenVIE
, pVIE
);
661 #ifdef DOT11_N_SUPPORT
663 if (pAd
->ChannelList
[pAd
->CommonCfg
.ChannelListIdx
].bEffectedChannel
== TRUE
)
666 PeerBeaconAndProbeRspSanity2(pAd
, Elem
->Msg
, Elem
->MsgLen
, &RegClass
);
667 TriEventTableSetEntry(pAd
, &pAd
->CommonCfg
.TriggerEventTab
, Bssid
, &HtCapability
, HtCapabilityLen
, RegClass
, Channel
);
669 #endif // DOT11N_DRAFT3 //
670 #endif // DOT11_N_SUPPORT //
671 if (Idx
!= BSS_NOT_FOUND
)
673 NdisMoveMemory(pAd
->ScanTab
.BssEntry
[Idx
].PTSF
, &Elem
->Msg
[24], 4);
674 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Idx
].TTSF
[0], &Elem
->TimeStamp
.u
.LowPart
, 4);
675 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Idx
].TTSF
[4], &Elem
->TimeStamp
.u
.LowPart
, 4);
679 // sanity check fail, ignored
683 ==========================================================================
685 When waiting joining the (I)BSS, beacon received from external
686 ==========================================================================
688 VOID
PeerBeaconAtJoinAction(
689 IN PRTMP_ADAPTER pAd
,
690 IN MLME_QUEUE_ELEM
*Elem
)
692 UCHAR Bssid
[MAC_ADDR_LEN
], Addr2
[MAC_ADDR_LEN
];
693 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
, BssType
, Channel
, MessageToMe
,
694 DtimCount
, DtimPeriod
, BcastFlag
, NewChannel
;
695 LARGE_INTEGER TimeStamp
;
696 USHORT BeaconPeriod
, AtimWin
, CapabilityInfo
;
698 BOOLEAN TimerCancelled
;
700 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
701 UCHAR SupRateLen
, ExtRateLen
;
704 UCHAR AironetCellPowerLimit
;
706 QBSS_LOAD_PARM QbssLoad
;
707 QOS_CAPABILITY_PARM QosCapability
;
709 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
710 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
713 HT_CAPABILITY_IE HtCapability
;
714 ADD_HT_INFO_IE AddHtInfo
; // AP might use this additional ht info IE
715 UCHAR HtCapabilityLen
= 0, PreNHtCapabilityLen
= 0;
717 UCHAR NewExtChannelOffset
= 0xff;
718 #ifdef DOT11_N_SUPPORT
719 UCHAR CentralChannel
;
720 BOOLEAN bAllowNrate
= FALSE
;
721 #endif // DOT11_N_SUPPORT //
723 // Init Variable IE structure
724 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
726 RTMPZeroMemory(&HtCapability
, sizeof(HtCapability
));
727 RTMPZeroMemory(&AddHtInfo
, sizeof(ADD_HT_INFO_IE
));
730 if (PeerBeaconAndProbeRspSanity(pAd
,
756 &AironetCellPowerLimit
,
762 &PreNHtCapabilityLen
,
766 &NewExtChannelOffset
,
770 // Disqualify 11b only adhoc when we are in 11g only adhoc mode
771 if ((BssType
== BSS_ADHOC
) && (pAd
->CommonCfg
.PhyMode
== PHY_11G
) && ((SupRateLen
+ExtRateLen
)< 12))
774 // BEACON from desired BSS/IBSS found. We should be able to decide most
775 // BSS parameters here.
776 // Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
777 // Do we need to receover back all parameters belonging to previous BSS?
778 // A. Should be not. There's no back-door recover to previous AP. It still need
779 // a new JOIN-AUTH-ASSOC sequence.
780 if (MAC_ADDR_EQUAL(pAd
->MlmeAux
.Bssid
, Bssid
))
782 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel
));
783 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
785 // Update RSSI to prevent No signal display when cards first initialized
786 pAd
->StaCfg
.RssiSample
.LastRssi0
= ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
);
787 pAd
->StaCfg
.RssiSample
.LastRssi1
= ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
);
788 pAd
->StaCfg
.RssiSample
.LastRssi2
= ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
);
789 pAd
->StaCfg
.RssiSample
.AvgRssi0
= pAd
->StaCfg
.RssiSample
.LastRssi0
;
790 pAd
->StaCfg
.RssiSample
.AvgRssi0X8
= pAd
->StaCfg
.RssiSample
.AvgRssi0
<< 3;
791 pAd
->StaCfg
.RssiSample
.AvgRssi1
= pAd
->StaCfg
.RssiSample
.LastRssi1
;
792 pAd
->StaCfg
.RssiSample
.AvgRssi1X8
= pAd
->StaCfg
.RssiSample
.AvgRssi1
<< 3;
793 pAd
->StaCfg
.RssiSample
.AvgRssi2
= pAd
->StaCfg
.RssiSample
.LastRssi2
;
794 pAd
->StaCfg
.RssiSample
.AvgRssi2X8
= pAd
->StaCfg
.RssiSample
.AvgRssi2
<< 3;
797 // We need to check if SSID only set to any, then we can record the current SSID.
798 // Otherwise will cause hidden SSID association failed.
800 if (pAd
->MlmeAux
.SsidLen
== 0)
802 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, Ssid
, SsidLen
);
803 pAd
->MlmeAux
.SsidLen
= SsidLen
;
807 Idx
= BssSsidTableSearch(&pAd
->ScanTab
, Bssid
, pAd
->MlmeAux
.Ssid
, pAd
->MlmeAux
.SsidLen
, Channel
);
809 if (Idx
== BSS_NOT_FOUND
)
812 Rssi
= RTMPMaxRssi(pAd
, ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
), ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
), ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
));
813 Idx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, (CHAR
*) Ssid
, SsidLen
, BssType
, BeaconPeriod
,
814 &Cf
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
, &HtCapability
,
815 &AddHtInfo
, HtCapabilityLen
, AddHtInfoLen
, NewExtChannelOffset
, Channel
, Rssi
, TimeStamp
, CkipFlag
,
816 &EdcaParm
, &QosCapability
, &QbssLoad
, LenVIE
, pVIE
);
817 if (Idx
!= BSS_NOT_FOUND
)
819 NdisMoveMemory(pAd
->ScanTab
.BssEntry
[Idx
].PTSF
, &Elem
->Msg
[24], 4);
820 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Idx
].TTSF
[0], &Elem
->TimeStamp
.u
.LowPart
, 4);
821 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Idx
].TTSF
[4], &Elem
->TimeStamp
.u
.LowPart
, 4);
822 CapabilityInfo
= pAd
->ScanTab
.BssEntry
[Idx
].CapabilityInfo
;
828 // Multiple SSID case, used correct CapabilityInfo
830 CapabilityInfo
= pAd
->ScanTab
.BssEntry
[Idx
].CapabilityInfo
;
833 NdisMoveMemory(pAd
->MlmeAux
.Bssid
, Bssid
, MAC_ADDR_LEN
);
834 pAd
->MlmeAux
.CapabilityInfo
= CapabilityInfo
& SUPPORTED_CAPABILITY_INFO
;
835 pAd
->MlmeAux
.BssType
= BssType
;
836 pAd
->MlmeAux
.BeaconPeriod
= BeaconPeriod
;
837 pAd
->MlmeAux
.Channel
= Channel
;
838 pAd
->MlmeAux
.AtimWin
= AtimWin
;
839 pAd
->MlmeAux
.CfpPeriod
= Cf
.CfpPeriod
;
840 pAd
->MlmeAux
.CfpMaxDuration
= Cf
.CfpMaxDuration
;
841 pAd
->MlmeAux
.APRalinkIe
= RalinkIe
;
843 // Copy AP's supported rate to MlmeAux for creating assoication request
844 // Also filter out not supported rate
845 pAd
->MlmeAux
.SupRateLen
= SupRateLen
;
846 NdisMoveMemory(pAd
->MlmeAux
.SupRate
, SupRate
, SupRateLen
);
847 RTMPCheckRates(pAd
, pAd
->MlmeAux
.SupRate
, &pAd
->MlmeAux
.SupRateLen
);
848 pAd
->MlmeAux
.ExtRateLen
= ExtRateLen
;
849 NdisMoveMemory(pAd
->MlmeAux
.ExtRate
, ExtRate
, ExtRateLen
);
850 RTMPCheckRates(pAd
, pAd
->MlmeAux
.ExtRate
, &pAd
->MlmeAux
.ExtRateLen
);
852 NdisZeroMemory(pAd
->StaActive
.SupportedPhyInfo
.MCSSet
, 16);
855 #ifdef DOT11_N_SUPPORT
856 if (((pAd
->StaCfg
.WepStatus
!= Ndis802_11WEPEnabled
) && (pAd
->StaCfg
.WepStatus
!= Ndis802_11Encryption2Enabled
))
857 || (pAd
->CommonCfg
.HT_DisallowTKIP
== FALSE
))
862 pAd
->MlmeAux
.NewExtChannelOffset
= NewExtChannelOffset
;
863 pAd
->MlmeAux
.HtCapabilityLen
= HtCapabilityLen
;
865 RTMPZeroMemory(&pAd
->MlmeAux
.HtCapability
, SIZE_HT_CAP_IE
);
866 // filter out un-supported ht rates
867 if (((HtCapabilityLen
> 0) || (PreNHtCapabilityLen
> 0)) &&
868 ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
) && (bAllowNrate
)))
870 RTMPMoveMemory(&pAd
->MlmeAux
.AddHtInfo
, &AddHtInfo
, SIZE_ADD_HT_INFO_IE
);
872 // StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
873 NdisMoveMemory(pAd
->StaActive
.SupportedPhyInfo
.MCSSet
, HtCapability
.MCSSet
, 16);
874 pAd
->MlmeAux
.NewExtChannelOffset
= NewExtChannelOffset
;
875 pAd
->MlmeAux
.HtCapabilityLen
= SIZE_HT_CAP_IE
;
876 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= TRUE
;
877 if (PreNHtCapabilityLen
> 0)
878 pAd
->StaActive
.SupportedPhyInfo
.bPreNHt
= TRUE
;
879 RTMPCheckHt(pAd
, BSSID_WCID
, &HtCapability
, &AddHtInfo
);
880 // Copy AP Parameter to StaActive. This is also in LinkUp.
881 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
882 pAd
->StaActive
.SupportedHtPhy
.MpduDensity
, pAd
->StaActive
.SupportedHtPhy
.MaxRAmpduFactor
, HtCapability
.HtCapInfo
.ChannelWidth
));
884 if (AddHtInfoLen
> 0)
886 CentralChannel
= AddHtInfo
.ControlChan
;
887 // Check again the Bandwidth capability of this AP.
888 if ((AddHtInfo
.ControlChan
> 2)&& (AddHtInfo
.AddHtInfo
.ExtChanOffset
== EXTCHA_BELOW
) && (HtCapability
.HtCapInfo
.ChannelWidth
== BW_40
))
890 CentralChannel
= AddHtInfo
.ControlChan
- 2;
892 else if ((AddHtInfo
.AddHtInfo
.ExtChanOffset
== EXTCHA_ABOVE
) && (HtCapability
.HtCapInfo
.ChannelWidth
== BW_40
))
894 CentralChannel
= AddHtInfo
.ControlChan
+ 2;
898 if (pAd
->MlmeAux
.CentralChannel
!= CentralChannel
)
899 DBGPRINT(RT_DEBUG_ERROR
, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel
, AddHtInfo
.ControlChan
, pAd
->MlmeAux
.CentralChannel
));
901 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel
, AddHtInfo
.ControlChan
));
907 #endif // DOT11_N_SUPPORT //
909 // To prevent error, let legacy AP must have same CentralChannel and Channel.
910 if ((HtCapabilityLen
== 0) && (PreNHtCapabilityLen
== 0))
911 pAd
->MlmeAux
.CentralChannel
= pAd
->MlmeAux
.Channel
;
913 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
914 pAd
->MlmeAux
.NewExtChannelOffset
= 0xff;
915 RTMPZeroMemory(&pAd
->MlmeAux
.HtCapability
, SIZE_HT_CAP_IE
);
916 pAd
->MlmeAux
.HtCapabilityLen
= 0;
917 RTMPZeroMemory(&pAd
->MlmeAux
.AddHtInfo
, SIZE_ADD_HT_INFO_IE
);
920 RTMPUpdateMlmeRate(pAd
);
922 // copy QOS related information
923 if ((pAd
->CommonCfg
.bWmmCapable
)
924 #ifdef DOT11_N_SUPPORT
925 || (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
926 #endif // DOT11_N_SUPPORT //
929 NdisMoveMemory(&pAd
->MlmeAux
.APEdcaParm
, &EdcaParm
, sizeof(EDCA_PARM
));
930 NdisMoveMemory(&pAd
->MlmeAux
.APQbssLoad
, &QbssLoad
, sizeof(QBSS_LOAD_PARM
));
931 NdisMoveMemory(&pAd
->MlmeAux
.APQosCapability
, &QosCapability
, sizeof(QOS_CAPABILITY_PARM
));
935 NdisZeroMemory(&pAd
->MlmeAux
.APEdcaParm
, sizeof(EDCA_PARM
));
936 NdisZeroMemory(&pAd
->MlmeAux
.APQbssLoad
, sizeof(QBSS_LOAD_PARM
));
937 NdisZeroMemory(&pAd
->MlmeAux
.APQosCapability
, sizeof(QOS_CAPABILITY_PARM
));
940 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
941 pAd
->MlmeAux
.SupRateLen
, pAd
->MlmeAux
.ExtRateLen
));
943 if (AironetCellPowerLimit
!= 0xFF)
945 //We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
946 ChangeToCellPowerLimit(pAd
, AironetCellPowerLimit
);
948 else //Used the default TX Power Percentage.
949 pAd
->CommonCfg
.TxPowerPercentage
= pAd
->CommonCfg
.TxPowerDefault
;
951 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
952 Status
= MLME_SUCCESS
;
953 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_JOIN_CONF
, 2, &Status
);
955 // not to me BEACON, ignored
957 // sanity check fail, ignore this frame
961 ==========================================================================
963 receive BEACON from peer
965 IRQL = DISPATCH_LEVEL
967 ==========================================================================
970 IN PRTMP_ADAPTER pAd
,
971 IN MLME_QUEUE_ELEM
*Elem
)
973 UCHAR Bssid
[MAC_ADDR_LEN
], Addr2
[MAC_ADDR_LEN
];
974 CHAR Ssid
[MAX_LEN_OF_SSID
];
976 UCHAR SsidLen
, MessageToMe
=0, BssType
, Channel
, NewChannel
, index
=0;
977 UCHAR DtimCount
=0, DtimPeriod
=0, BcastFlag
=0;
978 USHORT CapabilityInfo
, AtimWin
, BeaconPeriod
;
979 LARGE_INTEGER TimeStamp
;
980 USHORT TbttNumToNextWakeUp
;
982 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
983 UCHAR SupRateLen
, ExtRateLen
;
986 UCHAR AironetCellPowerLimit
;
988 QBSS_LOAD_PARM QbssLoad
;
989 QOS_CAPABILITY_PARM QosCapability
;
991 // New for WPA security suites
992 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
993 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
994 HT_CAPABILITY_IE HtCapability
;
995 ADD_HT_INFO_IE AddHtInfo
; // AP might use this additional ht info IE
996 UCHAR HtCapabilityLen
, PreNHtCapabilityLen
;
998 UCHAR NewExtChannelOffset
= 0xff;
1006 #endif // RALINK_ATE //
1008 if (!(INFRA_ON(pAd
) || ADHOC_ON(pAd
)
1012 // Init Variable IE structure
1013 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
1015 RTMPZeroMemory(&HtCapability
, sizeof(HtCapability
));
1016 RTMPZeroMemory(&AddHtInfo
, sizeof(ADD_HT_INFO_IE
));
1018 if (PeerBeaconAndProbeRspSanity(pAd
,
1044 &AironetCellPowerLimit
,
1050 &PreNHtCapabilityLen
,
1054 &NewExtChannelOffset
,
1058 BOOLEAN is_my_bssid
, is_my_ssid
;
1061 CHAR RealRssi
= RTMPMaxRssi(pAd
, ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
), ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
), ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
));
1063 is_my_bssid
= MAC_ADDR_EQUAL(Bssid
, pAd
->CommonCfg
.Bssid
)? TRUE
: FALSE
;
1064 is_my_ssid
= SSID_EQUAL(Ssid
, SsidLen
, pAd
->CommonCfg
.Ssid
, pAd
->CommonCfg
.SsidLen
)? TRUE
:FALSE
;
1067 // ignore BEACON not for my SSID
1068 if ((! is_my_ssid
) && (! is_my_bssid
))
1071 // It means STA waits disassoc completely from this AP, ignores this beacon.
1072 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_WAIT_DISASSOC
)
1075 #ifdef DOT11_N_SUPPORT
1076 // Copy Control channel for this BSSID.
1077 if (AddHtInfoLen
!= 0)
1078 Channel
= AddHtInfo
.ControlChan
;
1080 if ((HtCapabilityLen
> 0) || (PreNHtCapabilityLen
> 0))
1081 HtCapabilityLen
= SIZE_HT_CAP_IE
;
1082 #endif // DOT11_N_SUPPORT //
1085 // Housekeeping "SsidBssTab" table for later-on ROAMing usage.
1087 Bssidx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
1088 if (Bssidx
== BSS_NOT_FOUND
)
1090 // discover new AP of this network, create BSS entry
1091 Bssidx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
1092 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,
1093 &HtCapability
, &AddHtInfo
,HtCapabilityLen
,AddHtInfoLen
,NewExtChannelOffset
, Channel
,
1094 RealRssi
, TimeStamp
, CkipFlag
, &EdcaParm
, &QosCapability
,
1095 &QbssLoad
, LenVIE
, pVIE
);
1096 if (Bssidx
== BSS_NOT_FOUND
) // return if BSS table full
1099 NdisMoveMemory(pAd
->ScanTab
.BssEntry
[Bssidx
].PTSF
, &Elem
->Msg
[24], 4);
1100 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Bssidx
].TTSF
[0], &Elem
->TimeStamp
.u
.LowPart
, 4);
1101 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Bssidx
].TTSF
[4], &Elem
->TimeStamp
.u
.LowPart
, 4);
1107 if ((pAd
->CommonCfg
.bIEEE80211H
== 1) && (NewChannel
!= 0) && (Channel
!= NewChannel
))
1109 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1110 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1111 AsicSwitchChannel(pAd
, 1, FALSE
);
1112 AsicLockChannel(pAd
, 1);
1113 LinkDown(pAd
, FALSE
);
1114 MlmeQueueInit(&pAd
->Mlme
.Queue
);
1115 BssTableInit(&pAd
->ScanTab
);
1116 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1118 // channel sanity check
1119 for (index
= 0 ; index
< pAd
->ChannelListNum
; index
++)
1121 if (pAd
->ChannelList
[index
].Channel
== NewChannel
)
1123 pAd
->ScanTab
.BssEntry
[Bssidx
].Channel
= NewChannel
;
1124 pAd
->CommonCfg
.Channel
= NewChannel
;
1125 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.Channel
, FALSE
);
1126 AsicLockChannel(pAd
, pAd
->CommonCfg
.Channel
);
1127 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel
));
1132 if (index
>= pAd
->ChannelListNum
)
1134 DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd
->CommonCfg
.Channel
, pAd
->ChannelListNum
));
1138 // if the ssid matched & bssid unmatched, we should select the bssid with large value.
1139 // This might happened when two STA start at the same time
1140 if ((! is_my_bssid
) && ADHOC_ON(pAd
))
1144 // Add the safeguard against the mismatch of adhoc wep status
1145 if (pAd
->StaCfg
.WepStatus
!= pAd
->ScanTab
.BssEntry
[Bssidx
].WepStatus
)
1150 // collapse into the ADHOC network which has bigger BSSID value.
1151 for (i
= 0; i
< 6; i
++)
1153 if (Bssid
[i
] > pAd
->CommonCfg
.Bssid
[i
])
1155 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
1156 Bssid
[0], Bssid
[1], Bssid
[2], Bssid
[3], Bssid
[4], Bssid
[5]));
1157 AsicDisableSync(pAd
);
1158 COPY_MAC_ADDR(pAd
->CommonCfg
.Bssid
, Bssid
);
1159 AsicSetBssid(pAd
, pAd
->CommonCfg
.Bssid
);
1160 MakeIbssBeacon(pAd
); // re-build BEACON frame
1161 AsicEnableIbssSync(pAd
); // copy BEACON frame to on-chip memory
1165 else if (Bssid
[i
] < pAd
->CommonCfg
.Bssid
[i
])
1171 NdisGetSystemUpTime(&Now
);
1172 pBss
= &pAd
->ScanTab
.BssEntry
[Bssidx
];
1173 pBss
->Rssi
= RealRssi
; // lastest RSSI
1174 pBss
->LastBeaconRxTime
= Now
; // last RX timestamp
1177 // BEACON from my BSSID - either IBSS or INFRA network
1183 pAd
->StaCfg
.DtimCount
= DtimCount
;
1184 pAd
->StaCfg
.DtimPeriod
= DtimPeriod
;
1185 pAd
->StaCfg
.LastBeaconRxTime
= Now
;
1188 RxWI
.RSSI0
= Elem
->Rssi0
;
1189 RxWI
.RSSI1
= Elem
->Rssi1
;
1190 RxWI
.RSSI2
= Elem
->Rssi2
;
1192 Update_Rssi_Sample(pAd
, &pAd
->StaCfg
.RssiSample
, &RxWI
);
1193 if (AironetCellPowerLimit
!= 0xFF)
1196 // We get the Cisco (ccx) "TxPower Limit" required
1197 // Changed to appropriate TxPower Limit for Ciso Compatible Extensions
1199 ChangeToCellPowerLimit(pAd
, AironetCellPowerLimit
);
1204 // AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
1205 // Used the default TX Power Percentage, that set from UI.
1207 pAd
->CommonCfg
.TxPowerPercentage
= pAd
->CommonCfg
.TxPowerDefault
;
1210 if (ADHOC_ON(pAd
) && (CAP_IS_IBSS_ON(CapabilityInfo
)))
1212 UCHAR MaxSupportedRateIn500Kbps
= 0;
1214 MAC_TABLE_ENTRY
*pEntry
;
1216 // supported rates array may not be sorted. sort it and find the maximum rate
1217 for (idx
=0; idx
<SupRateLen
; idx
++)
1219 if (MaxSupportedRateIn500Kbps
< (SupRate
[idx
] & 0x7f))
1220 MaxSupportedRateIn500Kbps
= SupRate
[idx
] & 0x7f;
1223 for (idx
=0; idx
<ExtRateLen
; idx
++)
1225 if (MaxSupportedRateIn500Kbps
< (ExtRate
[idx
] & 0x7f))
1226 MaxSupportedRateIn500Kbps
= ExtRate
[idx
] & 0x7f;
1229 // look up the existing table
1230 pEntry
= MacTableLookup(pAd
, Addr2
);
1232 // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
1233 // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
1234 if ((ADHOC_ON(pAd
) && (Elem
->Wcid
== RESERVED_WCID
)) ||
1235 (pEntry
&& ((pEntry
->LastBeaconRxTime
+ ADHOC_ENTRY_BEACON_LOST_TIME
) < Now
)))
1238 // Another adhoc joining, add to our MAC table.
1239 pEntry
= MacTableInsertEntry(pAd
, Addr2
, BSS0
, FALSE
);
1241 if (StaAddMacTableEntry(pAd
,
1243 MaxSupportedRateIn500Kbps
,
1248 CapabilityInfo
) == FALSE
)
1250 DBGPRINT(RT_DEBUG_TRACE
, ("ADHOC - Add Entry failed.\n"));
1255 (Elem
->Wcid
== RESERVED_WCID
))
1257 idx
= pAd
->StaCfg
.DefaultKeyId
;
1258 RTMP_STA_SECURITY_INFO_ADD(pAd
, BSS0
, idx
, pEntry
);
1262 if (pEntry
&& pEntry
->ValidAsCLI
)
1263 pEntry
->LastBeaconRxTime
= Now
;
1265 // At least another peer in this IBSS, declare MediaState as CONNECTED
1266 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1268 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
);
1270 pAd
->IndicateMediaState
= NdisMediaStateConnected
;
1271 RTMP_IndicateMediaState(pAd
);
1272 pAd
->ExtraInfo
= GENERAL_LINK_UP
;
1273 AsicSetBssid(pAd
, pAd
->CommonCfg
.Bssid
);
1275 // 2003/03/12 - john
1276 // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
1277 // "site survey" result should always include the current connected network.
1279 Bssidx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
1280 if (Bssidx
== BSS_NOT_FOUND
)
1282 Bssidx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
1283 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
, &HtCapability
,
1284 &AddHtInfo
, HtCapabilityLen
, AddHtInfoLen
, NewExtChannelOffset
, Channel
, RealRssi
, TimeStamp
, 0,
1285 &EdcaParm
, &QosCapability
, &QbssLoad
, LenVIE
, pVIE
);
1287 DBGPRINT(RT_DEBUG_TRACE
, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1293 BOOLEAN bUseShortSlot
, bUseBGProtection
;
1295 // decide to use/change to -
1296 // 1. long slot (20 us) or short slot (9 us) time
1297 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1298 // 3. short preamble
1300 //bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
1301 bUseShortSlot
= CAP_IS_SHORT_SLOT(CapabilityInfo
);
1302 if (bUseShortSlot
!= OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_SHORT_SLOT_INUSED
))
1303 AsicSetSlotTime(pAd
, bUseShortSlot
);
1305 bUseBGProtection
= (pAd
->CommonCfg
.UseBGProtection
== 1) || // always use
1306 ((pAd
->CommonCfg
.UseBGProtection
== 0) && ERP_IS_USE_PROTECTION(Erp
));
1308 if (pAd
->CommonCfg
.Channel
> 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
1309 bUseBGProtection
= FALSE
;
1311 if (bUseBGProtection
!= OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
))
1313 if (bUseBGProtection
)
1315 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
);
1316 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, (OFDMSETPROTECT
|CCKSETPROTECT
|ALLN_SETPROTECT
),FALSE
,(pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
== 1));
1320 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
);
1321 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, (OFDMSETPROTECT
|CCKSETPROTECT
|ALLN_SETPROTECT
),TRUE
,(pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
== 1));
1324 DBGPRINT(RT_DEBUG_WARN
, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection
));
1327 #ifdef DOT11_N_SUPPORT
1328 // check Ht protection mode. and adhere to the Non-GF device indication by AP.
1329 if ((AddHtInfoLen
!= 0) &&
1330 ((AddHtInfo
.AddHtInfo2
.OperaionMode
!= pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
) ||
1331 (AddHtInfo
.AddHtInfo2
.NonGfPresent
!= pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
)))
1333 pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
= AddHtInfo
.AddHtInfo2
.NonGfPresent
;
1334 pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
= AddHtInfo
.AddHtInfo2
.OperaionMode
;
1335 if (pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
== 1)
1337 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, FALSE
, TRUE
);
1340 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, FALSE
, FALSE
);
1342 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - AP changed N OperaionMode to %d\n", pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
));
1344 #endif // DOT11_N_SUPPORT //
1346 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_SHORT_PREAMBLE_INUSED
) &&
1347 ERP_IS_USE_BARKER_PREAMBLE(Erp
))
1349 MlmeSetTxPreamble(pAd
, Rt802_11PreambleLong
);
1350 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - AP forced to use LONG preamble\n"));
1353 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_WMM_INUSED
) &&
1354 (EdcaParm
.bValid
== TRUE
) &&
1355 (EdcaParm
.EdcaUpdateCount
!= pAd
->CommonCfg
.APEdcaParm
.EdcaUpdateCount
))
1357 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1358 pAd
->CommonCfg
.APEdcaParm
.EdcaUpdateCount
,
1359 EdcaParm
.EdcaUpdateCount
));
1360 AsicSetEdcaParm(pAd
, &EdcaParm
);
1363 // copy QOS related information
1364 NdisMoveMemory(&pAd
->CommonCfg
.APQbssLoad
, &QbssLoad
, sizeof(QBSS_LOAD_PARM
));
1365 NdisMoveMemory(&pAd
->CommonCfg
.APQosCapability
, &QosCapability
, sizeof(QOS_CAPABILITY_PARM
));
1368 // only INFRASTRUCTURE mode support power-saving feature
1369 if ((INFRA_ON(pAd
) && (pAd
->StaCfg
.Psm
== PWR_SAVE
)) || (pAd
->CommonCfg
.bAPSDForcePowerSave
))
1372 // 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
1373 // 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
1374 // 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
1375 // 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
1376 // 5. otherwise, put PHY back to sleep to save battery.
1380 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_PCIE_DEVICE
))
1382 // Restore to correct BBP R3 value
1383 if (pAd
->Antenna
.field
.RxPath
> 1)
1384 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, pAd
->StaCfg
.BBPR3
);
1385 // Turn clk to 80Mhz.
1387 #endif // RTMP_MAC_PCI //
1388 if (pAd
->CommonCfg
.bAPSDCapable
&& pAd
->CommonCfg
.APEdcaParm
.bAPSDCapable
&&
1389 pAd
->CommonCfg
.bAPSDAC_BE
&& pAd
->CommonCfg
.bAPSDAC_BK
&& pAd
->CommonCfg
.bAPSDAC_VI
&& pAd
->CommonCfg
.bAPSDAC_VO
)
1391 pAd
->CommonCfg
.bNeedSendTriggerFrame
= TRUE
;
1394 RTMP_PS_POLL_ENQUEUE(pAd
);
1396 else if (BcastFlag
&& (DtimCount
== 0) && OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_RECEIVE_DTIM
))
1399 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_PCIE_DEVICE
))
1401 if (pAd
->Antenna
.field
.RxPath
> 1)
1402 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, pAd
->StaCfg
.BBPR3
);
1404 #endif // RTMP_MAC_PCI //
1406 else if ((pAd
->TxSwQueue
[QID_AC_BK
].Number
!= 0) ||
1407 (pAd
->TxSwQueue
[QID_AC_BE
].Number
!= 0) ||
1408 (pAd
->TxSwQueue
[QID_AC_VI
].Number
!= 0) ||
1409 (pAd
->TxSwQueue
[QID_AC_VO
].Number
!= 0) ||
1410 (RTMPFreeTXDRequest(pAd
, QID_AC_BK
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1411 (RTMPFreeTXDRequest(pAd
, QID_AC_BE
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1412 (RTMPFreeTXDRequest(pAd
, QID_AC_VI
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1413 (RTMPFreeTXDRequest(pAd
, QID_AC_VO
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1414 (RTMPFreeTXDRequest(pAd
, QID_MGMT
, MGMT_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
))
1416 // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
1417 // can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
1419 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_PCIE_DEVICE
))
1421 if (pAd
->Antenna
.field
.RxPath
> 1)
1422 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, pAd
->StaCfg
.BBPR3
);
1424 #endif // RTMP_MAC_PCI //
1428 if ((pAd
->CommonCfg
.bACMAPSDTr
[QID_AC_VO
]) ||
1429 (pAd
->CommonCfg
.bACMAPSDTr
[QID_AC_VI
]) ||
1430 (pAd
->CommonCfg
.bACMAPSDTr
[QID_AC_BK
]) ||
1431 (pAd
->CommonCfg
.bACMAPSDTr
[QID_AC_BE
]))
1434 WMM Spec v1.0 3.6.2.4,
1435 The WMM STA shall remain awake until it receives a
1436 QoS Data or Null frame addressed to it, with the
1437 EOSP subfield in QoS Control field set to 1.
1439 So we can not sleep here or we will suffer a case:
1441 PS Management Frame -->
1443 Beacon (TIM=0) (Beacon is closer to Trig frame) -->
1444 Station goes to sleep -->
1445 AP delivery queued UAPSD packets -->
1446 Station can NOT receive the reply
1448 Maybe we need a timeout timer to avoid that we do
1449 NOT receive the EOSP frame.
1451 We can not use More Data to check if SP is ended
1457 USHORT NextDtim
= DtimCount
;
1461 NextDtim
= DtimPeriod
;
1463 TbttNumToNextWakeUp
= pAd
->StaCfg
.DefaultListenCount
;
1464 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_RECEIVE_DTIM
) && (TbttNumToNextWakeUp
> NextDtim
))
1465 TbttNumToNextWakeUp
= NextDtim
;
1467 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
))
1469 // Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode.
1470 pAd
->ThisTbttNumToNextWakeUp
= TbttNumToNextWakeUp
;
1471 AsicSleepThenAutoWakeup(pAd
, pAd
->ThisTbttNumToNextWakeUp
);
1478 // not my BSSID, ignore it
1480 // sanity check fail, ignore this frame
1484 ==========================================================================
1486 Receive PROBE REQ from remote peer when operating in IBSS mode
1487 ==========================================================================
1489 VOID
PeerProbeReqAction(
1490 IN PRTMP_ADAPTER pAd
,
1491 IN MLME_QUEUE_ELEM
*Elem
)
1493 UCHAR Addr2
[MAC_ADDR_LEN
];
1494 CHAR Ssid
[MAX_LEN_OF_SSID
];
1496 #ifdef DOT11_N_SUPPORT
1497 UCHAR HtLen
, AddHtLen
, NewExtLen
;
1498 #endif // DOT11_N_SUPPORT //
1499 HEADER_802_11 ProbeRspHdr
;
1500 NDIS_STATUS NStatus
;
1501 PUCHAR pOutBuffer
= NULL
;
1503 LARGE_INTEGER FakeTimestamp
;
1504 UCHAR DsLen
= 1, IbssLen
= 2;
1505 UCHAR LocalErpIe
[3] = {IE_ERP
, 1, 0};
1507 USHORT CapabilityInfo
;
1508 UCHAR RSNIe
= IE_WPA
;
1510 if (! ADHOC_ON(pAd
))
1513 if (PeerProbeReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, Addr2
, Ssid
, &SsidLen
))
1515 if ((SsidLen
== 0) || SSID_EQUAL(Ssid
, SsidLen
, pAd
->CommonCfg
.Ssid
, pAd
->CommonCfg
.SsidLen
))
1517 // allocate and send out ProbeRsp frame
1518 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
1519 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1522 //pAd->StaCfg.AtimWin = 0; // ??????
1524 Privacy
= (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption1Enabled
) ||
1525 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) ||
1526 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
);
1527 CapabilityInfo
= CAP_GENERATE(0, 1, Privacy
, (pAd
->CommonCfg
.TxPreamble
== Rt802_11PreambleShort
), 0, 0);
1529 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1530 sizeof(HEADER_802_11
), &ProbeRspHdr
,
1531 TIMESTAMP_LEN
, &FakeTimestamp
,
1532 2, &pAd
->CommonCfg
.BeaconPeriod
,
1535 1, &pAd
->CommonCfg
.SsidLen
,
1536 pAd
->CommonCfg
.SsidLen
, pAd
->CommonCfg
.Ssid
,
1538 1, &pAd
->StaActive
.SupRateLen
,
1539 pAd
->StaActive
.SupRateLen
, pAd
->StaActive
.SupRate
,
1542 1, &pAd
->CommonCfg
.Channel
,
1545 2, &pAd
->StaActive
.AtimWin
,
1548 if (pAd
->StaActive
.ExtRateLen
)
1551 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
1554 1, &pAd
->StaActive
.ExtRateLen
,
1555 pAd
->StaActive
.ExtRateLen
, &pAd
->StaActive
.ExtRate
,
1560 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1561 if (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPANone
)
1564 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
1566 1, &pAd
->StaCfg
.RSNIE_Len
,
1567 pAd
->StaCfg
.RSNIE_Len
, pAd
->StaCfg
.RSN_IE
,
1571 #ifdef DOT11_N_SUPPORT
1572 if (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
1575 UCHAR BROADCOM
[4] = {0x0, 0x90, 0x4c, 0x33};
1576 HtLen
= sizeof(pAd
->CommonCfg
.HtCapability
);
1577 AddHtLen
= sizeof(pAd
->CommonCfg
.AddHTInfo
);
1579 //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
1580 if (pAd
->bBroadComHT
== TRUE
)
1582 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &TmpLen
,
1585 pAd
->MlmeAux
.HtCapabilityLen
, &pAd
->MlmeAux
.HtCapability
,
1590 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &TmpLen
,
1593 sizeof(HT_CAPABILITY_IE
), &pAd
->CommonCfg
.HtCapability
,
1596 sizeof(ADD_HT_INFO_IE
), &pAd
->CommonCfg
.AddHTInfo
,
1599 sizeof(NEW_EXT_CHAN_IE
), &pAd
->CommonCfg
.NewExtChanOffset
,
1604 #endif // DOT11_N_SUPPORT //
1605 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
1606 MlmeFreeMemory(pAd
, pOutBuffer
);
1611 VOID
BeaconTimeoutAtJoinAction(
1612 IN PRTMP_ADAPTER pAd
,
1613 IN MLME_QUEUE_ELEM
*Elem
)
1616 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1617 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1618 Status
= MLME_REJ_TIMEOUT
;
1619 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_JOIN_CONF
, 2, &Status
);
1623 ==========================================================================
1625 Scan timeout procedure. basically add channel index by 1 and rescan
1626 ==========================================================================
1628 VOID
ScanTimeoutAction(
1629 IN PRTMP_ADAPTER pAd
,
1630 IN MLME_QUEUE_ELEM
*Elem
)
1632 pAd
->MlmeAux
.Channel
= NextChannel(pAd
, pAd
->MlmeAux
.Channel
);
1634 // Only one channel scanned for CISCO beacon request
1635 if ((pAd
->MlmeAux
.ScanType
== SCAN_CISCO_ACTIVE
) ||
1636 (pAd
->MlmeAux
.ScanType
== SCAN_CISCO_PASSIVE
) ||
1637 (pAd
->MlmeAux
.ScanType
== SCAN_CISCO_NOISE
) ||
1638 (pAd
->MlmeAux
.ScanType
== SCAN_CISCO_CHANNEL_LOAD
))
1639 pAd
->MlmeAux
.Channel
= 0;
1641 // this routine will stop if pAd->MlmeAux.Channel == 0
1642 ScanNextChannel(pAd
);
1646 ==========================================================================
1648 ==========================================================================
1650 VOID
InvalidStateWhenScan(
1651 IN PRTMP_ADAPTER pAd
,
1652 IN MLME_QUEUE_ELEM
*Elem
)
1655 DBGPRINT(RT_DEBUG_TRACE
, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
));
1656 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1657 Status
= MLME_STATE_MACHINE_REJECT
;
1658 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_SCAN_CONF
, 2, &Status
);
1662 ==========================================================================
1664 ==========================================================================
1666 VOID
InvalidStateWhenJoin(
1667 IN PRTMP_ADAPTER pAd
,
1668 IN MLME_QUEUE_ELEM
*Elem
)
1671 DBGPRINT(RT_DEBUG_TRACE
, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
));
1672 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1673 Status
= MLME_STATE_MACHINE_REJECT
;
1674 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_JOIN_CONF
, 2, &Status
);
1678 ==========================================================================
1680 ==========================================================================
1682 VOID
InvalidStateWhenStart(
1683 IN PRTMP_ADAPTER pAd
,
1684 IN MLME_QUEUE_ELEM
*Elem
)
1687 DBGPRINT(RT_DEBUG_TRACE
, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
));
1688 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1689 Status
= MLME_STATE_MACHINE_REJECT
;
1690 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_START_CONF
, 2, &Status
);
1694 ==========================================================================
1697 IRQL = DISPATCH_LEVEL
1699 ==========================================================================
1702 IN PRTMP_ADAPTER pAd
)
1709 #endif // RALINK_ATE //
1712 if (pAd
->StaCfg
.WindowsPowerMode
== Ndis802_11PowerModeLegacy_PSP
)
1713 pAd
->PsPollFrame
.FC
.PwrMgmt
= PWR_SAVE
;
1714 MiniportMMRequest(pAd
, 0, (PUCHAR
)&pAd
->PsPollFrame
, sizeof(PSPOLL_FRAME
));
1719 ==========================================================================
1721 ==========================================================================
1723 VOID
EnqueueProbeRequest(
1724 IN PRTMP_ADAPTER pAd
)
1729 HEADER_802_11 Hdr80211
;
1731 DBGPRINT(RT_DEBUG_TRACE
, ("force out a ProbeRequest ...\n"));
1733 NState
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
1734 if (NState
== NDIS_STATUS_SUCCESS
)
1736 MgtMacHeaderInit(pAd
, &Hdr80211
, SUBTYPE_PROBE_REQ
, 0, BROADCAST_ADDR
, BROADCAST_ADDR
);
1738 // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
1739 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1740 sizeof(HEADER_802_11
), &Hdr80211
,
1742 1, &pAd
->CommonCfg
.SsidLen
,
1743 pAd
->CommonCfg
.SsidLen
, pAd
->CommonCfg
.Ssid
,
1745 1, &pAd
->StaActive
.SupRateLen
,
1746 pAd
->StaActive
.SupRateLen
, pAd
->StaActive
.SupRate
,
1748 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
1749 MlmeFreeMemory(pAd
, pOutBuffer
);
1754 #ifdef DOT11_N_SUPPORT
1755 #ifdef DOT11N_DRAFT3
1756 VOID
BuildEffectedChannelList(
1757 IN PRTMP_ADAPTER pAd
)
1761 UCHAR UpperChannel
= 0, LowerChannel
= 0;
1763 RTMPZeroMemory(EChannel
, 11);
1765 // Find upper channel and lower channel.
1766 if (pAd
->CommonCfg
.CentralChannel
< pAd
->CommonCfg
.Channel
)
1768 UpperChannel
= pAd
->CommonCfg
.Channel
;
1769 LowerChannel
= pAd
->CommonCfg
.CentralChannel
;
1771 else if (pAd
->CommonCfg
.CentralChannel
> pAd
->CommonCfg
.Channel
)
1773 UpperChannel
= pAd
->CommonCfg
.CentralChannel
;
1774 LowerChannel
= pAd
->CommonCfg
.Channel
;
1781 // Record channels that is below lower channel..
1782 if (LowerChannel
> 1)
1784 EChannel
[0] = LowerChannel
- 1;
1786 if (LowerChannel
> 2)
1788 EChannel
[1] = LowerChannel
- 2;
1790 if (LowerChannel
> 3)
1792 EChannel
[2] = LowerChannel
- 3;
1797 // Record channels that is between lower channel and upper channel.
1798 for (k
= LowerChannel
;k
< UpperChannel
;k
++)
1803 // Record channels that is above upper channel..
1804 if (LowerChannel
< 11)
1806 EChannel
[i
] = UpperChannel
+ 1;
1808 if (LowerChannel
< 10)
1810 EChannel
[i
] = LowerChannel
+ 2;
1812 if (LowerChannel
< 9)
1814 EChannel
[i
] = LowerChannel
+ 3;
1820 for (j
= 0;j
< i
;j
++)
1822 for (k
= 0;k
< pAd
->ChannelListNum
;k
++)
1824 if (pAd
->ChannelList
[k
].Channel
== EChannel
[j
])
1826 pAd
->ChannelList
[k
].bEffectedChannel
= TRUE
;
1827 DBGPRINT(RT_DEBUG_TRACE
,(" EffectedChannel( =%d)\n", EChannel
[j
]));
1833 #endif // DOT11N_DRAFT3 //
1834 #endif // DOT11_N_SUPPORT //
1836 BOOLEAN
ScanRunning(
1837 IN PRTMP_ADAPTER pAd
)
1839 return (pAd
->Mlme
.SyncMachine
.CurrState
== SCAN_LISTEN
) ? TRUE
: FALSE
;