2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 modified for rt2561/2661
36 Jan Lee 2006-08-01 modified for rt2860 for 802.11n
38 #include "../rt_config.h"
41 #define AC0_DEF_TXOP 0
42 #define AC1_DEF_TXOP 0
43 #define AC2_DEF_TXOP 94
44 #define AC3_DEF_TXOP 47
49 // Turn on QOs if use HT rate.
50 if (pAd
->CommonCfg
.APEdcaParm
.bValid
== FALSE
)
52 pAd
->CommonCfg
.APEdcaParm
.bValid
= TRUE
;
53 pAd
->CommonCfg
.APEdcaParm
.Aifsn
[0] = 3;
54 pAd
->CommonCfg
.APEdcaParm
.Aifsn
[1] = 7;
55 pAd
->CommonCfg
.APEdcaParm
.Aifsn
[2] = 1;
56 pAd
->CommonCfg
.APEdcaParm
.Aifsn
[3] = 1;
58 pAd
->CommonCfg
.APEdcaParm
.Cwmin
[0] = 4;
59 pAd
->CommonCfg
.APEdcaParm
.Cwmin
[1] = 4;
60 pAd
->CommonCfg
.APEdcaParm
.Cwmin
[2] = 3;
61 pAd
->CommonCfg
.APEdcaParm
.Cwmin
[3] = 2;
63 pAd
->CommonCfg
.APEdcaParm
.Cwmax
[0] = 10;
64 pAd
->CommonCfg
.APEdcaParm
.Cwmax
[1] = 6;
65 pAd
->CommonCfg
.APEdcaParm
.Cwmax
[2] = 4;
66 pAd
->CommonCfg
.APEdcaParm
.Cwmax
[3] = 3;
68 pAd
->CommonCfg
.APEdcaParm
.Txop
[0] = 0;
69 pAd
->CommonCfg
.APEdcaParm
.Txop
[1] = 0;
70 pAd
->CommonCfg
.APEdcaParm
.Txop
[2] = AC2_DEF_TXOP
;
71 pAd
->CommonCfg
.APEdcaParm
.Txop
[3] = AC3_DEF_TXOP
;
73 AsicSetEdcaParm(pAd
, &pAd
->CommonCfg
.APEdcaParm
);
77 #define ADHOC_ENTRY_BEACON_LOST_TIME (2*OS_HZ) // 2 sec
81 ==========================================================================
83 The sync state machine,
85 Sm - pointer to the state machine
87 the state machine looks like the following
89 ==========================================================================
91 VOID
SyncStateMachineInit(
94 OUT STATE_MACHINE_FUNC Trans
[])
96 StateMachineInit(Sm
, Trans
, MAX_SYNC_STATE
, MAX_SYNC_MSG
, (STATE_MACHINE_FUNC
)Drop
, SYNC_IDLE
, SYNC_MACHINE_BASE
);
99 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_MLME_SCAN_REQ
, (STATE_MACHINE_FUNC
)MlmeScanReqAction
);
100 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_MLME_JOIN_REQ
, (STATE_MACHINE_FUNC
)MlmeJoinReqAction
);
101 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_MLME_START_REQ
, (STATE_MACHINE_FUNC
)MlmeStartReqAction
);
102 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_PEER_BEACON
, (STATE_MACHINE_FUNC
)PeerBeacon
);
103 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_PEER_PROBE_REQ
, (STATE_MACHINE_FUNC
)PeerProbeReqAction
);
106 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_MLME_SCAN_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenScan
);
107 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_MLME_JOIN_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenJoin
);
108 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_MLME_START_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenStart
);
109 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_PEER_BEACON
, (STATE_MACHINE_FUNC
)PeerBeaconAtJoinAction
);
110 StateMachineSetAction(Sm
, JOIN_WAIT_BEACON
, MT2_BEACON_TIMEOUT
, (STATE_MACHINE_FUNC
)BeaconTimeoutAtJoinAction
);
113 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_MLME_SCAN_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenScan
);
114 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_MLME_JOIN_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenJoin
);
115 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_MLME_START_REQ
, (STATE_MACHINE_FUNC
)InvalidStateWhenStart
);
116 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_PEER_BEACON
, (STATE_MACHINE_FUNC
)PeerBeaconAtScanAction
);
117 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_PEER_PROBE_RSP
, (STATE_MACHINE_FUNC
)PeerBeaconAtScanAction
);
118 StateMachineSetAction(Sm
, SCAN_LISTEN
, MT2_SCAN_TIMEOUT
, (STATE_MACHINE_FUNC
)ScanTimeoutAction
);
121 RTMPInitTimer(pAd
, &pAd
->MlmeAux
.BeaconTimer
, GET_TIMER_FUNCTION(BeaconTimeout
), pAd
, FALSE
);
122 RTMPInitTimer(pAd
, &pAd
->MlmeAux
.ScanTimer
, GET_TIMER_FUNCTION(ScanTimeout
), pAd
, FALSE
);
126 ==========================================================================
128 Beacon timeout handler, executed in timer thread
130 IRQL = DISPATCH_LEVEL
132 ==========================================================================
135 IN PVOID SystemSpecific1
,
136 IN PVOID FunctionContext
,
137 IN PVOID SystemSpecific2
,
138 IN PVOID SystemSpecific3
)
140 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
142 DBGPRINT(RT_DEBUG_TRACE
,("SYNC - BeaconTimeout\n"));
144 // Do nothing if the driver is starting halt state.
145 // This might happen when timer already been fired before cancel timer with mlmehalt
146 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
))
149 if ((pAd
->CommonCfg
.BBPCurrentBW
== BW_40
)
153 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.CentralChannel
, FALSE
);
154 AsicLockChannel(pAd
, pAd
->CommonCfg
.CentralChannel
);
155 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
158 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
159 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd
->CommonCfg
.CentralChannel
, pAd
->ScanTab
.BssNr
));
162 MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_BEACON_TIMEOUT
, 0, NULL
);
163 RT28XX_MLME_HANDLER(pAd
);
167 ==========================================================================
169 Scan timeout handler, executed in timer thread
171 IRQL = DISPATCH_LEVEL
173 ==========================================================================
176 IN PVOID SystemSpecific1
,
177 IN PVOID FunctionContext
,
178 IN PVOID SystemSpecific2
,
179 IN PVOID SystemSpecific3
)
181 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
184 // Do nothing if the driver is starting halt state.
185 // This might happen when timer already been fired before cancel timer with mlmehalt
186 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
))
189 if (MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_SCAN_TIMEOUT
, 0, NULL
))
191 RT28XX_MLME_HANDLER(pAd
);
195 // To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
196 pAd
->MlmeAux
.Channel
= 0;
197 ScanNextChannel(pAd
);
198 if (pAd
->CommonCfg
.bWirelessEvent
)
200 RTMPSendWirelessEvent(pAd
, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG
, pAd
->MacTab
.Content
[BSSID_WCID
].Addr
, BSS0
, 0);
206 ==========================================================================
208 MLME SCAN req state machine procedure
209 ==========================================================================
211 VOID
MlmeScanReqAction(
212 IN PRTMP_ADAPTER pAd
,
213 IN MLME_QUEUE_ELEM
*Elem
)
215 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
, ScanType
, BssType
, BBPValue
= 0;
216 BOOLEAN TimerCancelled
;
219 PHEADER_802_11 pHdr80211
;
220 PUCHAR pOutBuffer
= NULL
;
223 // Check the total scan tries for one single OID command
224 // If this is the CCX 2.0 Case, skip that!
225 if ( !RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_START_UP
))
227 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - MlmeScanReqAction before Startup\n"));
231 // Increase the scan retry counters.
232 pAd
->StaCfg
.ScanCnt
++;
235 if ((OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
)) &&
237 (pAd
->StaCfg
.bRadio
== TRUE
) &&
238 (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
)))
240 RT28xxPciAsicRadioOn(pAd
, GUI_IDLE_POWER_SAVE
);
244 // first check the parameter sanity
245 if (MlmeScanReqSanity(pAd
,
254 // Check for channel load and noise hist request
255 // Suspend MSDU only at scan request, not the last two mentioned
256 if ((ScanType
== SCAN_CISCO_NOISE
) || (ScanType
== SCAN_CISCO_CHANNEL_LOAD
))
258 if (pAd
->StaCfg
.CCXScanChannel
!= pAd
->CommonCfg
.Channel
)
259 RTMPSuspendMsduTransmission(pAd
); // Suspend MSDU transmission here
263 // Suspend MSDU transmission here
264 RTMPSuspendMsduTransmission(pAd
);
268 // To prevent data lost.
269 // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
270 // And should send an NULL data with turned PSM bit off to AP, when scan progress done
272 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
) && (INFRA_ON(pAd
)))
274 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&pOutBuffer
);
275 if (NStatus
== NDIS_STATUS_SUCCESS
)
277 pHdr80211
= (PHEADER_802_11
) pOutBuffer
;
278 MgtMacHeaderInit(pAd
, pHdr80211
, SUBTYPE_NULL_FUNC
, 1, pAd
->CommonCfg
.Bssid
, pAd
->CommonCfg
.Bssid
);
279 pHdr80211
->Duration
= 0;
280 pHdr80211
->FC
.Type
= BTYPE_DATA
;
281 pHdr80211
->FC
.PwrMgmt
= PWR_SAVE
;
283 // Send using priority queue
284 MiniportMMRequest(pAd
, 0, pOutBuffer
, sizeof(HEADER_802_11
));
285 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
286 MlmeFreeMemory(pAd
, pOutBuffer
);
291 NdisGetSystemUpTime(&Now
);
292 pAd
->StaCfg
.LastScanTime
= Now
;
293 // reset all the timers
294 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
295 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &TimerCancelled
);
297 // record desired BSS parameters
298 pAd
->MlmeAux
.BssType
= BssType
;
299 pAd
->MlmeAux
.ScanType
= ScanType
;
300 pAd
->MlmeAux
.SsidLen
= SsidLen
;
301 NdisZeroMemory(pAd
->MlmeAux
.Ssid
, MAX_LEN_OF_SSID
);
302 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, Ssid
, SsidLen
);
304 // start from the first channel
305 pAd
->MlmeAux
.Channel
= FirstChannel(pAd
);
307 // Change the scan channel when dealing with CCX beacon report
308 if ((ScanType
== SCAN_CISCO_PASSIVE
) || (ScanType
== SCAN_CISCO_ACTIVE
) ||
309 (ScanType
== SCAN_CISCO_CHANNEL_LOAD
) || (ScanType
== SCAN_CISCO_NOISE
))
310 pAd
->MlmeAux
.Channel
= pAd
->StaCfg
.CCXScanChannel
;
312 // Let BBP register at 20MHz to do scan
313 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
315 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
316 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - BBP R4 to 20MHz.l\n"));
317 ScanNextChannel(pAd
);
321 DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
322 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
323 Status
= MLME_INVALID_FORMAT
;
324 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_SCAN_CONF
, 2, &Status
);
329 ==========================================================================
331 MLME JOIN req state machine procedure
332 ==========================================================================
334 VOID
MlmeJoinReqAction(
335 IN PRTMP_ADAPTER pAd
,
336 IN MLME_QUEUE_ELEM
*Elem
)
340 BOOLEAN TimerCancelled
;
341 HEADER_802_11 Hdr80211
;
344 PUCHAR pOutBuffer
= NULL
;
345 PUCHAR pSupRate
= NULL
;
347 PUCHAR pExtRate
= NULL
;
349 UCHAR ASupRate
[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
350 UCHAR ASupRateLen
= sizeof(ASupRate
)/sizeof(UCHAR
);
351 MLME_JOIN_REQ_STRUCT
*pInfo
= (MLME_JOIN_REQ_STRUCT
*)(Elem
->Msg
);
353 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo
->BssIdx
));
356 if ((OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
)) &&
358 (pAd
->StaCfg
.bRadio
== TRUE
) &&
359 (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
)))
361 RT28xxPciAsicRadioOn(pAd
, GUI_IDLE_POWER_SAVE
);
365 // reset all the timers
366 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &TimerCancelled
);
367 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
369 pBss
= &pAd
->MlmeAux
.SsidBssTab
.BssEntry
[pInfo
->BssIdx
];
371 // record the desired SSID & BSSID we're waiting for
372 COPY_MAC_ADDR(pAd
->MlmeAux
.Bssid
, pBss
->Bssid
);
374 // If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
375 if (pBss
->Hidden
== 0)
377 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, pBss
->Ssid
, pBss
->SsidLen
);
378 pAd
->MlmeAux
.SsidLen
= pBss
->SsidLen
;
381 pAd
->MlmeAux
.BssType
= pBss
->BssType
;
382 pAd
->MlmeAux
.Channel
= pBss
->Channel
;
383 pAd
->MlmeAux
.CentralChannel
= pBss
->CentralChannel
;
385 // Let BBP register at 20MHz to do scan
386 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R4
, &BBPValue
);
388 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R4
, BBPValue
);
389 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - BBP R4 to 20MHz.l\n"));
391 // switch channel and waiting for beacon timer
392 AsicSwitchChannel(pAd
, pAd
->MlmeAux
.Channel
, FALSE
);
393 AsicLockChannel(pAd
, pAd
->MlmeAux
.Channel
);
394 RTMPSetTimer(&pAd
->MlmeAux
.BeaconTimer
, JOIN_TIMEOUT
);
398 if (((pAd
->CommonCfg
.bIEEE80211H
== 1) &&
399 (pAd
->MlmeAux
.Channel
> 14) &&
400 RadarChannelCheck(pAd
, pAd
->MlmeAux
.Channel
))
404 // We can't send any Probe request frame to meet 802.11h.
406 if (pBss
->Hidden
== 0)
411 // send probe request
413 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
);
414 if (NStatus
== NDIS_STATUS_SUCCESS
)
416 if (pAd
->MlmeAux
.Channel
<= 14)
418 pSupRate
= pAd
->CommonCfg
.SupRate
;
419 SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
420 pExtRate
= pAd
->CommonCfg
.ExtRate
;
421 ExtRateLen
= pAd
->CommonCfg
.ExtRateLen
;
426 // Overwrite Support Rate, CCK rate are not allowed
429 SupRateLen
= ASupRateLen
;
433 if (pAd
->MlmeAux
.BssType
== BSS_INFRA
)
434 MgtMacHeaderInit(pAd
, &Hdr80211
, SUBTYPE_PROBE_REQ
, 0, pAd
->MlmeAux
.Bssid
, pAd
->MlmeAux
.Bssid
);
436 MgtMacHeaderInit(pAd
, &Hdr80211
, SUBTYPE_PROBE_REQ
, 0, BROADCAST_ADDR
, BROADCAST_ADDR
);
438 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
439 sizeof(HEADER_802_11
), &Hdr80211
,
441 1, &pAd
->MlmeAux
.SsidLen
,
442 pAd
->MlmeAux
.SsidLen
, pAd
->MlmeAux
.Ssid
,
445 SupRateLen
, pSupRate
,
451 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &Tmp
,
454 ExtRateLen
, pExtRate
,
460 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
461 MlmeFreeMemory(pAd
, pOutBuffer
);
465 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
466 pBss
->Channel
, pBss
->Bssid
[0], pBss
->Bssid
[1], pBss
->Bssid
[2], pBss
->Bssid
[3], pBss
->Bssid
[4], pBss
->Bssid
[5]));
468 pAd
->Mlme
.SyncMachine
.CurrState
= JOIN_WAIT_BEACON
;
472 ==========================================================================
474 MLME START Request state machine procedure, starting an IBSS
475 ==========================================================================
477 VOID
MlmeStartReqAction(
478 IN PRTMP_ADAPTER pAd
,
479 IN MLME_QUEUE_ELEM
*Elem
)
481 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
;
482 BOOLEAN TimerCancelled
;
484 // New for WPA security suites
485 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
486 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
487 LARGE_INTEGER TimeStamp
;
491 // Init Variable IE structure
492 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
494 TimeStamp
.u
.LowPart
= 0;
495 TimeStamp
.u
.HighPart
= 0;
497 if (MlmeStartReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, Ssid
, &SsidLen
))
499 // reset all the timers
500 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &TimerCancelled
);
501 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
504 // Start a new IBSS. All IBSS parameters are decided now....
506 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
507 pAd
->MlmeAux
.BssType
= BSS_ADHOC
;
508 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, Ssid
, SsidLen
);
509 pAd
->MlmeAux
.SsidLen
= SsidLen
;
511 // generate a radom number as BSSID
512 MacAddrRandomBssid(pAd
, pAd
->MlmeAux
.Bssid
);
513 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
515 Privacy
= (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption1Enabled
) ||
516 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) ||
517 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
);
518 pAd
->MlmeAux
.CapabilityInfo
= CAP_GENERATE(0,1,Privacy
, (pAd
->CommonCfg
.TxPreamble
== Rt802_11PreambleShort
), 1, 0);
519 pAd
->MlmeAux
.BeaconPeriod
= pAd
->CommonCfg
.BeaconPeriod
;
520 pAd
->MlmeAux
.AtimWin
= pAd
->StaCfg
.AtimWin
;
521 pAd
->MlmeAux
.Channel
= pAd
->CommonCfg
.Channel
;
523 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
;
524 pAd
->MlmeAux
.CentralChannel
= pAd
->CommonCfg
.CentralChannel
;
526 pAd
->MlmeAux
.SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
527 NdisMoveMemory(pAd
->MlmeAux
.SupRate
, pAd
->CommonCfg
.SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
528 RTMPCheckRates(pAd
, pAd
->MlmeAux
.SupRate
, &pAd
->MlmeAux
.SupRateLen
);
529 pAd
->MlmeAux
.ExtRateLen
= pAd
->CommonCfg
.ExtRateLen
;
530 NdisMoveMemory(pAd
->MlmeAux
.ExtRate
, pAd
->CommonCfg
.ExtRate
, MAX_LEN_OF_SUPPORTED_RATES
);
531 RTMPCheckRates(pAd
, pAd
->MlmeAux
.ExtRate
, &pAd
->MlmeAux
.ExtRateLen
);
533 if (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
535 RTMPUpdateHTIE(&pAd
->CommonCfg
.DesiredHtPhy
, &pAd
->StaCfg
.DesiredHtPhyInfo
.MCSSet
[0], &pAd
->MlmeAux
.HtCapability
, &pAd
->MlmeAux
.AddHtInfo
);
536 pAd
->MlmeAux
.HtCapabilityLen
= sizeof(HT_CAPABILITY_IE
);
537 // Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
538 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
542 pAd
->MlmeAux
.HtCapabilityLen
= 0;
543 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
545 // temporarily not support QOS in IBSS
546 NdisZeroMemory(&pAd
->MlmeAux
.APEdcaParm
, sizeof(EDCA_PARM
));
547 NdisZeroMemory(&pAd
->MlmeAux
.APQbssLoad
, sizeof(QBSS_LOAD_PARM
));
548 NdisZeroMemory(&pAd
->MlmeAux
.APQosCapability
, sizeof(QOS_CAPABILITY_PARM
));
550 AsicSwitchChannel(pAd
, pAd
->MlmeAux
.Channel
, FALSE
);
551 AsicLockChannel(pAd
, pAd
->MlmeAux
.Channel
);
553 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
554 pAd
->MlmeAux
.Channel
, pAd
->MlmeAux
.SupRateLen
, pAd
->MlmeAux
.ExtRateLen
));
556 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
557 Status
= MLME_SUCCESS
;
558 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_START_CONF
, 2, &Status
);
562 DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
563 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
564 Status
= MLME_INVALID_FORMAT
;
565 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_START_CONF
, 2, &Status
);
570 ==========================================================================
572 peer sends beacon back when scanning
573 ==========================================================================
575 VOID
PeerBeaconAtScanAction(
576 IN PRTMP_ADAPTER pAd
,
577 IN MLME_QUEUE_ELEM
*Elem
)
579 UCHAR Bssid
[MAC_ADDR_LEN
], Addr2
[MAC_ADDR_LEN
];
580 UCHAR Ssid
[MAX_LEN_OF_SSID
], BssType
, Channel
, NewChannel
,
581 SsidLen
, DtimCount
, DtimPeriod
, BcastFlag
, MessageToMe
;
583 USHORT BeaconPeriod
, AtimWin
, CapabilityInfo
;
584 PFRAME_802_11 pFrame
;
585 LARGE_INTEGER TimeStamp
;
587 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
588 UCHAR SupRateLen
, ExtRateLen
;
591 UCHAR AironetCellPowerLimit
;
593 QBSS_LOAD_PARM QbssLoad
;
594 QOS_CAPABILITY_PARM QosCapability
;
596 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
597 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
598 HT_CAPABILITY_IE HtCapability
;
599 ADD_HT_INFO_IE AddHtInfo
; // AP might use this additional ht info IE
600 UCHAR HtCapabilityLen
= 0, PreNHtCapabilityLen
= 0;
602 UCHAR NewExtChannelOffset
= 0xff;
604 pFrame
= (PFRAME_802_11
) Elem
->Msg
;
605 // Init Variable IE structure
606 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
609 RTMPZeroMemory(&HtCapability
, sizeof(HtCapability
));
610 RTMPZeroMemory(&AddHtInfo
, sizeof(ADD_HT_INFO_IE
));
612 if (PeerBeaconAndProbeRspSanity(pAd
,
638 &AironetCellPowerLimit
,
644 &PreNHtCapabilityLen
,
648 &NewExtChannelOffset
,
655 Idx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
656 if (Idx
!= BSS_NOT_FOUND
)
657 Rssi
= pAd
->ScanTab
.BssEntry
[Idx
].Rssi
;
659 Rssi
= RTMPMaxRssi(pAd
, ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
), ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
), ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
));
661 if ((HtCapabilityLen
> 0) || (PreNHtCapabilityLen
> 0))
662 HtCapabilityLen
= SIZE_HT_CAP_IE
;
664 if ((pAd
->StaCfg
.CCXReqType
!= MSRN_TYPE_UNUSED
) && (Channel
== pAd
->StaCfg
.CCXScanChannel
))
666 Idx
= BssTableSetEntry(pAd
, &pAd
->StaCfg
.CCXBssTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
667 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
,ExtRate
, ExtRateLen
, &HtCapability
,
668 &AddHtInfo
, HtCapabilityLen
, AddHtInfoLen
, NewExtChannelOffset
, Channel
, Rssi
, TimeStamp
, CkipFlag
,
669 &EdcaParm
, &QosCapability
, &QbssLoad
, LenVIE
, pVIE
);
670 if (Idx
!= BSS_NOT_FOUND
)
672 NdisMoveMemory(pAd
->StaCfg
.CCXBssTab
.BssEntry
[Idx
].PTSF
, &Elem
->Msg
[24], 4);
673 NdisMoveMemory(&pAd
->StaCfg
.CCXBssTab
.BssEntry
[Idx
].TTSF
[0], &Elem
->TimeStamp
.u
.LowPart
, 4);
674 NdisMoveMemory(&pAd
->StaCfg
.CCXBssTab
.BssEntry
[Idx
].TTSF
[4], &Elem
->TimeStamp
.u
.LowPart
, 4);
675 if (pAd
->StaCfg
.CCXReqType
== MSRN_TYPE_BEACON_REQ
)
676 AironetAddBeaconReport(pAd
, Idx
, Elem
);
681 Idx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
682 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
, &HtCapability
,
683 &AddHtInfo
, HtCapabilityLen
, AddHtInfoLen
, NewExtChannelOffset
, Channel
, Rssi
, TimeStamp
, CkipFlag
,
684 &EdcaParm
, &QosCapability
, &QbssLoad
, LenVIE
, pVIE
);
686 if (Idx
!= BSS_NOT_FOUND
)
688 NdisMoveMemory(pAd
->ScanTab
.BssEntry
[Idx
].PTSF
, &Elem
->Msg
[24], 4);
689 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Idx
].TTSF
[0], &Elem
->TimeStamp
.u
.LowPart
, 4);
690 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Idx
].TTSF
[4], &Elem
->TimeStamp
.u
.LowPart
, 4);
694 // sanity check fail, ignored
698 ==========================================================================
700 When waiting joining the (I)BSS, beacon received from external
701 ==========================================================================
703 VOID
PeerBeaconAtJoinAction(
704 IN PRTMP_ADAPTER pAd
,
705 IN MLME_QUEUE_ELEM
*Elem
)
707 UCHAR Bssid
[MAC_ADDR_LEN
], Addr2
[MAC_ADDR_LEN
];
708 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
, BssType
, Channel
, MessageToMe
,
709 DtimCount
, DtimPeriod
, BcastFlag
, NewChannel
;
710 LARGE_INTEGER TimeStamp
;
711 USHORT BeaconPeriod
, AtimWin
, CapabilityInfo
;
713 BOOLEAN TimerCancelled
;
715 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
716 UCHAR SupRateLen
, ExtRateLen
;
719 UCHAR AironetCellPowerLimit
;
721 QBSS_LOAD_PARM QbssLoad
;
722 QOS_CAPABILITY_PARM QosCapability
;
724 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
725 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
728 HT_CAPABILITY_IE HtCapability
;
729 ADD_HT_INFO_IE AddHtInfo
; // AP might use this additional ht info IE
730 UCHAR HtCapabilityLen
= 0, PreNHtCapabilityLen
= 0;
732 UCHAR NewExtChannelOffset
= 0xff;
733 UCHAR CentralChannel
;
735 // Init Variable IE structure
736 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
738 RTMPZeroMemory(&HtCapability
, sizeof(HtCapability
));
739 RTMPZeroMemory(&AddHtInfo
, sizeof(ADD_HT_INFO_IE
));
742 if (PeerBeaconAndProbeRspSanity(pAd
,
768 &AironetCellPowerLimit
,
774 &PreNHtCapabilityLen
,
778 &NewExtChannelOffset
,
782 // Disqualify 11b only adhoc when we are in 11g only adhoc mode
783 if ((BssType
== BSS_ADHOC
) && (pAd
->CommonCfg
.PhyMode
== PHY_11G
) && ((SupRateLen
+ExtRateLen
)< 12))
786 // BEACON from desired BSS/IBSS found. We should be able to decide most
787 // BSS parameters here.
788 // Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
789 // Do we need to receover back all parameters belonging to previous BSS?
790 // A. Should be not. There's no back-door recover to previous AP. It still need
791 // a new JOIN-AUTH-ASSOC sequence.
792 if (MAC_ADDR_EQUAL(pAd
->MlmeAux
.Bssid
, Bssid
))
794 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel
));
795 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &TimerCancelled
);
797 // Update RSSI to prevent No signal display when cards first initialized
798 pAd
->StaCfg
.RssiSample
.LastRssi0
= ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
);
799 pAd
->StaCfg
.RssiSample
.LastRssi1
= ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
);
800 pAd
->StaCfg
.RssiSample
.LastRssi2
= ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
);
801 pAd
->StaCfg
.RssiSample
.AvgRssi0
= pAd
->StaCfg
.RssiSample
.LastRssi0
;
802 pAd
->StaCfg
.RssiSample
.AvgRssi0X8
= pAd
->StaCfg
.RssiSample
.AvgRssi0
<< 3;
803 pAd
->StaCfg
.RssiSample
.AvgRssi1
= pAd
->StaCfg
.RssiSample
.LastRssi1
;
804 pAd
->StaCfg
.RssiSample
.AvgRssi1X8
= pAd
->StaCfg
.RssiSample
.AvgRssi1
<< 3;
805 pAd
->StaCfg
.RssiSample
.AvgRssi2
= pAd
->StaCfg
.RssiSample
.LastRssi2
;
806 pAd
->StaCfg
.RssiSample
.AvgRssi2X8
= pAd
->StaCfg
.RssiSample
.AvgRssi2
<< 3;
809 // We need to check if SSID only set to any, then we can record the current SSID.
810 // Otherwise will cause hidden SSID association failed.
812 if (pAd
->MlmeAux
.SsidLen
== 0)
814 NdisMoveMemory(pAd
->MlmeAux
.Ssid
, Ssid
, SsidLen
);
815 pAd
->MlmeAux
.SsidLen
= SsidLen
;
819 Idx
= BssSsidTableSearch(&pAd
->ScanTab
, Bssid
, pAd
->MlmeAux
.Ssid
, pAd
->MlmeAux
.SsidLen
, Channel
);
821 if (Idx
!= BSS_NOT_FOUND
)
824 // Multiple SSID case, used correct CapabilityInfo
826 CapabilityInfo
= pAd
->ScanTab
.BssEntry
[Idx
].CapabilityInfo
;
829 NdisMoveMemory(pAd
->MlmeAux
.Bssid
, Bssid
, MAC_ADDR_LEN
);
830 pAd
->MlmeAux
.CapabilityInfo
= CapabilityInfo
& SUPPORTED_CAPABILITY_INFO
;
831 pAd
->MlmeAux
.BssType
= BssType
;
832 pAd
->MlmeAux
.BeaconPeriod
= BeaconPeriod
;
833 pAd
->MlmeAux
.Channel
= Channel
;
834 pAd
->MlmeAux
.AtimWin
= AtimWin
;
835 pAd
->MlmeAux
.CfpPeriod
= Cf
.CfpPeriod
;
836 pAd
->MlmeAux
.CfpMaxDuration
= Cf
.CfpMaxDuration
;
837 pAd
->MlmeAux
.APRalinkIe
= RalinkIe
;
839 // Copy AP's supported rate to MlmeAux for creating assoication request
840 // Also filter out not supported rate
841 pAd
->MlmeAux
.SupRateLen
= SupRateLen
;
842 NdisMoveMemory(pAd
->MlmeAux
.SupRate
, SupRate
, SupRateLen
);
843 RTMPCheckRates(pAd
, pAd
->MlmeAux
.SupRate
, &pAd
->MlmeAux
.SupRateLen
);
844 pAd
->MlmeAux
.ExtRateLen
= ExtRateLen
;
845 NdisMoveMemory(pAd
->MlmeAux
.ExtRate
, ExtRate
, ExtRateLen
);
846 RTMPCheckRates(pAd
, pAd
->MlmeAux
.ExtRate
, &pAd
->MlmeAux
.ExtRateLen
);
848 NdisZeroMemory(pAd
->StaActive
.SupportedPhyInfo
.MCSSet
, 16);
850 pAd
->MlmeAux
.NewExtChannelOffset
= NewExtChannelOffset
;
851 pAd
->MlmeAux
.HtCapabilityLen
= HtCapabilityLen
;
853 // filter out un-supported ht rates
854 if (((HtCapabilityLen
> 0) || (PreNHtCapabilityLen
> 0)) && (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
856 RTMPZeroMemory(&pAd
->MlmeAux
.HtCapability
, SIZE_HT_CAP_IE
);
857 RTMPMoveMemory(&pAd
->MlmeAux
.AddHtInfo
, &AddHtInfo
, SIZE_ADD_HT_INFO_IE
);
859 // StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
860 NdisMoveMemory(pAd
->StaActive
.SupportedPhyInfo
.MCSSet
, HtCapability
.MCSSet
, 16);
861 pAd
->MlmeAux
.NewExtChannelOffset
= NewExtChannelOffset
;
862 pAd
->MlmeAux
.HtCapabilityLen
= SIZE_HT_CAP_IE
;
863 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= TRUE
;
864 if (PreNHtCapabilityLen
> 0)
865 pAd
->StaActive
.SupportedPhyInfo
.bPreNHt
= TRUE
;
866 RTMPCheckHt(pAd
, BSSID_WCID
, &HtCapability
, &AddHtInfo
);
867 // Copy AP Parameter to StaActive. This is also in LinkUp.
868 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
869 pAd
->StaActive
.SupportedHtPhy
.MpduDensity
, pAd
->StaActive
.SupportedHtPhy
.MaxRAmpduFactor
, HtCapability
.HtCapInfo
.ChannelWidth
));
871 if (AddHtInfoLen
> 0)
873 CentralChannel
= AddHtInfo
.ControlChan
;
874 // Check again the Bandwidth capability of this AP.
875 if ((AddHtInfo
.ControlChan
> 2)&& (AddHtInfo
.AddHtInfo
.ExtChanOffset
== EXTCHA_BELOW
) && (HtCapability
.HtCapInfo
.ChannelWidth
== BW_40
))
877 CentralChannel
= AddHtInfo
.ControlChan
- 2;
879 else if ((AddHtInfo
.AddHtInfo
.ExtChanOffset
== EXTCHA_ABOVE
) && (HtCapability
.HtCapInfo
.ChannelWidth
== BW_40
))
881 CentralChannel
= AddHtInfo
.ControlChan
+ 2;
885 if (pAd
->MlmeAux
.CentralChannel
!= CentralChannel
)
886 DBGPRINT(RT_DEBUG_ERROR
, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel
, AddHtInfo
.ControlChan
, pAd
->MlmeAux
.CentralChannel
));
888 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel
, AddHtInfo
.ControlChan
));
895 // To prevent error, let legacy AP must have same CentralChannel and Channel.
896 if ((HtCapabilityLen
== 0) && (PreNHtCapabilityLen
== 0))
897 pAd
->MlmeAux
.CentralChannel
= pAd
->MlmeAux
.Channel
;
899 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
900 RTMPZeroMemory(&pAd
->MlmeAux
.HtCapability
, SIZE_HT_CAP_IE
);
901 RTMPZeroMemory(&pAd
->MlmeAux
.AddHtInfo
, SIZE_ADD_HT_INFO_IE
);
904 RTMPUpdateMlmeRate(pAd
);
906 // copy QOS related information
907 if ((pAd
->CommonCfg
.bWmmCapable
)
908 || (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
911 NdisMoveMemory(&pAd
->MlmeAux
.APEdcaParm
, &EdcaParm
, sizeof(EDCA_PARM
));
912 NdisMoveMemory(&pAd
->MlmeAux
.APQbssLoad
, &QbssLoad
, sizeof(QBSS_LOAD_PARM
));
913 NdisMoveMemory(&pAd
->MlmeAux
.APQosCapability
, &QosCapability
, sizeof(QOS_CAPABILITY_PARM
));
917 NdisZeroMemory(&pAd
->MlmeAux
.APEdcaParm
, sizeof(EDCA_PARM
));
918 NdisZeroMemory(&pAd
->MlmeAux
.APQbssLoad
, sizeof(QBSS_LOAD_PARM
));
919 NdisZeroMemory(&pAd
->MlmeAux
.APQosCapability
, sizeof(QOS_CAPABILITY_PARM
));
922 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
923 pAd
->MlmeAux
.SupRateLen
, pAd
->MlmeAux
.ExtRateLen
));
925 if (AironetCellPowerLimit
!= 0xFF)
927 //We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
928 ChangeToCellPowerLimit(pAd
, AironetCellPowerLimit
);
930 else //Used the default TX Power Percentage.
931 pAd
->CommonCfg
.TxPowerPercentage
= pAd
->CommonCfg
.TxPowerDefault
;
933 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
934 Status
= MLME_SUCCESS
;
935 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_JOIN_CONF
, 2, &Status
);
937 // not to me BEACON, ignored
939 // sanity check fail, ignore this frame
943 ==========================================================================
945 receive BEACON from peer
947 IRQL = DISPATCH_LEVEL
949 ==========================================================================
952 IN PRTMP_ADAPTER pAd
,
953 IN MLME_QUEUE_ELEM
*Elem
)
955 UCHAR Bssid
[MAC_ADDR_LEN
], Addr2
[MAC_ADDR_LEN
];
956 CHAR Ssid
[MAX_LEN_OF_SSID
];
958 UCHAR SsidLen
, MessageToMe
=0, BssType
, Channel
, NewChannel
, index
=0;
959 UCHAR DtimCount
=0, DtimPeriod
=0, BcastFlag
=0;
960 USHORT CapabilityInfo
, AtimWin
, BeaconPeriod
;
961 LARGE_INTEGER TimeStamp
;
962 USHORT TbttNumToNextWakeUp
;
964 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
965 UCHAR SupRateLen
, ExtRateLen
;
968 UCHAR AironetCellPowerLimit
;
970 QBSS_LOAD_PARM QbssLoad
;
971 QOS_CAPABILITY_PARM QosCapability
;
973 // New for WPA security suites
974 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
975 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
976 HT_CAPABILITY_IE HtCapability
;
977 ADD_HT_INFO_IE AddHtInfo
; // AP might use this additional ht info IE
978 UCHAR HtCapabilityLen
, PreNHtCapabilityLen
;
980 UCHAR NewExtChannelOffset
= 0xff;
982 if (!(INFRA_ON(pAd
) || ADHOC_ON(pAd
)
986 // Init Variable IE structure
987 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
989 RTMPZeroMemory(&HtCapability
, sizeof(HtCapability
));
990 RTMPZeroMemory(&AddHtInfo
, sizeof(ADD_HT_INFO_IE
));
992 if (PeerBeaconAndProbeRspSanity(pAd
,
1018 &AironetCellPowerLimit
,
1024 &PreNHtCapabilityLen
,
1028 &NewExtChannelOffset
,
1032 BOOLEAN is_my_bssid
, is_my_ssid
;
1035 CHAR RealRssi
= RTMPMaxRssi(pAd
, ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
), ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
), ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
));
1037 is_my_bssid
= MAC_ADDR_EQUAL(Bssid
, pAd
->CommonCfg
.Bssid
)? TRUE
: FALSE
;
1038 is_my_ssid
= SSID_EQUAL(Ssid
, SsidLen
, pAd
->CommonCfg
.Ssid
, pAd
->CommonCfg
.SsidLen
)? TRUE
:FALSE
;
1041 // ignore BEACON not for my SSID
1042 if ((! is_my_ssid
) && (! is_my_bssid
))
1045 // It means STA waits disassoc completely from this AP, ignores this beacon.
1046 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_WAIT_DISASSOC
)
1049 // Copy Control channel for this BSSID.
1050 if (AddHtInfoLen
!= 0)
1051 Channel
= AddHtInfo
.ControlChan
;
1053 if ((HtCapabilityLen
> 0) || (PreNHtCapabilityLen
> 0))
1054 HtCapabilityLen
= SIZE_HT_CAP_IE
;
1057 // Housekeeping "SsidBssTab" table for later-on ROAMing usage.
1059 Bssidx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
1060 if (Bssidx
== BSS_NOT_FOUND
)
1062 // discover new AP of this network, create BSS entry
1063 Bssidx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
1064 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,
1065 &HtCapability
, &AddHtInfo
,HtCapabilityLen
,AddHtInfoLen
,NewExtChannelOffset
, Channel
,
1066 RealRssi
, TimeStamp
, CkipFlag
, &EdcaParm
, &QosCapability
,
1067 &QbssLoad
, LenVIE
, pVIE
);
1068 if (Bssidx
== BSS_NOT_FOUND
) // return if BSS table full
1071 NdisMoveMemory(pAd
->ScanTab
.BssEntry
[Bssidx
].PTSF
, &Elem
->Msg
[24], 4);
1072 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Bssidx
].TTSF
[0], &Elem
->TimeStamp
.u
.LowPart
, 4);
1073 NdisMoveMemory(&pAd
->ScanTab
.BssEntry
[Bssidx
].TTSF
[4], &Elem
->TimeStamp
.u
.LowPart
, 4);
1079 if ((pAd
->CommonCfg
.bIEEE80211H
== 1) && (NewChannel
!= 0) && (Channel
!= NewChannel
))
1081 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1082 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1083 AsicSwitchChannel(pAd
, 1, FALSE
);
1084 AsicLockChannel(pAd
, 1);
1085 LinkDown(pAd
, FALSE
);
1086 MlmeQueueInit(&pAd
->Mlme
.Queue
);
1087 BssTableInit(&pAd
->ScanTab
);
1088 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1090 // channel sanity check
1091 for (index
= 0 ; index
< pAd
->ChannelListNum
; index
++)
1093 if (pAd
->ChannelList
[index
].Channel
== NewChannel
)
1095 pAd
->ScanTab
.BssEntry
[Bssidx
].Channel
= NewChannel
;
1096 pAd
->CommonCfg
.Channel
= NewChannel
;
1097 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.Channel
, FALSE
);
1098 AsicLockChannel(pAd
, pAd
->CommonCfg
.Channel
);
1099 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel
));
1104 if (index
>= pAd
->ChannelListNum
)
1106 DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd
->CommonCfg
.Channel
, pAd
->ChannelListNum
));
1110 // if the ssid matched & bssid unmatched, we should select the bssid with large value.
1111 // This might happened when two STA start at the same time
1112 if ((! is_my_bssid
) && ADHOC_ON(pAd
))
1116 // Add the safeguard against the mismatch of adhoc wep status
1117 if (pAd
->StaCfg
.WepStatus
!= pAd
->ScanTab
.BssEntry
[Bssidx
].WepStatus
)
1119 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - Not matched wep status %d %d\n", pAd
->StaCfg
.WepStatus
, pAd
->ScanTab
.BssEntry
[Bssidx
].WepStatus
));
1120 DBGPRINT(RT_DEBUG_TRACE
, ("bssid=%s\n", pAd
->ScanTab
.BssEntry
[Bssidx
].Bssid
));
1124 // collapse into the ADHOC network which has bigger BSSID value.
1125 for (i
= 0; i
< 6; i
++)
1127 if (Bssid
[i
] > pAd
->CommonCfg
.Bssid
[i
])
1129 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
1130 Bssid
[0], Bssid
[1], Bssid
[2], Bssid
[3], Bssid
[4], Bssid
[5]));
1131 AsicDisableSync(pAd
);
1132 COPY_MAC_ADDR(pAd
->CommonCfg
.Bssid
, Bssid
);
1133 AsicSetBssid(pAd
, pAd
->CommonCfg
.Bssid
);
1134 MakeIbssBeacon(pAd
); // re-build BEACON frame
1135 AsicEnableIbssSync(pAd
); // copy BEACON frame to on-chip memory
1139 else if (Bssid
[i
] < pAd
->CommonCfg
.Bssid
[i
])
1145 NdisGetSystemUpTime(&Now
);
1146 pBss
= &pAd
->ScanTab
.BssEntry
[Bssidx
];
1147 pBss
->Rssi
= RealRssi
; // lastest RSSI
1148 pBss
->LastBeaconRxTime
= Now
; // last RX timestamp
1151 // BEACON from my BSSID - either IBSS or INFRA network
1157 pAd
->StaCfg
.DtimCount
= DtimCount
;
1158 pAd
->StaCfg
.DtimPeriod
= DtimPeriod
;
1159 pAd
->StaCfg
.LastBeaconRxTime
= Now
;
1162 RxWI
.RSSI0
= Elem
->Rssi0
;
1163 RxWI
.RSSI1
= Elem
->Rssi1
;
1164 RxWI
.RSSI2
= Elem
->Rssi2
;
1166 Update_Rssi_Sample(pAd
, &pAd
->StaCfg
.RssiSample
, &RxWI
);
1167 if (AironetCellPowerLimit
!= 0xFF)
1170 // We get the Cisco (ccx) "TxPower Limit" required
1171 // Changed to appropriate TxPower Limit for Ciso Compatible Extensions
1173 ChangeToCellPowerLimit(pAd
, AironetCellPowerLimit
);
1178 // AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
1179 // Used the default TX Power Percentage, that set from UI.
1181 pAd
->CommonCfg
.TxPowerPercentage
= pAd
->CommonCfg
.TxPowerDefault
;
1185 // at least one 11b peer joined. downgrade the MaxTxRate to 11Mbps
1186 // after last 11b peer left for several seconds, we'll auto switch back to 11G rate
1187 // in MlmePeriodicExec()
1189 if (ADHOC_ON(pAd
) && (CAP_IS_IBSS_ON(CapabilityInfo
)))
1200 if ((SupRateLen
+ExtRateLen
<= 4) && (pAd
->CommonCfg
.MaxTxRate
> RATE_11
))
1202 if (pAd
->StaCfg
.AdhocBOnlyJoined
== FALSE
)
1204 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - 11b peer joined. down-grade to 11b TX rates \n"));
1206 NdisMoveMemory(pAd
->StaActive
.SupRate
, SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1207 pAd
->StaActive
.SupRateLen
= SupRateLen
;
1208 NdisMoveMemory(pAd
->StaActive
.ExtRate
, ExtRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1209 pAd
->StaActive
.ExtRateLen
= ExtRateLen
;
1210 pAd
->StaCfg
.AdhocBOnlyJoined
= TRUE
;
1211 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
1212 AsicSetEdcaParm(pAd
, NULL
);
1215 // this timestamp is for MlmePeriodicExec() to check if all 11B peers have left
1216 pAd
->StaCfg
.Last11bBeaconRxTime
= Now
;
1221 if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
))
1223 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
) &&
1224 !pAd
->StaCfg
.AdhocBGJoined
&&
1225 !pAd
->StaCfg
.AdhocBOnlyJoined
)
1226 AdhocTurnOnQos(pAd
);
1228 // Handle rate switch issue when Adhoc mode
1229 if ((SupRateLen
+ExtRateLen
>= 8) && (HtCapability
.MCSSet
[0] == 0) && (HtCapability
.MCSSet
[1] == 0))
1231 if (pAd
->StaCfg
.AdhocBGJoined
== FALSE
)
1233 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - 11g peer joined. down-grade to 11g TX rates \n"));
1235 NdisMoveMemory(pAd
->StaActive
.SupRate
, SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1236 pAd
->StaActive
.SupRateLen
= SupRateLen
;
1237 NdisMoveMemory(pAd
->StaActive
.ExtRate
, ExtRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1238 pAd
->StaActive
.ExtRateLen
= ExtRateLen
;
1239 pAd
->StaCfg
.AdhocBGJoined
= TRUE
;
1240 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= FALSE
;
1241 AsicSetEdcaParm(pAd
, NULL
);
1244 // this timestamp is for MlmePeriodicExec() to check if all 11g peers have left
1245 pAd
->StaCfg
.Last11gBeaconRxTime
= Now
;
1248 else if (!pAd
->StaCfg
.AdhocBGJoined
&&
1249 !pAd
->StaCfg
.AdhocBOnlyJoined
&&
1250 (pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
== BW_40
) &&
1251 (HtCapability
.HtCapInfo
.ChannelWidth
== BW_20
))
1253 if (pAd
->StaCfg
.Adhoc20NJoined
== FALSE
)
1255 pAd
->CommonCfg
.CentralChannel
= pAd
->CommonCfg
.Channel
;
1257 pAd
->StaCfg
.Adhoc20NJoined
= TRUE
;
1258 NdisMoveMemory(&pAd
->MlmeAux
.HtCapability
, &HtCapability
, SIZE_HT_CAP_IE
);
1259 if (AddHtInfoLen
!= 0)
1260 NdisMoveMemory(&pAd
->MlmeAux
.AddHtInfo
, &AddHtInfo
, AddHtInfoLen
);
1261 NdisMoveMemory(pAd
->StaActive
.SupportedPhyInfo
.MCSSet
, HtCapability
.MCSSet
, 16);
1263 RTMPCheckHt(pAd
, Elem
->Wcid
, &pAd
->MlmeAux
.HtCapability
, &pAd
->MlmeAux
.AddHtInfo
);
1264 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd
);
1265 pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
= TRUE
;
1269 // this timestamp is for MlmePeriodicExec() to check if all 20MHz N peers have left
1270 pAd
->StaCfg
.Last20NBeaconRxTime
= Now
;
1276 RTMPZeroMemory(&pAd
->MlmeAux
.HtCapability
, SIZE_HT_CAP_IE
);
1277 RTMPZeroMemory(&pAd
->MlmeAux
.AddHtInfo
, SIZE_ADD_HT_INFO_IE
);
1281 // If peer Adhoc is legacy mode, I don't need to call MlmeUpdateHtTxRates no matter I support HT or not
1282 if ((bRestart
== TRUE
) && (bnRestart
== FALSE
))
1284 MlmeUpdateTxRates(pAd
, FALSE
, 0);
1285 MakeIbssBeacon(pAd
); // re-build BEACON frame
1286 AsicEnableIbssSync(pAd
); // copy to on-chip memory
1288 else if ((bRestart
== TRUE
) && (bnRestart
== TRUE
))
1290 MlmeUpdateTxRates(pAd
, FALSE
, BSS0
);
1291 MlmeUpdateHtTxRates(pAd
, BSS0
);
1292 MakeIbssBeacon(pAd
); // re-build BEACON frame
1293 AsicEnableIbssSync(pAd
); // copy to on-chip memory
1296 // At least another peer in this IBSS, declare MediaState as CONNECTED
1297 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1299 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
);
1301 pAd
->IndicateMediaState
= NdisMediaStateConnected
;
1302 RTMP_IndicateMediaState(pAd
);
1303 pAd
->ExtraInfo
= GENERAL_LINK_UP
;
1304 AsicSetBssid(pAd
, pAd
->CommonCfg
.Bssid
);
1306 // 2003/03/12 - john
1307 // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
1308 // "site survey" result should always include the current connected network.
1310 Bssidx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
1311 if (Bssidx
== BSS_NOT_FOUND
)
1313 Bssidx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
1314 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
, &HtCapability
,
1315 &AddHtInfo
, HtCapabilityLen
, AddHtInfoLen
, NewExtChannelOffset
, Channel
, RealRssi
, TimeStamp
, 0,
1316 &EdcaParm
, &QosCapability
, &QbssLoad
, LenVIE
, pVIE
);
1318 DBGPRINT(RT_DEBUG_TRACE
, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1321 // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
1322 // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
1323 if (ADHOC_ON(pAd
) && (Elem
->Wcid
== RESERVED_WCID
))
1326 MAC_TABLE_ENTRY
*pEntry
;
1328 // look up the existing table
1329 pEntry
= MacTableLookup(pAd
, Addr2
);
1332 // Another adhoc joining, add to our MAC table.
1333 pEntry
= MacTableInsertEntry(pAd
, Addr2
, BSS0
, FALSE
);
1336 pEntry
->Sst
= SST_ASSOC
;
1337 idx
= pAd
->StaCfg
.DefaultKeyId
;
1338 // After InsertEntry, Write to ASIC on-chip table.
1339 RT28XX_STA_SECURITY_INFO_ADD(pAd
, BSS0
, idx
, pEntry
);
1340 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
));
1342 pEntry
->HTPhyMode
.word
= pAd
->StaCfg
.HTPhyMode
.word
;
1343 if (HtCapabilityLen
<= 0)
1345 pEntry
->HTPhyMode
.field
.STBC
= 0;
1346 pEntry
->HTPhyMode
.field
.BW
= 0;
1347 pEntry
->HTPhyMode
.field
.ShortGI
= 0;
1348 if ((SupRateLen
+ExtRateLen
<= 4) && (pAd
->CommonCfg
.Channel
<= 14))
1350 pEntry
->HTPhyMode
.field
.MODE
= MODE_CCK
;
1354 pEntry
->HTPhyMode
.field
.MODE
= MODE_OFDM
;
1356 MlmeUpdateTxRates(pAd
, FALSE
, 0);
1360 MlmeUpdateTxRates(pAd
, FALSE
, 0);
1361 MlmeUpdateHtTxRates(pAd
, BSS0
);
1365 union iwreq_data wrqu
;
1366 wext_notify_event_assoc(pAd
);
1368 memset(wrqu
.ap_addr
.sa_data
, 0, MAC_ADDR_LEN
);
1369 memcpy(wrqu
.ap_addr
.sa_data
, pAd
->MlmeAux
.Bssid
, MAC_ADDR_LEN
);
1370 wireless_send_event(pAd
->net_dev
, SIOCGIWAP
, &wrqu
, NULL
);
1378 UCHAR MaxSupportedRateIn500Kbps
= 0;
1380 MAC_TABLE_ENTRY
*pEntry
;
1382 // supported rates array may not be sorted. sort it and find the maximum rate
1383 for (idx
=0; idx
<SupRateLen
; idx
++)
1385 if (MaxSupportedRateIn500Kbps
< (SupRate
[idx
] & 0x7f))
1386 MaxSupportedRateIn500Kbps
= SupRate
[idx
] & 0x7f;
1389 for (idx
=0; idx
<ExtRateLen
; idx
++)
1391 if (MaxSupportedRateIn500Kbps
< (ExtRate
[idx
] & 0x7f))
1392 MaxSupportedRateIn500Kbps
= ExtRate
[idx
] & 0x7f;
1395 // look up the existing table
1396 pEntry
= MacTableLookup(pAd
, Addr2
);
1398 // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
1399 // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
1400 if ((ADHOC_ON(pAd
) && (Elem
->Wcid
== RESERVED_WCID
)) ||
1401 (pEntry
&& ((pEntry
->LastBeaconRxTime
+ ADHOC_ENTRY_BEACON_LOST_TIME
) < Now
)))
1404 // Another adhoc joining, add to our MAC table.
1405 pEntry
= MacTableInsertEntry(pAd
, Addr2
, BSS0
, FALSE
);
1407 if (StaAddMacTableEntry(pAd
, pEntry
, MaxSupportedRateIn500Kbps
, &HtCapability
, HtCapabilityLen
, CapabilityInfo
) == FALSE
)
1409 DBGPRINT(RT_DEBUG_TRACE
, ("ADHOC - Add Entry failed.\n"));
1414 (Elem
->Wcid
== RESERVED_WCID
))
1416 idx
= pAd
->StaCfg
.DefaultKeyId
;
1417 RT28XX_STA_SECURITY_INFO_ADD(pAd
, BSS0
, idx
, pEntry
);
1421 if (pEntry
&& pEntry
->ValidAsCLI
)
1422 pEntry
->LastBeaconRxTime
= Now
;
1424 // At least another peer in this IBSS, declare MediaState as CONNECTED
1425 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1427 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
);
1429 pAd
->IndicateMediaState
= NdisMediaStateConnected
;
1430 RTMP_IndicateMediaState(pAd
);
1431 pAd
->ExtraInfo
= GENERAL_LINK_UP
;
1432 AsicSetBssid(pAd
, pAd
->CommonCfg
.Bssid
);
1434 // 2003/03/12 - john
1435 // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
1436 // "site survey" result should always include the current connected network.
1438 Bssidx
= BssTableSearch(&pAd
->ScanTab
, Bssid
, Channel
);
1439 if (Bssidx
== BSS_NOT_FOUND
)
1441 Bssidx
= BssTableSetEntry(pAd
, &pAd
->ScanTab
, Bssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,
1442 &CfParm
, AtimWin
, CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
, &HtCapability
,
1443 &AddHtInfo
, HtCapabilityLen
, AddHtInfoLen
, NewExtChannelOffset
, Channel
, RealRssi
, TimeStamp
, 0,
1444 &EdcaParm
, &QosCapability
, &QbssLoad
, LenVIE
, pVIE
);
1446 DBGPRINT(RT_DEBUG_TRACE
, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1453 BOOLEAN bUseShortSlot
, bUseBGProtection
;
1455 // decide to use/change to -
1456 // 1. long slot (20 us) or short slot (9 us) time
1457 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1458 // 3. short preamble
1460 //bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
1461 bUseShortSlot
= CAP_IS_SHORT_SLOT(CapabilityInfo
);
1462 if (bUseShortSlot
!= OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_SHORT_SLOT_INUSED
))
1463 AsicSetSlotTime(pAd
, bUseShortSlot
);
1465 bUseBGProtection
= (pAd
->CommonCfg
.UseBGProtection
== 1) || // always use
1466 ((pAd
->CommonCfg
.UseBGProtection
== 0) && ERP_IS_USE_PROTECTION(Erp
));
1468 if (pAd
->CommonCfg
.Channel
> 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
1469 bUseBGProtection
= FALSE
;
1471 if (bUseBGProtection
!= OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
))
1473 if (bUseBGProtection
)
1475 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
);
1476 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, (OFDMSETPROTECT
|CCKSETPROTECT
|ALLN_SETPROTECT
),FALSE
,(pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
== 1));
1480 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
);
1481 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, (OFDMSETPROTECT
|CCKSETPROTECT
|ALLN_SETPROTECT
),TRUE
,(pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
== 1));
1484 DBGPRINT(RT_DEBUG_WARN
, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection
));
1487 // check Ht protection mode. and adhere to the Non-GF device indication by AP.
1488 if ((AddHtInfoLen
!= 0) &&
1489 ((AddHtInfo
.AddHtInfo2
.OperaionMode
!= pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
) ||
1490 (AddHtInfo
.AddHtInfo2
.NonGfPresent
!= pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
)))
1492 pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
= AddHtInfo
.AddHtInfo2
.NonGfPresent
;
1493 pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
= AddHtInfo
.AddHtInfo2
.OperaionMode
;
1494 if (pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
== 1)
1496 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, FALSE
, TRUE
);
1499 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, FALSE
, FALSE
);
1501 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - AP changed N OperaionMode to %d\n", pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
));
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
);
1543 if (pAd
->CommonCfg
.bAPSDCapable
&& pAd
->CommonCfg
.APEdcaParm
.bAPSDCapable
&&
1544 pAd
->CommonCfg
.bAPSDAC_BE
&& pAd
->CommonCfg
.bAPSDAC_BK
&& pAd
->CommonCfg
.bAPSDAC_VI
&& pAd
->CommonCfg
.bAPSDAC_VO
)
1546 pAd
->CommonCfg
.bNeedSendTriggerFrame
= TRUE
;
1549 RT28XX_PS_POLL_ENQUEUE(pAd
);
1551 else if (BcastFlag
&& (DtimCount
== 0) && OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_RECEIVE_DTIM
))
1554 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
))
1556 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, pAd
->StaCfg
.BBPR3
);
1560 else if ((pAd
->TxSwQueue
[QID_AC_BK
].Number
!= 0) ||
1561 (pAd
->TxSwQueue
[QID_AC_BE
].Number
!= 0) ||
1562 (pAd
->TxSwQueue
[QID_AC_VI
].Number
!= 0) ||
1563 (pAd
->TxSwQueue
[QID_AC_VO
].Number
!= 0) ||
1564 (RTMPFreeTXDRequest(pAd
, QID_AC_BK
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1565 (RTMPFreeTXDRequest(pAd
, QID_AC_BE
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1566 (RTMPFreeTXDRequest(pAd
, QID_AC_VI
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1567 (RTMPFreeTXDRequest(pAd
, QID_AC_VO
, TX_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
) ||
1568 (RTMPFreeTXDRequest(pAd
, QID_MGMT
, MGMT_RING_SIZE
- 1, &FreeNumber
) != NDIS_STATUS_SUCCESS
))
1570 // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
1571 // can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
1573 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
))
1575 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, pAd
->StaCfg
.BBPR3
);
1581 USHORT NextDtim
= DtimCount
;
1584 NextDtim
= DtimPeriod
;
1586 TbttNumToNextWakeUp
= pAd
->StaCfg
.DefaultListenCount
;
1587 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_RECEIVE_DTIM
) && (TbttNumToNextWakeUp
> NextDtim
))
1588 TbttNumToNextWakeUp
= NextDtim
;
1590 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
))
1593 // Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode.
1594 RTMP_SET_PSFLAG(pAd
, fRTMP_PS_GO_TO_SLEEP_NOW
);
1595 pAd
->ThisTbttNumToNextWakeUp
= TbttNumToNextWakeUp
;
1598 AsicSleepThenAutoWakeup(pAd
, TbttNumToNextWakeUp
);
1604 // not my BSSID, ignore it
1606 // sanity check fail, ignore this frame
1610 ==========================================================================
1612 Receive PROBE REQ from remote peer when operating in IBSS mode
1613 ==========================================================================
1615 VOID
PeerProbeReqAction(
1616 IN PRTMP_ADAPTER pAd
,
1617 IN MLME_QUEUE_ELEM
*Elem
)
1619 UCHAR Addr2
[MAC_ADDR_LEN
];
1620 CHAR Ssid
[MAX_LEN_OF_SSID
];
1622 UCHAR HtLen
, AddHtLen
, NewExtLen
;
1623 HEADER_802_11 ProbeRspHdr
;
1624 NDIS_STATUS NStatus
;
1625 PUCHAR pOutBuffer
= NULL
;
1627 LARGE_INTEGER FakeTimestamp
;
1628 UCHAR DsLen
= 1, IbssLen
= 2;
1629 UCHAR LocalErpIe
[3] = {IE_ERP
, 1, 0};
1631 USHORT CapabilityInfo
;
1632 UCHAR RSNIe
= IE_WPA
;
1634 if (! ADHOC_ON(pAd
))
1637 if (PeerProbeReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, Addr2
, Ssid
, &SsidLen
))
1639 if ((SsidLen
== 0) || SSID_EQUAL(Ssid
, SsidLen
, pAd
->CommonCfg
.Ssid
, pAd
->CommonCfg
.SsidLen
))
1641 // allocate and send out ProbeRsp frame
1642 NStatus
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
1643 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1646 //pAd->StaCfg.AtimWin = 0; // ??????
1648 Privacy
= (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption1Enabled
) ||
1649 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) ||
1650 (pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption3Enabled
);
1651 CapabilityInfo
= CAP_GENERATE(0, 1, Privacy
, (pAd
->CommonCfg
.TxPreamble
== Rt802_11PreambleShort
), 0, 0);
1653 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1654 sizeof(HEADER_802_11
), &ProbeRspHdr
,
1655 TIMESTAMP_LEN
, &FakeTimestamp
,
1656 2, &pAd
->CommonCfg
.BeaconPeriod
,
1659 1, &pAd
->CommonCfg
.SsidLen
,
1660 pAd
->CommonCfg
.SsidLen
, pAd
->CommonCfg
.Ssid
,
1662 1, &pAd
->StaActive
.SupRateLen
,
1663 pAd
->StaActive
.SupRateLen
, pAd
->StaActive
.SupRate
,
1666 1, &pAd
->CommonCfg
.Channel
,
1669 2, &pAd
->StaActive
.AtimWin
,
1672 if (pAd
->StaActive
.ExtRateLen
)
1675 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
1678 1, &pAd
->StaActive
.ExtRateLen
,
1679 pAd
->StaActive
.ExtRateLen
, &pAd
->StaActive
.ExtRate
,
1684 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1685 if (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPANone
)
1688 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &tmp
,
1690 1, &pAd
->StaCfg
.RSNIE_Len
,
1691 pAd
->StaCfg
.RSNIE_Len
, pAd
->StaCfg
.RSN_IE
,
1696 if (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
1699 UCHAR BROADCOM
[4] = {0x0, 0x90, 0x4c, 0x33};
1700 HtLen
= sizeof(pAd
->CommonCfg
.HtCapability
);
1701 AddHtLen
= sizeof(pAd
->CommonCfg
.AddHTInfo
);
1703 //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
1704 if (pAd
->bBroadComHT
== TRUE
)
1706 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &TmpLen
,
1709 pAd
->MlmeAux
.HtCapabilityLen
, &pAd
->MlmeAux
.HtCapability
,
1714 MakeOutgoingFrame(pOutBuffer
+ FrameLen
, &TmpLen
,
1717 sizeof(HT_CAPABILITY_IE
), &pAd
->CommonCfg
.HtCapability
,
1720 sizeof(ADD_HT_INFO_IE
), &pAd
->CommonCfg
.AddHTInfo
,
1723 sizeof(NEW_EXT_CHAN_IE
), &pAd
->CommonCfg
.NewExtChanOffset
,
1729 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
1730 MlmeFreeMemory(pAd
, pOutBuffer
);
1735 VOID
BeaconTimeoutAtJoinAction(
1736 IN PRTMP_ADAPTER pAd
,
1737 IN MLME_QUEUE_ELEM
*Elem
)
1740 DBGPRINT(RT_DEBUG_TRACE
, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1741 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1742 Status
= MLME_REJ_TIMEOUT
;
1743 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_JOIN_CONF
, 2, &Status
);
1747 ==========================================================================
1749 Scan timeout procedure. basically add channel index by 1 and rescan
1750 ==========================================================================
1752 VOID
ScanTimeoutAction(
1753 IN PRTMP_ADAPTER pAd
,
1754 IN MLME_QUEUE_ELEM
*Elem
)
1756 pAd
->MlmeAux
.Channel
= NextChannel(pAd
, pAd
->MlmeAux
.Channel
);
1758 // Only one channel scanned for CISCO beacon request
1759 if ((pAd
->MlmeAux
.ScanType
== SCAN_CISCO_ACTIVE
) ||
1760 (pAd
->MlmeAux
.ScanType
== SCAN_CISCO_PASSIVE
) ||
1761 (pAd
->MlmeAux
.ScanType
== SCAN_CISCO_NOISE
) ||
1762 (pAd
->MlmeAux
.ScanType
== SCAN_CISCO_CHANNEL_LOAD
))
1763 pAd
->MlmeAux
.Channel
= 0;
1765 // this routine will stop if pAd->MlmeAux.Channel == 0
1766 ScanNextChannel(pAd
);
1770 ==========================================================================
1772 ==========================================================================
1774 VOID
InvalidStateWhenScan(
1775 IN PRTMP_ADAPTER pAd
,
1776 IN MLME_QUEUE_ELEM
*Elem
)
1779 DBGPRINT(RT_DEBUG_TRACE
, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
));
1780 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1781 Status
= MLME_STATE_MACHINE_REJECT
;
1782 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_SCAN_CONF
, 2, &Status
);
1786 ==========================================================================
1788 ==========================================================================
1790 VOID
InvalidStateWhenJoin(
1791 IN PRTMP_ADAPTER pAd
,
1792 IN MLME_QUEUE_ELEM
*Elem
)
1795 DBGPRINT(RT_DEBUG_TRACE
, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
));
1796 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1797 Status
= MLME_STATE_MACHINE_REJECT
;
1798 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_JOIN_CONF
, 2, &Status
);
1802 ==========================================================================
1804 ==========================================================================
1806 VOID
InvalidStateWhenStart(
1807 IN PRTMP_ADAPTER pAd
,
1808 IN MLME_QUEUE_ELEM
*Elem
)
1811 DBGPRINT(RT_DEBUG_TRACE
, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
));
1812 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1813 Status
= MLME_STATE_MACHINE_REJECT
;
1814 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_START_CONF
, 2, &Status
);
1818 ==========================================================================
1821 IRQL = DISPATCH_LEVEL
1823 ==========================================================================
1826 IN PRTMP_ADAPTER pAd
)
1828 if (pAd
->StaCfg
.WindowsPowerMode
== Ndis802_11PowerModeLegacy_PSP
)
1829 pAd
->PsPollFrame
.FC
.PwrMgmt
= PWR_SAVE
;
1830 MiniportMMRequest(pAd
, 0, (PUCHAR
)&pAd
->PsPollFrame
, sizeof(PSPOLL_FRAME
));
1835 ==========================================================================
1837 ==========================================================================
1839 VOID
EnqueueProbeRequest(
1840 IN PRTMP_ADAPTER pAd
)
1845 HEADER_802_11 Hdr80211
;
1847 DBGPRINT(RT_DEBUG_TRACE
, ("force out a ProbeRequest ...\n"));
1849 NState
= MlmeAllocateMemory(pAd
, &pOutBuffer
); //Get an unused nonpaged memory
1850 if (NState
== NDIS_STATUS_SUCCESS
)
1852 MgtMacHeaderInit(pAd
, &Hdr80211
, SUBTYPE_PROBE_REQ
, 0, BROADCAST_ADDR
, BROADCAST_ADDR
);
1854 // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
1855 MakeOutgoingFrame(pOutBuffer
, &FrameLen
,
1856 sizeof(HEADER_802_11
), &Hdr80211
,
1858 1, &pAd
->CommonCfg
.SsidLen
,
1859 pAd
->CommonCfg
.SsidLen
, pAd
->CommonCfg
.Ssid
,
1861 1, &pAd
->StaActive
.SupRateLen
,
1862 pAd
->StaActive
.SupRateLen
, pAd
->StaActive
.SupRate
,
1864 MiniportMMRequest(pAd
, 0, pOutBuffer
, FrameLen
);
1865 MlmeFreeMemory(pAd
, pOutBuffer
);
1870 BOOLEAN
ScanRunning(
1871 IN PRTMP_ADAPTER pAd
)
1873 return (pAd
->Mlme
.SyncMachine
.CurrState
== SCAN_LISTEN
) ? TRUE
: FALSE
;