2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 modified for rt2561/2661
36 Jan Lee 2006-08-01 modified for rt2860 for 802.11n
38 #include "../rt_config.h"
40 #define AC0_DEF_TXOP 0
41 #define AC1_DEF_TXOP 0
42 #define AC2_DEF_TXOP 94
43 #define AC3_DEF_TXOP 47
48 // Turn on QOs if use HT rate.
49 if (pAd
->CommonCfg
.APEdcaParm
.bValid
== FALSE
)
51 pAd
->CommonCfg
.APEdcaParm
.bValid
= TRUE
;
52 pAd
->CommonCfg
.APEdcaParm
.Aifsn
[0] = 3;
53 pAd
->CommonCfg
.APEdcaParm
.Aifsn
[1] = 7;
54 pAd
->CommonCfg
.APEdcaParm
.Aifsn
[2] = 1;
55 pAd
->CommonCfg
.APEdcaParm
.Aifsn
[3] = 1;
57 pAd
->CommonCfg
.APEdcaParm
.Cwmin
[0] = 4;
58 pAd
->CommonCfg
.APEdcaParm
.Cwmin
[1] = 4;
59 pAd
->CommonCfg
.APEdcaParm
.Cwmin
[2] = 3;
60 pAd
->CommonCfg
.APEdcaParm
.Cwmin
[3] = 2;
62 pAd
->CommonCfg
.APEdcaParm
.Cwmax
[0] = 10;
63 pAd
->CommonCfg
.APEdcaParm
.Cwmax
[1] = 6;
64 pAd
->CommonCfg
.APEdcaParm
.Cwmax
[2] = 4;
65 pAd
->CommonCfg
.APEdcaParm
.Cwmax
[3] = 3;
67 pAd
->CommonCfg
.APEdcaParm
.Txop
[0] = 0;
68 pAd
->CommonCfg
.APEdcaParm
.Txop
[1] = 0;
69 pAd
->CommonCfg
.APEdcaParm
.Txop
[2] = AC2_DEF_TXOP
;
70 pAd
->CommonCfg
.APEdcaParm
.Txop
[3] = AC3_DEF_TXOP
;
72 AsicSetEdcaParm(pAd
, &pAd
->CommonCfg
.APEdcaParm
);
76 ==========================================================================
78 The sync state machine,
80 Sm - pointer to the state machine
82 the state machine looks like the following
84 ==========================================================================
86 VOID
SyncStateMachineInit(
89 OUT STATE_MACHINE_FUNC Trans
[])
91 StateMachineInit(Sm
, Trans
, MAX_SYNC_STATE
, MAX_SYNC_MSG
, (STATE_MACHINE_FUNC
)Drop
, SYNC_IDLE
, SYNC_MACHINE_BASE
);
94 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_MLME_SCAN_REQ
, (STATE_MACHINE_FUNC
)MlmeScanReqAction
);
95 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_MLME_JOIN_REQ
, (STATE_MACHINE_FUNC
)MlmeJoinReqAction
);
96 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_MLME_START_REQ
, (STATE_MACHINE_FUNC
)MlmeStartReqAction
);
97 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_PEER_BEACON
, (STATE_MACHINE_FUNC
)PeerBeacon
);
98 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_PEER_PROBE_REQ
, (STATE_MACHINE_FUNC
)PeerProbeReqAction
);
101 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_MLME_SCAN_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenScan
);
102 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_MLME_JOIN_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenJoin
);
103 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_MLME_START_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenStart
);
104 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_PEER_BEACON
, (STATE_MACHINE_FUNC
)PeerBeaconAtJoinAction
);
105 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_BEACON_TIMEOUT
, (STATE_MACHINE_FUNC
)BeaconTimeoutAtJoinAction
);
108 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_MLME_SCAN_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenScan
);
109 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_MLME_JOIN_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenJoin
);
110 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_MLME_START_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenStart
);
111 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_PEER_BEACON
, (STATE_MACHINE_FUNC
)PeerBeaconAtScanAction
);
112 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_PEER_PROBE_RSP
, (STATE_MACHINE_FUNC
)PeerBeaconAtScanAction
);
113 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_SCAN_TIMEOUT
, (STATE_MACHINE_FUNC
)ScanTimeoutAction
);
116 RTMPInitTimer(pAd
, &pAd
->MlmeAux
.BeaconTimer
, GET_TIMER_FUNCTION(BeaconTimeout
), pAd
, FALSE
);
117 RTMPInitTimer(pAd
, &pAd
->MlmeAux
.ScanTimer
, GET_TIMER_FUNCTION(ScanTimeout
), pAd
, FALSE
);
121 ==========================================================================
123 Beacon timeout handler, executed in timer thread
125 IRQL = DISPATCH_LEVEL
127 ==========================================================================
130 IN PVOID SystemSpecific1
,
131 IN PVOID FunctionContext
,
132 IN PVOID SystemSpecific2
,
133 IN PVOID SystemSpecific3
)
135 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
137 DBGPRINT(RT_DEBUG_TRACE
,("SYNC - BeaconTimeout\n"));
139 // Do nothing if the driver is starting halt state.
140 // This might happen when timer already been fired before cancel timer with mlmehalt
141 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
))
144 #ifdef DOT11_N_SUPPORT
145 if ((pAd
->CommonCfg
.BBPCurrentBW
== BW_40
)
149 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.CentralChannel
, FALSE
);
150 AsicLockChannel(pAd
, pAd
->CommonCfg
.CentralChannel
);
151 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
154 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
155 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd
->CommonCfg
.CentralChannel
, pAd
->ScanTab
.BssNr
));
157 #endif // DOT11_N_SUPPORT //
159 MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_BEACON_TIMEOUT
, 0, NULL
);
160 RT28XX_MLME_HANDLER(pAd
);
164 ==========================================================================
166 Scan timeout handler, executed in timer thread
168 IRQL = DISPATCH_LEVEL
170 ==========================================================================
173 IN PVOID SystemSpecific1
,
174 IN PVOID FunctionContext
,
175 IN PVOID SystemSpecific2
,
176 IN PVOID SystemSpecific3
)
178 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
181 // Do nothing if the driver is starting halt state.
182 // This might happen when timer already been fired before cancel timer with mlmehalt
183 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
))
186 if (MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_SCAN_TIMEOUT
, 0, NULL
))
188 RT28XX_MLME_HANDLER(pAd
);
192 // To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
193 pAd
->MlmeAux
.Channel
= 0;
194 ScanNextChannel(pAd
);
195 if (pAd
->CommonCfg
.bWirelessEvent
)
197 RTMPSendWirelessEvent(pAd
, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG
, pAd
->MacTab
.Content
[BSSID_WCID
].Addr
, BSS0
, 0);
203 ==========================================================================
205 MLME SCAN req state machine procedure
206 ==========================================================================
208 VOID
MlmeScanReqAction(
209 IN PRTMP_ADAPTER pAd
,
210 IN MLME_QUEUE_ELEM
*Elem
)
212 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
, ScanType
, BssType
, BBPValue
= 0;
213 BOOLEAN TimerCancelled
;
216 PHEADER_802_11 pHdr80211
;
217 PUCHAR pOutBuffer
= NULL
;
220 // Check the total scan tries for one single OID command
221 // If this is the CCX 2.0 Case, skip that!
222 if ( !RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_START_UP
))
224 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - MlmeScanReqAction before Startup\n"));
228 // Increase the scan retry counters.
229 pAd
->StaCfg
.ScanCnt
++;
232 if ((OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
)) &&
234 (pAd
->StaCfg
.bRadio
== TRUE
) &&
235 (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
)))
237 RT28xxPciAsicRadioOn(pAd
, GUI_IDLE_POWER_SAVE
);
241 // first check the parameter sanity
242 if (MlmeScanReqSanity(pAd
,
251 // Check for channel load and noise hist request
252 // Suspend MSDU only at scan request, not the last two mentioned
253 if ((ScanType
== SCAN_CISCO_NOISE
) || (ScanType
== SCAN_CISCO_CHANNEL_LOAD
))
255 if (pAd
->StaCfg
.CCXScanChannel
!= pAd
->CommonCfg
.Channel
)
256 RTMPSuspendMsduTransmission(pAd
); // Suspend MSDU transmission here
260 // Suspend MSDU transmission here
261 RTMPSuspendMsduTransmission(pAd
);
265 // To prevent data lost.
266 // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
267 // And should send an NULL data with turned PSM bit off to AP, when scan progress done
269 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
) && (INFRA_ON(pAd
)))
271 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&pOutBuffer
);
272 if (NStatus
== NDIS_STATUS_SUCCESS
)
274 pHdr80211
= (PHEADER_802_11
) pOutBuffer
;
275 MgtMacHeaderInit(pAd
, pHdr80211
, SUBTYPE_NULL_FUNC
, 1, pAd
->CommonCfg
.Bssid
, pAd
->CommonCfg
.Bssid
);
276 pHdr80211
->Duration
= 0;
277 pHdr80211
->FC
.Type
= BTYPE_DATA
;
278 pHdr80211
->FC
.PwrMgmt
= PWR_SAVE
;
280 // Send using priority queue
281 MiniportMMRequest(pAd
, 0, pOutBuffer
, sizeof(HEADER_802_11
));
282 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
283 MlmeFreeMemory(pAd
, pOutBuffer
);
288 NdisGetSystemUpTime(&Now
);
289 pAd
->StaCfg
.LastScanTime
= Now
;
290 // reset all the timers
291 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
292 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &TimerCancelled
);
294 // record desired BSS parameters
295 pAd
->MlmeAux
.BssType
= BssType
;
296 pAd
->MlmeAux
.ScanType
= ScanType
;
297 pAd
->MlmeAux
.SsidLen
= SsidLen
;
298 NdisZeroMemory(pAd
->MlmeAux
.Ssid
, MAX_LEN_OF_SSID
);
299 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, Ssid
, SsidLen
);
301 // start from the first channel
302 pAd
->MlmeAux
.Channel
= FirstChannel(pAd
);
304 // Change the scan channel when dealing with CCX beacon report
305 if ((ScanType
== SCAN_CISCO_PASSIVE
) || (ScanType
== SCAN_CISCO_ACTIVE
) ||
306 (ScanType
== SCAN_CISCO_CHANNEL_LOAD
) || (ScanType
== SCAN_CISCO_NOISE
))
307 pAd
->MlmeAux
.Channel
= pAd
->StaCfg
.CCXScanChannel
;
309 // Let BBP register at 20MHz to do scan
310 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
312 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
313 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - BBP R4 to 20MHz.l\n"));
314 ScanNextChannel(pAd
);
318 DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
319 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
320 Status
= MLME_INVALID_FORMAT
;
321 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_SCAN_CONF
, 2, &Status
);
326 ==========================================================================
328 MLME JOIN req state machine procedure
329 ==========================================================================
331 VOID
MlmeJoinReqAction(
332 IN PRTMP_ADAPTER pAd
,
333 IN MLME_QUEUE_ELEM
*Elem
)
337 BOOLEAN TimerCancelled
;
338 HEADER_802_11 Hdr80211
;
341 PUCHAR pOutBuffer
= NULL
;
342 PUCHAR pSupRate
= NULL
;
344 PUCHAR pExtRate
= NULL
;
346 UCHAR ASupRate
[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
347 UCHAR ASupRateLen
= sizeof(ASupRate
)/sizeof(UCHAR
);
348 MLME_JOIN_REQ_STRUCT
*pInfo
= (MLME_JOIN_REQ_STRUCT
*)(Elem
->Msg
);
350 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo
->BssIdx
));
353 if ((OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
)) &&
355 (pAd
->StaCfg
.bRadio
== TRUE
) &&
356 (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
)))
358 RT28xxPciAsicRadioOn(pAd
, GUI_IDLE_POWER_SAVE
);
362 // reset all the timers
363 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &TimerCancelled
);
364 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
366 pBss
= &pAd
->MlmeAux
.SsidBssTab
.BssEntry
[pInfo
->BssIdx
];
368 // record the desired SSID & BSSID we're waiting for
369 COPY_MAC_ADDR(pAd
->MlmeAux
.Bssid
, pBss
->Bssid
);
371 // If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
372 if (pBss
->Hidden
== 0)
374 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, pBss
->Ssid
, pBss
->SsidLen
);
375 pAd
->MlmeAux
.SsidLen
= pBss
->SsidLen
;
378 pAd
->MlmeAux
.BssType
= pBss
->BssType
;
379 pAd
->MlmeAux
.Channel
= pBss
->Channel
;
380 pAd
->MlmeAux
.CentralChannel
= pBss
->CentralChannel
;
382 #ifdef EXT_BUILD_CHANNEL_LIST
383 // Country IE of the AP will be evaluated and will be used.
384 if ((pAd
->StaCfg
.IEEE80211dClientMode
!= Rt802_11_D_None
) &&
385 (pBss
->bHasCountryIE
== TRUE
))
387 NdisMoveMemory(&pAd
->CommonCfg
.CountryCode
[0], &pBss
->CountryString
[0], 2);
388 if (pBss
->CountryString
[2] == 'I')
389 pAd
->CommonCfg
.Geography
= IDOR
;
390 else if (pBss
->CountryString
[2] == 'O')
391 pAd
->CommonCfg
.Geography
= ODOR
;
393 pAd
->CommonCfg
.Geography
= BOTH
;
394 BuildChannelListEx(pAd
);
396 #endif // EXT_BUILD_CHANNEL_LIST //
398 // Let BBP register at 20MHz to do scan
399 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
401 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
402 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - BBP R4 to 20MHz.l\n"));
404 // switch channel and waiting for beacon timer
405 AsicSwitchChannel(pAd
, pAd
->MlmeAux
.Channel
, FALSE
);
406 AsicLockChannel(pAd
, pAd
->MlmeAux
.Channel
);
407 RTMPSetTimer(&pAd
->MlmeAux
.BeaconTimer
, JOIN_TIMEOUT
);
411 if (((pAd
->CommonCfg
.bIEEE80211H
== 1) &&
412 (pAd
->MlmeAux
.Channel
> 14) &&
413 RadarChannelCheck(pAd
, pAd
->MlmeAux
.Channel
))
414 #ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
415 || (pAd
->CommonCfg
.CarrierDetect
.Enable
== TRUE
)
416 #endif // CARRIER_DETECTION_SUPPORT //
420 // We can't send any Probe request frame to meet 802.11h.
422 if (pBss
->Hidden
== 0)
427 // send probe request
429 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
);
430 if (NStatus
== NDIS_STATUS_SUCCESS
)
432 if (pAd
->MlmeAux
.Channel
<= 14)
434 pSupRate
= pAd
->CommonCfg
.SupRate
;
435 SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
436 pExtRate
= pAd
->CommonCfg
.ExtRate
;
437 ExtRateLen
= pAd
->CommonCfg
.ExtRateLen
;
442 // Overwrite Support Rate, CCK rate are not allowed
445 SupRateLen
= ASupRateLen
;
449 if (pAd
->MlmeAux
.BssType
== BSS_INFRA
)
450 MgtMacHeaderInit(pAd
, &Hdr80211
, SUBTYPE_PROBE_REQ
, 0, pAd
->MlmeAux
.Bssid
, pAd
->MlmeAux
.Bssid
);
452 MgtMacHeaderInit(pAd
, &Hdr80211
, SUBTYPE_PROBE_REQ
, 0, BROADCAST_ADDR
, BROADCAST_ADDR
);
454 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
455 sizeof(HEADER_802_11
), &Hdr80211
,
457 1, &pAd
->MlmeAux
.SsidLen
,
458 pAd
->MlmeAux
.SsidLen
, pAd
->MlmeAux
.Ssid
,
461 SupRateLen
, pSupRate
,
467 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &Tmp
,
470 ExtRateLen
, pExtRate
,
476 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
477 MlmeFreeMemory(pAd
, pOutBuffer
);
481 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
482 pBss
->Channel
, pBss
->Bssid
[0], pBss
->Bssid
[1], pBss
->Bssid
[2], pBss
->Bssid
[3], pBss
->Bssid
[4], pBss
->Bssid
[5]));
484 pAd
->Mlme
.SyncMachine
.CurrState
= JOIN_WAIT_BEACON
;
488 ==========================================================================
490 MLME START Request state machine procedure, starting an IBSS
491 ==========================================================================
493 VOID
MlmeStartReqAction(
494 IN PRTMP_ADAPTER pAd
,
495 IN MLME_QUEUE_ELEM
*Elem
)
497 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
;
498 BOOLEAN TimerCancelled
;
500 // New for WPA security suites
501 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
502 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
503 LARGE_INTEGER TimeStamp
;
507 // Init Variable IE structure
508 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
510 TimeStamp
.u
.LowPart
= 0;
511 TimeStamp
.u
.HighPart
= 0;
513 if (MlmeStartReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, Ssid
, &SsidLen
))
515 // reset all the timers
516 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &TimerCancelled
);
517 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
520 // Start a new IBSS. All IBSS parameters are decided now....
522 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
523 pAd
->MlmeAux
.BssType
= BSS_ADHOC
;
524 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, Ssid
, SsidLen
);
525 pAd
->MlmeAux
.SsidLen
= SsidLen
;
527 // generate a radom number as BSSID
528 MacAddrRandomBssid(pAd
, pAd
->MlmeAux
.Bssid
);
529 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
531 Privacy
= (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption1Enabled
) ||
532 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) ||
533 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
);
534 pAd
->MlmeAux
.CapabilityInfo
= CAP_GENERATE(0,1,Privacy
, (pAd
->CommonCfg
.TxPreamble
== Rt802_11PreambleShort
), 1, 0);
535 pAd
->MlmeAux
.BeaconPeriod
= pAd
->CommonCfg
.BeaconPeriod
;
536 pAd
->MlmeAux
.AtimWin
= pAd
->StaCfg
.AtimWin
;
537 pAd
->MlmeAux
.Channel
= pAd
->CommonCfg
.Channel
;
539 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
;
540 pAd
->MlmeAux
.CentralChannel
= pAd
->CommonCfg
.CentralChannel
;
542 pAd
->MlmeAux
.SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
543 NdisMoveMemory(pAd
->MlmeAux
.SupRate
, pAd
->CommonCfg
.SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
544 RTMPCheckRates(pAd
, pAd
->MlmeAux
.SupRate
, &pAd
->MlmeAux
.SupRateLen
);
545 pAd
->MlmeAux
.ExtRateLen
= pAd
->CommonCfg
.ExtRateLen
;
546 NdisMoveMemory(pAd
->MlmeAux
.ExtRate
, pAd
->CommonCfg
.ExtRate
, MAX_LEN_OF_SUPPORTED_RATES
);
547 RTMPCheckRates(pAd
, pAd
->MlmeAux
.ExtRate
, &pAd
->MlmeAux
.ExtRateLen
);
548 #ifdef DOT11_N_SUPPORT
549 if (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
551 RTMPUpdateHTIE(&pAd
->CommonCfg
.DesiredHtPhy
, &pAd
->StaCfg
.DesiredHtPhyInfo
.MCSSet
[0], &pAd
->MlmeAux
.HtCapability
, &pAd
->MlmeAux
.AddHtInfo
);
552 pAd
->MlmeAux
.HtCapabilityLen
= sizeof(HT_CAPABILITY_IE
);
553 // Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
554 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
557 #endif // DOT11_N_SUPPORT //
559 pAd
->MlmeAux
.HtCapabilityLen
= 0;
560 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
562 // temporarily not support QOS in IBSS
563 NdisZeroMemory(&pAd
->MlmeAux
.APEdcaParm
, sizeof(EDCA_PARM
));
564 NdisZeroMemory(&pAd
->MlmeAux
.APQbssLoad
, sizeof(QBSS_LOAD_PARM
));
565 NdisZeroMemory(&pAd
->MlmeAux
.APQosCapability
, sizeof(QOS_CAPABILITY_PARM
));
567 AsicSwitchChannel(pAd
, pAd
->MlmeAux
.Channel
, FALSE
);
568 AsicLockChannel(pAd
, pAd
->MlmeAux
.Channel
);
570 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
571 pAd
->MlmeAux
.Channel
, pAd
->MlmeAux
.SupRateLen
, pAd
->MlmeAux
.ExtRateLen
));
573 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
574 Status
= MLME_SUCCESS
;
575 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_START_CONF
, 2, &Status
);
579 DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
580 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
581 Status
= MLME_INVALID_FORMAT
;
582 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_START_CONF
, 2, &Status
);
587 ==========================================================================
589 peer sends beacon back when scanning
590 ==========================================================================
592 VOID
PeerBeaconAtScanAction(
593 IN PRTMP_ADAPTER pAd
,
594 IN MLME_QUEUE_ELEM
*Elem
)
596 UCHAR Bssid
[MAC_ADDR_LEN
], Addr2
[MAC_ADDR_LEN
];
597 UCHAR Ssid
[MAX_LEN_OF_SSID
], BssType
, Channel
, NewChannel
,
598 SsidLen
, DtimCount
, DtimPeriod
, BcastFlag
, MessageToMe
;
600 USHORT BeaconPeriod
, AtimWin
, CapabilityInfo
;
601 PFRAME_802_11 pFrame
;
602 LARGE_INTEGER TimeStamp
;
604 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
605 UCHAR SupRateLen
, ExtRateLen
;
608 UCHAR AironetCellPowerLimit
;
610 QBSS_LOAD_PARM QbssLoad
;
611 QOS_CAPABILITY_PARM QosCapability
;
613 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
614 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
615 HT_CAPABILITY_IE HtCapability
;
616 ADD_HT_INFO_IE AddHtInfo
; // AP might use this additional ht info IE
617 UCHAR HtCapabilityLen
= 0, PreNHtCapabilityLen
= 0;
619 UCHAR NewExtChannelOffset
= 0xff;
621 pFrame
= (PFRAME_802_11
) Elem
->Msg
;
622 // Init Variable IE structure
623 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
625 #ifdef DOT11_N_SUPPORT
626 RTMPZeroMemory(&HtCapability
, sizeof(HtCapability
));
627 RTMPZeroMemory(&AddHtInfo
, sizeof(ADD_HT_INFO_IE
));
628 #endif // DOT11_N_SUPPORT //
630 if (PeerBeaconAndProbeRspSanity(pAd
,
656 &AironetCellPowerLimit
,
662 &PreNHtCapabilityLen
,
666 &NewExtChannelOffset
,
673 Idx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
674 if (Idx
!= BSS_NOT_FOUND
)
675 Rssi
= pAd
->ScanTab
.BssEntry
[Idx
].Rssi
;
677 Rssi
= RTMPMaxRssi(pAd
, ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
), ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
), ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
));
680 #ifdef DOT11_N_SUPPORT
681 if ((HtCapabilityLen
> 0) || (PreNHtCapabilityLen
> 0))
682 HtCapabilityLen
= SIZE_HT_CAP_IE
;
683 #endif // DOT11_N_SUPPORT //
684 if ((pAd
->StaCfg
.CCXReqType
!= MSRN_TYPE_UNUSED
) && (Channel
== pAd
->StaCfg
.CCXScanChannel
))
686 Idx
= BssTableSetEntry(pAd
, &pAd
->StaCfg
.CCXBssTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
687 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
,ExtRate
, ExtRateLen
, &HtCapability
,
688 &AddHtInfo
, HtCapabilityLen
, AddHtInfoLen
, NewExtChannelOffset
, Channel
, Rssi
, TimeStamp
, CkipFlag
,
689 &EdcaParm
, &QosCapability
, &QbssLoad
, LenVIE
, pVIE
);
690 if (Idx
!= BSS_NOT_FOUND
)
692 NdisMoveMemory(pAd
->StaCfg
.CCXBssTab
.BssEntry
[Idx
].PTSF
, &Elem
->Msg
[24], 4);
693 NdisMoveMemory(&pAd
->StaCfg
.CCXBssTab
.BssEntry
[Idx
].TTSF
[0], &Elem
->TimeStamp
.u
.LowPart
, 4);
694 NdisMoveMemory(&pAd
->StaCfg
.CCXBssTab
.BssEntry
[Idx
].TTSF
[4], &Elem
->TimeStamp
.u
.LowPart
, 4);
695 if (pAd
->StaCfg
.CCXReqType
== MSRN_TYPE_BEACON_REQ
)
696 AironetAddBeaconReport(pAd
, Idx
, Elem
);
701 Idx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
702 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
, &HtCapability
,
703 &AddHtInfo
, HtCapabilityLen
, AddHtInfoLen
, NewExtChannelOffset
, Channel
, Rssi
, TimeStamp
, CkipFlag
,
704 &EdcaParm
, &QosCapability
, &QbssLoad
, LenVIE
, pVIE
);
705 #ifdef DOT11_N_SUPPORT
707 if (pAd
->ChannelList
[pAd
->CommonCfg
.ChannelListIdx
].bEffectedChannel
== TRUE
)
710 PeerBeaconAndProbeRspSanity2(pAd
, Elem
->Msg
, Elem
->MsgLen
, &RegClass
);
711 TriEventTableSetEntry(pAd
, &pAd
->CommonCfg
.TriggerEventTab
, Bssid
, &HtCapability
, HtCapabilityLen
, RegClass
, Channel
);
713 #endif // DOT11N_DRAFT3 //
714 #endif // DOT11_N_SUPPORT //
715 if (Idx
!= BSS_NOT_FOUND
)
717 NdisMoveMemory(pAd
->ScanTab
.BssEntry
[Idx
].PTSF
, &Elem
->Msg
[24], 4);
718 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Idx
].TTSF
[0], &Elem
->TimeStamp
.u
.LowPart
, 4);
719 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Idx
].TTSF
[4], &Elem
->TimeStamp
.u
.LowPart
, 4);
723 // sanity check fail, ignored
727 ==========================================================================
729 When waiting joining the (I)BSS, beacon received from external
730 ==========================================================================
732 VOID
PeerBeaconAtJoinAction(
733 IN PRTMP_ADAPTER pAd
,
734 IN MLME_QUEUE_ELEM
*Elem
)
736 UCHAR Bssid
[MAC_ADDR_LEN
], Addr2
[MAC_ADDR_LEN
];
737 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
, BssType
, Channel
, MessageToMe
,
738 DtimCount
, DtimPeriod
, BcastFlag
, NewChannel
;
739 LARGE_INTEGER TimeStamp
;
740 USHORT BeaconPeriod
, AtimWin
, CapabilityInfo
;
742 BOOLEAN TimerCancelled
;
744 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
745 UCHAR SupRateLen
, ExtRateLen
;
748 UCHAR AironetCellPowerLimit
;
750 QBSS_LOAD_PARM QbssLoad
;
751 QOS_CAPABILITY_PARM QosCapability
;
753 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
754 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
757 HT_CAPABILITY_IE HtCapability
;
758 ADD_HT_INFO_IE AddHtInfo
; // AP might use this additional ht info IE
759 UCHAR HtCapabilityLen
= 0, PreNHtCapabilityLen
= 0;
761 UCHAR NewExtChannelOffset
= 0xff;
762 #ifdef DOT11_N_SUPPORT
763 UCHAR CentralChannel
;
764 #endif // DOT11_N_SUPPORT //
766 // Init Variable IE structure
767 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
769 RTMPZeroMemory(&HtCapability
, sizeof(HtCapability
));
770 RTMPZeroMemory(&AddHtInfo
, sizeof(ADD_HT_INFO_IE
));
773 if (PeerBeaconAndProbeRspSanity(pAd
,
799 &AironetCellPowerLimit
,
805 &PreNHtCapabilityLen
,
809 &NewExtChannelOffset
,
813 // Disqualify 11b only adhoc when we are in 11g only adhoc mode
814 if ((BssType
== BSS_ADHOC
) && (pAd
->CommonCfg
.PhyMode
== PHY_11G
) && ((SupRateLen
+ExtRateLen
)< 12))
817 // BEACON from desired BSS/IBSS found. We should be able to decide most
818 // BSS parameters here.
819 // Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
820 // Do we need to receover back all parameters belonging to previous BSS?
821 // A. Should be not. There's no back-door recover to previous AP. It still need
822 // a new JOIN-AUTH-ASSOC sequence.
823 if (MAC_ADDR_EQUAL(pAd
->MlmeAux
.Bssid
, Bssid
))
825 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel
));
826 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
828 // Update RSSI to prevent No signal display when cards first initialized
829 pAd
->StaCfg
.RssiSample
.LastRssi0
= ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
);
830 pAd
->StaCfg
.RssiSample
.LastRssi1
= ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
);
831 pAd
->StaCfg
.RssiSample
.LastRssi2
= ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
);
832 pAd
->StaCfg
.RssiSample
.AvgRssi0
= pAd
->StaCfg
.RssiSample
.LastRssi0
;
833 pAd
->StaCfg
.RssiSample
.AvgRssi0X8
= pAd
->StaCfg
.RssiSample
.AvgRssi0
<< 3;
834 pAd
->StaCfg
.RssiSample
.AvgRssi1
= pAd
->StaCfg
.RssiSample
.LastRssi1
;
835 pAd
->StaCfg
.RssiSample
.AvgRssi1X8
= pAd
->StaCfg
.RssiSample
.AvgRssi1
<< 3;
836 pAd
->StaCfg
.RssiSample
.AvgRssi2
= pAd
->StaCfg
.RssiSample
.LastRssi2
;
837 pAd
->StaCfg
.RssiSample
.AvgRssi2X8
= pAd
->StaCfg
.RssiSample
.AvgRssi2
<< 3;
840 // We need to check if SSID only set to any, then we can record the current SSID.
841 // Otherwise will cause hidden SSID association failed.
843 if (pAd
->MlmeAux
.SsidLen
== 0)
845 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, Ssid
, SsidLen
);
846 pAd
->MlmeAux
.SsidLen
= SsidLen
;
850 Idx
= BssSsidTableSearch(&pAd
->ScanTab
, Bssid
, pAd
->MlmeAux
.Ssid
, pAd
->MlmeAux
.SsidLen
, Channel
);
852 if (Idx
!= BSS_NOT_FOUND
)
855 // Multiple SSID case, used correct CapabilityInfo
857 CapabilityInfo
= pAd
->ScanTab
.BssEntry
[Idx
].CapabilityInfo
;
860 NdisMoveMemory(pAd
->MlmeAux
.Bssid
, Bssid
, MAC_ADDR_LEN
);
861 pAd
->MlmeAux
.CapabilityInfo
= CapabilityInfo
& SUPPORTED_CAPABILITY_INFO
;
862 pAd
->MlmeAux
.BssType
= BssType
;
863 pAd
->MlmeAux
.BeaconPeriod
= BeaconPeriod
;
864 pAd
->MlmeAux
.Channel
= Channel
;
865 pAd
->MlmeAux
.AtimWin
= AtimWin
;
866 pAd
->MlmeAux
.CfpPeriod
= Cf
.CfpPeriod
;
867 pAd
->MlmeAux
.CfpMaxDuration
= Cf
.CfpMaxDuration
;
868 pAd
->MlmeAux
.APRalinkIe
= RalinkIe
;
870 // Copy AP's supported rate to MlmeAux for creating assoication request
871 // Also filter out not supported rate
872 pAd
->MlmeAux
.SupRateLen
= SupRateLen
;
873 NdisMoveMemory(pAd
->MlmeAux
.SupRate
, SupRate
, SupRateLen
);
874 RTMPCheckRates(pAd
, pAd
->MlmeAux
.SupRate
, &pAd
->MlmeAux
.SupRateLen
);
875 pAd
->MlmeAux
.ExtRateLen
= ExtRateLen
;
876 NdisMoveMemory(pAd
->MlmeAux
.ExtRate
, ExtRate
, ExtRateLen
);
877 RTMPCheckRates(pAd
, pAd
->MlmeAux
.ExtRate
, &pAd
->MlmeAux
.ExtRateLen
);
879 NdisZeroMemory(pAd
->StaActive
.SupportedPhyInfo
.MCSSet
, 16);
880 #ifdef DOT11_N_SUPPORT
881 pAd
->MlmeAux
.NewExtChannelOffset
= NewExtChannelOffset
;
882 pAd
->MlmeAux
.HtCapabilityLen
= HtCapabilityLen
;
884 // filter out un-supported ht rates
885 if (((HtCapabilityLen
> 0) || (PreNHtCapabilityLen
> 0)) && (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
887 RTMPZeroMemory(&pAd
->MlmeAux
.HtCapability
, SIZE_HT_CAP_IE
);
888 RTMPMoveMemory(&pAd
->MlmeAux
.AddHtInfo
, &AddHtInfo
, SIZE_ADD_HT_INFO_IE
);
890 // StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
891 NdisMoveMemory(pAd
->StaActive
.SupportedPhyInfo
.MCSSet
, HtCapability
.MCSSet
, 16);
892 pAd
->MlmeAux
.NewExtChannelOffset
= NewExtChannelOffset
;
893 pAd
->MlmeAux
.HtCapabilityLen
= SIZE_HT_CAP_IE
;
894 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= TRUE
;
895 if (PreNHtCapabilityLen
> 0)
896 pAd
->StaActive
.SupportedPhyInfo
.bPreNHt
= TRUE
;
897 RTMPCheckHt(pAd
, BSSID_WCID
, &HtCapability
, &AddHtInfo
);
898 // Copy AP Parameter to StaActive. This is also in LinkUp.
899 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
900 pAd
->StaActive
.SupportedHtPhy
.MpduDensity
, pAd
->StaActive
.SupportedHtPhy
.MaxRAmpduFactor
, HtCapability
.HtCapInfo
.ChannelWidth
));
902 if (AddHtInfoLen
> 0)
904 CentralChannel
= AddHtInfo
.ControlChan
;
905 // Check again the Bandwidth capability of this AP.
906 if ((AddHtInfo
.ControlChan
> 2)&& (AddHtInfo
.AddHtInfo
.ExtChanOffset
== EXTCHA_BELOW
) && (HtCapability
.HtCapInfo
.ChannelWidth
== BW_40
))
908 CentralChannel
= AddHtInfo
.ControlChan
- 2;
910 else if ((AddHtInfo
.AddHtInfo
.ExtChanOffset
== EXTCHA_ABOVE
) && (HtCapability
.HtCapInfo
.ChannelWidth
== BW_40
))
912 CentralChannel
= AddHtInfo
.ControlChan
+ 2;
916 if (pAd
->MlmeAux
.CentralChannel
!= CentralChannel
)
917 DBGPRINT(RT_DEBUG_ERROR
, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel
, AddHtInfo
.ControlChan
, pAd
->MlmeAux
.CentralChannel
));
919 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel
, AddHtInfo
.ControlChan
));
925 #endif // DOT11_N_SUPPORT //
927 // To prevent error, let legacy AP must have same CentralChannel and Channel.
928 if ((HtCapabilityLen
== 0) && (PreNHtCapabilityLen
== 0))
929 pAd
->MlmeAux
.CentralChannel
= pAd
->MlmeAux
.Channel
;
931 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
932 RTMPZeroMemory(&pAd
->MlmeAux
.HtCapability
, SIZE_HT_CAP_IE
);
933 RTMPZeroMemory(&pAd
->MlmeAux
.AddHtInfo
, SIZE_ADD_HT_INFO_IE
);
936 RTMPUpdateMlmeRate(pAd
);
938 // copy QOS related information
939 if ((pAd
->CommonCfg
.bWmmCapable
)
940 #ifdef DOT11_N_SUPPORT
941 || (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
942 #endif // DOT11_N_SUPPORT //
945 NdisMoveMemory(&pAd
->MlmeAux
.APEdcaParm
, &EdcaParm
, sizeof(EDCA_PARM
));
946 NdisMoveMemory(&pAd
->MlmeAux
.APQbssLoad
, &QbssLoad
, sizeof(QBSS_LOAD_PARM
));
947 NdisMoveMemory(&pAd
->MlmeAux
.APQosCapability
, &QosCapability
, sizeof(QOS_CAPABILITY_PARM
));
951 NdisZeroMemory(&pAd
->MlmeAux
.APEdcaParm
, sizeof(EDCA_PARM
));
952 NdisZeroMemory(&pAd
->MlmeAux
.APQbssLoad
, sizeof(QBSS_LOAD_PARM
));
953 NdisZeroMemory(&pAd
->MlmeAux
.APQosCapability
, sizeof(QOS_CAPABILITY_PARM
));
956 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
957 pAd
->MlmeAux
.SupRateLen
, pAd
->MlmeAux
.ExtRateLen
));
961 pAd
->StaCfg
.CkipFlag
= CkipFlag
;
963 // Keep TimeStamp for Re-Association used.
964 if (LEAP_CCKM_ON(pAd
) && (pAd
->StaCfg
.CCKMLinkUpFlag
== TRUE
))
965 pAd
->StaCfg
.CCKMBeaconAtJoinTimeStamp
= TimeStamp
;
966 #endif // LEAP_SUPPORT //
968 if (AironetCellPowerLimit
!= 0xFF)
970 //We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
971 ChangeToCellPowerLimit(pAd
, AironetCellPowerLimit
);
973 else //Used the default TX Power Percentage.
974 pAd
->CommonCfg
.TxPowerPercentage
= pAd
->CommonCfg
.TxPowerDefault
;
976 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
977 Status
= MLME_SUCCESS
;
978 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_JOIN_CONF
, 2, &Status
);
980 // not to me BEACON, ignored
982 // sanity check fail, ignore this frame
986 ==========================================================================
988 receive BEACON from peer
990 IRQL = DISPATCH_LEVEL
992 ==========================================================================
995 IN PRTMP_ADAPTER pAd
,
996 IN MLME_QUEUE_ELEM
*Elem
)
998 UCHAR Bssid
[MAC_ADDR_LEN
], Addr2
[MAC_ADDR_LEN
];
999 CHAR Ssid
[MAX_LEN_OF_SSID
];
1001 UCHAR SsidLen
, MessageToMe
=0, BssType
, Channel
, NewChannel
, index
=0;
1002 UCHAR DtimCount
=0, DtimPeriod
=0, BcastFlag
=0;
1003 USHORT CapabilityInfo
, AtimWin
, BeaconPeriod
;
1004 LARGE_INTEGER TimeStamp
;
1005 USHORT TbttNumToNextWakeUp
;
1007 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
1008 UCHAR SupRateLen
, ExtRateLen
;
1011 UCHAR AironetCellPowerLimit
;
1013 QBSS_LOAD_PARM QbssLoad
;
1014 QOS_CAPABILITY_PARM QosCapability
;
1016 // New for WPA security suites
1017 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
1018 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
1019 HT_CAPABILITY_IE HtCapability
;
1020 ADD_HT_INFO_IE AddHtInfo
; // AP might use this additional ht info IE
1021 UCHAR HtCapabilityLen
, PreNHtCapabilityLen
;
1023 UCHAR NewExtChannelOffset
= 0xff;
1031 #endif // RALINK_ATE //
1033 if (!(INFRA_ON(pAd
) || ADHOC_ON(pAd
)
1037 // Init Variable IE structure
1038 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
1040 RTMPZeroMemory(&HtCapability
, sizeof(HtCapability
));
1041 RTMPZeroMemory(&AddHtInfo
, sizeof(ADD_HT_INFO_IE
));
1043 if (PeerBeaconAndProbeRspSanity(pAd
,
1069 &AironetCellPowerLimit
,
1075 &PreNHtCapabilityLen
,
1079 &NewExtChannelOffset
,
1083 BOOLEAN is_my_bssid
, is_my_ssid
;
1086 CHAR RealRssi
= RTMPMaxRssi(pAd
, ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
), ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
), ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
));
1088 is_my_bssid
= MAC_ADDR_EQUAL(Bssid
, pAd
->CommonCfg
.Bssid
)? TRUE
: FALSE
;
1089 is_my_ssid
= SSID_EQUAL(Ssid
, SsidLen
, pAd
->CommonCfg
.Ssid
, pAd
->CommonCfg
.SsidLen
)? TRUE
:FALSE
;
1092 // ignore BEACON not for my SSID
1093 if ((! is_my_ssid
) && (! is_my_bssid
))
1096 // It means STA waits disassoc completely from this AP, ignores this beacon.
1097 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_WAIT_DISASSOC
)
1100 #ifdef DOT11_N_SUPPORT
1101 // Copy Control channel for this BSSID.
1102 if (AddHtInfoLen
!= 0)
1103 Channel
= AddHtInfo
.ControlChan
;
1105 if ((HtCapabilityLen
> 0) || (PreNHtCapabilityLen
> 0))
1106 HtCapabilityLen
= SIZE_HT_CAP_IE
;
1107 #endif // DOT11_N_SUPPORT //
1110 // Housekeeping "SsidBssTab" table for later-on ROAMing usage.
1112 Bssidx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
1113 if (Bssidx
== BSS_NOT_FOUND
)
1115 // discover new AP of this network, create BSS entry
1116 Bssidx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
1117 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,
1118 &HtCapability
, &AddHtInfo
,HtCapabilityLen
,AddHtInfoLen
,NewExtChannelOffset
, Channel
,
1119 RealRssi
, TimeStamp
, CkipFlag
, &EdcaParm
, &QosCapability
,
1120 &QbssLoad
, LenVIE
, pVIE
);
1121 if (Bssidx
== BSS_NOT_FOUND
) // return if BSS table full
1124 NdisMoveMemory(pAd
->ScanTab
.BssEntry
[Bssidx
].PTSF
, &Elem
->Msg
[24], 4);
1125 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Bssidx
].TTSF
[0], &Elem
->TimeStamp
.u
.LowPart
, 4);
1126 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Bssidx
].TTSF
[4], &Elem
->TimeStamp
.u
.LowPart
, 4);
1132 if ((pAd
->CommonCfg
.bIEEE80211H
== 1) && (NewChannel
!= 0) && (Channel
!= NewChannel
))
1134 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1135 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1136 AsicSwitchChannel(pAd
, 1, FALSE
);
1137 AsicLockChannel(pAd
, 1);
1138 LinkDown(pAd
, FALSE
);
1139 MlmeQueueInit(&pAd
->Mlme
.Queue
);
1140 BssTableInit(&pAd
->ScanTab
);
1141 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1143 // channel sanity check
1144 for (index
= 0 ; index
< pAd
->ChannelListNum
; index
++)
1146 if (pAd
->ChannelList
[index
].Channel
== NewChannel
)
1148 pAd
->ScanTab
.BssEntry
[Bssidx
].Channel
= NewChannel
;
1149 pAd
->CommonCfg
.Channel
= NewChannel
;
1150 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.Channel
, FALSE
);
1151 AsicLockChannel(pAd
, pAd
->CommonCfg
.Channel
);
1152 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel
));
1157 if (index
>= pAd
->ChannelListNum
)
1159 DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd
->CommonCfg
.Channel
, pAd
->ChannelListNum
));
1163 // if the ssid matched & bssid unmatched, we should select the bssid with large value.
1164 // This might happened when two STA start at the same time
1165 if ((! is_my_bssid
) && ADHOC_ON(pAd
))
1169 // Add the safeguard against the mismatch of adhoc wep status
1170 if (pAd
->StaCfg
.WepStatus
!= pAd
->ScanTab
.BssEntry
[Bssidx
].WepStatus
)
1175 // collapse into the ADHOC network which has bigger BSSID value.
1176 for (i
= 0; i
< 6; i
++)
1178 if (Bssid
[i
] > pAd
->CommonCfg
.Bssid
[i
])
1180 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
1181 Bssid
[0], Bssid
[1], Bssid
[2], Bssid
[3], Bssid
[4], Bssid
[5]));
1182 AsicDisableSync(pAd
);
1183 COPY_MAC_ADDR(pAd
->CommonCfg
.Bssid
, Bssid
);
1184 AsicSetBssid(pAd
, pAd
->CommonCfg
.Bssid
);
1185 MakeIbssBeacon(pAd
); // re-build BEACON frame
1186 AsicEnableIbssSync(pAd
); // copy BEACON frame to on-chip memory
1190 else if (Bssid
[i
] < pAd
->CommonCfg
.Bssid
[i
])
1196 NdisGetSystemUpTime(&Now
);
1197 pBss
= &pAd
->ScanTab
.BssEntry
[Bssidx
];
1198 pBss
->Rssi
= RealRssi
; // lastest RSSI
1199 pBss
->LastBeaconRxTime
= Now
; // last RX timestamp
1202 // BEACON from my BSSID - either IBSS or INFRA network
1208 pAd
->StaCfg
.DtimCount
= DtimCount
;
1209 pAd
->StaCfg
.DtimPeriod
= DtimPeriod
;
1210 pAd
->StaCfg
.LastBeaconRxTime
= Now
;
1213 RxWI
.RSSI0
= Elem
->Rssi0
;
1214 RxWI
.RSSI1
= Elem
->Rssi1
;
1215 RxWI
.RSSI2
= Elem
->Rssi2
;
1217 Update_Rssi_Sample(pAd
, &pAd
->StaCfg
.RssiSample
, &RxWI
);
1218 if (AironetCellPowerLimit
!= 0xFF)
1221 // We get the Cisco (ccx) "TxPower Limit" required
1222 // Changed to appropriate TxPower Limit for Ciso Compatible Extensions
1224 ChangeToCellPowerLimit(pAd
, AironetCellPowerLimit
);
1229 // AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
1230 // Used the default TX Power Percentage, that set from UI.
1232 pAd
->CommonCfg
.TxPowerPercentage
= pAd
->CommonCfg
.TxPowerDefault
;
1235 // at least one 11b peer joined. downgrade the MaxTxRate to 11Mbps
1236 // after last 11b peer left for several seconds, we'll auto switch back to 11G rate
1237 // in MlmePeriodicExec()
1238 if (ADHOC_ON(pAd
) && (CAP_IS_IBSS_ON(CapabilityInfo
)))
1248 if ((SupRateLen
+ExtRateLen
<= 4) && (pAd
->CommonCfg
.MaxTxRate
> RATE_11
))
1250 if (pAd
->StaCfg
.AdhocBOnlyJoined
== FALSE
)
1252 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - 11b peer joined. down-grade to 11b TX rates \n"));
1254 NdisMoveMemory(pAd
->StaActive
.SupRate
, SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1255 pAd
->StaActive
.SupRateLen
= SupRateLen
;
1256 NdisMoveMemory(pAd
->StaActive
.ExtRate
, ExtRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1257 pAd
->StaActive
.ExtRateLen
= ExtRateLen
;
1258 pAd
->StaCfg
.AdhocBOnlyJoined
= TRUE
;
1259 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
1260 AsicSetEdcaParm(pAd
, NULL
);
1263 // this timestamp is for MlmePeriodicExec() to check if all 11B peers have left
1264 pAd
->StaCfg
.Last11bBeaconRxTime
= Now
;
1267 #ifdef DOT11_N_SUPPORT
1269 if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
1271 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
) &&
1272 !pAd
->StaCfg
.AdhocBGJoined
&&
1273 !pAd
->StaCfg
.AdhocBOnlyJoined
)
1274 AdhocTurnOnQos(pAd
);
1276 // Handle rate switch issue when Adhoc mode
1277 if ((SupRateLen
+ExtRateLen
>= 8) && (HtCapability
.MCSSet
[0] == 0) && (HtCapability
.MCSSet
[1] == 0))
1279 if (pAd
->StaCfg
.AdhocBGJoined
== FALSE
)
1281 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - 11g peer joined. down-grade to 11g TX rates \n"));
1283 NdisMoveMemory(pAd
->StaActive
.SupRate
, SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1284 pAd
->StaActive
.SupRateLen
= SupRateLen
;
1285 NdisMoveMemory(pAd
->StaActive
.ExtRate
, ExtRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1286 pAd
->StaActive
.ExtRateLen
= ExtRateLen
;
1287 pAd
->StaCfg
.AdhocBGJoined
= TRUE
;
1288 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
1289 AsicSetEdcaParm(pAd
, NULL
);
1292 // this timestamp is for MlmePeriodicExec() to check if all 11g peers have left
1293 pAd
->StaCfg
.Last11gBeaconRxTime
= Now
;
1296 else if (!pAd
->StaCfg
.AdhocBGJoined
&&
1297 !pAd
->StaCfg
.AdhocBOnlyJoined
&&
1298 (pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
== BW_40
) &&
1299 (HtCapability
.HtCapInfo
.ChannelWidth
== BW_20
))
1301 if (pAd
->StaCfg
.Adhoc20NJoined
== FALSE
)
1303 UCHAR ByteValue
= 0;
1305 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
;
1307 pAd
->StaCfg
.Adhoc20NJoined
= TRUE
;
1308 NdisMoveMemory(&pAd
->MlmeAux
.HtCapability
, &HtCapability
, SIZE_HT_CAP_IE
);
1309 if (AddHtInfoLen
!= 0)
1310 NdisMoveMemory(&pAd
->MlmeAux
.AddHtInfo
, &AddHtInfo
, AddHtInfoLen
);
1311 NdisMoveMemory(pAd
->StaActive
.SupportedPhyInfo
.MCSSet
, HtCapability
.MCSSet
, 16);
1313 RTMPCheckHt(pAd
, Elem
->Wcid
, &pAd
->MlmeAux
.HtCapability
, &pAd
->MlmeAux
.AddHtInfo
);
1314 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd
);
1315 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= TRUE
;
1319 // this timestamp is for MlmePeriodicExec() to check if all 20MHz N peers have left
1320 pAd
->StaCfg
.Last20NBeaconRxTime
= Now
;
1325 #endif // DOT11_N_SUPPORT //
1327 RTMPZeroMemory(&pAd
->MlmeAux
.HtCapability
, SIZE_HT_CAP_IE
);
1328 RTMPZeroMemory(&pAd
->MlmeAux
.AddHtInfo
, SIZE_ADD_HT_INFO_IE
);
1332 // If peer Adhoc is legacy mode, I don't need to call MlmeUpdateHtTxRates no matter I support HT or not
1333 if ((bRestart
== TRUE
) && (bnRestart
== FALSE
))
1335 MlmeUpdateTxRates(pAd
, FALSE
, 0);
1336 MakeIbssBeacon(pAd
); // re-build BEACON frame
1337 AsicEnableIbssSync(pAd
); // copy to on-chip memory
1339 #ifdef DOT11_N_SUPPORT
1340 else if ((bRestart
== TRUE
) && (bnRestart
== TRUE
))
1342 MlmeUpdateTxRates(pAd
, FALSE
, BSS0
);
1343 MlmeUpdateHtTxRates(pAd
, BSS0
);
1344 MakeIbssBeacon(pAd
); // re-build BEACON frame
1345 AsicEnableIbssSync(pAd
); // copy to on-chip memory
1347 #endif // DOT11_N_SUPPORT //
1349 // At least another peer in this IBSS, declare MediaState as CONNECTED
1350 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1352 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
);
1354 pAd
->IndicateMediaState
= NdisMediaStateConnected
;
1355 RTMP_IndicateMediaState(pAd
);
1356 pAd
->ExtraInfo
= GENERAL_LINK_UP
;
1357 AsicSetBssid(pAd
, pAd
->CommonCfg
.Bssid
);
1359 // 2003/03/12 - john
1360 // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
1361 // "site survey" result should always include the current connected network.
1363 Bssidx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
1364 if (Bssidx
== BSS_NOT_FOUND
)
1366 Bssidx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
1367 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
, &HtCapability
,
1368 &AddHtInfo
, HtCapabilityLen
, AddHtInfoLen
, NewExtChannelOffset
, Channel
, RealRssi
, TimeStamp
, 0,
1369 &EdcaParm
, &QosCapability
, &QbssLoad
, LenVIE
, pVIE
);
1371 DBGPRINT(RT_DEBUG_TRACE
, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1374 // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
1375 // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
1376 if (ADHOC_ON(pAd
) && (Elem
->Wcid
== RESERVED_WCID
))
1379 MAC_TABLE_ENTRY
*pEntry
;
1381 // look up the existing table
1382 pEntry
= MacTableLookup(pAd
, Addr2
);
1385 // Another adhoc joining, add to our MAC table.
1386 pEntry
= MacTableInsertEntry(pAd
, Addr2
, BSS0
, FALSE
);
1389 pEntry
->Sst
= SST_ASSOC
;
1390 idx
= pAd
->StaCfg
.DefaultKeyId
;
1391 // After InsertEntry, Write to ASIC on-chip table.
1392 RT28XX_STA_SECURITY_INFO_ADD(pAd
, BSS0
, idx
, pEntry
);
1393 DBGPRINT(RT_DEBUG_TRACE
, ("ADHOC %x:%x:%x:%x:%x:%x join in.Entry=%d\n", Addr2
[0],Addr2
[1],Addr2
[2],Addr2
[3],Addr2
[4],Addr2
[5], pEntry
->Aid
));
1395 pEntry
->HTPhyMode
.word
= pAd
->StaCfg
.HTPhyMode
.word
;
1396 if (HtCapabilityLen
<= 0)
1398 pEntry
->HTPhyMode
.field
.STBC
= 0;
1399 pEntry
->HTPhyMode
.field
.BW
= 0;
1400 pEntry
->HTPhyMode
.field
.ShortGI
= 0;
1401 if ((SupRateLen
+ExtRateLen
<= 4) && (pAd
->CommonCfg
.Channel
<= 14))
1403 pEntry
->HTPhyMode
.field
.MODE
= MODE_CCK
;
1407 pEntry
->HTPhyMode
.field
.MODE
= MODE_OFDM
;
1409 MlmeUpdateTxRates(pAd
, FALSE
, 0);
1411 #ifdef DOT11_N_SUPPORT
1414 MlmeUpdateTxRates(pAd
, FALSE
, 0);
1415 MlmeUpdateHtTxRates(pAd
, BSS0
);
1417 #endif // DOT11_N_SUPPORT //
1419 #ifdef WPA_SUPPLICANT_SUPPORT
1420 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1421 if (pAd
->StaCfg
.WpaSupplicantUP
)
1423 union iwreq_data wrqu
;
1425 SendAssocIEsToWpaSupplicant(pAd
);
1426 memset(&wrqu
, 0, sizeof(wrqu
));
1427 wrqu
.data
.flags
= RT_ASSOC_EVENT_FLAG
;
1428 wireless_send_event(pAd
->net_dev
, IWEVCUSTOM
, &wrqu
, NULL
);
1430 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1431 #endif // WPA_SUPPLICANT_SUPPORT //
1433 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1435 union iwreq_data wrqu
;
1436 wext_notify_event_assoc(pAd
);
1438 memset(wrqu
.ap_addr
.sa_data
, 0, MAC_ADDR_LEN
);
1439 memcpy(wrqu
.ap_addr
.sa_data
, pAd
->MlmeAux
.Bssid
, MAC_ADDR_LEN
);
1440 wireless_send_event(pAd
->net_dev
, SIOCGIWAP
, &wrqu
, NULL
);
1443 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1451 BOOLEAN bUseShortSlot
, bUseBGProtection
;
1453 // decide to use/change to -
1454 // 1. long slot (20 us) or short slot (9 us) time
1455 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1456 // 3. short preamble
1458 //bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
1459 bUseShortSlot
= CAP_IS_SHORT_SLOT(CapabilityInfo
);
1460 if (bUseShortSlot
!= OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_SHORT_SLOT_INUSED
))
1461 AsicSetSlotTime(pAd
, bUseShortSlot
);
1463 bUseBGProtection
= (pAd
->CommonCfg
.UseBGProtection
== 1) || // always use
1464 ((pAd
->CommonCfg
.UseBGProtection
== 0) && ERP_IS_USE_PROTECTION(Erp
));
1466 if (pAd
->CommonCfg
.Channel
> 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
1467 bUseBGProtection
= FALSE
;
1469 if (bUseBGProtection
!= OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
))
1471 if (bUseBGProtection
)
1473 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
);
1474 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, (OFDMSETPROTECT
|CCKSETPROTECT
|ALLN_SETPROTECT
),FALSE
,(pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
== 1));
1478 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
);
1479 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, (OFDMSETPROTECT
|CCKSETPROTECT
|ALLN_SETPROTECT
),TRUE
,(pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
== 1));
1482 DBGPRINT(RT_DEBUG_WARN
, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection
));
1485 #ifdef DOT11_N_SUPPORT
1486 // check Ht protection mode. and adhere to the Non-GF device indication by AP.
1487 if ((AddHtInfoLen
!= 0) &&
1488 ((AddHtInfo
.AddHtInfo2
.OperaionMode
!= pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
) ||
1489 (AddHtInfo
.AddHtInfo2
.NonGfPresent
!= pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
)))
1491 pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
= AddHtInfo
.AddHtInfo2
.NonGfPresent
;
1492 pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
= AddHtInfo
.AddHtInfo2
.OperaionMode
;
1493 if (pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
== 1)
1495 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, FALSE
, TRUE
);
1498 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, FALSE
, FALSE
);
1500 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - AP changed N OperaionMode to %d\n", pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
));
1502 #endif // DOT11_N_SUPPORT //
1504 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_SHORT_PREAMBLE_INUSED
) &&
1505 ERP_IS_USE_BARKER_PREAMBLE(Erp
))
1507 MlmeSetTxPreamble(pAd
, Rt802_11PreambleLong
);
1508 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - AP forced to use LONG preamble\n"));
1511 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_WMM_INUSED
) &&
1512 (EdcaParm
.bValid
== TRUE
) &&
1513 (EdcaParm
.EdcaUpdateCount
!= pAd
->CommonCfg
.APEdcaParm
.EdcaUpdateCount
))
1515 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1516 pAd
->CommonCfg
.APEdcaParm
.EdcaUpdateCount
,
1517 EdcaParm
.EdcaUpdateCount
));
1518 AsicSetEdcaParm(pAd
, &EdcaParm
);
1521 // copy QOS related information
1522 NdisMoveMemory(&pAd
->CommonCfg
.APQbssLoad
, &QbssLoad
, sizeof(QBSS_LOAD_PARM
));
1523 NdisMoveMemory(&pAd
->CommonCfg
.APQosCapability
, &QosCapability
, sizeof(QOS_CAPABILITY_PARM
));
1526 // only INFRASTRUCTURE mode support power-saving feature
1527 if ((INFRA_ON(pAd
) && (pAd
->StaCfg
.Psm
== PWR_SAVE
)) || (pAd
->CommonCfg
.bAPSDForcePowerSave
))
1530 // 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
1531 // 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
1532 // 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
1533 // 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
1534 // 5. otherwise, put PHY back to sleep to save battery.
1538 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
))
1540 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, pAd
->StaCfg
.BBPR3
);
1541 // Turn clk to 80Mhz.
1544 if (pAd
->CommonCfg
.bAPSDCapable
&& pAd
->CommonCfg
.APEdcaParm
.bAPSDCapable
&&
1545 pAd
->CommonCfg
.bAPSDAC_BE
&& pAd
->CommonCfg
.bAPSDAC_BK
&& pAd
->CommonCfg
.bAPSDAC_VI
&& pAd
->CommonCfg
.bAPSDAC_VO
)
1547 pAd
->CommonCfg
.bNeedSendTriggerFrame
= TRUE
;
1550 RT28XX_PS_POLL_ENQUEUE(pAd
);
1552 else if (BcastFlag
&& (DtimCount
== 0) && OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_RECEIVE_DTIM
))
1555 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
))
1557 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, pAd
->StaCfg
.BBPR3
);
1561 else if ((pAd
->TxSwQueue
[QID_AC_BK
].Number
!= 0) ||
1562 (pAd
->TxSwQueue
[QID_AC_BE
].Number
!= 0) ||
1563 (pAd
->TxSwQueue
[QID_AC_VI
].Number
!= 0) ||
1564 (pAd
->TxSwQueue
[QID_AC_VO
].Number
!= 0) ||
1565 (RTMPFreeTXDRequest(pAd
, QID_AC_BK
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1566 (RTMPFreeTXDRequest(pAd
, QID_AC_BE
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1567 (RTMPFreeTXDRequest(pAd
, QID_AC_VI
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1568 (RTMPFreeTXDRequest(pAd
, QID_AC_VO
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1569 (RTMPFreeTXDRequest(pAd
, QID_MGMT
, MGMT_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
))
1571 // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
1572 // can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
1574 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
))
1576 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, pAd
->StaCfg
.BBPR3
);
1582 USHORT NextDtim
= DtimCount
;
1585 NextDtim
= DtimPeriod
;
1587 TbttNumToNextWakeUp
= pAd
->StaCfg
.DefaultListenCount
;
1588 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_RECEIVE_DTIM
) && (TbttNumToNextWakeUp
> NextDtim
))
1589 TbttNumToNextWakeUp
= NextDtim
;
1591 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
))
1593 AsicSleepThenAutoWakeup(pAd
, TbttNumToNextWakeUp
);
1598 // not my BSSID, ignore it
1600 // sanity check fail, ignore this frame
1604 ==========================================================================
1606 Receive PROBE REQ from remote peer when operating in IBSS mode
1607 ==========================================================================
1609 VOID
PeerProbeReqAction(
1610 IN PRTMP_ADAPTER pAd
,
1611 IN MLME_QUEUE_ELEM
*Elem
)
1613 UCHAR Addr2
[MAC_ADDR_LEN
];
1614 CHAR Ssid
[MAX_LEN_OF_SSID
];
1616 #ifdef DOT11_N_SUPPORT
1617 UCHAR HtLen
, AddHtLen
, NewExtLen
;
1618 #endif // DOT11_N_SUPPORT //
1619 HEADER_802_11 ProbeRspHdr
;
1620 NDIS_STATUS NStatus
;
1621 PUCHAR pOutBuffer
= NULL
;
1623 LARGE_INTEGER FakeTimestamp
;
1624 UCHAR DsLen
= 1, IbssLen
= 2;
1625 UCHAR LocalErpIe
[3] = {IE_ERP
, 1, 0};
1627 USHORT CapabilityInfo
;
1628 UCHAR RSNIe
= IE_WPA
;
1630 if (! ADHOC_ON(pAd
))
1633 if (PeerProbeReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, Addr2
, Ssid
, &SsidLen
))
1635 if ((SsidLen
== 0) || SSID_EQUAL(Ssid
, SsidLen
, pAd
->CommonCfg
.Ssid
, pAd
->CommonCfg
.SsidLen
))
1637 // allocate and send out ProbeRsp frame
1638 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
1639 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1642 //pAd->StaCfg.AtimWin = 0; // ??????
1644 Privacy
= (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption1Enabled
) ||
1645 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) ||
1646 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
);
1647 CapabilityInfo
= CAP_GENERATE(0, 1, Privacy
, (pAd
->CommonCfg
.TxPreamble
== Rt802_11PreambleShort
), 0, 0);
1649 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1650 sizeof(HEADER_802_11
), &ProbeRspHdr
,
1651 TIMESTAMP_LEN
, &FakeTimestamp
,
1652 2, &pAd
->CommonCfg
.BeaconPeriod
,
1655 1, &pAd
->CommonCfg
.SsidLen
,
1656 pAd
->CommonCfg
.SsidLen
, pAd
->CommonCfg
.Ssid
,
1658 1, &pAd
->StaActive
.SupRateLen
,
1659 pAd
->StaActive
.SupRateLen
, pAd
->StaActive
.SupRate
,
1662 1, &pAd
->CommonCfg
.Channel
,
1665 2, &pAd
->StaActive
.AtimWin
,
1668 if (pAd
->StaActive
.ExtRateLen
)
1671 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
1674 1, &pAd
->StaActive
.ExtRateLen
,
1675 pAd
->StaActive
.ExtRateLen
, &pAd
->StaActive
.ExtRate
,
1680 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1681 if (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPANone
)
1684 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
1686 1, &pAd
->StaCfg
.RSNIE_Len
,
1687 pAd
->StaCfg
.RSNIE_Len
, pAd
->StaCfg
.RSN_IE
,
1691 #ifdef DOT11_N_SUPPORT
1692 if (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
1695 UCHAR BROADCOM
[4] = {0x0, 0x90, 0x4c, 0x33};
1696 HtLen
= sizeof(pAd
->CommonCfg
.HtCapability
);
1697 AddHtLen
= sizeof(pAd
->CommonCfg
.AddHTInfo
);
1699 //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
1700 if (pAd
->bBroadComHT
== TRUE
)
1702 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &TmpLen
,
1705 pAd
->MlmeAux
.HtCapabilityLen
, &pAd
->MlmeAux
.HtCapability
,
1710 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &TmpLen
,
1713 sizeof(HT_CAPABILITY_IE
), &pAd
->CommonCfg
.HtCapability
,
1716 sizeof(ADD_HT_INFO_IE
), &pAd
->CommonCfg
.AddHTInfo
,
1719 sizeof(NEW_EXT_CHAN_IE
), &pAd
->CommonCfg
.NewExtChanOffset
,
1724 #endif // DOT11_N_SUPPORT //
1725 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
1726 MlmeFreeMemory(pAd
, pOutBuffer
);
1731 VOID
BeaconTimeoutAtJoinAction(
1732 IN PRTMP_ADAPTER pAd
,
1733 IN MLME_QUEUE_ELEM
*Elem
)
1736 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1737 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1738 Status
= MLME_REJ_TIMEOUT
;
1739 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_JOIN_CONF
, 2, &Status
);
1743 ==========================================================================
1745 Scan timeout procedure. basically add channel index by 1 and rescan
1746 ==========================================================================
1748 VOID
ScanTimeoutAction(
1749 IN PRTMP_ADAPTER pAd
,
1750 IN MLME_QUEUE_ELEM
*Elem
)
1752 pAd
->MlmeAux
.Channel
= NextChannel(pAd
, pAd
->MlmeAux
.Channel
);
1754 // Only one channel scanned for CISCO beacon request
1755 if ((pAd
->MlmeAux
.ScanType
== SCAN_CISCO_ACTIVE
) ||
1756 (pAd
->MlmeAux
.ScanType
== SCAN_CISCO_PASSIVE
) ||
1757 (pAd
->MlmeAux
.ScanType
== SCAN_CISCO_NOISE
) ||
1758 (pAd
->MlmeAux
.ScanType
== SCAN_CISCO_CHANNEL_LOAD
))
1759 pAd
->MlmeAux
.Channel
= 0;
1761 // this routine will stop if pAd->MlmeAux.Channel == 0
1762 ScanNextChannel(pAd
);
1766 ==========================================================================
1768 ==========================================================================
1770 VOID
InvalidStateWhenScan(
1771 IN PRTMP_ADAPTER pAd
,
1772 IN MLME_QUEUE_ELEM
*Elem
)
1775 DBGPRINT(RT_DEBUG_TRACE
, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
));
1776 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1777 Status
= MLME_STATE_MACHINE_REJECT
;
1778 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_SCAN_CONF
, 2, &Status
);
1782 ==========================================================================
1784 ==========================================================================
1786 VOID
InvalidStateWhenJoin(
1787 IN PRTMP_ADAPTER pAd
,
1788 IN MLME_QUEUE_ELEM
*Elem
)
1791 DBGPRINT(RT_DEBUG_TRACE
, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
));
1792 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1793 Status
= MLME_STATE_MACHINE_REJECT
;
1794 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_JOIN_CONF
, 2, &Status
);
1798 ==========================================================================
1800 ==========================================================================
1802 VOID
InvalidStateWhenStart(
1803 IN PRTMP_ADAPTER pAd
,
1804 IN MLME_QUEUE_ELEM
*Elem
)
1807 DBGPRINT(RT_DEBUG_TRACE
, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
));
1808 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1809 Status
= MLME_STATE_MACHINE_REJECT
;
1810 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_START_CONF
, 2, &Status
);
1814 ==========================================================================
1817 IRQL = DISPATCH_LEVEL
1819 ==========================================================================
1822 IN PRTMP_ADAPTER pAd
)
1829 #endif // RALINK_ATE //
1832 if (pAd
->StaCfg
.WindowsPowerMode
== Ndis802_11PowerModeLegacy_PSP
)
1833 pAd
->PsPollFrame
.FC
.PwrMgmt
= PWR_SAVE
;
1834 MiniportMMRequest(pAd
, 0, (PUCHAR
)&pAd
->PsPollFrame
, sizeof(PSPOLL_FRAME
));
1839 ==========================================================================
1841 ==========================================================================
1843 VOID
EnqueueProbeRequest(
1844 IN PRTMP_ADAPTER pAd
)
1849 HEADER_802_11 Hdr80211
;
1851 DBGPRINT(RT_DEBUG_TRACE
, ("force out a ProbeRequest ...\n"));
1853 NState
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
1854 if (NState
== NDIS_STATUS_SUCCESS
)
1856 MgtMacHeaderInit(pAd
, &Hdr80211
, SUBTYPE_PROBE_REQ
, 0, BROADCAST_ADDR
, BROADCAST_ADDR
);
1858 // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
1859 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1860 sizeof(HEADER_802_11
), &Hdr80211
,
1862 1, &pAd
->CommonCfg
.SsidLen
,
1863 pAd
->CommonCfg
.SsidLen
, pAd
->CommonCfg
.Ssid
,
1865 1, &pAd
->StaActive
.SupRateLen
,
1866 pAd
->StaActive
.SupRateLen
, pAd
->StaActive
.SupRate
,
1868 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
1869 MlmeFreeMemory(pAd
, pOutBuffer
);
1874 #ifdef DOT11_N_SUPPORT
1875 #ifdef DOT11N_DRAFT3
1876 VOID
BuildEffectedChannelList(
1877 IN PRTMP_ADAPTER pAd
)
1881 UCHAR UpperChannel
= 0, LowerChannel
= 0;
1883 RTMPZeroMemory(EChannel
, 11);
1885 // Find upper channel and lower channel.
1886 if (pAd
->CommonCfg
.CentralChannel
< pAd
->CommonCfg
.Channel
)
1888 UpperChannel
= pAd
->CommonCfg
.Channel
;
1889 LowerChannel
= pAd
->CommonCfg
.CentralChannel
;
1891 else if (pAd
->CommonCfg
.CentralChannel
> pAd
->CommonCfg
.Channel
)
1893 UpperChannel
= pAd
->CommonCfg
.CentralChannel
;
1894 LowerChannel
= pAd
->CommonCfg
.Channel
;
1901 // Record channels that is below lower channel..
1902 if (LowerChannel
> 1)
1904 EChannel
[0] = LowerChannel
- 1;
1906 if (LowerChannel
> 2)
1908 EChannel
[1] = LowerChannel
- 2;
1910 if (LowerChannel
> 3)
1912 EChannel
[2] = LowerChannel
- 3;
1917 // Record channels that is between lower channel and upper channel.
1918 for (k
= LowerChannel
;k
< UpperChannel
;k
++)
1923 // Record channels that is above upper channel..
1924 if (LowerChannel
< 11)
1926 EChannel
[i
] = UpperChannel
+ 1;
1928 if (LowerChannel
< 10)
1930 EChannel
[i
] = LowerChannel
+ 2;
1932 if (LowerChannel
< 9)
1934 EChannel
[i
] = LowerChannel
+ 3;
1940 for (j
= 0;j
< i
;j
++)
1942 for (k
= 0;k
< pAd
->ChannelListNum
;k
++)
1944 if (pAd
->ChannelList
[k
].Channel
== EChannel
[j
])
1946 pAd
->ChannelList
[k
].bEffectedChannel
= TRUE
;
1947 DBGPRINT(RT_DEBUG_TRACE
,(" EffectedChannel( =%d)\n", EChannel
[j
]));
1953 #endif // DOT11N_DRAFT3 //
1954 #endif // DOT11_N_SUPPORT //
1956 BOOLEAN
ScanRunning(
1957 IN PRTMP_ADAPTER pAd
)
1959 return (pAd
->Mlme
.SyncMachine
.CurrState
== SCAN_LISTEN
) ? TRUE
: FALSE
;