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 if ((pAd
->CommonCfg
.BBPCurrentBW
== BW_40
)
148 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.CentralChannel
, FALSE
);
149 AsicLockChannel(pAd
, pAd
->CommonCfg
.CentralChannel
);
150 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
153 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
154 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd
->CommonCfg
.CentralChannel
, pAd
->ScanTab
.BssNr
));
157 MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_BEACON_TIMEOUT
, 0, NULL
);
158 RT28XX_MLME_HANDLER(pAd
);
162 ==========================================================================
164 Scan timeout handler, executed in timer thread
166 IRQL = DISPATCH_LEVEL
168 ==========================================================================
171 IN PVOID SystemSpecific1
,
172 IN PVOID FunctionContext
,
173 IN PVOID SystemSpecific2
,
174 IN PVOID SystemSpecific3
)
176 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
179 // Do nothing if the driver is starting halt state.
180 // This might happen when timer already been fired before cancel timer with mlmehalt
181 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
))
184 if (MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_SCAN_TIMEOUT
, 0, NULL
))
186 RT28XX_MLME_HANDLER(pAd
);
190 // To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
191 pAd
->MlmeAux
.Channel
= 0;
192 ScanNextChannel(pAd
);
193 if (pAd
->CommonCfg
.bWirelessEvent
)
195 RTMPSendWirelessEvent(pAd
, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG
, pAd
->MacTab
.Content
[BSSID_WCID
].Addr
, BSS0
, 0);
201 ==========================================================================
203 MLME SCAN req state machine procedure
204 ==========================================================================
206 VOID
MlmeScanReqAction(
207 IN PRTMP_ADAPTER pAd
,
208 IN MLME_QUEUE_ELEM
*Elem
)
210 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
, ScanType
, BssType
, BBPValue
= 0;
211 BOOLEAN TimerCancelled
;
214 PHEADER_802_11 pHdr80211
;
215 PUCHAR pOutBuffer
= NULL
;
218 // Check the total scan tries for one single OID command
219 // If this is the CCX 2.0 Case, skip that!
220 if ( !RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_START_UP
))
222 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - MlmeScanReqAction before Startup\n"));
226 // Increase the scan retry counters.
227 pAd
->StaCfg
.ScanCnt
++;
229 if ((OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
)) &&
231 (pAd
->StaCfg
.bRadio
== TRUE
) &&
232 (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
)))
234 RT28xxPciAsicRadioOn(pAd
, GUI_IDLE_POWER_SAVE
);
237 // first check the parameter sanity
238 if (MlmeScanReqSanity(pAd
,
247 // Check for channel load and noise hist request
248 // Suspend MSDU only at scan request, not the last two mentioned
249 if ((ScanType
== SCAN_CISCO_NOISE
) || (ScanType
== SCAN_CISCO_CHANNEL_LOAD
))
251 if (pAd
->StaCfg
.CCXScanChannel
!= pAd
->CommonCfg
.Channel
)
252 RTMPSuspendMsduTransmission(pAd
); // Suspend MSDU transmission here
256 // Suspend MSDU transmission here
257 RTMPSuspendMsduTransmission(pAd
);
261 // To prevent data lost.
262 // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
263 // And should send an NULL data with turned PSM bit off to AP, when scan progress done
265 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
) && (INFRA_ON(pAd
)))
267 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&pOutBuffer
);
268 if (NStatus
== NDIS_STATUS_SUCCESS
)
270 pHdr80211
= (PHEADER_802_11
) pOutBuffer
;
271 MgtMacHeaderInit(pAd
, pHdr80211
, SUBTYPE_NULL_FUNC
, 1, pAd
->CommonCfg
.Bssid
, pAd
->CommonCfg
.Bssid
);
272 pHdr80211
->Duration
= 0;
273 pHdr80211
->FC
.Type
= BTYPE_DATA
;
274 pHdr80211
->FC
.PwrMgmt
= PWR_SAVE
;
276 // Send using priority queue
277 MiniportMMRequest(pAd
, 0, pOutBuffer
, sizeof(HEADER_802_11
));
278 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
279 MlmeFreeMemory(pAd
, pOutBuffer
);
284 NdisGetSystemUpTime(&Now
);
285 pAd
->StaCfg
.LastScanTime
= Now
;
286 // reset all the timers
287 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
288 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &TimerCancelled
);
290 // record desired BSS parameters
291 pAd
->MlmeAux
.BssType
= BssType
;
292 pAd
->MlmeAux
.ScanType
= ScanType
;
293 pAd
->MlmeAux
.SsidLen
= SsidLen
;
294 NdisZeroMemory(pAd
->MlmeAux
.Ssid
, MAX_LEN_OF_SSID
);
295 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, Ssid
, SsidLen
);
297 // start from the first channel
298 pAd
->MlmeAux
.Channel
= FirstChannel(pAd
);
300 // Change the scan channel when dealing with CCX beacon report
301 if ((ScanType
== SCAN_CISCO_PASSIVE
) || (ScanType
== SCAN_CISCO_ACTIVE
) ||
302 (ScanType
== SCAN_CISCO_CHANNEL_LOAD
) || (ScanType
== SCAN_CISCO_NOISE
))
303 pAd
->MlmeAux
.Channel
= pAd
->StaCfg
.CCXScanChannel
;
305 // Let BBP register at 20MHz to do scan
306 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
308 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
309 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - BBP R4 to 20MHz.l\n"));
310 ScanNextChannel(pAd
);
314 DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
315 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
316 Status
= MLME_INVALID_FORMAT
;
317 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_SCAN_CONF
, 2, &Status
);
322 ==========================================================================
324 MLME JOIN req state machine procedure
325 ==========================================================================
327 VOID
MlmeJoinReqAction(
328 IN PRTMP_ADAPTER pAd
,
329 IN MLME_QUEUE_ELEM
*Elem
)
333 BOOLEAN TimerCancelled
;
334 HEADER_802_11 Hdr80211
;
337 PUCHAR pOutBuffer
= NULL
;
338 PUCHAR pSupRate
= NULL
;
340 PUCHAR pExtRate
= NULL
;
342 UCHAR ASupRate
[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
343 UCHAR ASupRateLen
= sizeof(ASupRate
)/sizeof(UCHAR
);
344 MLME_JOIN_REQ_STRUCT
*pInfo
= (MLME_JOIN_REQ_STRUCT
*)(Elem
->Msg
);
346 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo
->BssIdx
));
348 if ((OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
)) &&
350 (pAd
->StaCfg
.bRadio
== TRUE
) &&
351 (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
)))
353 RT28xxPciAsicRadioOn(pAd
, GUI_IDLE_POWER_SAVE
);
356 // reset all the timers
357 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &TimerCancelled
);
358 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
360 pBss
= &pAd
->MlmeAux
.SsidBssTab
.BssEntry
[pInfo
->BssIdx
];
362 // record the desired SSID & BSSID we're waiting for
363 COPY_MAC_ADDR(pAd
->MlmeAux
.Bssid
, pBss
->Bssid
);
365 // If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
366 if (pBss
->Hidden
== 0)
368 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, pBss
->Ssid
, pBss
->SsidLen
);
369 pAd
->MlmeAux
.SsidLen
= pBss
->SsidLen
;
372 pAd
->MlmeAux
.BssType
= pBss
->BssType
;
373 pAd
->MlmeAux
.Channel
= pBss
->Channel
;
374 pAd
->MlmeAux
.CentralChannel
= pBss
->CentralChannel
;
376 // Let BBP register at 20MHz to do scan
377 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
379 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
380 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - BBP R4 to 20MHz.l\n"));
382 // switch channel and waiting for beacon timer
383 AsicSwitchChannel(pAd
, pAd
->MlmeAux
.Channel
, FALSE
);
384 AsicLockChannel(pAd
, pAd
->MlmeAux
.Channel
);
385 RTMPSetTimer(&pAd
->MlmeAux
.BeaconTimer
, JOIN_TIMEOUT
);
389 if (((pAd
->CommonCfg
.bIEEE80211H
== 1) &&
390 (pAd
->MlmeAux
.Channel
> 14) &&
391 RadarChannelCheck(pAd
, pAd
->MlmeAux
.Channel
))
395 // We can't send any Probe request frame to meet 802.11h.
397 if (pBss
->Hidden
== 0)
402 // send probe request
404 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
);
405 if (NStatus
== NDIS_STATUS_SUCCESS
)
407 if (pAd
->MlmeAux
.Channel
<= 14)
409 pSupRate
= pAd
->CommonCfg
.SupRate
;
410 SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
411 pExtRate
= pAd
->CommonCfg
.ExtRate
;
412 ExtRateLen
= pAd
->CommonCfg
.ExtRateLen
;
417 // Overwrite Support Rate, CCK rate are not allowed
420 SupRateLen
= ASupRateLen
;
424 if (pAd
->MlmeAux
.BssType
== BSS_INFRA
)
425 MgtMacHeaderInit(pAd
, &Hdr80211
, SUBTYPE_PROBE_REQ
, 0, pAd
->MlmeAux
.Bssid
, pAd
->MlmeAux
.Bssid
);
427 MgtMacHeaderInit(pAd
, &Hdr80211
, SUBTYPE_PROBE_REQ
, 0, BROADCAST_ADDR
, BROADCAST_ADDR
);
429 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
430 sizeof(HEADER_802_11
), &Hdr80211
,
432 1, &pAd
->MlmeAux
.SsidLen
,
433 pAd
->MlmeAux
.SsidLen
, pAd
->MlmeAux
.Ssid
,
436 SupRateLen
, pSupRate
,
442 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &Tmp
,
445 ExtRateLen
, pExtRate
,
451 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
452 MlmeFreeMemory(pAd
, pOutBuffer
);
456 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
457 pBss
->Channel
, pBss
->Bssid
[0], pBss
->Bssid
[1], pBss
->Bssid
[2], pBss
->Bssid
[3], pBss
->Bssid
[4], pBss
->Bssid
[5]));
459 pAd
->Mlme
.SyncMachine
.CurrState
= JOIN_WAIT_BEACON
;
463 ==========================================================================
465 MLME START Request state machine procedure, starting an IBSS
466 ==========================================================================
468 VOID
MlmeStartReqAction(
469 IN PRTMP_ADAPTER pAd
,
470 IN MLME_QUEUE_ELEM
*Elem
)
472 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
;
473 BOOLEAN TimerCancelled
;
475 // New for WPA security suites
476 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
477 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
478 LARGE_INTEGER TimeStamp
;
482 // Init Variable IE structure
483 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
485 TimeStamp
.u
.LowPart
= 0;
486 TimeStamp
.u
.HighPart
= 0;
488 if (MlmeStartReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, Ssid
, &SsidLen
))
490 // reset all the timers
491 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &TimerCancelled
);
492 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
495 // Start a new IBSS. All IBSS parameters are decided now....
497 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
498 pAd
->MlmeAux
.BssType
= BSS_ADHOC
;
499 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, Ssid
, SsidLen
);
500 pAd
->MlmeAux
.SsidLen
= SsidLen
;
502 // generate a radom number as BSSID
503 MacAddrRandomBssid(pAd
, pAd
->MlmeAux
.Bssid
);
504 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
506 Privacy
= (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption1Enabled
) ||
507 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) ||
508 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
);
509 pAd
->MlmeAux
.CapabilityInfo
= CAP_GENERATE(0,1,Privacy
, (pAd
->CommonCfg
.TxPreamble
== Rt802_11PreambleShort
), 1, 0);
510 pAd
->MlmeAux
.BeaconPeriod
= pAd
->CommonCfg
.BeaconPeriod
;
511 pAd
->MlmeAux
.AtimWin
= pAd
->StaCfg
.AtimWin
;
512 pAd
->MlmeAux
.Channel
= pAd
->CommonCfg
.Channel
;
514 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
;
515 pAd
->MlmeAux
.CentralChannel
= pAd
->CommonCfg
.CentralChannel
;
517 pAd
->MlmeAux
.SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
518 NdisMoveMemory(pAd
->MlmeAux
.SupRate
, pAd
->CommonCfg
.SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
519 RTMPCheckRates(pAd
, pAd
->MlmeAux
.SupRate
, &pAd
->MlmeAux
.SupRateLen
);
520 pAd
->MlmeAux
.ExtRateLen
= pAd
->CommonCfg
.ExtRateLen
;
521 NdisMoveMemory(pAd
->MlmeAux
.ExtRate
, pAd
->CommonCfg
.ExtRate
, MAX_LEN_OF_SUPPORTED_RATES
);
522 RTMPCheckRates(pAd
, pAd
->MlmeAux
.ExtRate
, &pAd
->MlmeAux
.ExtRateLen
);
524 if (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
526 RTMPUpdateHTIE(&pAd
->CommonCfg
.DesiredHtPhy
, &pAd
->StaCfg
.DesiredHtPhyInfo
.MCSSet
[0], &pAd
->MlmeAux
.HtCapability
, &pAd
->MlmeAux
.AddHtInfo
);
527 pAd
->MlmeAux
.HtCapabilityLen
= sizeof(HT_CAPABILITY_IE
);
528 // Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
529 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
533 pAd
->MlmeAux
.HtCapabilityLen
= 0;
534 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
536 // temporarily not support QOS in IBSS
537 NdisZeroMemory(&pAd
->MlmeAux
.APEdcaParm
, sizeof(EDCA_PARM
));
538 NdisZeroMemory(&pAd
->MlmeAux
.APQbssLoad
, sizeof(QBSS_LOAD_PARM
));
539 NdisZeroMemory(&pAd
->MlmeAux
.APQosCapability
, sizeof(QOS_CAPABILITY_PARM
));
541 AsicSwitchChannel(pAd
, pAd
->MlmeAux
.Channel
, FALSE
);
542 AsicLockChannel(pAd
, pAd
->MlmeAux
.Channel
);
544 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
545 pAd
->MlmeAux
.Channel
, pAd
->MlmeAux
.SupRateLen
, pAd
->MlmeAux
.ExtRateLen
));
547 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
548 Status
= MLME_SUCCESS
;
549 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_START_CONF
, 2, &Status
);
553 DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
554 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
555 Status
= MLME_INVALID_FORMAT
;
556 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_START_CONF
, 2, &Status
);
561 ==========================================================================
563 peer sends beacon back when scanning
564 ==========================================================================
566 VOID
PeerBeaconAtScanAction(
567 IN PRTMP_ADAPTER pAd
,
568 IN MLME_QUEUE_ELEM
*Elem
)
570 UCHAR Bssid
[MAC_ADDR_LEN
], Addr2
[MAC_ADDR_LEN
];
571 UCHAR Ssid
[MAX_LEN_OF_SSID
], BssType
, Channel
, NewChannel
,
572 SsidLen
, DtimCount
, DtimPeriod
, BcastFlag
, MessageToMe
;
574 USHORT BeaconPeriod
, AtimWin
, CapabilityInfo
;
575 PFRAME_802_11 pFrame
;
576 LARGE_INTEGER TimeStamp
;
578 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
579 UCHAR SupRateLen
, ExtRateLen
;
582 UCHAR AironetCellPowerLimit
;
584 QBSS_LOAD_PARM QbssLoad
;
585 QOS_CAPABILITY_PARM QosCapability
;
587 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
588 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
589 HT_CAPABILITY_IE HtCapability
;
590 ADD_HT_INFO_IE AddHtInfo
; // AP might use this additional ht info IE
591 UCHAR HtCapabilityLen
= 0, PreNHtCapabilityLen
= 0;
593 UCHAR NewExtChannelOffset
= 0xff;
595 pFrame
= (PFRAME_802_11
) Elem
->Msg
;
596 // Init Variable IE structure
597 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
600 RTMPZeroMemory(&HtCapability
, sizeof(HtCapability
));
601 RTMPZeroMemory(&AddHtInfo
, sizeof(ADD_HT_INFO_IE
));
603 if (PeerBeaconAndProbeRspSanity(pAd
,
629 &AironetCellPowerLimit
,
635 &PreNHtCapabilityLen
,
639 &NewExtChannelOffset
,
646 Idx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
647 if (Idx
!= BSS_NOT_FOUND
)
648 Rssi
= pAd
->ScanTab
.BssEntry
[Idx
].Rssi
;
650 Rssi
= RTMPMaxRssi(pAd
, ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
), ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
), ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
));
652 if ((HtCapabilityLen
> 0) || (PreNHtCapabilityLen
> 0))
653 HtCapabilityLen
= SIZE_HT_CAP_IE
;
655 if ((pAd
->StaCfg
.CCXReqType
!= MSRN_TYPE_UNUSED
) && (Channel
== pAd
->StaCfg
.CCXScanChannel
))
657 Idx
= BssTableSetEntry(pAd
, &pAd
->StaCfg
.CCXBssTab
, Bssid
, 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 if (Idx
!= BSS_NOT_FOUND
)
663 NdisMoveMemory(pAd
->StaCfg
.CCXBssTab
.BssEntry
[Idx
].PTSF
, &Elem
->Msg
[24], 4);
664 NdisMoveMemory(&pAd
->StaCfg
.CCXBssTab
.BssEntry
[Idx
].TTSF
[0], &Elem
->TimeStamp
.u
.LowPart
, 4);
665 NdisMoveMemory(&pAd
->StaCfg
.CCXBssTab
.BssEntry
[Idx
].TTSF
[4], &Elem
->TimeStamp
.u
.LowPart
, 4);
666 if (pAd
->StaCfg
.CCXReqType
== MSRN_TYPE_BEACON_REQ
)
667 AironetAddBeaconReport(pAd
, Idx
, Elem
);
672 Idx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
673 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
, &HtCapability
,
674 &AddHtInfo
, HtCapabilityLen
, AddHtInfoLen
, NewExtChannelOffset
, Channel
, Rssi
, TimeStamp
, CkipFlag
,
675 &EdcaParm
, &QosCapability
, &QbssLoad
, LenVIE
, pVIE
);
677 if (Idx
!= BSS_NOT_FOUND
)
679 NdisMoveMemory(pAd
->ScanTab
.BssEntry
[Idx
].PTSF
, &Elem
->Msg
[24], 4);
680 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Idx
].TTSF
[0], &Elem
->TimeStamp
.u
.LowPart
, 4);
681 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Idx
].TTSF
[4], &Elem
->TimeStamp
.u
.LowPart
, 4);
685 // sanity check fail, ignored
689 ==========================================================================
691 When waiting joining the (I)BSS, beacon received from external
692 ==========================================================================
694 VOID
PeerBeaconAtJoinAction(
695 IN PRTMP_ADAPTER pAd
,
696 IN MLME_QUEUE_ELEM
*Elem
)
698 UCHAR Bssid
[MAC_ADDR_LEN
], Addr2
[MAC_ADDR_LEN
];
699 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
, BssType
, Channel
, MessageToMe
,
700 DtimCount
, DtimPeriod
, BcastFlag
, NewChannel
;
701 LARGE_INTEGER TimeStamp
;
702 USHORT BeaconPeriod
, AtimWin
, CapabilityInfo
;
704 BOOLEAN TimerCancelled
;
706 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
707 UCHAR SupRateLen
, ExtRateLen
;
710 UCHAR AironetCellPowerLimit
;
712 QBSS_LOAD_PARM QbssLoad
;
713 QOS_CAPABILITY_PARM QosCapability
;
715 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
716 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
719 HT_CAPABILITY_IE HtCapability
;
720 ADD_HT_INFO_IE AddHtInfo
; // AP might use this additional ht info IE
721 UCHAR HtCapabilityLen
= 0, PreNHtCapabilityLen
= 0;
723 UCHAR NewExtChannelOffset
= 0xff;
724 UCHAR CentralChannel
;
726 // Init Variable IE structure
727 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
729 RTMPZeroMemory(&HtCapability
, sizeof(HtCapability
));
730 RTMPZeroMemory(&AddHtInfo
, sizeof(ADD_HT_INFO_IE
));
733 if (PeerBeaconAndProbeRspSanity(pAd
,
759 &AironetCellPowerLimit
,
765 &PreNHtCapabilityLen
,
769 &NewExtChannelOffset
,
773 // Disqualify 11b only adhoc when we are in 11g only adhoc mode
774 if ((BssType
== BSS_ADHOC
) && (pAd
->CommonCfg
.PhyMode
== PHY_11G
) && ((SupRateLen
+ExtRateLen
)< 12))
777 // BEACON from desired BSS/IBSS found. We should be able to decide most
778 // BSS parameters here.
779 // Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
780 // Do we need to receover back all parameters belonging to previous BSS?
781 // A. Should be not. There's no back-door recover to previous AP. It still need
782 // a new JOIN-AUTH-ASSOC sequence.
783 if (MAC_ADDR_EQUAL(pAd
->MlmeAux
.Bssid
, Bssid
))
785 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel
));
786 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
788 // Update RSSI to prevent No signal display when cards first initialized
789 pAd
->StaCfg
.RssiSample
.LastRssi0
= ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
);
790 pAd
->StaCfg
.RssiSample
.LastRssi1
= ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
);
791 pAd
->StaCfg
.RssiSample
.LastRssi2
= ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
);
792 pAd
->StaCfg
.RssiSample
.AvgRssi0
= pAd
->StaCfg
.RssiSample
.LastRssi0
;
793 pAd
->StaCfg
.RssiSample
.AvgRssi0X8
= pAd
->StaCfg
.RssiSample
.AvgRssi0
<< 3;
794 pAd
->StaCfg
.RssiSample
.AvgRssi1
= pAd
->StaCfg
.RssiSample
.LastRssi1
;
795 pAd
->StaCfg
.RssiSample
.AvgRssi1X8
= pAd
->StaCfg
.RssiSample
.AvgRssi1
<< 3;
796 pAd
->StaCfg
.RssiSample
.AvgRssi2
= pAd
->StaCfg
.RssiSample
.LastRssi2
;
797 pAd
->StaCfg
.RssiSample
.AvgRssi2X8
= pAd
->StaCfg
.RssiSample
.AvgRssi2
<< 3;
800 // We need to check if SSID only set to any, then we can record the current SSID.
801 // Otherwise will cause hidden SSID association failed.
803 if (pAd
->MlmeAux
.SsidLen
== 0)
805 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, Ssid
, SsidLen
);
806 pAd
->MlmeAux
.SsidLen
= SsidLen
;
810 Idx
= BssSsidTableSearch(&pAd
->ScanTab
, Bssid
, pAd
->MlmeAux
.Ssid
, pAd
->MlmeAux
.SsidLen
, Channel
);
812 if (Idx
!= BSS_NOT_FOUND
)
815 // Multiple SSID case, used correct CapabilityInfo
817 CapabilityInfo
= pAd
->ScanTab
.BssEntry
[Idx
].CapabilityInfo
;
820 NdisMoveMemory(pAd
->MlmeAux
.Bssid
, Bssid
, MAC_ADDR_LEN
);
821 pAd
->MlmeAux
.CapabilityInfo
= CapabilityInfo
& SUPPORTED_CAPABILITY_INFO
;
822 pAd
->MlmeAux
.BssType
= BssType
;
823 pAd
->MlmeAux
.BeaconPeriod
= BeaconPeriod
;
824 pAd
->MlmeAux
.Channel
= Channel
;
825 pAd
->MlmeAux
.AtimWin
= AtimWin
;
826 pAd
->MlmeAux
.CfpPeriod
= Cf
.CfpPeriod
;
827 pAd
->MlmeAux
.CfpMaxDuration
= Cf
.CfpMaxDuration
;
828 pAd
->MlmeAux
.APRalinkIe
= RalinkIe
;
830 // Copy AP's supported rate to MlmeAux for creating assoication request
831 // Also filter out not supported rate
832 pAd
->MlmeAux
.SupRateLen
= SupRateLen
;
833 NdisMoveMemory(pAd
->MlmeAux
.SupRate
, SupRate
, SupRateLen
);
834 RTMPCheckRates(pAd
, pAd
->MlmeAux
.SupRate
, &pAd
->MlmeAux
.SupRateLen
);
835 pAd
->MlmeAux
.ExtRateLen
= ExtRateLen
;
836 NdisMoveMemory(pAd
->MlmeAux
.ExtRate
, ExtRate
, ExtRateLen
);
837 RTMPCheckRates(pAd
, pAd
->MlmeAux
.ExtRate
, &pAd
->MlmeAux
.ExtRateLen
);
839 NdisZeroMemory(pAd
->StaActive
.SupportedPhyInfo
.MCSSet
, 16);
841 pAd
->MlmeAux
.NewExtChannelOffset
= NewExtChannelOffset
;
842 pAd
->MlmeAux
.HtCapabilityLen
= HtCapabilityLen
;
844 // filter out un-supported ht rates
845 if (((HtCapabilityLen
> 0) || (PreNHtCapabilityLen
> 0)) && (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
847 RTMPZeroMemory(&pAd
->MlmeAux
.HtCapability
, SIZE_HT_CAP_IE
);
848 RTMPMoveMemory(&pAd
->MlmeAux
.AddHtInfo
, &AddHtInfo
, SIZE_ADD_HT_INFO_IE
);
850 // StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
851 NdisMoveMemory(pAd
->StaActive
.SupportedPhyInfo
.MCSSet
, HtCapability
.MCSSet
, 16);
852 pAd
->MlmeAux
.NewExtChannelOffset
= NewExtChannelOffset
;
853 pAd
->MlmeAux
.HtCapabilityLen
= SIZE_HT_CAP_IE
;
854 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= TRUE
;
855 if (PreNHtCapabilityLen
> 0)
856 pAd
->StaActive
.SupportedPhyInfo
.bPreNHt
= TRUE
;
857 RTMPCheckHt(pAd
, BSSID_WCID
, &HtCapability
, &AddHtInfo
);
858 // Copy AP Parameter to StaActive. This is also in LinkUp.
859 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
860 pAd
->StaActive
.SupportedHtPhy
.MpduDensity
, pAd
->StaActive
.SupportedHtPhy
.MaxRAmpduFactor
, HtCapability
.HtCapInfo
.ChannelWidth
));
862 if (AddHtInfoLen
> 0)
864 CentralChannel
= AddHtInfo
.ControlChan
;
865 // Check again the Bandwidth capability of this AP.
866 if ((AddHtInfo
.ControlChan
> 2)&& (AddHtInfo
.AddHtInfo
.ExtChanOffset
== EXTCHA_BELOW
) && (HtCapability
.HtCapInfo
.ChannelWidth
== BW_40
))
868 CentralChannel
= AddHtInfo
.ControlChan
- 2;
870 else if ((AddHtInfo
.AddHtInfo
.ExtChanOffset
== EXTCHA_ABOVE
) && (HtCapability
.HtCapInfo
.ChannelWidth
== BW_40
))
872 CentralChannel
= AddHtInfo
.ControlChan
+ 2;
876 if (pAd
->MlmeAux
.CentralChannel
!= CentralChannel
)
877 DBGPRINT(RT_DEBUG_ERROR
, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel
, AddHtInfo
.ControlChan
, pAd
->MlmeAux
.CentralChannel
));
879 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel
, AddHtInfo
.ControlChan
));
886 // To prevent error, let legacy AP must have same CentralChannel and Channel.
887 if ((HtCapabilityLen
== 0) && (PreNHtCapabilityLen
== 0))
888 pAd
->MlmeAux
.CentralChannel
= pAd
->MlmeAux
.Channel
;
890 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
891 RTMPZeroMemory(&pAd
->MlmeAux
.HtCapability
, SIZE_HT_CAP_IE
);
892 RTMPZeroMemory(&pAd
->MlmeAux
.AddHtInfo
, SIZE_ADD_HT_INFO_IE
);
895 RTMPUpdateMlmeRate(pAd
);
897 // copy QOS related information
898 if ((pAd
->CommonCfg
.bWmmCapable
)
899 || (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
902 NdisMoveMemory(&pAd
->MlmeAux
.APEdcaParm
, &EdcaParm
, sizeof(EDCA_PARM
));
903 NdisMoveMemory(&pAd
->MlmeAux
.APQbssLoad
, &QbssLoad
, sizeof(QBSS_LOAD_PARM
));
904 NdisMoveMemory(&pAd
->MlmeAux
.APQosCapability
, &QosCapability
, sizeof(QOS_CAPABILITY_PARM
));
908 NdisZeroMemory(&pAd
->MlmeAux
.APEdcaParm
, sizeof(EDCA_PARM
));
909 NdisZeroMemory(&pAd
->MlmeAux
.APQbssLoad
, sizeof(QBSS_LOAD_PARM
));
910 NdisZeroMemory(&pAd
->MlmeAux
.APQosCapability
, sizeof(QOS_CAPABILITY_PARM
));
913 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
914 pAd
->MlmeAux
.SupRateLen
, pAd
->MlmeAux
.ExtRateLen
));
916 if (AironetCellPowerLimit
!= 0xFF)
918 //We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
919 ChangeToCellPowerLimit(pAd
, AironetCellPowerLimit
);
921 else //Used the default TX Power Percentage.
922 pAd
->CommonCfg
.TxPowerPercentage
= pAd
->CommonCfg
.TxPowerDefault
;
924 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
925 Status
= MLME_SUCCESS
;
926 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_JOIN_CONF
, 2, &Status
);
928 // not to me BEACON, ignored
930 // sanity check fail, ignore this frame
934 ==========================================================================
936 receive BEACON from peer
938 IRQL = DISPATCH_LEVEL
940 ==========================================================================
943 IN PRTMP_ADAPTER pAd
,
944 IN MLME_QUEUE_ELEM
*Elem
)
946 UCHAR Bssid
[MAC_ADDR_LEN
], Addr2
[MAC_ADDR_LEN
];
947 CHAR Ssid
[MAX_LEN_OF_SSID
];
949 UCHAR SsidLen
, MessageToMe
=0, BssType
, Channel
, NewChannel
, index
=0;
950 UCHAR DtimCount
=0, DtimPeriod
=0, BcastFlag
=0;
951 USHORT CapabilityInfo
, AtimWin
, BeaconPeriod
;
952 LARGE_INTEGER TimeStamp
;
953 USHORT TbttNumToNextWakeUp
;
955 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
956 UCHAR SupRateLen
, ExtRateLen
;
959 UCHAR AironetCellPowerLimit
;
961 QBSS_LOAD_PARM QbssLoad
;
962 QOS_CAPABILITY_PARM QosCapability
;
964 // New for WPA security suites
965 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
966 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
967 HT_CAPABILITY_IE HtCapability
;
968 ADD_HT_INFO_IE AddHtInfo
; // AP might use this additional ht info IE
969 UCHAR HtCapabilityLen
, PreNHtCapabilityLen
;
971 UCHAR NewExtChannelOffset
= 0xff;
973 if (!(INFRA_ON(pAd
) || ADHOC_ON(pAd
)
977 // Init Variable IE structure
978 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
980 RTMPZeroMemory(&HtCapability
, sizeof(HtCapability
));
981 RTMPZeroMemory(&AddHtInfo
, sizeof(ADD_HT_INFO_IE
));
983 if (PeerBeaconAndProbeRspSanity(pAd
,
1009 &AironetCellPowerLimit
,
1015 &PreNHtCapabilityLen
,
1019 &NewExtChannelOffset
,
1023 BOOLEAN is_my_bssid
, is_my_ssid
;
1026 CHAR RealRssi
= RTMPMaxRssi(pAd
, ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
), ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
), ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
));
1028 is_my_bssid
= MAC_ADDR_EQUAL(Bssid
, pAd
->CommonCfg
.Bssid
)? TRUE
: FALSE
;
1029 is_my_ssid
= SSID_EQUAL(Ssid
, SsidLen
, pAd
->CommonCfg
.Ssid
, pAd
->CommonCfg
.SsidLen
)? TRUE
:FALSE
;
1032 // ignore BEACON not for my SSID
1033 if ((! is_my_ssid
) && (! is_my_bssid
))
1036 // It means STA waits disassoc completely from this AP, ignores this beacon.
1037 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_WAIT_DISASSOC
)
1040 // Copy Control channel for this BSSID.
1041 if (AddHtInfoLen
!= 0)
1042 Channel
= AddHtInfo
.ControlChan
;
1044 if ((HtCapabilityLen
> 0) || (PreNHtCapabilityLen
> 0))
1045 HtCapabilityLen
= SIZE_HT_CAP_IE
;
1048 // Housekeeping "SsidBssTab" table for later-on ROAMing usage.
1050 Bssidx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
1051 if (Bssidx
== BSS_NOT_FOUND
)
1053 // discover new AP of this network, create BSS entry
1054 Bssidx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
1055 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,
1056 &HtCapability
, &AddHtInfo
,HtCapabilityLen
,AddHtInfoLen
,NewExtChannelOffset
, Channel
,
1057 RealRssi
, TimeStamp
, CkipFlag
, &EdcaParm
, &QosCapability
,
1058 &QbssLoad
, LenVIE
, pVIE
);
1059 if (Bssidx
== BSS_NOT_FOUND
) // return if BSS table full
1062 NdisMoveMemory(pAd
->ScanTab
.BssEntry
[Bssidx
].PTSF
, &Elem
->Msg
[24], 4);
1063 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Bssidx
].TTSF
[0], &Elem
->TimeStamp
.u
.LowPart
, 4);
1064 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Bssidx
].TTSF
[4], &Elem
->TimeStamp
.u
.LowPart
, 4);
1070 if ((pAd
->CommonCfg
.bIEEE80211H
== 1) && (NewChannel
!= 0) && (Channel
!= NewChannel
))
1072 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1073 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1074 AsicSwitchChannel(pAd
, 1, FALSE
);
1075 AsicLockChannel(pAd
, 1);
1076 LinkDown(pAd
, FALSE
);
1077 MlmeQueueInit(&pAd
->Mlme
.Queue
);
1078 BssTableInit(&pAd
->ScanTab
);
1079 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1081 // channel sanity check
1082 for (index
= 0 ; index
< pAd
->ChannelListNum
; index
++)
1084 if (pAd
->ChannelList
[index
].Channel
== NewChannel
)
1086 pAd
->ScanTab
.BssEntry
[Bssidx
].Channel
= NewChannel
;
1087 pAd
->CommonCfg
.Channel
= NewChannel
;
1088 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.Channel
, FALSE
);
1089 AsicLockChannel(pAd
, pAd
->CommonCfg
.Channel
);
1090 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel
));
1095 if (index
>= pAd
->ChannelListNum
)
1097 DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd
->CommonCfg
.Channel
, pAd
->ChannelListNum
));
1101 // if the ssid matched & bssid unmatched, we should select the bssid with large value.
1102 // This might happened when two STA start at the same time
1103 if ((! is_my_bssid
) && ADHOC_ON(pAd
))
1107 // Add the safeguard against the mismatch of adhoc wep status
1108 if (pAd
->StaCfg
.WepStatus
!= pAd
->ScanTab
.BssEntry
[Bssidx
].WepStatus
)
1113 // collapse into the ADHOC network which has bigger BSSID value.
1114 for (i
= 0; i
< 6; i
++)
1116 if (Bssid
[i
] > pAd
->CommonCfg
.Bssid
[i
])
1118 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
1119 Bssid
[0], Bssid
[1], Bssid
[2], Bssid
[3], Bssid
[4], Bssid
[5]));
1120 AsicDisableSync(pAd
);
1121 COPY_MAC_ADDR(pAd
->CommonCfg
.Bssid
, Bssid
);
1122 AsicSetBssid(pAd
, pAd
->CommonCfg
.Bssid
);
1123 MakeIbssBeacon(pAd
); // re-build BEACON frame
1124 AsicEnableIbssSync(pAd
); // copy BEACON frame to on-chip memory
1128 else if (Bssid
[i
] < pAd
->CommonCfg
.Bssid
[i
])
1134 NdisGetSystemUpTime(&Now
);
1135 pBss
= &pAd
->ScanTab
.BssEntry
[Bssidx
];
1136 pBss
->Rssi
= RealRssi
; // lastest RSSI
1137 pBss
->LastBeaconRxTime
= Now
; // last RX timestamp
1140 // BEACON from my BSSID - either IBSS or INFRA network
1146 pAd
->StaCfg
.DtimCount
= DtimCount
;
1147 pAd
->StaCfg
.DtimPeriod
= DtimPeriod
;
1148 pAd
->StaCfg
.LastBeaconRxTime
= Now
;
1151 RxWI
.RSSI0
= Elem
->Rssi0
;
1152 RxWI
.RSSI1
= Elem
->Rssi1
;
1153 RxWI
.RSSI2
= Elem
->Rssi2
;
1155 Update_Rssi_Sample(pAd
, &pAd
->StaCfg
.RssiSample
, &RxWI
);
1156 if (AironetCellPowerLimit
!= 0xFF)
1159 // We get the Cisco (ccx) "TxPower Limit" required
1160 // Changed to appropriate TxPower Limit for Ciso Compatible Extensions
1162 ChangeToCellPowerLimit(pAd
, AironetCellPowerLimit
);
1167 // AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
1168 // Used the default TX Power Percentage, that set from UI.
1170 pAd
->CommonCfg
.TxPowerPercentage
= pAd
->CommonCfg
.TxPowerDefault
;
1173 // at least one 11b peer joined. downgrade the MaxTxRate to 11Mbps
1174 // after last 11b peer left for several seconds, we'll auto switch back to 11G rate
1175 // in MlmePeriodicExec()
1176 if (ADHOC_ON(pAd
) && (CAP_IS_IBSS_ON(CapabilityInfo
)))
1186 if ((SupRateLen
+ExtRateLen
<= 4) && (pAd
->CommonCfg
.MaxTxRate
> RATE_11
))
1188 if (pAd
->StaCfg
.AdhocBOnlyJoined
== FALSE
)
1190 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - 11b peer joined. down-grade to 11b TX rates \n"));
1192 NdisMoveMemory(pAd
->StaActive
.SupRate
, SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1193 pAd
->StaActive
.SupRateLen
= SupRateLen
;
1194 NdisMoveMemory(pAd
->StaActive
.ExtRate
, ExtRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1195 pAd
->StaActive
.ExtRateLen
= ExtRateLen
;
1196 pAd
->StaCfg
.AdhocBOnlyJoined
= TRUE
;
1197 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
1198 AsicSetEdcaParm(pAd
, NULL
);
1201 // this timestamp is for MlmePeriodicExec() to check if all 11B peers have left
1202 pAd
->StaCfg
.Last11bBeaconRxTime
= Now
;
1207 if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
1209 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
) &&
1210 !pAd
->StaCfg
.AdhocBGJoined
&&
1211 !pAd
->StaCfg
.AdhocBOnlyJoined
)
1212 AdhocTurnOnQos(pAd
);
1214 // Handle rate switch issue when Adhoc mode
1215 if ((SupRateLen
+ExtRateLen
>= 8) && (HtCapability
.MCSSet
[0] == 0) && (HtCapability
.MCSSet
[1] == 0))
1217 if (pAd
->StaCfg
.AdhocBGJoined
== FALSE
)
1219 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - 11g peer joined. down-grade to 11g TX rates \n"));
1221 NdisMoveMemory(pAd
->StaActive
.SupRate
, SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1222 pAd
->StaActive
.SupRateLen
= SupRateLen
;
1223 NdisMoveMemory(pAd
->StaActive
.ExtRate
, ExtRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1224 pAd
->StaActive
.ExtRateLen
= ExtRateLen
;
1225 pAd
->StaCfg
.AdhocBGJoined
= TRUE
;
1226 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
1227 AsicSetEdcaParm(pAd
, NULL
);
1230 // this timestamp is for MlmePeriodicExec() to check if all 11g peers have left
1231 pAd
->StaCfg
.Last11gBeaconRxTime
= Now
;
1234 else if (!pAd
->StaCfg
.AdhocBGJoined
&&
1235 !pAd
->StaCfg
.AdhocBOnlyJoined
&&
1236 (pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
== BW_40
) &&
1237 (HtCapability
.HtCapInfo
.ChannelWidth
== BW_20
))
1239 if (pAd
->StaCfg
.Adhoc20NJoined
== FALSE
)
1241 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
;
1243 pAd
->StaCfg
.Adhoc20NJoined
= TRUE
;
1244 NdisMoveMemory(&pAd
->MlmeAux
.HtCapability
, &HtCapability
, SIZE_HT_CAP_IE
);
1245 if (AddHtInfoLen
!= 0)
1246 NdisMoveMemory(&pAd
->MlmeAux
.AddHtInfo
, &AddHtInfo
, AddHtInfoLen
);
1247 NdisMoveMemory(pAd
->StaActive
.SupportedPhyInfo
.MCSSet
, HtCapability
.MCSSet
, 16);
1249 RTMPCheckHt(pAd
, Elem
->Wcid
, &pAd
->MlmeAux
.HtCapability
, &pAd
->MlmeAux
.AddHtInfo
);
1250 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd
);
1251 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= TRUE
;
1255 // this timestamp is for MlmePeriodicExec() to check if all 20MHz N peers have left
1256 pAd
->StaCfg
.Last20NBeaconRxTime
= Now
;
1262 RTMPZeroMemory(&pAd
->MlmeAux
.HtCapability
, SIZE_HT_CAP_IE
);
1263 RTMPZeroMemory(&pAd
->MlmeAux
.AddHtInfo
, SIZE_ADD_HT_INFO_IE
);
1267 // If peer Adhoc is legacy mode, I don't need to call MlmeUpdateHtTxRates no matter I support HT or not
1268 if ((bRestart
== TRUE
) && (bnRestart
== FALSE
))
1270 MlmeUpdateTxRates(pAd
, FALSE
, 0);
1271 MakeIbssBeacon(pAd
); // re-build BEACON frame
1272 AsicEnableIbssSync(pAd
); // copy to on-chip memory
1274 else if ((bRestart
== TRUE
) && (bnRestart
== TRUE
))
1276 MlmeUpdateTxRates(pAd
, FALSE
, BSS0
);
1277 MlmeUpdateHtTxRates(pAd
, BSS0
);
1278 MakeIbssBeacon(pAd
); // re-build BEACON frame
1279 AsicEnableIbssSync(pAd
); // copy to on-chip memory
1282 // At least another peer in this IBSS, declare MediaState as CONNECTED
1283 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1285 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
);
1287 pAd
->IndicateMediaState
= NdisMediaStateConnected
;
1288 RTMP_IndicateMediaState(pAd
);
1289 pAd
->ExtraInfo
= GENERAL_LINK_UP
;
1290 AsicSetBssid(pAd
, pAd
->CommonCfg
.Bssid
);
1292 // 2003/03/12 - john
1293 // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
1294 // "site survey" result should always include the current connected network.
1296 Bssidx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
1297 if (Bssidx
== BSS_NOT_FOUND
)
1299 Bssidx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
1300 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
, &HtCapability
,
1301 &AddHtInfo
, HtCapabilityLen
, AddHtInfoLen
, NewExtChannelOffset
, Channel
, RealRssi
, TimeStamp
, 0,
1302 &EdcaParm
, &QosCapability
, &QbssLoad
, LenVIE
, pVIE
);
1304 DBGPRINT(RT_DEBUG_TRACE
, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1307 // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
1308 // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
1309 if (ADHOC_ON(pAd
) && (Elem
->Wcid
== RESERVED_WCID
))
1312 MAC_TABLE_ENTRY
*pEntry
;
1314 // look up the existing table
1315 pEntry
= MacTableLookup(pAd
, Addr2
);
1318 // Another adhoc joining, add to our MAC table.
1319 pEntry
= MacTableInsertEntry(pAd
, Addr2
, BSS0
, FALSE
);
1322 pEntry
->Sst
= SST_ASSOC
;
1323 idx
= pAd
->StaCfg
.DefaultKeyId
;
1324 // After InsertEntry, Write to ASIC on-chip table.
1325 RT28XX_STA_SECURITY_INFO_ADD(pAd
, BSS0
, idx
, pEntry
);
1326 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
));
1328 pEntry
->HTPhyMode
.word
= pAd
->StaCfg
.HTPhyMode
.word
;
1329 if (HtCapabilityLen
<= 0)
1331 pEntry
->HTPhyMode
.field
.STBC
= 0;
1332 pEntry
->HTPhyMode
.field
.BW
= 0;
1333 pEntry
->HTPhyMode
.field
.ShortGI
= 0;
1334 if ((SupRateLen
+ExtRateLen
<= 4) && (pAd
->CommonCfg
.Channel
<= 14))
1336 pEntry
->HTPhyMode
.field
.MODE
= MODE_CCK
;
1340 pEntry
->HTPhyMode
.field
.MODE
= MODE_OFDM
;
1342 MlmeUpdateTxRates(pAd
, FALSE
, 0);
1346 MlmeUpdateTxRates(pAd
, FALSE
, 0);
1347 MlmeUpdateHtTxRates(pAd
, BSS0
);
1351 union iwreq_data wrqu
;
1352 wext_notify_event_assoc(pAd
);
1354 memset(wrqu
.ap_addr
.sa_data
, 0, MAC_ADDR_LEN
);
1355 memcpy(wrqu
.ap_addr
.sa_data
, pAd
->MlmeAux
.Bssid
, MAC_ADDR_LEN
);
1356 wireless_send_event(pAd
->net_dev
, SIOCGIWAP
, &wrqu
, NULL
);
1366 BOOLEAN bUseShortSlot
, bUseBGProtection
;
1368 // decide to use/change to -
1369 // 1. long slot (20 us) or short slot (9 us) time
1370 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1371 // 3. short preamble
1373 //bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
1374 bUseShortSlot
= CAP_IS_SHORT_SLOT(CapabilityInfo
);
1375 if (bUseShortSlot
!= OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_SHORT_SLOT_INUSED
))
1376 AsicSetSlotTime(pAd
, bUseShortSlot
);
1378 bUseBGProtection
= (pAd
->CommonCfg
.UseBGProtection
== 1) || // always use
1379 ((pAd
->CommonCfg
.UseBGProtection
== 0) && ERP_IS_USE_PROTECTION(Erp
));
1381 if (pAd
->CommonCfg
.Channel
> 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
1382 bUseBGProtection
= FALSE
;
1384 if (bUseBGProtection
!= OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
))
1386 if (bUseBGProtection
)
1388 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
);
1389 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, (OFDMSETPROTECT
|CCKSETPROTECT
|ALLN_SETPROTECT
),FALSE
,(pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
== 1));
1393 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
);
1394 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, (OFDMSETPROTECT
|CCKSETPROTECT
|ALLN_SETPROTECT
),TRUE
,(pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
== 1));
1397 DBGPRINT(RT_DEBUG_WARN
, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection
));
1400 // check Ht protection mode. and adhere to the Non-GF device indication by AP.
1401 if ((AddHtInfoLen
!= 0) &&
1402 ((AddHtInfo
.AddHtInfo2
.OperaionMode
!= pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
) ||
1403 (AddHtInfo
.AddHtInfo2
.NonGfPresent
!= pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
)))
1405 pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
= AddHtInfo
.AddHtInfo2
.NonGfPresent
;
1406 pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
= AddHtInfo
.AddHtInfo2
.OperaionMode
;
1407 if (pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
== 1)
1409 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, FALSE
, TRUE
);
1412 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, FALSE
, FALSE
);
1414 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - AP changed N OperaionMode to %d\n", pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
));
1417 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_SHORT_PREAMBLE_INUSED
) &&
1418 ERP_IS_USE_BARKER_PREAMBLE(Erp
))
1420 MlmeSetTxPreamble(pAd
, Rt802_11PreambleLong
);
1421 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - AP forced to use LONG preamble\n"));
1424 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_WMM_INUSED
) &&
1425 (EdcaParm
.bValid
== TRUE
) &&
1426 (EdcaParm
.EdcaUpdateCount
!= pAd
->CommonCfg
.APEdcaParm
.EdcaUpdateCount
))
1428 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1429 pAd
->CommonCfg
.APEdcaParm
.EdcaUpdateCount
,
1430 EdcaParm
.EdcaUpdateCount
));
1431 AsicSetEdcaParm(pAd
, &EdcaParm
);
1434 // copy QOS related information
1435 NdisMoveMemory(&pAd
->CommonCfg
.APQbssLoad
, &QbssLoad
, sizeof(QBSS_LOAD_PARM
));
1436 NdisMoveMemory(&pAd
->CommonCfg
.APQosCapability
, &QosCapability
, sizeof(QOS_CAPABILITY_PARM
));
1439 // only INFRASTRUCTURE mode support power-saving feature
1440 if ((INFRA_ON(pAd
) && (pAd
->StaCfg
.Psm
== PWR_SAVE
)) || (pAd
->CommonCfg
.bAPSDForcePowerSave
))
1443 // 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
1444 // 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
1445 // 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
1446 // 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
1447 // 5. otherwise, put PHY back to sleep to save battery.
1450 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
))
1452 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, pAd
->StaCfg
.BBPR3
);
1454 if (pAd
->CommonCfg
.bAPSDCapable
&& pAd
->CommonCfg
.APEdcaParm
.bAPSDCapable
&&
1455 pAd
->CommonCfg
.bAPSDAC_BE
&& pAd
->CommonCfg
.bAPSDAC_BK
&& pAd
->CommonCfg
.bAPSDAC_VI
&& pAd
->CommonCfg
.bAPSDAC_VO
)
1457 pAd
->CommonCfg
.bNeedSendTriggerFrame
= TRUE
;
1460 RT28XX_PS_POLL_ENQUEUE(pAd
);
1462 else if (BcastFlag
&& (DtimCount
== 0) && OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_RECEIVE_DTIM
))
1464 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
))
1466 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, pAd
->StaCfg
.BBPR3
);
1469 else if ((pAd
->TxSwQueue
[QID_AC_BK
].Number
!= 0) ||
1470 (pAd
->TxSwQueue
[QID_AC_BE
].Number
!= 0) ||
1471 (pAd
->TxSwQueue
[QID_AC_VI
].Number
!= 0) ||
1472 (pAd
->TxSwQueue
[QID_AC_VO
].Number
!= 0) ||
1473 (RTMPFreeTXDRequest(pAd
, QID_AC_BK
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1474 (RTMPFreeTXDRequest(pAd
, QID_AC_BE
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1475 (RTMPFreeTXDRequest(pAd
, QID_AC_VI
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1476 (RTMPFreeTXDRequest(pAd
, QID_AC_VO
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1477 (RTMPFreeTXDRequest(pAd
, QID_MGMT
, MGMT_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
))
1479 // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
1480 // can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
1481 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
))
1483 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, pAd
->StaCfg
.BBPR3
);
1488 USHORT NextDtim
= DtimCount
;
1491 NextDtim
= DtimPeriod
;
1493 TbttNumToNextWakeUp
= pAd
->StaCfg
.DefaultListenCount
;
1494 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_RECEIVE_DTIM
) && (TbttNumToNextWakeUp
> NextDtim
))
1495 TbttNumToNextWakeUp
= NextDtim
;
1497 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
))
1499 // Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode.
1500 RTMP_SET_PSFLAG(pAd
, fRTMP_PS_GO_TO_SLEEP_NOW
);
1501 pAd
->ThisTbttNumToNextWakeUp
= TbttNumToNextWakeUp
;
1506 // not my BSSID, ignore it
1508 // sanity check fail, ignore this frame
1512 ==========================================================================
1514 Receive PROBE REQ from remote peer when operating in IBSS mode
1515 ==========================================================================
1517 VOID
PeerProbeReqAction(
1518 IN PRTMP_ADAPTER pAd
,
1519 IN MLME_QUEUE_ELEM
*Elem
)
1521 UCHAR Addr2
[MAC_ADDR_LEN
];
1522 CHAR Ssid
[MAX_LEN_OF_SSID
];
1524 UCHAR HtLen
, AddHtLen
, NewExtLen
;
1525 HEADER_802_11 ProbeRspHdr
;
1526 NDIS_STATUS NStatus
;
1527 PUCHAR pOutBuffer
= NULL
;
1529 LARGE_INTEGER FakeTimestamp
;
1530 UCHAR DsLen
= 1, IbssLen
= 2;
1531 UCHAR LocalErpIe
[3] = {IE_ERP
, 1, 0};
1533 USHORT CapabilityInfo
;
1534 UCHAR RSNIe
= IE_WPA
;
1536 if (! ADHOC_ON(pAd
))
1539 if (PeerProbeReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, Addr2
, Ssid
, &SsidLen
))
1541 if ((SsidLen
== 0) || SSID_EQUAL(Ssid
, SsidLen
, pAd
->CommonCfg
.Ssid
, pAd
->CommonCfg
.SsidLen
))
1543 // allocate and send out ProbeRsp frame
1544 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
1545 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1548 //pAd->StaCfg.AtimWin = 0; // ??????
1550 Privacy
= (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption1Enabled
) ||
1551 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) ||
1552 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
);
1553 CapabilityInfo
= CAP_GENERATE(0, 1, Privacy
, (pAd
->CommonCfg
.TxPreamble
== Rt802_11PreambleShort
), 0, 0);
1555 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1556 sizeof(HEADER_802_11
), &ProbeRspHdr
,
1557 TIMESTAMP_LEN
, &FakeTimestamp
,
1558 2, &pAd
->CommonCfg
.BeaconPeriod
,
1561 1, &pAd
->CommonCfg
.SsidLen
,
1562 pAd
->CommonCfg
.SsidLen
, pAd
->CommonCfg
.Ssid
,
1564 1, &pAd
->StaActive
.SupRateLen
,
1565 pAd
->StaActive
.SupRateLen
, pAd
->StaActive
.SupRate
,
1568 1, &pAd
->CommonCfg
.Channel
,
1571 2, &pAd
->StaActive
.AtimWin
,
1574 if (pAd
->StaActive
.ExtRateLen
)
1577 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
1580 1, &pAd
->StaActive
.ExtRateLen
,
1581 pAd
->StaActive
.ExtRateLen
, &pAd
->StaActive
.ExtRate
,
1586 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1587 if (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPANone
)
1590 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
1592 1, &pAd
->StaCfg
.RSNIE_Len
,
1593 pAd
->StaCfg
.RSNIE_Len
, pAd
->StaCfg
.RSN_IE
,
1598 if (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
1601 UCHAR BROADCOM
[4] = {0x0, 0x90, 0x4c, 0x33};
1602 HtLen
= sizeof(pAd
->CommonCfg
.HtCapability
);
1603 AddHtLen
= sizeof(pAd
->CommonCfg
.AddHTInfo
);
1605 //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
1606 if (pAd
->bBroadComHT
== TRUE
)
1608 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &TmpLen
,
1611 pAd
->MlmeAux
.HtCapabilityLen
, &pAd
->MlmeAux
.HtCapability
,
1616 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &TmpLen
,
1619 sizeof(HT_CAPABILITY_IE
), &pAd
->CommonCfg
.HtCapability
,
1622 sizeof(ADD_HT_INFO_IE
), &pAd
->CommonCfg
.AddHTInfo
,
1625 sizeof(NEW_EXT_CHAN_IE
), &pAd
->CommonCfg
.NewExtChanOffset
,
1631 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
1632 MlmeFreeMemory(pAd
, pOutBuffer
);
1637 VOID
BeaconTimeoutAtJoinAction(
1638 IN PRTMP_ADAPTER pAd
,
1639 IN MLME_QUEUE_ELEM
*Elem
)
1642 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1643 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1644 Status
= MLME_REJ_TIMEOUT
;
1645 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_JOIN_CONF
, 2, &Status
);
1649 ==========================================================================
1651 Scan timeout procedure. basically add channel index by 1 and rescan
1652 ==========================================================================
1654 VOID
ScanTimeoutAction(
1655 IN PRTMP_ADAPTER pAd
,
1656 IN MLME_QUEUE_ELEM
*Elem
)
1658 pAd
->MlmeAux
.Channel
= NextChannel(pAd
, pAd
->MlmeAux
.Channel
);
1660 // Only one channel scanned for CISCO beacon request
1661 if ((pAd
->MlmeAux
.ScanType
== SCAN_CISCO_ACTIVE
) ||
1662 (pAd
->MlmeAux
.ScanType
== SCAN_CISCO_PASSIVE
) ||
1663 (pAd
->MlmeAux
.ScanType
== SCAN_CISCO_NOISE
) ||
1664 (pAd
->MlmeAux
.ScanType
== SCAN_CISCO_CHANNEL_LOAD
))
1665 pAd
->MlmeAux
.Channel
= 0;
1667 // this routine will stop if pAd->MlmeAux.Channel == 0
1668 ScanNextChannel(pAd
);
1672 ==========================================================================
1674 ==========================================================================
1676 VOID
InvalidStateWhenScan(
1677 IN PRTMP_ADAPTER pAd
,
1678 IN MLME_QUEUE_ELEM
*Elem
)
1681 DBGPRINT(RT_DEBUG_TRACE
, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
));
1682 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1683 Status
= MLME_STATE_MACHINE_REJECT
;
1684 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_SCAN_CONF
, 2, &Status
);
1688 ==========================================================================
1690 ==========================================================================
1692 VOID
InvalidStateWhenJoin(
1693 IN PRTMP_ADAPTER pAd
,
1694 IN MLME_QUEUE_ELEM
*Elem
)
1697 DBGPRINT(RT_DEBUG_TRACE
, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
));
1698 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1699 Status
= MLME_STATE_MACHINE_REJECT
;
1700 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_JOIN_CONF
, 2, &Status
);
1704 ==========================================================================
1706 ==========================================================================
1708 VOID
InvalidStateWhenStart(
1709 IN PRTMP_ADAPTER pAd
,
1710 IN MLME_QUEUE_ELEM
*Elem
)
1713 DBGPRINT(RT_DEBUG_TRACE
, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
));
1714 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1715 Status
= MLME_STATE_MACHINE_REJECT
;
1716 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_START_CONF
, 2, &Status
);
1720 ==========================================================================
1723 IRQL = DISPATCH_LEVEL
1725 ==========================================================================
1728 IN PRTMP_ADAPTER pAd
)
1730 if (pAd
->StaCfg
.WindowsPowerMode
== Ndis802_11PowerModeLegacy_PSP
)
1731 pAd
->PsPollFrame
.FC
.PwrMgmt
= PWR_SAVE
;
1732 MiniportMMRequest(pAd
, 0, (PUCHAR
)&pAd
->PsPollFrame
, sizeof(PSPOLL_FRAME
));
1737 ==========================================================================
1739 ==========================================================================
1741 VOID
EnqueueProbeRequest(
1742 IN PRTMP_ADAPTER pAd
)
1747 HEADER_802_11 Hdr80211
;
1749 DBGPRINT(RT_DEBUG_TRACE
, ("force out a ProbeRequest ...\n"));
1751 NState
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
1752 if (NState
== NDIS_STATUS_SUCCESS
)
1754 MgtMacHeaderInit(pAd
, &Hdr80211
, SUBTYPE_PROBE_REQ
, 0, BROADCAST_ADDR
, BROADCAST_ADDR
);
1756 // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
1757 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1758 sizeof(HEADER_802_11
), &Hdr80211
,
1760 1, &pAd
->CommonCfg
.SsidLen
,
1761 pAd
->CommonCfg
.SsidLen
, pAd
->CommonCfg
.Ssid
,
1763 1, &pAd
->StaActive
.SupRateLen
,
1764 pAd
->StaActive
.SupRateLen
, pAd
->StaActive
.SupRate
,
1766 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
1767 MlmeFreeMemory(pAd
, pOutBuffer
);
1772 BOOLEAN
ScanRunning(
1773 IN PRTMP_ADAPTER pAd
)
1775 return (pAd
->Mlme
.SyncMachine
.CurrState
== SCAN_LISTEN
) ? TRUE
: FALSE
;