MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink / sync.c
blob590d6693aa4daaf315b084a42d90837b05c8776b
1 /*************************************************************************
2 * Ralink Tech Inc. *
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
6 * *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
8 * *
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. *
13 * *
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. *
18 * *
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. *
23 * *
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};
38 // 5 Ghz channel plan
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 ==========================================================================
51 Description:
52 The sync state machine,
53 Parameters:
54 Sm - pointer to the state machine
55 Note:
56 the state machine looks like the following
58 Column 1-2
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
71 column 3
72 SCAN_LISTEN
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
78 MT2_PEER_ATIM drop
79 MT2_SCAN_TIMEOUT scan_timeout_action
80 MT2_BEACON_TIMEOUT Drop
81 MT2_ATIM_TIMEOUT Drop
82 MT2_PEER_PROBE_REQ drop
83 ==========================================================================
85 VOID SyncStateMachineInit(
86 IN PRTMP_ADAPTER pAd,
87 IN STATE_MACHINE *Sm,
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);
92 // column 1
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);
100 //column 2
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);
107 // column 3
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);
115 // timer init
116 RTMPInitTimer(pAd, &pAd->Mlme.SyncAux.BeaconTimer, BeaconTimeout);
117 RTMPInitTimer(pAd, &pAd->Mlme.SyncAux.ScanTimer, ScanTimeout);
121 ==========================================================================
122 Description:
123 Becaon timeout handler, executed in timer thread
124 ==========================================================================
126 VOID BeaconTimeout(
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);
133 MlmeHandler(pAd);
137 ==========================================================================
138 Description:
139 ATIM timeout handler, executed in timer thread
140 ==========================================================================
142 VOID AtimTimeout(
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);
149 MlmeHandler(pAd);
153 ==========================================================================
154 Description:
155 Scan timeout handler, executed in timer thread
156 ==========================================================================
158 VOID ScanTimeout(
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);
165 MlmeHandler(pAd);
169 ==========================================================================
170 Description:
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;
179 ULONG Now;
181 // Suspend MSDU transmission here
182 RTMPSuspendMsduTransmission(pAd);
184 // first check the parameter sanity
185 if (MlmeScanReqSanity(pAd,
186 Elem->Msg,
187 Elem->MsgLen,
188 &BssType,
189 Ssid,
190 &SsidLen,
191 &ScanType))
193 DBGPRINT(RT_DEBUG_TRACE, "SYNC - MlmeScanReqAction\n");
194 Now = jiffies;
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);
210 else
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 ==========================================================================
220 Description:
221 MLME JOIN req state machine procedure
222 ==========================================================================
224 VOID MlmeJoinReqAction(
225 IN PRTMP_ADAPTER pAd,
226 IN MLME_QUEUE_ELEM *Elem)
228 BSS_ENTRY *pBss;
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 ==========================================================================
259 Description:
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;
273 BOOLEAN Privacy;
274 #ifdef SINGLE_ADHOC_LINKUP
275 ULONG Bssidx;
276 BOOLEAN CfExist = FALSE;
277 CF_PARM CfParm;
278 #endif
280 // Init Variable IE structure
281 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
282 pVIE->Length = 0;
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);
312 else
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);
339 #endif
341 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
342 MlmeCntlConfirm(pAd, MT2_START_CONF, (USHORT)MLME_SUCCESS);
344 else
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 ==========================================================================
354 Description:
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;
365 CF_PARM CfParm;
366 USHORT BeaconPeriod, AtimWin, CapabilityInfo;
367 MACFRAME *Fr;
368 LARGE_INTEGER TimeStamp;
369 BOOLEAN CfExist = FALSE;
370 BOOLEAN ExtendedRateIeExist;
371 UCHAR Erp;
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;
383 pVIE->Length = 0;
384 if (PeerBeaconAndProbeRspSanity(pAd,
385 Elem->Msg,
386 Elem->MsgLen,
387 &Addr2,
388 &Bssid, Ssid,
389 &SsidLen,
390 &BssType,
391 &BeaconPeriod,
392 &Channel,
393 &TimeStamp,
394 &CfExist,
395 &CfParm,
396 &AtimWin,
397 &CapabilityInfo,
398 Rates,
399 &RatesLen,
400 &ExtendedRateIeExist,
401 &Erp,
402 &DtimCount,
403 &DtimPeriod,
404 &BcastFlag,
405 &MessageToMe,
406 &Legacy,
407 SupRate,
408 &SupRateLen,
409 ExtRate,
410 &ExtRateLen,
411 pVIE))
413 ULONG Idx;
414 UCHAR Rssi = 0;
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)
424 Rssi = Elem->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 ==========================================================================
440 Description:
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;
453 CF_PARM Cf;
454 BOOLEAN CfExist = FALSE, ExtendedRateIeExist;
455 UCHAR Erp;
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;
465 pVIE->Length = 0;
466 if (PeerBeaconAndProbeRspSanity(pAd,
467 Elem->Msg,
468 Elem->MsgLen,
469 &Addr2,
470 &Bssid,
471 Ssid,
472 &SsidLen,
473 &BssType,
474 &BeaconPeriod,
475 &Channel,
476 &TimeStamp,
477 &CfExist,
478 &Cf,
479 &AtimWin,
480 &CapabilityInfo,
481 Rates,
482 &RatesLen,
483 &ExtendedRateIeExist,
484 &Erp,
485 &DtimCount,
486 &DtimPeriod,
487 &BcastFlag,
488 &MessageToMe,
489 &Legacy,
490 SupRate,
491 &SupRateLen,
492 ExtRate,
493 &ExtRateLen,
494 pVIE))
496 // Disqualify 11b only adhoc when we are in 11g only adhoc mode
497 if ((BssType == BSS_INDEP) && (pAd->PortCfg.AdhocMode == 2) && (RatesLen < 12))
498 return;
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;
514 else
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
529 int i;
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
554 // Supported rate
556 int i;
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
579 // Extended rate
580 if (ExtendedRateIeExist == TRUE)
582 int i;
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 ++;
602 else
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 ==========================================================================
642 Description:
643 receive BEACON from peer
644 ==========================================================================
646 VOID PeerBeacon(
647 IN PRTMP_ADAPTER pAd,
648 IN MLME_QUEUE_ELEM *Elem)
650 MACADDR Bssid, Addr2;
651 CHAR Ssid[MAX_LEN_OF_SSID];
652 CF_PARM CfParm;
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;
660 UCHAR Erp;
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))
669 return;
671 // Init Variable IE structure
672 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
673 pVIE->Length = 0;
674 if (PeerBeaconAndProbeRspSanity(pAd,
675 Elem->Msg,
676 Elem->MsgLen,
677 &Addr2,
678 &Bssid,
679 Ssid,
680 &SsidLen,
681 &BssType,
682 &BeaconPeriod,
683 &Channel,
684 &TimeStamp,
685 &CfExist,
686 &CfParm,
687 &AtimWin,
688 &CapabilityInfo,
689 Rates,
690 &RatesLen,
691 &ExtendedRateIeExist,
692 &Erp,
693 &DtimCount,
694 &DtimPeriod,
695 &BcastFlag,
696 &MessageToMe,
697 &Legacy,
698 SupRate,
699 &SupRateLen,
700 ExtRate,
701 &ExtRateLen,
702 pVIE))
704 BOOLEAN is_my_bssid, is_my_ssid;
705 ULONG Bssidx, Now;
706 BSS_ENTRY *pBss;
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))
715 return;
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)
726 return;
727 if (!RTMPEqualMemory(pAd->PortCfg.Ssid, pAd->Mlme.CntlAux.Ssid, pAd->PortCfg.SsidLen))
728 return;
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
736 return;
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))
747 INT i;
748 // Add to safe guard adhoc wep status mismatch
749 if (pAd->PortCfg.WepStatus != pAd->Mlme.CntlAux.SsidBssTab.BssEntry[Bssidx].WepStatus)
750 return;
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);
760 MakeIbssBeacon(pAd);
761 AsicEnableIbssSync(pAd);
762 break;
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);
772 Now = jiffies;
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
780 if (is_my_bssid)
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;
788 #if 1
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
806 #endif
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
832 // 3. short preamble
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.
860 if (MessageToMe)
862 DBGPRINT(RT_DEBUG_TRACE, "SYNC - AP backlog unicast-to-me, stay AWAKE, send PSPOLL\n");
863 EnqueuePsPoll(pAd);
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");
874 else
876 USHORT NextDtim = DtimCount;
878 if (NextDtim == 0)
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;
896 // 2003/03/12 - john
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);
908 #endif
910 // not my BSSID, ignore it
912 // sanity check fail, ignore this frame
916 ==========================================================================
917 Description:
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)
925 MACADDR Addr2;
926 CHAR Ssid[MAX_LEN_OF_SSID];
927 UCHAR SsidLen;
928 MACHDR ProbeRspHdr;
929 NDIS_STATUS NStatus;
930 UCHAR *OutBuffer = NULL;
931 ULONG FrameLen = 0;
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};
940 if (! ADHOC_ON(pAd))
941 return;
943 if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, &Addr2, Ssid, &SsidLen)) //, Rates, &RatesLen))
945 if ((SsidLen == 0) || RTMPEqualMemory(Ssid, pAd->PortCfg.Ssid, (ULONG) SsidLen))
947 CSR15_STRUC Csr15;
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] );
956 return;
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))
963 int i;
964 SupportedRatesLen=0;
965 for (i=0;i<pAd->PortCfg.SupportedRatesLen;i++)
967 switch (pAd->PortCfg.SupportedRates[i] & 0x7f)
969 case 2:
970 case 4:
971 case 11:
972 case 22:
973 SupportedRates[SupportedRatesLen] = pAd->PortCfg.SupportedRates[i];
974 SupportedRatesLen ++;
975 break;
976 default:
977 break;
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;
990 else
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)
999 return;
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,
1013 1, &SsidIe,
1014 1, &pAd->PortCfg.SsidLen,
1015 pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid,
1016 1, &SuppIe,
1017 1, &SupportedRatesLen,
1018 SupportedRatesLen, SupportedRates,
1019 1, &DsIe,
1020 1, &DsLen,
1021 1, &pAd->PortCfg.Channel,
1022 1, &IbssIe,
1023 1, &IbssLen,
1024 2, &pAd->PortCfg.AtimWin,
1025 END_OF_ARGS);
1027 else
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,
1036 1, &SsidIe,
1037 1, &pAd->PortCfg.SsidLen,
1038 pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid,
1039 1, &SuppIe,
1040 1, &SupportedRatesLen,
1041 SupportedRatesLen, SupportedRates,
1042 1, &DsIe,
1043 1, &DsLen,
1044 1, &pAd->PortCfg.Channel,
1045 1, &IbssIe,
1046 1, &IbssLen,
1047 2, &pAd->PortCfg.AtimWin,
1048 3, ErpIe,
1049 1, &ExtRateIe,
1050 1, &ExtRatesLen,
1051 ExtRatesLen, &SupportedRates[SupportedRatesLen],
1052 END_OF_ARGS);
1054 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1055 if (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPANone)
1057 ULONG tmp;
1058 UCHAR WpaIe = IE_WPA;
1060 if (pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) // Tkip
1062 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp,
1063 1, &WpaIe,
1064 1, &CipherSuiteWpaNoneTkipLen,
1065 CipherSuiteWpaNoneTkipLen, &CipherSuiteWpaNoneTkip[0],
1066 END_OF_ARGS);
1067 FrameLen += tmp;
1069 else if (pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) // Aes
1071 MakeOutgoingFrame(OutBuffer + FrameLen, &tmp,
1072 1, &WpaIe,
1073 1, &CipherSuiteWpaNoneAesLen,
1074 CipherSuiteWpaNoneAesLen, &CipherSuiteWpaNoneAes[0],
1075 END_OF_ARGS);
1076 FrameLen += tmp;
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 ==========================================================================
1095 Description:
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 ==========================================================================
1109 Description:
1110 Scan next channel
1111 ==========================================================================
1113 VOID ScanNextChannel(
1114 IN PRTMP_ADAPTER pAd)
1116 MACHDR Hdr;
1117 UCHAR SsidIe = IE_SSID, SuppRateIe = IE_SUPP_RATES;
1118 VOID *OutBuffer = NULL;
1119 VOID *OutBuffer2 = NULL;
1120 NDIS_STATUS NStatus;
1121 ULONG FrameLen = 0;
1122 UCHAR SsidLen = 0;
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);
1133 else
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);
1147 else
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);
1162 return;
1165 DBGPRINT(RT_DEBUG_INFO, "SYNC - send passive ProbeReq @ channel=%d...\n", pAd->Mlme.SyncAux.Channel);
1166 SsidLen = 0;
1167 MakeOutgoingFrame(OutBuffer, &FrameLen,
1168 sizeof(MACHDR), (UCHAR*)&Hdr,
1169 1, &SsidIe,
1170 1, &SsidLen,
1171 1, &SuppRateIe,
1172 1, &pAd->PortCfg.SupportedRatesLen,
1173 pAd->PortCfg.SupportedRatesLen, pAd->PortCfg.SupportedRates,
1174 END_OF_ARGS);
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);
1186 return;
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,
1192 1, &SsidIe,
1193 1, &SsidLen,
1194 SsidLen, pAd->Mlme.SyncAux.Ssid,
1195 1, &SuppRateIe,
1196 1, &pAd->PortCfg.SupportedRatesLen,
1197 pAd->PortCfg.SupportedRatesLen, pAd->PortCfg.SupportedRates,
1198 END_OF_ARGS);
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 ==========================================================================
1210 Description:
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 ==========================================================================
1224 Description:
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 ==========================================================================
1238 Description:
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 ==========================================================================
1252 Description:
1253 ==========================================================================
1255 VOID EnqueuePsPoll(
1256 IN PRTMP_ADAPTER pAd)
1258 NDIS_STATUS NState;
1259 PSPOLL_FRAME *PsFr;
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));
1271 // 2003-04-17 john
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)
1280 NDIS_STATUS NState;
1281 PTXD_STRUC pTxD = (PTXD_STRUC)pAd->BeaconRing.va_addr;
1282 CHAR *pBeacon;
1283 LARGE_INTEGER Tsf;
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 ==========================================================================
1299 Description:
1300 Send out a NULL frame to AP. The prpose is to inform AP this client
1301 current PSM bit.
1302 NOTE:
1303 This routine should only be used in infrastructure mode.
1304 ==========================================================================
1306 VOID EnqueueNullFrame(
1307 IN PRTMP_ADAPTER pAd,
1308 IN UCHAR TxRate)
1310 NDIS_STATUS NState;
1311 MACHDR *NullFr;
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 ==========================================================================
1325 Description:
1326 ==========================================================================
1328 VOID EnqueueProbeRequest(
1329 IN PRTMP_ADAPTER pAd)
1331 NDIS_STATUS NState;
1332 UCHAR SsidIe = IE_SSID, SuppRateIe = IE_SUPP_RATES;
1333 VOID *OutBuffer;
1334 ULONG FrameLen = 0;
1335 MACHDR Hdr;
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,
1347 1, &SsidIe,
1348 1, &pAd->PortCfg.SsidLen,
1349 pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid,
1350 1, &SuppRateIe,
1351 1, &pAd->PortCfg.SupportedRatesLen,
1352 pAd->PortCfg.SupportedRatesLen, pAd->PortCfg.SupportedRates,
1353 END_OF_ARGS);
1354 MiniportMMRequest(pAd, OutBuffer, FrameLen);
1359 ==========================================================================
1360 Description:
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)
1369 UCHAR i, index = 0;
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);
1380 break;
1381 case REGION_IC: // 1 -11
1382 NdisMoveMemory(&pAd->PortCfg.ChannelList[index], Ra24Ghz_IC, sizeof(Ra24Ghz_IC));
1383 index += sizeof(Ra24Ghz_IC);
1384 break;
1385 case REGION_ISRAEL: // 3 - 9
1386 NdisMoveMemory(&pAd->PortCfg.ChannelList[index], Ra24Ghz_ISRAEL, sizeof(Ra24Ghz_ISRAEL));
1387 index += sizeof(Ra24Ghz_ISRAEL);
1388 break;
1389 case REGION_ETSI: // 1 - 13
1390 NdisMoveMemory(&pAd->PortCfg.ChannelList[index], Ra24Ghz_ESTI, sizeof(Ra24Ghz_ESTI));
1391 index += sizeof(Ra24Ghz_ESTI);
1392 break;
1393 case REGION_SPAIN: // 10 - 11
1394 NdisMoveMemory(&pAd->PortCfg.ChannelList[index], Ra24Ghz_SPAIN, sizeof(Ra24Ghz_SPAIN));
1395 index += sizeof(Ra24Ghz_SPAIN);
1396 break;
1397 case REGION_FRANCE: // 10 -13
1398 NdisMoveMemory(&pAd->PortCfg.ChannelList[index], Ra24Ghz_FRANCE, sizeof(Ra24Ghz_FRANCE));
1399 index += sizeof(Ra24Ghz_FRANCE);
1400 break;
1401 case REGION_MKK: // 14
1402 NdisMoveMemory(&pAd->PortCfg.ChannelList[index], Ra24Ghz_MKK, sizeof(Ra24Ghz_MKK));
1403 index += sizeof(Ra24Ghz_MKK);
1404 break;
1405 case REGION_MKK1: // 1 - 14
1406 NdisMoveMemory(&pAd->PortCfg.ChannelList[index], Ra24Ghz_MKK1, sizeof(Ra24Ghz_MKK1));
1407 index += sizeof(Ra24Ghz_MKK1);
1408 break;
1409 default: // Error. should never happen
1410 break;
1414 if ((pAd->PortCfg.PhyMode == PHY_11A) || (pAd->PortCfg.PhyMode == PHY_11ABG_MIXED))
1416 #if 0
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);
1424 break;
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);
1430 break;
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);
1435 break;
1436 default: // Error. should never happen
1437 break;
1439 #else
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);
1444 #endif
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 ==========================================================================
1458 Description:
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.
1462 Return:
1463 ch - the first channel number of current country code setting
1464 ==========================================================================
1466 UCHAR FirstChannel(
1467 IN PRTMP_ADAPTER pAd)
1469 return pAd->PortCfg.ChannelList[0];
1473 ==========================================================================
1474 Description:
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.
1477 Return:
1478 next_channel - the next channel number valid in current country code setting.
1479 Note:
1480 return 0 if no more next channel
1481 ==========================================================================
1483 UCHAR NextChannel(
1484 IN PRTMP_ADAPTER pAd,
1485 IN UCHAR channel)
1487 int i;
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];
1494 break;
1496 return next_channel;