1 /*************************************************************************
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 ************************************************************************/
26 #include "rt_config.h"
28 // 2.4 Ghz channel plan
29 UCHAR Ra24Ghz_FCC
[] = {1,2,3,4,5,6,7,8,9,10,11};
30 UCHAR Ra24Ghz_IC
[] = {1,2,3,4,5,6,7,8,9,10,11};
31 UCHAR Ra24Ghz_ESTI
[]= {1,2,3,4,5,6,7,8,9,10,11,12,13};
32 UCHAR Ra24Ghz_SPAIN
[] = {10,11};
33 UCHAR Ra24Ghz_FRANCE
[] = {10,11,12,13};
34 UCHAR Ra24Ghz_MKK
[] = {14};
35 UCHAR Ra24Ghz_MKK1
[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14};
36 UCHAR Ra24Ghz_ISRAEL
[] = {3,4,5,6,7,8,9};
39 UCHAR Ra5Ghz_UNII
[] = {36,40,44,48,52,56,60,64, 149,153,157,161};
40 UCHAR Ra5Ghz_MMAC
[] = {34,38,42,46};
41 UCHAR Ra5Ghz_HyperLAN2
[] = {36,40,44,48,52,56,60,64, 100,104,108,112,116,120,124,128,132,136,140};
43 extern UCHAR CipherSuiteWpaNoneTkip
[];
44 extern UCHAR CipherSuiteWpaNoneTkipLen
;
46 extern UCHAR CipherSuiteWpaNoneAes
[];
47 extern UCHAR CipherSuiteWpaNoneAesLen
;
50 ==========================================================================
52 The sync state machine,
54 Sm - pointer to the state machine
56 the state machine looks like the following
59 SYNC_IDLE JOIN_WAIT_BEACON
60 MT2_MLME_SCAN_REQ mlme_scan_req_action invalid_state_when_scan
61 MT2_MLME_JOIN_REQ mlme_join_req_action invalid_state_when_join
62 MT2_MLME_START_REQ mlme_start_req_action invalid_state_when_start
63 MT2_PEER_BEACON peer_beacon peer_beacon_at_join_wait_beacon_action
64 MT2_PEER_PROBE_RSP peer_beacon drop
65 MT2_PEER_ATIM drop drop
66 MT2_SCAN_TIMEOUT Drop Drop
67 MT2_BEACON_TIMEOUT Drop beacon_timeout_at_join_wait_beacon_action
68 MT2_ATIM_TIMEOUT Drop Drop
69 MT2_PEER_PROBE_REQ ???? drop
73 MT2_MLME_SCAN_REQ invalid_state_when_scan
74 MT2_MLME_JOIN_REQ invalid_state_when_join
75 MT2_MLME_START_REQ invalid_state_when_start
76 MT2_PEER_BEACON peer_beacon_at_scan_action
77 MT2_PEER_PROBE_RSP peer_probe_rsp_at_scan_action
79 MT2_SCAN_TIMEOUT scan_timeout_action
80 MT2_BEACON_TIMEOUT Drop
82 MT2_PEER_PROBE_REQ drop
83 ==========================================================================
85 VOID
SyncStateMachineInit(
88 OUT STATE_MACHINE_FUNC Trans
[])
90 StateMachineInit(Sm
, (STATE_MACHINE_FUNC
*)Trans
, MAX_SYNC_STATE
, MAX_SYNC_MSG
, (STATE_MACHINE_FUNC
)Drop
, SYNC_IDLE
, SYNC_MACHINE_BASE
);
93 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_MLME_SCAN_REQ
, (STATE_MACHINE_FUNC
)MlmeScanReqAction
);
94 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_MLME_JOIN_REQ
, (STATE_MACHINE_FUNC
)MlmeJoinReqAction
);
95 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_MLME_START_REQ
, (STATE_MACHINE_FUNC
)MlmeStartReqAction
);
96 StateMachineSetAction(Sm
, SYNC_IDLE
, MT2_PEER_BEACON
, (STATE_MACHINE_FUNC
)PeerBeacon
);
97 // StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_RSP, (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
->Mlme
.SyncAux
.BeaconTimer
, BeaconTimeout
);
117 RTMPInitTimer(pAd
, &pAd
->Mlme
.SyncAux
.ScanTimer
, ScanTimeout
);
121 ==========================================================================
123 Becaon timeout handler, executed in timer thread
124 ==========================================================================
127 IN
unsigned long data
)
129 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)data
;
131 DBGPRINT(RT_DEBUG_TRACE
,"SYNC - BeaconTimeout\n");
132 MlmeEnqueue(&pAd
->Mlme
.Queue
, SYNC_STATE_MACHINE
, MT2_BEACON_TIMEOUT
, 0, NULL
);
137 ==========================================================================
139 ATIM timeout handler, executed in timer thread
140 ==========================================================================
143 IN
unsigned long data
)
145 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)data
;
147 DBGPRINT(RT_DEBUG_TRACE
,"SYNC - AtimTimeout \n");
148 MlmeEnqueue(&pAd
->Mlme
.Queue
, SYNC_STATE_MACHINE
, MT2_ATIM_TIMEOUT
, 0, NULL
);
153 ==========================================================================
155 Scan timeout handler, executed in timer thread
156 ==========================================================================
159 IN
unsigned long data
)
161 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)data
;
163 DBGPRINT(RT_DEBUG_INFO
,"SYNC - Scan Timeout \n");
164 MlmeEnqueue(&pAd
->Mlme
.Queue
, SYNC_STATE_MACHINE
, MT2_SCAN_TIMEOUT
, 0, NULL
);
169 ==========================================================================
171 MLME SCAN req state machine procedure
172 ==========================================================================
174 VOID
MlmeScanReqAction(
175 IN PRTMP_ADAPTER pAd
,
176 IN MLME_QUEUE_ELEM
*Elem
)
178 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
, ScanType
, BssType
;
181 // Suspend MSDU transmission here
182 RTMPSuspendMsduTransmission(pAd
);
184 // first check the parameter sanity
185 if (MlmeScanReqSanity(pAd
,
193 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - MlmeScanReqAction\n");
195 pAd
->PortCfg
.LastScanTime
= Now
;
196 // reset all the timers
197 RTMPCancelTimer(&pAd
->Mlme
.SyncAux
.BeaconTimer
);
198 RTMPCancelTimer(&pAd
->Mlme
.SyncAux
.ScanTimer
);
200 // record desired BSS parameters
201 pAd
->Mlme
.SyncAux
.BssType
= BssType
;
202 pAd
->Mlme
.SyncAux
.ScanType
= ScanType
;
203 pAd
->Mlme
.SyncAux
.SsidLen
= SsidLen
;
204 NdisMoveMemory(pAd
->Mlme
.SyncAux
.Ssid
, Ssid
, SsidLen
);
206 // start from the first channel
207 pAd
->Mlme
.SyncAux
.Channel
= FirstChannel(pAd
);
208 ScanNextChannel(pAd
);
212 DBGPRINT(RT_DEBUG_ERROR
, "SYNC - MlmeScanReqAction() sanity check fail. BUG!!!\n");
213 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
214 MlmeCntlConfirm(pAd
, MT2_SCAN_CONF
, MLME_INVALID_FORMAT
);
219 ==========================================================================
221 MLME JOIN req state machine procedure
222 ==========================================================================
224 VOID
MlmeJoinReqAction(
225 IN PRTMP_ADAPTER pAd
,
226 IN MLME_QUEUE_ELEM
*Elem
)
229 MLME_JOIN_REQ_STRUCT
*Info
= (MLME_JOIN_REQ_STRUCT
*)(Elem
->Msg
);
231 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - MlmeJoinReqAction(BSS #%d)\n", Info
->BssIdx
);
233 // reset all the timers
234 RTMPCancelTimer(&pAd
->Mlme
.SyncAux
.ScanTimer
);
235 RTMPCancelTimer(&pAd
->Mlme
.SyncAux
.BeaconTimer
);
237 pBss
= &pAd
->Mlme
.CntlAux
.SsidBssTab
.BssEntry
[Info
->BssIdx
];
239 // record the desired SSID & BSSID we're waiting for
240 COPY_MAC_ADDR(&pAd
->Mlme
.SyncAux
.Bssid
, &pBss
->Bssid
);
241 NdisMoveMemory(pAd
->Mlme
.SyncAux
.Ssid
, pBss
->Ssid
, pBss
->SsidLen
);
242 pAd
->Mlme
.SyncAux
.SsidLen
= pBss
->SsidLen
;
244 // switch channel and waiting for beacon timer
245 AsicSwitchChannel(pAd
, pBss
->Channel
);
246 AsicLockChannel(pAd
, pBss
->Channel
);
247 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - Switch to channel %d, SSID %s \n", pBss
->Channel
, pAd
->Mlme
.SyncAux
.Ssid
);
248 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x ...\n",
249 pAd
->Mlme
.SyncAux
.Bssid
.Octet
[0], pAd
->Mlme
.SyncAux
.Bssid
.Octet
[1],
250 pAd
->Mlme
.SyncAux
.Bssid
.Octet
[2], pAd
->Mlme
.SyncAux
.Bssid
.Octet
[3],
251 pAd
->Mlme
.SyncAux
.Bssid
.Octet
[4], pAd
->Mlme
.SyncAux
.Bssid
.Octet
[5]);
252 RTMPSetTimer(pAd
, &pAd
->Mlme
.SyncAux
.BeaconTimer
, JOIN_TIMEOUT
);
254 pAd
->Mlme
.SyncMachine
.CurrState
= JOIN_WAIT_BEACON
;
258 ==========================================================================
260 MLME START Request state machine procedure, starting an IBSS
261 ==========================================================================
263 VOID
MlmeStartReqAction(
264 IN PRTMP_ADAPTER pAd
,
265 IN MLME_QUEUE_ELEM
*Elem
)
267 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
;
269 // New for WPA security suites
270 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
271 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
272 LARGE_INTEGER TimeStamp
;
274 #ifdef SINGLE_ADHOC_LINKUP
276 BOOLEAN CfExist
= FALSE
;
280 // Init Variable IE structure
281 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
283 TimeStamp
.vv
.LowPart
= 0;
284 TimeStamp
.vv
.HighPart
= 0;
286 if (MlmeStartReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, Ssid
, &SsidLen
))
288 // reset all the timers
289 RTMPCancelTimer(&pAd
->Mlme
.SyncAux
.ScanTimer
);
290 RTMPCancelTimer(&pAd
->Mlme
.SyncAux
.BeaconTimer
);
292 // PortCfg.PrivacyInvoked should have been set via OID_802_11_WEP_STATUS.
293 // pAd->PortCfg.PrivacyInvoked = FALSE;
295 NdisMoveMemory(pAd
->PortCfg
.Ssid
, Ssid
, SsidLen
);
296 pAd
->PortCfg
.SsidLen
= SsidLen
;
297 pAd
->PortCfg
.BssType
= BSS_INDEP
;
298 Privacy
= (pAd
->PortCfg
.WepStatus
== Ndis802_11Encryption1Enabled
) ||
299 (pAd
->PortCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) ||
300 (pAd
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
);
301 pAd
->PortCfg
.CapabilityInfo
= CAP_GENERATE(0,1,0,0,Privacy
, (pAd
->PortCfg
.WindowsTxPreamble
== Rt802_11PreambleShort
));
302 pAd
->PortCfg
.BeaconPeriod
= pAd
->PortCfg
.IbssConfig
.BeaconPeriod
;
303 pAd
->PortCfg
.AtimWin
= pAd
->PortCfg
.IbssConfig
.AtimWin
;
304 pAd
->PortCfg
.Channel
= pAd
->PortCfg
.IbssConfig
.Channel
;
305 if ((pAd
->PortCfg
.PhyMode
== PHY_11ABG_MIXED
) && (pAd
->PortCfg
.Channel
> 14))
307 // no 1,2,5.5,11 Mbps when in 5Ghz band
308 pAd
->PortCfg
.SupportedRatesLen
= pAd
->PortCfg
.IbssConfig
.SupportedRatesLen
- 4;
309 NdisZeroMemory(pAd
->PortCfg
.SupportedRates
, MAX_LEN_OF_SUPPORTED_RATES
);
310 NdisMoveMemory(pAd
->PortCfg
.SupportedRates
, &pAd
->PortCfg
.IbssConfig
.SupportedRates
[4], MAX_LEN_OF_SUPPORTED_RATES
- 4);
314 pAd
->PortCfg
.SupportedRatesLen
= pAd
->PortCfg
.IbssConfig
.SupportedRatesLen
;
315 NdisMoveMemory(pAd
->PortCfg
.SupportedRates
, pAd
->PortCfg
.IbssConfig
.SupportedRates
, MAX_LEN_OF_SUPPORTED_RATES
);
317 // pAd->PortCfg.Pss = PWR_ACTIVE;
319 // generate a radom number as BSSID
320 MacAddrRandomBssid(pAd
, &pAd
->PortCfg
.Bssid
);
321 AsicSetBssid(pAd
, &pAd
->PortCfg
.Bssid
);
322 AsicSwitchChannel(pAd
, pAd
->PortCfg
.Channel
);
323 AsicLockChannel(pAd
, pAd
->PortCfg
.Channel
);
325 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - MlmeStartReqAction(ch= %d,supported rate len= %d)\n",
326 pAd
->PortCfg
.Channel
, pAd
->PortCfg
.SupportedRatesLen
);
328 #ifdef SINGLE_ADHOC_LINKUP
329 // Add itself as the entry within BSS table
330 Bssidx
= BssTableSearch(&pAd
->PortCfg
.BssTab
, &pAd
->PortCfg
.Bssid
);
331 if (Bssidx
== BSS_NOT_FOUND
)
333 Bssidx
= BssTableSetEntry(pAd
, &pAd
->PortCfg
.BssTab
, &pAd
->PortCfg
.Bssid
,
334 Ssid
, SsidLen
, pAd
->PortCfg
.BssType
, pAd
->PortCfg
.BeaconPeriod
,
335 CfExist
, &CfParm
, pAd
->PortCfg
.AtimWin
, pAd
->PortCfg
.CapabilityInfo
,
336 pAd
->PortCfg
.SupportedRates
, pAd
->PortCfg
.SupportedRatesLen
, TRUE
,
337 pAd
->PortCfg
.Channel
, Elem
->Rssi
, TimeStamp
, pVIE
);
341 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
342 MlmeCntlConfirm(pAd
, MT2_START_CONF
, (USHORT
)MLME_SUCCESS
);
346 DBGPRINT(RT_DEBUG_ERROR
, "SYNC - MlmeStartReqAction() sanity check fail. BUG!!!\n");
347 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
348 MlmeCntlConfirm(pAd
, MT2_START_CONF
, MLME_INVALID_FORMAT
);
353 ==========================================================================
355 peer sends beacon back when scanning
356 ==========================================================================
358 VOID
PeerBeaconAtScanAction(
359 IN PRTMP_ADAPTER pAd
,
360 IN MLME_QUEUE_ELEM
*Elem
)
362 MACADDR Bssid
, Addr2
;
363 UCHAR Ssid
[MAX_LEN_OF_SSID
], BssType
, Channel
, Rates
[MAX_LEN_OF_SUPPORTED_RATES
], RatesLen
,
364 SsidLen
, DtimCount
, DtimPeriod
, BcastFlag
, MessageToMe
, Legacy
;
366 USHORT BeaconPeriod
, AtimWin
, CapabilityInfo
;
368 LARGE_INTEGER TimeStamp
;
369 BOOLEAN CfExist
= FALSE
;
370 BOOLEAN ExtendedRateIeExist
;
372 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
373 UCHAR SupRateLen
, ExtRateLen
;
375 // New for WPA security suites
376 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
377 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
379 // NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00);
380 Fr
= (MACFRAME
*) Elem
->Msg
;
381 // Init Variable IE structure
382 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
384 if (PeerBeaconAndProbeRspSanity(pAd
,
400 &ExtendedRateIeExist
,
416 // This correct im-proper RSSI indication during SITE SURVEY issue.
417 // Always report bigger RSSI during SCANNING when receiving multiple BEACONs from the same AP.
418 // This case happens because BEACONs come from adjacent channels, so RSSI become weaker as we
419 // switch to more far away channels.
420 Idx
= BssTableSearch(&pAd
->PortCfg
.BssTab
, &Bssid
);
421 if (Idx
!= BSS_NOT_FOUND
)
422 Rssi
= pAd
->PortCfg
.BssTab
.BssEntry
[Idx
].Rssi
;
423 if (Elem
->Rssi
> Rssi
)
426 DBGPRINT(RT_DEBUG_INFO
, "SYNC - PeerBeaconAtScanAction (Subtype=%d, SsidLen=%d, Ssid=%s)\n", Fr
->Hdr
.SubType
, SsidLen
,Ssid
);
428 // Mask out unnecessary capability information
429 CapabilityInfo
&= SUPPORTED_CAPABILITY_INFO
;
431 BssTableSetEntry(pAd
, &pAd
->PortCfg
.BssTab
, &Bssid
, Ssid
, SsidLen
, BssType
,
432 BeaconPeriod
, CfExist
, &CfParm
, AtimWin
, CapabilityInfo
, Rates
,
433 RatesLen
, ExtendedRateIeExist
, Channel
, Rssi
, TimeStamp
, pVIE
);
435 // sanity check fail, ignored
439 ==========================================================================
441 When waiting joining the (I)BSS, beacon received from external
442 ==========================================================================
444 VOID
PeerBeaconAtJoinAction(
445 IN PRTMP_ADAPTER pAd
,
446 IN MLME_QUEUE_ELEM
*Elem
)
448 MACADDR Bssid
, Addr2
;
449 UCHAR Ssid
[MAX_LEN_OF_SSID
], SsidLen
, BssType
, Channel
, RatesLen
, MessageToMe
,
450 Rates
[MAX_LEN_OF_SUPPORTED_RATES
], DtimCount
, DtimPeriod
, BcastFlag
, Legacy
;
451 LARGE_INTEGER TimeStamp
;
452 USHORT BeaconPeriod
, AtimWin
, CapabilityInfo
;
454 BOOLEAN CfExist
= FALSE
, ExtendedRateIeExist
;
456 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
457 UCHAR SupRateLen
, ExtRateLen
;
459 // New for WPA security suites
460 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
461 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
463 // Init Variable IE structure
464 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
466 if (PeerBeaconAndProbeRspSanity(pAd
,
483 &ExtendedRateIeExist
,
496 // Disqualify 11b only adhoc when we are in 11g only adhoc mode
497 if ((BssType
== BSS_INDEP
) && (pAd
->PortCfg
.AdhocMode
== 2) && (RatesLen
< 12))
500 if (MAC_ADDR_EQUAL(&pAd
->Mlme
.SyncAux
.Bssid
, &Bssid
))
502 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - receive desired BEACON at JoinWaitBeacon...\n");
503 RTMPCancelTimer(&pAd
->Mlme
.SyncAux
.BeaconTimer
);
505 // Update RSSI to prevent No signal display when cards first initialized
506 pAd
->PortCfg
.LastRssi
= Elem
->Rssi
;
507 pAd
->PortCfg
.AvgRssi
= Elem
->Rssi
;
509 if (pAd
->Mlme
.CntlAux
.SsidLen
> 0)
511 NdisMoveMemory(pAd
->PortCfg
.Ssid
, pAd
->Mlme
.CntlAux
.Ssid
, pAd
->Mlme
.CntlAux
.SsidLen
);
512 pAd
->PortCfg
.SsidLen
= pAd
->Mlme
.CntlAux
.SsidLen
;
516 NdisMoveMemory(pAd
->PortCfg
.Ssid
, Ssid
, SsidLen
);
517 pAd
->PortCfg
.SsidLen
= SsidLen
;
520 COPY_MAC_ADDR(&pAd
->PortCfg
.Bssid
, &Bssid
);
521 AsicSetBssid(pAd
, &pAd
->PortCfg
.Bssid
);
523 pAd
->PortCfg
.BssType
= BssType
;
524 pAd
->PortCfg
.BeaconPeriod
= BeaconPeriod
;
525 pAd
->PortCfg
.Channel
= Channel
;
527 // filter out non-supported rates
530 pAd
->PortCfg
.SupportedRatesLen
= 0;
531 for (i
=0;i
<RatesLen
;i
++)
533 UCHAR Rate
= Rates
[i
] & 0x7f;
534 if ((pAd
->PortCfg
.PhyMode
== PHY_11B
) &&
535 (Rate
== 2 || Rate
== 4 || Rate
== 11 || Rate
== 22))
537 ///DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Supported Rate[%d] = 0x%02x\n",pAd->PortCfg.SupportedRatesLen, Rates[i]));
538 pAd
->PortCfg
.SupportedRates
[pAd
->PortCfg
.SupportedRatesLen
] = Rates
[i
];
539 pAd
->PortCfg
.SupportedRatesLen
++;
541 else if ((Rate
== 2 || Rate
== 4 || Rate
== 11 || Rate
== 22) ||
542 (Rate
== 12 || Rate
== 18 || Rate
== 24 || Rate
== 36) ||
543 (Rate
== 48 || Rate
== 72 || Rate
== 96 || Rate
== 108))
545 // DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Supported Rate[%d] = 0x%02x\n",pAd->PortCfg.SupportedRatesLen, Rates[i]));
546 pAd
->PortCfg
.SupportedRates
[pAd
->PortCfg
.SupportedRatesLen
] = Rates
[i
];
547 pAd
->PortCfg
.SupportedRatesLen
++;
552 // Copy AP's supported rate to portcfg for creating assoication request
553 // Also filter out not supported rate
557 pAd
->PortCfg
.SupRateLen
= 0;
558 for (i
= 0; i
< SupRateLen
; i
++)
560 UCHAR Rate
= SupRate
[i
] & 0x7f;
561 if ((pAd
->PortCfg
.PhyMode
== PHY_11B
) &&
562 (Rate
== 2 || Rate
== 4 || Rate
== 11 || Rate
== 22))
564 pAd
->PortCfg
.SupRate
[pAd
->PortCfg
.SupRateLen
] = SupRate
[i
];
565 pAd
->PortCfg
.SupRateLen
++;
567 else if ((Rate
== 2 || Rate
== 4 || Rate
== 11 || Rate
== 22) ||
568 (Rate
== 12 || Rate
== 18 || Rate
== 24 || Rate
== 36) ||
569 (Rate
== 48 || Rate
== 72 || Rate
== 96 || Rate
== 108))
571 pAd
->PortCfg
.SupRate
[pAd
->PortCfg
.SupRateLen
] = SupRate
[i
];
572 pAd
->PortCfg
.SupRateLen
++;
577 // Copy AP's supported rate to portcfg for creating assoication request
578 // Also filter out not supported rate
580 if (ExtendedRateIeExist
== TRUE
)
583 pAd
->PortCfg
.ExtRateLen
= 0;
584 for (i
= 0; i
< ExtRateLen
; i
++)
586 UCHAR Rate
= ExtRate
[i
] & 0x7f;
587 if ((pAd
->PortCfg
.PhyMode
== PHY_11B
) &&
588 (Rate
== 2 || Rate
== 4 || Rate
== 11 || Rate
== 22))
590 pAd
->PortCfg
.ExtRate
[pAd
->PortCfg
.ExtRateLen
] = ExtRate
[i
];
591 pAd
->PortCfg
.ExtRateLen
++;
593 else if ((Rate
== 2 || Rate
== 4 || Rate
== 11 || Rate
== 22) ||
594 (Rate
== 12 || Rate
== 18 || Rate
== 24 || Rate
== 36) ||
595 (Rate
== 48 || Rate
== 72 || Rate
== 96 || Rate
== 108))
597 pAd
->PortCfg
.ExtRate
[pAd
->PortCfg
.ExtRateLen
] = ExtRate
[i
];
598 pAd
->PortCfg
.ExtRateLen
++;
604 pAd
->PortCfg
.ExtRateLen
= 0;
607 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - AP's SupportedRatesLen=%d, set STA's SupportedRateLen=%d\n",
608 RatesLen
, pAd
->PortCfg
.SupportedRatesLen
);
610 // Mask out unnecessary capability information
611 CapabilityInfo
&= SUPPORTED_CAPABILITY_INFO
;
613 // Check for 802.11g information, if 802.11 b/g mixed mode.
614 // We can't support its short preamble for now.
615 pAd
->PortCfg
.CapabilityInfo
= CapabilityInfo
;
617 if ((BssType
== BSS_INDEP
) && (CAP_IS_IBSS_ON(CapabilityInfo
)))
619 pAd
->PortCfg
.AtimWin
= AtimWin
;
621 else if (BssType
== BSS_INFRA
)
623 pAd
->PortCfg
.CfpPeriod
= Cf
.CfpPeriod
;
624 pAd
->PortCfg
.CfpMaxDuration
= Cf
.CfpMaxDuration
;
625 pAd
->PortCfg
.CfpDurRemain
= Cf
.CfpDurRemaining
;
626 pAd
->PortCfg
.CfpCount
= Cf
.CfpCount
;
627 pAd
->PortCfg
.CfpPeriod
= Cf
.CfpPeriod
;
629 AsicEnableBssSync(pAd
);
632 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
633 MlmeCntlConfirm(pAd
, MT2_JOIN_CONF
, MLME_SUCCESS
);
635 // not to me BEACON, ignored
637 // sanity check fail, ignore this frame
641 ==========================================================================
643 receive BEACON from peer
644 ==========================================================================
647 IN PRTMP_ADAPTER pAd
,
648 IN MLME_QUEUE_ELEM
*Elem
)
650 MACADDR Bssid
, Addr2
;
651 CHAR Ssid
[MAX_LEN_OF_SSID
];
653 UCHAR SsidLen
, MessageToMe
=0, BssType
, Channel
, Rates
[MAX_LEN_OF_SUPPORTED_RATES
];
654 UCHAR RatesLen
, DtimCount
=0, DtimPeriod
=0, BcastFlag
=0, Legacy
;
655 USHORT CapabilityInfo
, AtimWin
, BeaconPeriod
;
656 LARGE_INTEGER TimeStamp
;
657 BOOLEAN CfExist
= FALSE
;
658 USHORT TbttNumToNextWakeUp
;
659 BOOLEAN ExtendedRateIeExist
;
661 UCHAR SupRate
[MAX_LEN_OF_SUPPORTED_RATES
], ExtRate
[MAX_LEN_OF_SUPPORTED_RATES
];
662 UCHAR SupRateLen
, ExtRateLen
;
664 // New for WPA security suites
665 UCHAR VarIE
[MAX_VIE_LEN
]; // Total VIE length = MAX_VIE_LEN - -5
666 NDIS_802_11_VARIABLE_IEs
*pVIE
= NULL
;
668 if (!INFRA_ON(pAd
) && !ADHOC_ON(pAd
))
671 // Init Variable IE structure
672 pVIE
= (PNDIS_802_11_VARIABLE_IEs
) VarIE
;
674 if (PeerBeaconAndProbeRspSanity(pAd
,
691 &ExtendedRateIeExist
,
704 BOOLEAN is_my_bssid
, is_my_ssid
;
708 is_my_bssid
= (MAC_ADDR_EQUAL(&Bssid
, &pAd
->PortCfg
.Bssid
) ? TRUE
: FALSE
);
709 is_my_ssid
= (((pAd
->PortCfg
.SsidLen
== SsidLen
) && RTMPEqualMemory(Ssid
, pAd
->PortCfg
.Ssid
, (ULONG
) SsidLen
)) ? TRUE
: FALSE
);
710 // Mask out unnecessary capability information
711 CapabilityInfo
&= SUPPORTED_CAPABILITY_INFO
;
713 // ignore BEACON not for my SSID
714 if ((! is_my_ssid
) && (! is_my_bssid
))
718 // Housekeeping "SsidBssTab" table for later-on ROAMing usage.
720 Bssidx
= BssTableSearch(&pAd
->Mlme
.CntlAux
.SsidBssTab
, &Bssid
);
721 if (Bssidx
== BSS_NOT_FOUND
)
723 // Return immediately when in transition process when changing association
724 // Found this bug when doing WHQL ad-hoc test case
725 if (pAd
->PortCfg
.SsidLen
!= pAd
->Mlme
.CntlAux
.SsidLen
)
727 if (!RTMPEqualMemory(pAd
->PortCfg
.Ssid
, pAd
->Mlme
.CntlAux
.Ssid
, pAd
->PortCfg
.SsidLen
))
730 // discover new AP of this network, create BSS entry
731 Bssidx
= BssTableSetEntry(pAd
, &pAd
->Mlme
.CntlAux
.SsidBssTab
, &Bssid
, Ssid
, SsidLen
,
732 BssType
, BeaconPeriod
, CfExist
, &CfParm
, AtimWin
, CapabilityInfo
,
733 Rates
, RatesLen
, ExtendedRateIeExist
, Channel
, Elem
->Rssi
, TimeStamp
, pVIE
);
735 if (Bssidx
== BSS_NOT_FOUND
) // return if BSS table full
738 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - New AP added to SsidBssTab[%d], RSSI=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
739 Bssidx
, Elem
->Rssi
, Bssid
.Octet
[0], Bssid
.Octet
[1], Bssid
.Octet
[2],
740 Bssid
.Octet
[3], Bssid
.Octet
[4], Bssid
.Octet
[5]);
743 // if the ssid matched & bssid unmatched, we should select the bssid with large value.
744 // This might happened when two STA start at the same time
745 if (is_my_ssid
&& (! is_my_bssid
) && ADHOC_ON(pAd
) && (BssType
== BSS_INDEP
))
748 // Add to safe guard adhoc wep status mismatch
749 if (pAd
->PortCfg
.WepStatus
!= pAd
->Mlme
.CntlAux
.SsidBssTab
.BssEntry
[Bssidx
].WepStatus
)
752 // link down the one with smaller BSSID value.
753 for (i
= 0; i
< 6; i
++)
755 if (Bssid
.Octet
[i
] > pAd
->PortCfg
.Bssid
.Octet
[i
])
757 AsicDisableSync(pAd
);
758 NdisMoveMemory(&pAd
->PortCfg
.Bssid
, &Bssid
, 6);
759 AsicSetBssid(pAd
, &pAd
->PortCfg
.Bssid
);
761 AsicEnableIbssSync(pAd
);
767 DBGPRINT(RT_DEBUG_INFO
, "SYNC - PeerBeacon from %02x:%02x:%02x:%02x:%02x:%02x - Dtim=%d/%d, Rssi=%02x\n",
768 Bssid
.Octet
[0], Bssid
.Octet
[1], Bssid
.Octet
[2],
769 Bssid
.Octet
[3], Bssid
.Octet
[4], Bssid
.Octet
[5],
770 DtimCount
, DtimPeriod
, Elem
->Rssi
);
773 pBss
= &pAd
->Mlme
.CntlAux
.SsidBssTab
.BssEntry
[Bssidx
];
774 pBss
->Rssi
= Elem
->Rssi
; // lastest RSSI
775 pBss
->LastBeaconRxTime
= Now
; // last RX timestamp
778 // BEACON from my BSSID - either IBSS or INFRA network
782 // 2002/12/06 - patch Abocom AP bug, which forgets to set "Privacy" bit in
783 // AssocRsp even though this bit is ON in Beacon. So we update according
784 // to following Beacon frame.
785 // pAd->PortCfg.PrivacyInvoked = CAP_IS_PRIVACY_ON(CapabilityInfo);
787 pAd
->PortCfg
.LastBeaconRxTime
= Now
;
789 // at least one 11b peer joined. downgrade the MaxTxRate to 11Mbps
790 // after last 11b peer left for several seconds, we'll auto switch back to 11G rate
791 // in MlmePeriodicExec()
792 if (ADHOC_ON(pAd
) && (RatesLen
<= 4))
794 // this timestamp is for MlmePeriodicExec() to check if all 11B peers have left
795 pAd
->PortCfg
.Last11bBeaconRxTime
= Now
;
797 if (pAd
->PortCfg
.MaxTxRate
> RATE_11
)
799 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - 11b peer joined. down-grade to 11b TX rates \n");
800 NdisMoveMemory(pAd
->PortCfg
.SupportedRates
, Rates
, MAX_LEN_OF_SUPPORTED_RATES
);
801 pAd
->PortCfg
.SupportedRatesLen
= RatesLen
;
802 MlmeUpdateTxRates(pAd
, FALSE
);
803 MakeIbssBeacon(pAd
); // supported rates changed
807 // check if RSSI reaches threshold
808 pAd
->PortCfg
.LastRssi
= (pAd
->PortCfg
.LastRssi
+ Elem
->Rssi
) / 2;
809 pAd
->PortCfg
.AvgRssi
= (pAd
->PortCfg
.AvgRssi
* 7 + Elem
->Rssi
) >> 3;
810 if ((pAd
->PortCfg
.RssiTriggerMode
== RSSI_TRIGGERED_UPON_BELOW_THRESHOLD
) &&
811 (pAd
->PortCfg
.LastRssi
< pAd
->PortCfg
.RssiTrigger
))
813 // NDIS_802_11_RSSI Dbm = pAd->PortCfg.LastRssi - RSSI_TO_DBM_OFFSET;
814 // DBGPRINT(RT_DEBUG_TRACE, "SYNC - NdisMIndicateStatus *** RSSI %d dBm, less than threshold %d dBm\n",
815 // Dbm, pAd->PortCfg.RssiTrigger - RSSI_TO_DBM_OFFSET);
817 else if ((pAd
->PortCfg
.RssiTriggerMode
== RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD
) &&
818 (pAd
->PortCfg
.LastRssi
> pAd
->PortCfg
.RssiTrigger
))
820 // NDIS_802_11_RSSI Dbm = pAd->PortCfg.LastRssi - RSSI_TO_DBM_OFFSET;
821 // DBGPRINT(RT_DEBUG_TRACE, "SYNC - NdisMIndicateStatus *** RSSI %d dBm, greater than threshold %d dBm\n",
822 // Dbm, pAd->PortCfg.RssiTrigger - RSSI_TO_DBM_OFFSET);
825 if (INFRA_ON(pAd
)) // && (pAd->PortCfg.PhyMode == PHY_11BG_MIXED))
827 BOOLEAN bUseShortSlot
, bUseBGProtection
;
829 // decide to use/change to -
830 // 1. long slot (20 us) or short slot (9 us) time
831 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
833 bUseShortSlot
= (pAd
->PortCfg
.UseShortSlotTime
== TRUE
) && CAP_IS_SHORT_SLOT_TIME(CapabilityInfo
);
834 if (bUseShortSlot
!= pAd
->PortCfg
.ShortSlotInUsed
)
835 AsicSetSlotTime(pAd
, bUseShortSlot
);
837 bUseBGProtection
= (pAd
->PortCfg
.UseBGProtection
== 1) || // always use
838 ((pAd
->PortCfg
.UseBGProtection
== 0) && ERP_IS_USE_PROTECTION(Erp
));
839 if (bUseBGProtection
!= pAd
->PortCfg
.BGProtectionInUsed
)
841 pAd
->PortCfg
.BGProtectionInUsed
= bUseBGProtection
;
842 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - AP changed B/G protection to %d\n", bUseBGProtection
);
845 if ((pAd
->PortCfg
.TxPreambleInUsed
== Rt802_11PreambleShort
) && ERP_IS_USE_BARKER_PREAMBLE(Erp
))
847 MlmeSetTxPreamble(pAd
, Rt802_11PreambleLong
);
848 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - AP forced to use LONG preamble\n");
852 // only INFRASTRUCTURE mode support power-saving feature
853 if (INFRA_ON(pAd
) && (pAd
->PortCfg
.Psm
== PWR_SAVE
))
855 // 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
856 // 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
857 // 3. we have outgoing frames in TxRing or PrioRing, better stay AWAKE
858 // 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
859 // 5. otherwise, put PHY back to sleep to save battery.
862 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - AP backlog unicast-to-me, stay AWAKE, send PSPOLL\n");
865 else if (BcastFlag
&& (DtimCount
== 0) && pAd
->PortCfg
.RecvDtim
)
867 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - AP backlog broadcast/multicast, stay AWAKE\n");
869 else if ((RTMPFreeDescriptorRequest(pAd
, TX_RING
, TX_RING_SIZE
) != NDIS_STATUS_SUCCESS
) ||
870 (RTMPFreeDescriptorRequest(pAd
, PRIO_RING
, PRIO_RING_SIZE
) != NDIS_STATUS_SUCCESS
))
872 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - outgoing frame in TxRing/PrioRing, stay AWAKE\n");
876 USHORT NextDtim
= DtimCount
;
879 NextDtim
= DtimPeriod
;
881 TbttNumToNextWakeUp
= pAd
->PortCfg
.DefaultListenCount
;
882 if (pAd
->PortCfg
.RecvDtim
&& (TbttNumToNextWakeUp
> NextDtim
))
883 TbttNumToNextWakeUp
= NextDtim
;
885 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - PHY sleeps for %d Tbcn, Dtim=%d/%d\n", TbttNumToNextWakeUp
, DtimCount
, DtimPeriod
);
886 AsicSleepThenAutoWakeup(pAd
, TbttNumToNextWakeUp
);
890 #ifndef SINGLE_ADHOC_LINKUP
891 // At least another peer in this IBSS, declare MediaState as CONNECTED
892 if (ADHOC_ON(pAd
) && (pAd
->MediaState
== NdisMediaStateDisconnected
) && (BssType
== BSS_INDEP
))
894 pAd
->MediaState
= NdisMediaStateConnected
;
897 // Make sure this entry in "PortCfg.BssTab" table, thus complies to Microsoft's policy that
898 // "site survey" result should always include the current connected network.
900 Bssidx
= BssTableSearch(&pAd
->PortCfg
.BssTab
, &Bssid
);
901 if (Bssidx
== BSS_NOT_FOUND
)
903 Bssidx
= BssTableSetEntry(pAd
, &pAd
->PortCfg
.BssTab
, &Bssid
, Ssid
, SsidLen
,
904 BssType
, BeaconPeriod
, CfExist
, &CfParm
, AtimWin
, CapabilityInfo
,
905 Rates
, RatesLen
, ExtendedRateIeExist
, Channel
, Elem
->Rssi
, TimeStamp
, pVIE
);
910 // not my BSSID, ignore it
912 // sanity check fail, ignore this frame
916 ==========================================================================
918 Receive PROBE REQ from remote peer when operating in IBSS mode
919 ==========================================================================
921 VOID
PeerProbeReqAction(
922 IN PRTMP_ADAPTER pAd
,
923 IN MLME_QUEUE_ELEM
*Elem
)
926 CHAR Ssid
[MAX_LEN_OF_SSID
];
930 UCHAR
*OutBuffer
= NULL
;
932 LARGE_INTEGER FakeTimestamp
;
933 UCHAR SsidIe
= IE_SSID
, DsIe
= IE_DS_PARM
, IbssIe
= IE_IBSS_PARM
, SuppIe
= IE_SUPP_RATES
,
934 DsLen
= 1, IbssLen
= 2;
935 UCHAR SupportedRatesLen
;
936 UCHAR SupportedRates
[MAX_LEN_OF_SUPPORTED_RATES
];
937 UCHAR ExtRateIe
= IE_EXT_SUPP_RATES
, ExtRatesLen
;
938 UCHAR ErpIe
[3] = {IE_ERP
, 1, 0};
943 if (PeerProbeReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &Addr2
, Ssid
, &SsidLen
)) //, Rates, &RatesLen))
945 if ((SsidLen
== 0) || RTMPEqualMemory(Ssid
, pAd
->PortCfg
.Ssid
, (ULONG
) SsidLen
))
949 // we should respond a ProbeRsp only when we're the last BEACON transmitter
950 // in this ADHOC network.
951 RTMP_IO_READ32(pAd
, CSR15
, &Csr15
.word
);
952 if (Csr15
.field
.BeaconSent
== 0)
954 DBGPRINT(RT_DEBUG_INFO
, "SYNC - NOT last BEACON sender, no PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n",
955 Addr2
.Octet
[0],Addr2
.Octet
[1],Addr2
.Octet
[2],Addr2
.Octet
[3],Addr2
.Octet
[4],Addr2
.Octet
[5] );
959 // 2003-12-10 802.11g WIFI spec disallow OFDM rates in 802.11g ADHOC mode
960 // make sure 1,2,5.5,11 are the firt 4 rates in PortCfg.SupportedRates[] array
961 if ((pAd
->PortCfg
.PhyMode
== PHY_11BG_MIXED
) && (pAd
->PortCfg
.AdhocMode
== 0))
965 for (i
=0;i
<pAd
->PortCfg
.SupportedRatesLen
;i
++)
967 switch (pAd
->PortCfg
.SupportedRates
[i
] & 0x7f)
973 SupportedRates
[SupportedRatesLen
] = pAd
->PortCfg
.SupportedRates
[i
];
974 SupportedRatesLen
++;
980 // error handling - should never happen
981 if (SupportedRatesLen
!= 4)
983 SupportedRatesLen
= 4;
984 SupportedRates
[0] = 0x82;
985 SupportedRates
[1] = 0x84;
986 SupportedRates
[2] = 0x8b;
987 SupportedRates
[3] = 0x96;
992 SupportedRatesLen
= pAd
->PortCfg
.SupportedRatesLen
;
993 NdisMoveMemory(SupportedRates
, pAd
->PortCfg
.SupportedRates
, SupportedRatesLen
);
996 // allocate and send out ProbeRsp frame
997 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
998 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1001 pAd
->PortCfg
.AtimWin
= 0; // ??????
1002 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n",
1003 Addr2
.Octet
[0],Addr2
.Octet
[1],Addr2
.Octet
[2],Addr2
.Octet
[3],Addr2
.Octet
[4],Addr2
.Octet
[5] );
1004 MgtMacHeaderInit(pAd
, &ProbeRspHdr
, SUBTYPE_PROBE_RSP
, 0, &Addr2
, &pAd
->PortCfg
.Bssid
);
1006 if (SupportedRatesLen
<= 8)
1008 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
1009 MAC_HDR_LEN
, &ProbeRspHdr
,
1010 TIMESTAMP_LEN
, &FakeTimestamp
,
1011 2, &pAd
->PortCfg
.BeaconPeriod
,
1012 2, &pAd
->PortCfg
.CapabilityInfo
,
1014 1, &pAd
->PortCfg
.SsidLen
,
1015 pAd
->PortCfg
.SsidLen
, pAd
->PortCfg
.Ssid
,
1017 1, &SupportedRatesLen
,
1018 SupportedRatesLen
, SupportedRates
,
1021 1, &pAd
->PortCfg
.Channel
,
1024 2, &pAd
->PortCfg
.AtimWin
,
1029 ExtRatesLen
= SupportedRatesLen
- 8;
1030 SupportedRatesLen
= 8;
1031 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
1032 MAC_HDR_LEN
, &ProbeRspHdr
,
1033 TIMESTAMP_LEN
, &FakeTimestamp
,
1034 2, &pAd
->PortCfg
.BeaconPeriod
,
1035 2, &pAd
->PortCfg
.CapabilityInfo
,
1037 1, &pAd
->PortCfg
.SsidLen
,
1038 pAd
->PortCfg
.SsidLen
, pAd
->PortCfg
.Ssid
,
1040 1, &SupportedRatesLen
,
1041 SupportedRatesLen
, SupportedRates
,
1044 1, &pAd
->PortCfg
.Channel
,
1047 2, &pAd
->PortCfg
.AtimWin
,
1051 ExtRatesLen
, &SupportedRates
[SupportedRatesLen
],
1054 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1055 if (pAd
->PortCfg
.AuthMode
== Ndis802_11AuthModeWPANone
)
1058 UCHAR WpaIe
= IE_WPA
;
1060 if (pAd
->PortCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) // Tkip
1062 MakeOutgoingFrame(OutBuffer
+ FrameLen
, &tmp
,
1064 1, &CipherSuiteWpaNoneTkipLen
,
1065 CipherSuiteWpaNoneTkipLen
, &CipherSuiteWpaNoneTkip
[0],
1069 else if (pAd
->PortCfg
.WepStatus
== Ndis802_11Encryption3Enabled
) // Aes
1071 MakeOutgoingFrame(OutBuffer
+ FrameLen
, &tmp
,
1073 1, &CipherSuiteWpaNoneAesLen
,
1074 CipherSuiteWpaNoneAesLen
, &CipherSuiteWpaNoneAes
[0],
1079 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
1084 VOID
BeaconTimeoutAtJoinAction(
1085 IN PRTMP_ADAPTER pAd
,
1086 IN MLME_QUEUE_ELEM
*Elem
)
1088 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - BeaconTimeoutAtJoinAction\n");
1089 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1090 MlmeCntlConfirm(pAd
, MT2_JOIN_CONF
, MLME_REJ_TIMEOUT
);
1094 ==========================================================================
1096 Scan timeout procedure. basically add channel index by 1 and rescan
1097 ==========================================================================
1099 VOID
ScanTimeoutAction(
1100 IN PRTMP_ADAPTER pAd
,
1101 IN MLME_QUEUE_ELEM
*Elem
)
1103 pAd
->Mlme
.SyncAux
.Channel
= NextChannel(pAd
, pAd
->Mlme
.SyncAux
.Channel
);
1104 ScanNextChannel(pAd
);
1108 ==========================================================================
1111 ==========================================================================
1113 VOID
ScanNextChannel(
1114 IN PRTMP_ADAPTER pAd
)
1117 UCHAR SsidIe
= IE_SSID
, SuppRateIe
= IE_SUPP_RATES
;
1118 VOID
*OutBuffer
= NULL
;
1119 VOID
*OutBuffer2
= NULL
;
1120 NDIS_STATUS NStatus
;
1124 if (pAd
->Mlme
.SyncAux
.Channel
== 0)
1126 DBGPRINT(RT_DEBUG_INFO
, "SYNC - End of SCAN, restore to channel %d\n",pAd
->PortCfg
.Channel
);
1127 AsicSwitchChannel(pAd
, pAd
->PortCfg
.Channel
);
1128 AsicLockChannel(pAd
, pAd
->PortCfg
.Channel
);
1130 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1131 MlmeCntlConfirm(pAd
, MT2_SCAN_CONF
, MLME_SUCCESS
);
1135 AsicSwitchChannel(pAd
, pAd
->Mlme
.SyncAux
.Channel
);
1137 // Total SCAN time still limits within 3 sec (DDK constraint).
1138 // TODO: We need more intelligent rules here to further improve out-of-service issue.
1139 // e.g. temporary stop copying NDIS packet to TxRing until SCAN complete
1140 // if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1142 // We need to shorten active scan time in order for WZC connect issue
1143 if (pAd
->Mlme
.SyncAux
.ScanType
== SCAN_ACTIVE
)
1144 RTMPSetTimer(pAd
, &pAd
->Mlme
.SyncAux
.ScanTimer
, ACTIVE_SCAN_TIME
);
1145 else if (pAd
->PortCfg
.PhyMode
== PHY_11ABG_MIXED
)
1146 RTMPSetTimer(pAd
, &pAd
->Mlme
.SyncAux
.ScanTimer
, MIN_CHANNEL_TIME
);
1148 RTMPSetTimer(pAd
, &pAd
->Mlme
.SyncAux
.ScanTimer
, MAX_CHANNEL_TIME
);
1150 MgtMacHeaderInit(pAd
, &Hdr
, SUBTYPE_PROBE_REQ
, 0, &pAd
->PortCfg
.Broadcast
, &pAd
->PortCfg
.Broadcast
);
1151 // There is no need to send broadcast probe request if active scan is in effect.
1152 // The same rulr should apply to passive scan also.
1153 if (pAd
->Mlme
.SyncAux
.ScanType
== SCAN_PASSIVE
)
1155 // Send the first probe request with empty SSID
1156 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
1157 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1159 DBGPRINT(RT_DEBUG_INFO
, "SYNC - ScanNextChannel() allocate memory fail\n");
1160 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1161 MlmeCntlConfirm(pAd
, MT2_SCAN_CONF
, MLME_FAIL_NO_RESOURCE
);
1165 DBGPRINT(RT_DEBUG_INFO
, "SYNC - send passive ProbeReq @ channel=%d...\n", pAd
->Mlme
.SyncAux
.Channel
);
1167 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
1168 sizeof(MACHDR
), (UCHAR
*)&Hdr
,
1172 1, &pAd
->PortCfg
.SupportedRatesLen
,
1173 pAd
->PortCfg
.SupportedRatesLen
, pAd
->PortCfg
.SupportedRates
,
1175 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
1177 else if (pAd
->Mlme
.SyncAux
.ScanType
== SCAN_ACTIVE
)
1179 // Allocate another for probe scan with SSID
1180 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer2
); //Get an unused nonpaged memory
1181 if (NStatus
!= NDIS_STATUS_SUCCESS
)
1183 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - ScanNextChannel() allocate memory fail\n");
1184 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1185 MlmeCntlConfirm(pAd
, MT2_SCAN_CONF
, MLME_FAIL_NO_RESOURCE
);
1188 // make another probe scan with SSID from mlme.cntlaux.ssid
1189 SsidLen
= pAd
->Mlme
.SyncAux
.SsidLen
;
1190 MakeOutgoingFrame(OutBuffer2
, &FrameLen
,
1191 sizeof(MACHDR
), &Hdr
,
1194 SsidLen
, pAd
->Mlme
.SyncAux
.Ssid
,
1196 1, &pAd
->PortCfg
.SupportedRatesLen
,
1197 pAd
->PortCfg
.SupportedRatesLen
, pAd
->PortCfg
.SupportedRates
,
1199 MiniportMMRequest(pAd
, OutBuffer2
, FrameLen
);
1201 DBGPRINT(RT_DEBUG_INFO
, "SYNC - send active ProbeReq @ channel=%d...\n", pAd
->Mlme
.SyncAux
.Channel
);
1204 pAd
->Mlme
.SyncMachine
.CurrState
= SCAN_LISTEN
;
1209 ==========================================================================
1211 ==========================================================================
1213 VOID
InvalidStateWhenScan(
1214 IN PRTMP_ADAPTER pAd
,
1215 IN MLME_QUEUE_ELEM
*Elem
)
1217 DBGPRINT(RT_DEBUG_TRACE
, "AYNC - InvalidStateWhenScan(state=%d). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
);
1218 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1219 MlmeCntlConfirm(pAd
, MT2_SCAN_CONF
, MLME_STATE_MACHINE_REJECT
);
1223 ==========================================================================
1225 ==========================================================================
1227 VOID
InvalidStateWhenJoin(
1228 IN PRTMP_ADAPTER pAd
,
1229 IN MLME_QUEUE_ELEM
*Elem
)
1231 DBGPRINT(RT_DEBUG_TRACE
, "InvalidStateWhenJoin(state=%d). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
);
1232 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1233 MlmeCntlConfirm(pAd
, MT2_JOIN_CONF
, MLME_STATE_MACHINE_REJECT
);
1237 ==========================================================================
1239 ==========================================================================
1241 VOID
InvalidStateWhenStart(
1242 IN PRTMP_ADAPTER pAd
,
1243 IN MLME_QUEUE_ELEM
*Elem
)
1245 DBGPRINT(RT_DEBUG_TRACE
, "InvalidStateWhenStart(state=%d). Reset SYNC machine\n", pAd
->Mlme
.SyncMachine
.CurrState
);
1246 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
1247 MlmeCntlConfirm(pAd
, MT2_START_CONF
, MLME_STATE_MACHINE_REJECT
);
1251 ==========================================================================
1253 ==========================================================================
1256 IN PRTMP_ADAPTER pAd
)
1261 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - send PsPoll ...\n");
1263 NState
= MlmeAllocateMemory(pAd
, (PVOID
)&PsFr
); //Get an unused nonpaged memory
1264 if (NState
== NDIS_STATUS_SUCCESS
)
1266 NdisMoveMemory((VOID
*)PsFr
, (VOID
*)&pAd
->Mlme
.PsFr
, sizeof(PSPOLL_FRAME
));
1267 MiniportMMRequest(pAd
, (VOID
*)PsFr
, sizeof(PSPOLL_FRAME
));
1272 // driver force send out a BEACON frame to cover ADHOC mode BEACON starving issue
1273 // that is, in ADHOC mode, driver guarantee itself can send out at least a BEACON
1274 // per a specified duration, even the peer's clock is faster than us and win all the
1275 // hardware-based BEACON TX oppertunity.
1276 // we may remove this software feature once 2560 IC fix this problem in ASIC.
1277 VOID
EnqueueBeaconFrame(
1278 IN PRTMP_ADAPTER pAd
)
1281 PTXD_STRUC pTxD
= (PTXD_STRUC
)pAd
->BeaconRing
.va_addr
;
1285 NState
= MlmeAllocateMemory(pAd
, (PVOID
)&pBeacon
); //Get an unused nonpaged memory
1286 if (NState
== NDIS_STATUS_SUCCESS
)
1288 DBGPRINT(RT_DEBUG_TRACE
, "SYNC - driver sent BEACON (len=%d)...\n",pTxD
->DataByteCnt
);
1289 RTMP_IO_READ32(pAd
, CSR17
, &Tsf
.vv
.HighPart
);
1290 RTMP_IO_READ32(pAd
, CSR16
, &Tsf
.vv
.LowPart
);
1291 NdisMoveMemory(pBeacon
, pAd
->BeaconRing
.va_data_addr
, pTxD
->DataByteCnt
);
1292 NdisMoveMemory(pBeacon
+ MAC_HDR_LEN
, &Tsf
, TIMESTAMP_LEN
);
1293 MiniportMMRequest(pAd
, (VOID
*)pBeacon
, pTxD
->DataByteCnt
);
1298 ==========================================================================
1300 Send out a NULL frame to AP. The prpose is to inform AP this client
1303 This routine should only be used in infrastructure mode.
1304 ==========================================================================
1306 VOID
EnqueueNullFrame(
1307 IN PRTMP_ADAPTER pAd
,
1313 // since TxRate may change, we have to change Duration each time
1314 pAd
->Mlme
.NullFr
.Duration
= RTMPCalcDuration(pAd
, TxRate
, 14);
1315 NState
= MlmeAllocateMemory(pAd
, (PVOID
)&NullFr
); //Get an unused nonpaged memory
1316 if (NState
== NDIS_STATUS_SUCCESS
)
1318 NdisMoveMemory((VOID
*)NullFr
, (VOID
*)&pAd
->Mlme
.NullFr
, sizeof(MACHDR
));
1319 RTMPSendNullFrame(pAd
, (VOID
*)NullFr
, sizeof(MACHDR
), TxRate
);
1324 ==========================================================================
1326 ==========================================================================
1328 VOID
EnqueueProbeRequest(
1329 IN PRTMP_ADAPTER pAd
)
1332 UCHAR SsidIe
= IE_SSID
, SuppRateIe
= IE_SUPP_RATES
;
1337 DBGPRINT(RT_DEBUG_TRACE
, "force out a ProbeRequest ...\n");
1339 NState
= MlmeAllocateMemory(pAd
, (PVOID
)&OutBuffer
); //Get an unused nonpaged memory
1340 if (NState
== NDIS_STATUS_SUCCESS
)
1342 MgtMacHeaderInit(pAd
, &Hdr
, SUBTYPE_PROBE_REQ
, 0, &pAd
->PortCfg
.Broadcast
, &pAd
->PortCfg
.Broadcast
);
1344 // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
1345 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
1346 sizeof(MACHDR
), &Hdr
,
1348 1, &pAd
->PortCfg
.SsidLen
,
1349 pAd
->PortCfg
.SsidLen
, pAd
->PortCfg
.Ssid
,
1351 1, &pAd
->PortCfg
.SupportedRatesLen
,
1352 pAd
->PortCfg
.SupportedRatesLen
, pAd
->PortCfg
.SupportedRates
,
1354 MiniportMMRequest(pAd
, OutBuffer
, FrameLen
);
1359 ==========================================================================
1361 Update PortCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
1362 and 3) PHY-mode user selected.
1363 The outcome is used by driver when doing site survey.
1364 ==========================================================================
1366 VOID
BuildChannelList(
1367 IN PRTMP_ADAPTER pAd
)
1370 NdisZeroMemory(pAd
->PortCfg
.ChannelList
, MAX_LEN_OF_CHANNELS
);
1372 // if not 11a-only mode, channel list starts from 2.4Ghz band
1373 if (pAd
->PortCfg
.PhyMode
!= PHY_11A
)
1375 switch (pAd
->PortCfg
.CountryRegion
)
1377 case REGION_FCC
: // 1 - 11
1378 NdisMoveMemory(&pAd
->PortCfg
.ChannelList
[index
], Ra24Ghz_FCC
, sizeof(Ra24Ghz_FCC
));
1379 index
+= sizeof(Ra24Ghz_FCC
);
1381 case REGION_IC
: // 1 -11
1382 NdisMoveMemory(&pAd
->PortCfg
.ChannelList
[index
], Ra24Ghz_IC
, sizeof(Ra24Ghz_IC
));
1383 index
+= sizeof(Ra24Ghz_IC
);
1385 case REGION_ISRAEL
: // 3 - 9
1386 NdisMoveMemory(&pAd
->PortCfg
.ChannelList
[index
], Ra24Ghz_ISRAEL
, sizeof(Ra24Ghz_ISRAEL
));
1387 index
+= sizeof(Ra24Ghz_ISRAEL
);
1389 case REGION_ETSI
: // 1 - 13
1390 NdisMoveMemory(&pAd
->PortCfg
.ChannelList
[index
], Ra24Ghz_ESTI
, sizeof(Ra24Ghz_ESTI
));
1391 index
+= sizeof(Ra24Ghz_ESTI
);
1393 case REGION_SPAIN
: // 10 - 11
1394 NdisMoveMemory(&pAd
->PortCfg
.ChannelList
[index
], Ra24Ghz_SPAIN
, sizeof(Ra24Ghz_SPAIN
));
1395 index
+= sizeof(Ra24Ghz_SPAIN
);
1397 case REGION_FRANCE
: // 10 -13
1398 NdisMoveMemory(&pAd
->PortCfg
.ChannelList
[index
], Ra24Ghz_FRANCE
, sizeof(Ra24Ghz_FRANCE
));
1399 index
+= sizeof(Ra24Ghz_FRANCE
);
1401 case REGION_MKK
: // 14
1402 NdisMoveMemory(&pAd
->PortCfg
.ChannelList
[index
], Ra24Ghz_MKK
, sizeof(Ra24Ghz_MKK
));
1403 index
+= sizeof(Ra24Ghz_MKK
);
1405 case REGION_MKK1
: // 1 - 14
1406 NdisMoveMemory(&pAd
->PortCfg
.ChannelList
[index
], Ra24Ghz_MKK1
, sizeof(Ra24Ghz_MKK1
));
1407 index
+= sizeof(Ra24Ghz_MKK1
);
1409 default: // Error. should never happen
1414 if ((pAd
->PortCfg
.PhyMode
== PHY_11A
) || (pAd
->PortCfg
.PhyMode
== PHY_11ABG_MIXED
))
1417 switch (pAd
->PortCfg
.CountryRegion
)
1419 case REGION_FCC
: // UNII <36,40,44,48,52,56,60,64> <149,153,157,161>
1420 case REGION_IC
: // UNII <36,40,44,48,52,56,60,64> <149,153,157,161>
1421 case REGION_ISRAEL
: // UNII <36,40,44,48,52,56,60,64> <149,153,157,161>
1422 NdisMoveMemory(&pAd
->PortCfg
.ChannelList
[index
], Ra5Ghz_UNII
, sizeof(Ra5Ghz_UNII
));
1423 index
+= sizeof(Ra5Ghz_UNII
);
1425 case REGION_ETSI
: // HiperLAN2 <36,40,44,48,52,56,60,64> <100,104,108,112,116,120,124,128,132,136,140>
1426 case REGION_SPAIN
: // HiperLAN2 <36,40,44,48,52,56,60,64> <100,104,108,112,116,120,124,128,132,136,140>
1427 case REGION_FRANCE
: // HiperLAN2 <36,40,44,48,52,56,60,64> <100,104,108,112,116,120,124,128,132,136,140>
1428 NdisMoveMemory(&pAd
->PortCfg
.ChannelList
[index
], Ra5Ghz_HyperLAN2
, sizeof(Ra5Ghz_HyperLAN2
));
1429 index
+= sizeof(Ra5Ghz_HyperLAN2
);
1431 case REGION_MKK
: // Japan MMAC <34,38,42,46>
1432 case REGION_MKK1
: // Japan MMAC <34,38,42,46>
1433 NdisMoveMemory(&pAd
->PortCfg
.ChannelList
[index
], Ra5Ghz_MMAC
, sizeof(Ra5Ghz_MMAC
));
1434 index
+= sizeof(Ra5Ghz_MMAC
);
1436 default: // Error. should never happen
1440 // 2003-10-05 john - use UNII temoparaily for all regulation domains for easy test untill
1441 // RF guys confirm the supported channel plans
1442 NdisMoveMemory(&pAd
->PortCfg
.ChannelList
[index
], Ra5Ghz_UNII
, sizeof(Ra5Ghz_UNII
));
1443 index
+= sizeof(Ra5Ghz_UNII
);
1447 pAd
->PortCfg
.ChannelListNum
= index
;
1448 DBGPRINT(RT_DEBUG_TRACE
,"country code=%d, RFIC=%d, PHY mode=%d, support %d channels\n",
1449 pAd
->PortCfg
.CountryRegion
, pAd
->PortCfg
.RfType
, pAd
->PortCfg
.PhyMode
, pAd
->PortCfg
.ChannelListNum
);
1450 for (i
=0;i
<index
;i
++)
1452 DBGPRINT(RT_DEBUG_TRACE
,"channel #%d\n", pAd
->PortCfg
.ChannelList
[i
]);
1457 ==========================================================================
1459 This routine return the first channel number according to the country
1460 code selection and RF IC selection (signal band or dual band). It is called
1461 whenever driver need to start a site survey of all supported channels.
1463 ch - the first channel number of current country code setting
1464 ==========================================================================
1467 IN PRTMP_ADAPTER pAd
)
1469 return pAd
->PortCfg
.ChannelList
[0];
1473 ==========================================================================
1475 This routine returns the next channel number. This routine is called
1476 during driver need to start a site survey of all supported channels.
1478 next_channel - the next channel number valid in current country code setting.
1480 return 0 if no more next channel
1481 ==========================================================================
1484 IN PRTMP_ADAPTER pAd
,
1488 UCHAR next_channel
= 0;
1490 for (i
= 0; i
< (pAd
->PortCfg
.ChannelListNum
- 1); i
++)
1491 if (channel
== pAd
->PortCfg
.ChannelList
[i
])
1493 next_channel
= pAd
->PortCfg
.ChannelList
[i
+1];
1496 return next_channel
;