staging: Fix typos in rt2860
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rt2860 / sta / connect.c
blob4b2c84e6509eb8b858123cf9ff29bc18f591f6a3
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
27 Module Name:
28 connect.c
30 Abstract:
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John 2004-08-08 Major modification from RT2560
36 Justin P. Mattock 11/07/2010 Fix typos
38 #include "../rt_config.h"
40 u8 CipherSuiteWpaNoneTkip[] = {
41 0x00, 0x50, 0xf2, 0x01, /* oui */
42 0x01, 0x00, /* Version */
43 0x00, 0x50, 0xf2, 0x02, /* Multicast */
44 0x01, 0x00, /* Number of unicast */
45 0x00, 0x50, 0xf2, 0x02, /* unicast */
46 0x01, 0x00, /* number of authentication method */
47 0x00, 0x50, 0xf2, 0x00 /* authentication */
50 u8 CipherSuiteWpaNoneTkipLen =
51 (sizeof(CipherSuiteWpaNoneTkip) / sizeof(u8));
53 u8 CipherSuiteWpaNoneAes[] = {
54 0x00, 0x50, 0xf2, 0x01, /* oui */
55 0x01, 0x00, /* Version */
56 0x00, 0x50, 0xf2, 0x04, /* Multicast */
57 0x01, 0x00, /* Number of unicast */
58 0x00, 0x50, 0xf2, 0x04, /* unicast */
59 0x01, 0x00, /* number of authentication method */
60 0x00, 0x50, 0xf2, 0x00 /* authentication */
63 u8 CipherSuiteWpaNoneAesLen =
64 (sizeof(CipherSuiteWpaNoneAes) / sizeof(u8));
66 /* The following MACRO is called after 1. starting an new IBSS, 2. successfully JOIN an IBSS, */
67 /* or 3. successfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */
68 /* All settings successfuly negotiated firing MLME state machines become final settings */
69 /* and are copied to pAd->StaActive */
70 #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
71 { \
72 NdisZeroMemory((_pAd)->CommonCfg.Ssid, MAX_LEN_OF_SSID); \
73 (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \
74 NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
75 COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \
76 (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel; \
77 (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel; \
78 (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid; \
79 (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin; \
80 (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo; \
81 (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod; \
82 (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration; \
83 (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod; \
84 (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen; \
85 NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
86 (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen; \
87 NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
88 NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(struct rt_edca_parm));\
89 NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(struct rt_qos_capability_parm));\
90 NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(struct rt_qbss_load_parm));\
91 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid); \
92 (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid; \
93 (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
94 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
95 (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
99 ==========================================================================
100 Description:
102 IRQL = PASSIVE_LEVEL
104 ==========================================================================
106 void MlmeCntlInit(struct rt_rtmp_adapter *pAd,
107 struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
109 /* Control state machine differs from other state machines, the interface */
110 /* follows the standard interface */
111 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
115 ==========================================================================
116 Description:
118 IRQL = DISPATCH_LEVEL
120 ==========================================================================
122 void MlmeCntlMachinePerformAction(struct rt_rtmp_adapter *pAd,
123 struct rt_state_machine *S,
124 struct rt_mlme_queue_elem *Elem)
126 switch (pAd->Mlme.CntlMachine.CurrState) {
127 case CNTL_IDLE:
128 CntlIdleProc(pAd, Elem);
129 break;
130 case CNTL_WAIT_DISASSOC:
131 CntlWaitDisassocProc(pAd, Elem);
132 break;
133 case CNTL_WAIT_JOIN:
134 CntlWaitJoinProc(pAd, Elem);
135 break;
137 /* CNTL_WAIT_REASSOC is the only state in CNTL machine that does */
138 /* not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)". */
139 /* Therefore not protected by NDIS's "only one outstanding OID request" */
140 /* rule. Which means NDIS may SET OID in the middle of ROAMing attempts. */
141 /* Current approach is to block new SET request at RTMPSetInformation() */
142 /* when CntlMachine.CurrState is not CNTL_IDLE */
143 case CNTL_WAIT_REASSOC:
144 CntlWaitReassocProc(pAd, Elem);
145 break;
147 case CNTL_WAIT_START:
148 CntlWaitStartProc(pAd, Elem);
149 break;
150 case CNTL_WAIT_AUTH:
151 CntlWaitAuthProc(pAd, Elem);
152 break;
153 case CNTL_WAIT_AUTH2:
154 CntlWaitAuthProc2(pAd, Elem);
155 break;
156 case CNTL_WAIT_ASSOC:
157 CntlWaitAssocProc(pAd, Elem);
158 break;
160 case CNTL_WAIT_OID_LIST_SCAN:
161 if (Elem->MsgType == MT2_SCAN_CONF) {
162 /* Resume TxRing after SCANING complete. We hope the out-of-service time */
163 /* won't be too long to let upper layer time-out the waiting frames */
164 RTMPResumeMsduTransmission(pAd);
166 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
168 /* */
169 /* Set LED status to previous status. */
170 /* */
171 if (pAd->bLedOnScanning) {
172 pAd->bLedOnScanning = FALSE;
173 RTMPSetLED(pAd, pAd->LedStatus);
176 break;
178 case CNTL_WAIT_OID_DISASSOC:
179 if (Elem->MsgType == MT2_DISASSOC_CONF) {
180 LinkDown(pAd, FALSE);
181 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
183 break;
184 #ifdef RTMP_MAC_USB
185 /* */
186 /* This state is for that we want to connect to an AP but */
187 /* it didn't find on BSS List table. So we need to scan the air first, */
188 /* after that we can try to connect to the desired AP if available. */
189 /* */
190 case CNTL_WAIT_SCAN_FOR_CONNECT:
191 if (Elem->MsgType == MT2_SCAN_CONF) {
192 /* Resume TxRing after SCANING complete. We hope the out-of-service time */
193 /* won't be too long to let upper layer time-out the waiting frames */
194 RTMPResumeMsduTransmission(pAd);
195 #ifdef CCX_SUPPORT
196 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) {
197 /* Cisco scan request is finished, prepare beacon report */
198 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE,
199 MT2_AIRONET_SCAN_DONE, 0, NULL);
201 #endif /* CCX_SUPPORT // */
202 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
204 /* */
205 /* Check if we can connect to. */
206 /* */
207 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab,
208 (char *) pAd->MlmeAux.
209 AutoReconnectSsid,
210 pAd->MlmeAux.AutoReconnectSsidLen);
211 if (pAd->MlmeAux.SsidBssTab.BssNr > 0) {
212 MlmeAutoReconnectLastSSID(pAd);
215 break;
216 #endif /* RTMP_MAC_USB // */
217 default:
218 DBGPRINT_ERR(("ERROR! CNTL - Illegal message type(=%ld)",
219 Elem->MsgType));
220 break;
225 ==========================================================================
226 Description:
228 IRQL = DISPATCH_LEVEL
230 ==========================================================================
232 void CntlIdleProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
234 struct rt_mlme_disassoc_req DisassocReq;
236 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
237 return;
239 switch (Elem->MsgType) {
240 case OID_802_11_SSID:
241 CntlOidSsidProc(pAd, Elem);
242 break;
244 case OID_802_11_BSSID:
245 CntlOidRTBssidProc(pAd, Elem);
246 break;
248 case OID_802_11_BSSID_LIST_SCAN:
249 CntlOidScanProc(pAd, Elem);
250 break;
252 case OID_802_11_DISASSOCIATE:
253 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid,
254 REASON_DISASSOC_STA_LEAVING);
255 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
256 sizeof(struct rt_mlme_disassoc_req), &DisassocReq);
257 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
259 if (pAd->StaCfg.WpaSupplicantUP !=
260 WPA_SUPPLICANT_ENABLE_WITH_WEB_UI) {
261 /* Set the AutoReconnectSsid to prevent it reconnect to old SSID */
262 /* Since calling this indicate user don't want to connect to that SSID anymore. */
263 pAd->MlmeAux.AutoReconnectSsidLen = 32;
264 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid,
265 pAd->MlmeAux.AutoReconnectSsidLen);
267 break;
269 case MT2_MLME_ROAMING_REQ:
270 CntlMlmeRoamingProc(pAd, Elem);
271 break;
273 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
274 WpaMicFailureReportFrame(pAd, Elem);
275 break;
277 default:
278 DBGPRINT(RT_DEBUG_TRACE,
279 ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",
280 Elem->MsgType));
281 break;
285 void CntlOidScanProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
287 struct rt_mlme_scan_req ScanReq;
288 unsigned long BssIdx = BSS_NOT_FOUND;
289 struct rt_bss_entry CurrBss;
291 /* record current BSS if network is connected. */
292 /* 2003-2-13 do not include current IBSS if this is the only STA in this IBSS. */
293 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
294 BssIdx =
295 BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid,
296 (u8 *)pAd->CommonCfg.Ssid,
297 pAd->CommonCfg.SsidLen,
298 pAd->CommonCfg.Channel);
299 if (BssIdx != BSS_NOT_FOUND) {
300 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx],
301 sizeof(struct rt_bss_entry));
304 /* clean up previous SCAN result, add current BSS back to table if any */
305 BssTableInit(&pAd->ScanTab);
306 if (BssIdx != BSS_NOT_FOUND) {
307 /* DDK Note: If the NIC is associated with a particular BSSID and SSID */
308 /* that are not contained in the list of BSSIDs generated by this scan, the */
309 /* BSSID description of the currently associated BSSID and SSID should be */
310 /* appended to the list of BSSIDs in the NIC's database. */
311 /* To ensure this, we append this BSS as the first entry in SCAN result */
312 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss,
313 sizeof(struct rt_bss_entry));
314 pAd->ScanTab.BssNr = 1;
317 ScanParmFill(pAd, &ScanReq, (char *)Elem->Msg, Elem->MsgLen, BSS_ANY,
318 SCAN_ACTIVE);
319 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
320 sizeof(struct rt_mlme_scan_req), &ScanReq);
321 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
325 ==========================================================================
326 Description:
327 Before calling this routine, user desired SSID should already been
328 recorded in CommonCfg.Ssid[]
329 IRQL = DISPATCH_LEVEL
331 ==========================================================================
333 void CntlOidSsidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
335 struct rt_ndis_802_11_ssid * pOidSsid = (struct rt_ndis_802_11_ssid *) Elem->Msg;
336 struct rt_mlme_disassoc_req DisassocReq;
337 unsigned long Now;
339 /* Step 1. record the desired user settings to MlmeAux */
340 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
341 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
342 pAd->MlmeAux.SsidLen = (u8)pOidSsid->SsidLength;
343 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
344 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
346 pAd->StaCfg.bAutoConnectByBssid = FALSE;
348 /* */
349 /* Update Reconnect Ssid, that user desired to connect. */
350 /* */
351 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
352 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid,
353 pAd->MlmeAux.SsidLen);
354 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
356 /* step 2. find all matching BSS in the lastest SCAN result (inBssTab) */
357 /* & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order */
358 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab,
359 (char *)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
361 DBGPRINT(RT_DEBUG_TRACE,
362 ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
363 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr,
364 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
365 NdisGetSystemUpTime(&Now);
367 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
368 (pAd->CommonCfg.SsidLen ==
369 pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen)
370 && NdisEqualMemory(pAd->CommonCfg.Ssid,
371 pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid,
372 pAd->CommonCfg.SsidLen)
373 && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid,
374 pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid)) {
375 /* Case 1. already connected with an AP who has the desired SSID */
376 /* with highest RSSI */
378 /* Add checking Mode "LEAP" for CCX 1.0 */
379 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
380 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
381 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
382 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
383 ) &&
384 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) {
385 /* case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo */
386 /* connection process */
387 DBGPRINT(RT_DEBUG_TRACE,
388 ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
389 DisassocParmFill(pAd, &DisassocReq,
390 pAd->CommonCfg.Bssid,
391 REASON_DISASSOC_STA_LEAVING);
392 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
393 MT2_MLME_DISASSOC_REQ,
394 sizeof(struct rt_mlme_disassoc_req),
395 &DisassocReq);
396 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
397 } else if (pAd->bConfigChanged == TRUE) {
398 /* case 1.2 Important Config has changed, we have to reconnect to the same AP */
399 DBGPRINT(RT_DEBUG_TRACE,
400 ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
401 DisassocParmFill(pAd, &DisassocReq,
402 pAd->CommonCfg.Bssid,
403 REASON_DISASSOC_STA_LEAVING);
404 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
405 MT2_MLME_DISASSOC_REQ,
406 sizeof(struct rt_mlme_disassoc_req),
407 &DisassocReq);
408 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
409 } else {
410 /* case 1.3. already connected to the SSID with highest RSSI. */
411 DBGPRINT(RT_DEBUG_TRACE,
412 ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
413 /* */
414 /* (HCT 12.1) 1c_wlan_mediaevents required */
415 /* media connect events are indicated when associating with the same AP */
416 /* */
417 if (INFRA_ON(pAd)) {
418 /* */
419 /* Since MediaState already is NdisMediaStateConnected */
420 /* We just indicate the connect event again to meet the WHQL required. */
421 /* */
422 pAd->IndicateMediaState =
423 NdisMediaStateConnected;
424 RTMP_IndicateMediaState(pAd);
425 pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information to link is up */
428 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
429 RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1,
430 &pAd->MlmeAux.Bssid[0], NULL,
433 } else if (INFRA_ON(pAd)) {
434 /* */
435 /* For RT61 */
436 /* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */
437 /* RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect */
438 /* But media status is connected, so the SSID not report correctly. */
439 /* */
440 if (!SSID_EQUAL
441 (pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen,
442 pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)) {
443 /* */
444 /* Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event. */
445 /* */
446 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
448 /* case 2. active INFRA association existent */
449 /* roaming is done within miniport driver, nothing to do with configuration */
450 /* utility. so upon a new SET(OID_802_11_SSID) is received, we just */
451 /* disassociate with the current associated AP, */
452 /* then perform a new association with this new SSID, no matter the */
453 /* new/old SSID are the same or not. */
454 DBGPRINT(RT_DEBUG_TRACE,
455 ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
456 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid,
457 REASON_DISASSOC_STA_LEAVING);
458 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
459 sizeof(struct rt_mlme_disassoc_req), &DisassocReq);
460 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
461 } else {
462 if (ADHOC_ON(pAd)) {
463 DBGPRINT(RT_DEBUG_TRACE,
464 ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
465 LinkDown(pAd, FALSE);
466 OPSTATUS_CLEAR_FLAG(pAd,
467 fOP_STATUS_MEDIA_STATE_CONNECTED);
468 pAd->IndicateMediaState = NdisMediaStateDisconnected;
469 RTMP_IndicateMediaState(pAd);
470 pAd->ExtraInfo = GENERAL_LINK_DOWN;
471 DBGPRINT(RT_DEBUG_TRACE,
472 ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
475 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
476 (pAd->StaCfg.bAutoReconnect == TRUE) &&
477 (pAd->MlmeAux.BssType == BSS_INFRA) &&
478 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)
479 == TRUE)
481 struct rt_mlme_scan_req ScanReq;
483 DBGPRINT(RT_DEBUG_TRACE,
484 ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
485 ScanParmFill(pAd, &ScanReq, (char *)pAd->MlmeAux.Ssid,
486 pAd->MlmeAux.SsidLen, BSS_ANY,
487 SCAN_ACTIVE);
488 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
489 sizeof(struct rt_mlme_scan_req), &ScanReq);
490 pAd->Mlme.CntlMachine.CurrState =
491 CNTL_WAIT_OID_LIST_SCAN;
492 /* Reset Missed scan number */
493 pAd->StaCfg.LastScanTime = Now;
494 } else {
495 pAd->MlmeAux.BssIdx = 0;
496 IterateOnBssTab(pAd);
502 ==========================================================================
503 Description:
505 IRQL = DISPATCH_LEVEL
507 ==========================================================================
509 void CntlOidRTBssidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
511 unsigned long BssIdx;
512 u8 *pOidBssid = (u8 *)Elem->Msg;
513 struct rt_mlme_disassoc_req DisassocReq;
514 struct rt_mlme_join_req JoinReq;
516 /* record user desired settings */
517 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
518 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
520 /* find the desired BSS in the latest SCAN result table */
521 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
522 if (BssIdx == BSS_NOT_FOUND) {
523 struct rt_mlme_scan_req ScanReq;
525 DBGPRINT(RT_DEBUG_TRACE,
526 ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
527 /*pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; */
529 DBGPRINT(RT_DEBUG_TRACE,
530 ("CNTL - BSSID not found. start a new scan\n"));
531 ScanParmFill(pAd, &ScanReq, (char *)pAd->MlmeAux.Ssid,
532 pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
533 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
534 sizeof(struct rt_mlme_scan_req), &ScanReq);
535 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
536 /* Reset Missed scan number */
537 NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
538 return;
540 /* */
541 /* Update Reconnect Ssid, that user desired to connect. */
542 /* */
543 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
544 pAd->MlmeAux.AutoReconnectSsidLen =
545 pAd->ScanTab.BssEntry[BssIdx].SsidLen;
546 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid,
547 pAd->ScanTab.BssEntry[BssIdx].Ssid,
548 pAd->ScanTab.BssEntry[BssIdx].SsidLen);
550 /* copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why? */
551 /* Because we need this entry to become the JOIN target in later on SYNC state machine */
552 pAd->MlmeAux.BssIdx = 0;
553 pAd->MlmeAux.SsidBssTab.BssNr = 1;
554 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0],
555 &pAd->ScanTab.BssEntry[BssIdx], sizeof(struct rt_bss_entry));
557 /* Add SSID into MlmeAux for site survey joining hidden SSID */
558 pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
559 NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid,
560 pAd->MlmeAux.SsidLen);
563 if (INFRA_ON(pAd)) {
564 /* disassoc from current AP first */
565 DBGPRINT(RT_DEBUG_TRACE,
566 ("CNTL - disassociate with current AP ...\n"));
567 DisassocParmFill(pAd, &DisassocReq,
568 pAd->CommonCfg.Bssid,
569 REASON_DISASSOC_STA_LEAVING);
570 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
571 MT2_MLME_DISASSOC_REQ,
572 sizeof(struct rt_mlme_disassoc_req),
573 &DisassocReq);
575 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
576 } else {
577 if (ADHOC_ON(pAd)) {
578 DBGPRINT(RT_DEBUG_TRACE,
579 ("CNTL - drop current ADHOC\n"));
580 LinkDown(pAd, FALSE);
581 OPSTATUS_CLEAR_FLAG(pAd,
582 fOP_STATUS_MEDIA_STATE_CONNECTED);
583 pAd->IndicateMediaState =
584 NdisMediaStateDisconnected;
585 RTMP_IndicateMediaState(pAd);
586 pAd->ExtraInfo = GENERAL_LINK_DOWN;
587 DBGPRINT(RT_DEBUG_TRACE,
588 ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
590 /* Change the wepstatus to original wepstatus */
591 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
592 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
593 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
595 /* Check cipher suite, AP must have more secured cipher than station setting */
596 /* Set the Pairwise and Group cipher to match the intended AP setting */
597 /* We can only connect to AP with less secured cipher setting */
598 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
599 || (pAd->StaCfg.AuthMode ==
600 Ndis802_11AuthModeWPAPSK)) {
601 pAd->StaCfg.GroupCipher =
602 pAd->ScanTab.BssEntry[BssIdx].WPA.
603 GroupCipher;
605 if (pAd->StaCfg.WepStatus ==
606 pAd->ScanTab.BssEntry[BssIdx].WPA.
607 PairCipher)
608 pAd->StaCfg.PairCipher =
609 pAd->ScanTab.BssEntry[BssIdx].WPA.
610 PairCipher;
611 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.
612 PairCipherAux != Ndis802_11WEPDisabled)
613 pAd->StaCfg.PairCipher =
614 pAd->ScanTab.BssEntry[BssIdx].WPA.
615 PairCipherAux;
616 else /* There is no PairCipher Aux, downgrade our capability to TKIP */
617 pAd->StaCfg.PairCipher =
618 Ndis802_11Encryption2Enabled;
619 } else
620 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
621 || (pAd->StaCfg.AuthMode ==
622 Ndis802_11AuthModeWPA2PSK)) {
623 pAd->StaCfg.GroupCipher =
624 pAd->ScanTab.BssEntry[BssIdx].WPA2.
625 GroupCipher;
627 if (pAd->StaCfg.WepStatus ==
628 pAd->ScanTab.BssEntry[BssIdx].WPA2.
629 PairCipher)
630 pAd->StaCfg.PairCipher =
631 pAd->ScanTab.BssEntry[BssIdx].WPA2.
632 PairCipher;
633 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.
634 PairCipherAux != Ndis802_11WEPDisabled)
635 pAd->StaCfg.PairCipher =
636 pAd->ScanTab.BssEntry[BssIdx].WPA2.
637 PairCipherAux;
638 else /* There is no PairCipher Aux, downgrade our capability to TKIP */
639 pAd->StaCfg.PairCipher =
640 Ndis802_11Encryption2Enabled;
642 /* RSN capability */
643 pAd->StaCfg.RsnCapability =
644 pAd->ScanTab.BssEntry[BssIdx].WPA2.
645 RsnCapability;
647 /* Set Mix cipher flag */
648 pAd->StaCfg.bMixCipher =
649 (pAd->StaCfg.PairCipher ==
650 pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
651 /*if (pAd->StaCfg.bMixCipher == TRUE)
653 // If mix cipher, re-build RSNIE
654 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
655 } */
656 /* No active association, join the BSS immediately */
657 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %pM ...\n",
658 pOidBssid));
660 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
661 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ,
662 sizeof(struct rt_mlme_join_req), &JoinReq);
664 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
669 /* Roaming is the only external request triggering CNTL state machine */
670 /* despite of other "SET OID" operation. All "SET OID" related operations */
671 /* happen in sequence, because no other SET OID will be sent to this device */
672 /* until the the previous SET operation is complete (successful o failed). */
673 /* So, how do we quarantee this ROAMING request won't corrupt other "SET OID"? */
674 /* or been corrupted by other "SET OID"? */
675 /* */
676 /* IRQL = DISPATCH_LEVEL */
677 void CntlMlmeRoamingProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
679 u8 BBPValue = 0;
681 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Roaming in MlmeAux.RoamTab...\n"));
684 /*Let BBP register at 20MHz to do (fast) roaming. */
685 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
686 BBPValue &= (~0x18);
687 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
689 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab,
690 sizeof(pAd->MlmeAux.RoamTab));
691 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
693 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
694 pAd->MlmeAux.BssIdx = 0;
695 IterateOnBssTab(pAd);
700 ==========================================================================
701 Description:
703 IRQL = DISPATCH_LEVEL
705 ==========================================================================
707 void CntlWaitDisassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
709 struct rt_mlme_start_req StartReq;
711 if (Elem->MsgType == MT2_DISASSOC_CONF) {
712 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
714 if (pAd->CommonCfg.bWirelessEvent) {
715 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG,
716 pAd->MacTab.Content[BSSID_WCID].
717 Addr, BSS0, 0);
720 LinkDown(pAd, FALSE);
722 /* case 1. no matching BSS, and user wants ADHOC, so we just start a new one */
723 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0)
724 && (pAd->StaCfg.BssType == BSS_ADHOC)) {
725 DBGPRINT(RT_DEBUG_TRACE,
726 ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",
727 pAd->MlmeAux.Ssid));
728 StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid,
729 pAd->MlmeAux.SsidLen);
730 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
731 sizeof(struct rt_mlme_start_req), &StartReq);
732 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
734 /* case 2. try each matched BSS */
735 else {
736 pAd->MlmeAux.BssIdx = 0;
738 IterateOnBssTab(pAd);
744 ==========================================================================
745 Description:
747 IRQL = DISPATCH_LEVEL
749 ==========================================================================
751 void CntlWaitJoinProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
753 u16 Reason;
754 struct rt_mlme_auth_req AuthReq;
756 if (Elem->MsgType == MT2_JOIN_CONF) {
757 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
758 if (Reason == MLME_SUCCESS) {
759 /* 1. joined an IBSS, we are pretty much done here */
760 if (pAd->MlmeAux.BssType == BSS_ADHOC) {
761 /* */
762 /* 5G bands rules of Japan: */
763 /* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */
764 /* */
765 if ((pAd->CommonCfg.bIEEE80211H == 1) &&
766 RadarChannelCheck(pAd,
767 pAd->CommonCfg.Channel)
769 pAd->Mlme.CntlMachine.CurrState =
770 CNTL_IDLE;
771 DBGPRINT(RT_DEBUG_TRACE,
772 ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n",
773 pAd->CommonCfg.Channel));
774 return;
777 LinkUp(pAd, BSS_ADHOC);
778 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
779 DBGPRINT(RT_DEBUG_TRACE,
780 ("CNTL - join the IBSS = %pM ...\n",
781 pAd->CommonCfg.Bssid));
783 pAd->IndicateMediaState =
784 NdisMediaStateConnected;
785 pAd->ExtraInfo = GENERAL_LINK_UP;
787 /* 2. joined a new INFRA network, start from authentication */
788 else {
790 /* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */
791 if ((pAd->StaCfg.AuthMode ==
792 Ndis802_11AuthModeShared)
793 || (pAd->StaCfg.AuthMode ==
794 Ndis802_11AuthModeAutoSwitch)) {
795 AuthParmFill(pAd, &AuthReq,
796 pAd->MlmeAux.Bssid,
797 AUTH_MODE_KEY);
798 } else {
799 AuthParmFill(pAd, &AuthReq,
800 pAd->MlmeAux.Bssid,
801 AUTH_MODE_OPEN);
803 MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
804 MT2_MLME_AUTH_REQ,
805 sizeof
806 (struct rt_mlme_auth_req),
807 &AuthReq);
810 pAd->Mlme.CntlMachine.CurrState =
811 CNTL_WAIT_AUTH;
813 } else {
814 /* 3. failed, try next BSS */
815 pAd->MlmeAux.BssIdx++;
816 IterateOnBssTab(pAd);
822 ==========================================================================
823 Description:
825 IRQL = DISPATCH_LEVEL
827 ==========================================================================
829 void CntlWaitStartProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
831 u16 Result;
833 if (Elem->MsgType == MT2_START_CONF) {
834 NdisMoveMemory(&Result, Elem->Msg, sizeof(u16));
835 if (Result == MLME_SUCCESS) {
836 /* */
837 /* 5G bands rules of Japan: */
838 /* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */
839 /* */
840 if ((pAd->CommonCfg.bIEEE80211H == 1) &&
841 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
843 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
844 DBGPRINT(RT_DEBUG_TRACE,
845 ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n",
846 pAd->CommonCfg.Channel));
847 return;
849 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.
850 MCSSet[0], 16);
851 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
852 N_ChannelCheck(pAd);
853 SetCommonHT(pAd);
854 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo,
855 &pAd->CommonCfg.AddHTInfo,
856 sizeof(struct rt_add_ht_info_ie));
857 RTMPCheckHt(pAd, BSSID_WCID,
858 &pAd->CommonCfg.HtCapability,
859 &pAd->CommonCfg.AddHTInfo);
860 pAd->StaActive.SupportedPhyInfo.bHtEnable =
861 TRUE;
862 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.
863 MCSSet[0],
864 &pAd->CommonCfg.HtCapability.
865 MCSSet[0], 16);
866 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG
867 (pAd);
869 if ((pAd->CommonCfg.HtCapability.HtCapInfo.
870 ChannelWidth == BW_40)
871 && (pAd->CommonCfg.AddHTInfo.AddHtInfo.
872 ExtChanOffset == EXTCHA_ABOVE)) {
873 pAd->MlmeAux.CentralChannel =
874 pAd->CommonCfg.Channel + 2;
875 } else
876 if ((pAd->CommonCfg.HtCapability.HtCapInfo.
877 ChannelWidth == BW_40)
878 && (pAd->CommonCfg.AddHTInfo.AddHtInfo.
879 ExtChanOffset == EXTCHA_BELOW)) {
880 pAd->MlmeAux.CentralChannel =
881 pAd->CommonCfg.Channel - 2;
883 } else {
884 pAd->StaActive.SupportedPhyInfo.bHtEnable =
885 FALSE;
887 LinkUp(pAd, BSS_ADHOC);
888 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
889 /* Before send beacon, driver need do radar detection */
890 if ((pAd->CommonCfg.Channel > 14)
891 && (pAd->CommonCfg.bIEEE80211H == 1)
892 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) {
893 pAd->CommonCfg.RadarDetect.RDMode =
894 RD_SILENCE_MODE;
895 pAd->CommonCfg.RadarDetect.RDCount = 0;
898 DBGPRINT(RT_DEBUG_TRACE,
899 ("CNTL - start a new IBSS = %pM ...\n",
900 pAd->CommonCfg.Bssid));
901 } else {
902 DBGPRINT(RT_DEBUG_TRACE,
903 ("CNTL - Start IBSS fail. BUG!\n"));
904 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
910 ==========================================================================
911 Description:
913 IRQL = DISPATCH_LEVEL
915 ==========================================================================
917 void CntlWaitAuthProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
919 u16 Reason;
920 struct rt_mlme_assoc_req AssocReq;
921 struct rt_mlme_auth_req AuthReq;
923 if (Elem->MsgType == MT2_AUTH_CONF) {
924 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
925 if (Reason == MLME_SUCCESS) {
926 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
927 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid,
928 pAd->MlmeAux.CapabilityInfo,
929 ASSOC_TIMEOUT,
930 pAd->StaCfg.DefaultListenCount);
933 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
934 MT2_MLME_ASSOC_REQ,
935 sizeof(struct rt_mlme_assoc_req),
936 &AssocReq);
938 pAd->Mlme.CntlMachine.CurrState =
939 CNTL_WAIT_ASSOC;
941 } else {
942 /* This fail may because of the AP already keep us in its MAC table without */
943 /* ageing-out. The previous authentication attempt must have let it remove us. */
944 /* so try Authentication again may help. For D-Link DWL-900AP+ compatibility. */
945 DBGPRINT(RT_DEBUG_TRACE,
946 ("CNTL - AUTH FAIL, try again...\n"));
949 if ((pAd->StaCfg.AuthMode ==
950 Ndis802_11AuthModeShared)
951 || (pAd->StaCfg.AuthMode ==
952 Ndis802_11AuthModeAutoSwitch)) {
953 /* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */
954 AuthParmFill(pAd, &AuthReq,
955 pAd->MlmeAux.Bssid,
956 AUTH_MODE_KEY);
957 } else {
958 AuthParmFill(pAd, &AuthReq,
959 pAd->MlmeAux.Bssid,
960 AUTH_MODE_OPEN);
962 MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
963 MT2_MLME_AUTH_REQ,
964 sizeof(struct rt_mlme_auth_req),
965 &AuthReq);
968 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
974 ==========================================================================
975 Description:
977 IRQL = DISPATCH_LEVEL
979 ==========================================================================
981 void CntlWaitAuthProc2(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
983 u16 Reason;
984 struct rt_mlme_assoc_req AssocReq;
985 struct rt_mlme_auth_req AuthReq;
987 if (Elem->MsgType == MT2_AUTH_CONF) {
988 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
989 if (Reason == MLME_SUCCESS) {
990 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
991 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid,
992 pAd->MlmeAux.CapabilityInfo,
993 ASSOC_TIMEOUT,
994 pAd->StaCfg.DefaultListenCount);
996 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
997 MT2_MLME_ASSOC_REQ,
998 sizeof(struct rt_mlme_assoc_req),
999 &AssocReq);
1001 pAd->Mlme.CntlMachine.CurrState =
1002 CNTL_WAIT_ASSOC;
1004 } else {
1005 if ((pAd->StaCfg.AuthMode ==
1006 Ndis802_11AuthModeAutoSwitch)
1007 && (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared)) {
1008 DBGPRINT(RT_DEBUG_TRACE,
1009 ("CNTL - AUTH FAIL, try OPEN system...\n"));
1010 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid,
1011 Ndis802_11AuthModeOpen);
1012 MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
1013 MT2_MLME_AUTH_REQ,
1014 sizeof(struct rt_mlme_auth_req),
1015 &AuthReq);
1017 pAd->Mlme.CntlMachine.CurrState =
1018 CNTL_WAIT_AUTH2;
1019 } else {
1020 /* not success, try next BSS */
1021 DBGPRINT(RT_DEBUG_TRACE,
1022 ("CNTL - AUTH FAIL, give up; try next BSS\n"));
1023 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; /*??????? */
1024 pAd->MlmeAux.BssIdx++;
1025 IterateOnBssTab(pAd);
1032 ==========================================================================
1033 Description:
1035 IRQL = DISPATCH_LEVEL
1037 ==========================================================================
1039 void CntlWaitAssocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1041 u16 Reason;
1043 if (Elem->MsgType == MT2_ASSOC_CONF) {
1044 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
1045 if (Reason == MLME_SUCCESS) {
1046 if (pAd->CommonCfg.bWirelessEvent) {
1047 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG,
1048 pAd->MacTab.
1049 Content[BSSID_WCID].Addr,
1050 BSS0, 0);
1053 LinkUp(pAd, BSS_INFRA);
1054 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1055 DBGPRINT(RT_DEBUG_TRACE,
1056 ("CNTL - Association successful on BSS #%ld\n",
1057 pAd->MlmeAux.BssIdx));
1058 } else {
1059 /* not success, try next BSS */
1060 DBGPRINT(RT_DEBUG_TRACE,
1061 ("CNTL - Association fails on BSS #%ld\n",
1062 pAd->MlmeAux.BssIdx));
1063 pAd->MlmeAux.BssIdx++;
1064 IterateOnBssTab(pAd);
1070 ==========================================================================
1071 Description:
1073 IRQL = DISPATCH_LEVEL
1075 ==========================================================================
1077 void CntlWaitReassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1079 u16 Result;
1081 if (Elem->MsgType == MT2_REASSOC_CONF) {
1082 NdisMoveMemory(&Result, Elem->Msg, sizeof(u16));
1083 if (Result == MLME_SUCCESS) {
1084 /* send wireless event - for association */
1085 if (pAd->CommonCfg.bWirelessEvent)
1086 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG,
1087 pAd->MacTab.
1088 Content[BSSID_WCID].Addr,
1089 BSS0, 0);
1091 /* */
1092 /* NDIS requires a new Link UP indication but no Link Down for RE-ASSOC */
1093 /* */
1094 LinkUp(pAd, BSS_INFRA);
1096 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1097 DBGPRINT(RT_DEBUG_TRACE,
1098 ("CNTL - Re-assocition successful on BSS #%ld\n",
1099 pAd->MlmeAux.RoamIdx));
1100 } else {
1101 /* reassoc failed, try to pick next BSS in the BSS Table */
1102 DBGPRINT(RT_DEBUG_TRACE,
1103 ("CNTL - Re-assocition fails on BSS #%ld\n",
1104 pAd->MlmeAux.RoamIdx));
1106 pAd->MlmeAux.RoamIdx++;
1107 IterateOnBssTab2(pAd);
1113 void AdhocTurnOnQos(struct rt_rtmp_adapter *pAd)
1115 #define AC0_DEF_TXOP 0
1116 #define AC1_DEF_TXOP 0
1117 #define AC2_DEF_TXOP 94
1118 #define AC3_DEF_TXOP 47
1120 /* Turn on QOs if use HT rate. */
1121 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) {
1122 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1123 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1124 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1125 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1126 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1128 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1129 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1130 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1131 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1133 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1134 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1135 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1136 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1138 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1139 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1140 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1141 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1143 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1147 ==========================================================================
1148 Description:
1150 IRQL = DISPATCH_LEVEL
1152 ==========================================================================
1154 void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType)
1156 unsigned long Now;
1157 u32 Data;
1158 BOOLEAN Cancelled;
1159 u8 Value = 0, idx = 0, HashIdx = 0;
1160 struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry = NULL;
1162 /* Init ChannelQuality to prevent DEAD_CQI at initial LinkUp */
1163 pAd->Mlme.ChannelQuality = 50;
1165 pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid);
1166 if (pEntry) {
1167 MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
1168 pEntry = NULL;
1171 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1173 /* */
1174 /* ASSOC - DisassocTimeoutAction */
1175 /* CNTL - Dis-associate successful */
1176 /* ! LINK DOWN ! */
1177 /* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */
1178 /* */
1179 /* To prevent DisassocTimeoutAction to call Link down after we link up, */
1180 /* cancel the DisassocTimer no matter what it start or not. */
1181 /* */
1182 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1184 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1186 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1188 #ifdef RTMP_MAC_PCI
1189 /* Before power save before link up function, We will force use 1R. */
1190 /* So after link up, check Rx antenna # again. */
1191 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1192 if (pAd->Antenna.field.RxPath == 3) {
1193 Value |= (0x10);
1194 } else if (pAd->Antenna.field.RxPath == 2) {
1195 Value |= (0x8);
1196 } else if (pAd->Antenna.field.RxPath == 1) {
1197 Value |= (0x0);
1199 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1200 pAd->StaCfg.BBPR3 = Value;
1201 #endif /* RTMP_MAC_PCI // */
1203 if (BssType == BSS_ADHOC) {
1204 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1205 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1207 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1208 AdhocTurnOnQos(pAd);
1210 DBGPRINT(RT_DEBUG_TRACE, ("Adhoc LINK UP!\n"));
1211 } else {
1212 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1213 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1215 DBGPRINT(RT_DEBUG_TRACE, ("Infra LINK UP!\n"));
1218 /* 3*3 */
1219 /* reset Tx beamforming bit */
1220 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1221 Value &= (~0x01);
1222 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1223 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1225 /* Change to AP channel */
1226 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
1227 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) {
1228 /* Must use 40MHz. */
1229 pAd->CommonCfg.BBPCurrentBW = BW_40;
1230 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1231 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1233 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1234 Value &= (~0x18);
1235 Value |= 0x10;
1236 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1238 /* RX : control channel at lower */
1239 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1240 Value &= (~0x20);
1241 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1242 #ifdef RTMP_MAC_PCI
1243 pAd->StaCfg.BBPR3 = Value;
1244 #endif /* RTMP_MAC_PCI // */
1246 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1247 Data &= 0xfffffffe;
1248 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1250 if (pAd->MACVersion == 0x28600100) {
1251 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1252 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1253 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1254 DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
1257 DBGPRINT(RT_DEBUG_TRACE,
1258 ("40MHz Lower LINK UP! Control Channel at Below. Central = %d \n",
1259 pAd->CommonCfg.CentralChannel));
1260 } else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
1261 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth ==
1262 BW_40)) {
1263 /* Must use 40MHz. */
1264 pAd->CommonCfg.BBPCurrentBW = BW_40;
1265 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1266 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1268 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1269 Value &= (~0x18);
1270 Value |= 0x10;
1271 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1273 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1274 Data |= 0x1;
1275 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1277 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1278 Value |= (0x20);
1279 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1280 #ifdef RTMP_MAC_PCI
1281 pAd->StaCfg.BBPR3 = Value;
1282 #endif /* RTMP_MAC_PCI // */
1284 if (pAd->MACVersion == 0x28600100) {
1285 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1286 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1287 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1288 DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
1291 DBGPRINT(RT_DEBUG_TRACE,
1292 ("40MHz Upper LINK UP! Control Channel at UpperCentral = %d \n",
1293 pAd->CommonCfg.CentralChannel));
1294 } else {
1295 pAd->CommonCfg.BBPCurrentBW = BW_20;
1296 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1297 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1298 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1300 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1301 Value &= (~0x18);
1302 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1304 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1305 Data &= 0xfffffffe;
1306 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1308 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1309 Value &= (~0x20);
1310 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1311 #ifdef RTMP_MAC_PCI
1312 pAd->StaCfg.BBPR3 = Value;
1313 #endif /* RTMP_MAC_PCI // */
1315 if (pAd->MACVersion == 0x28600100) {
1316 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1317 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1318 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1319 DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
1322 DBGPRINT(RT_DEBUG_TRACE, ("20MHz LINK UP!\n"));
1325 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1327 /* */
1328 /* Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission */
1329 /* */
1330 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66,
1331 &pAd->BbpTuning.R66CurrentValue);
1333 DBGPRINT(RT_DEBUG_TRACE,
1334 ("LINK UP! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1335 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid,
1336 pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1338 DBGPRINT(RT_DEBUG_TRACE,
1339 ("LINK UP! (Density =%d, )\n",
1340 pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1342 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1344 AsicSetSlotTime(pAd, TRUE);
1345 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1347 /* Call this for RTS protection for legacy rate, we will always enable RTS threshold, but normally it will not hit */
1348 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE,
1349 FALSE);
1351 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)) {
1352 /* Update HT protection for based on AP's operating mode. */
1353 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) {
1354 AsicUpdateProtect(pAd,
1355 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1356 OperaionMode, ALLN_SETPROTECT, FALSE,
1357 TRUE);
1358 } else
1359 AsicUpdateProtect(pAd,
1360 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1361 OperaionMode, ALLN_SETPROTECT, FALSE,
1362 FALSE);
1365 NdisZeroMemory(&pAd->DrsCounters, sizeof(struct rt_counter_drs));
1367 NdisGetSystemUpTime(&Now);
1368 pAd->StaCfg.LastBeaconRxTime = Now; /* last RX timestamp */
1370 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1371 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo)) {
1372 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1375 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1377 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE) {
1379 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1381 if (BssType == BSS_ADHOC) {
1382 MakeIbssBeacon(pAd);
1383 if ((pAd->CommonCfg.Channel > 14)
1384 && (pAd->CommonCfg.bIEEE80211H == 1)
1385 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) {
1386 ; /*Do nothing */
1387 } else {
1388 AsicEnableIbssSync(pAd);
1391 /* In ad hoc mode, use MAC table from index 1. */
1392 /* p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here. */
1393 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1394 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1396 /* If WEP is enabled, add key material and cipherAlg into Asic */
1397 /* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */
1399 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) {
1400 u8 *Key;
1401 u8 CipherAlg;
1403 for (idx = 0; idx < SHARE_KEY_NUM; idx++) {
1404 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1405 Key = pAd->SharedKey[BSS0][idx].Key;
1407 if (pAd->SharedKey[BSS0][idx].KeyLen > 0) {
1408 /* Set key material and cipherAlg to Asic */
1409 AsicAddSharedKeyEntry(pAd, BSS0, idx,
1410 CipherAlg, Key,
1411 NULL, NULL);
1413 if (idx == pAd->StaCfg.DefaultKeyId) {
1414 /* Update WCID attribute table and IVEIV table for this group key table */
1415 RTMPAddWcidAttributeEntry(pAd,
1416 BSS0,
1417 idx,
1418 CipherAlg,
1419 NULL);
1425 /* If WPANone is enabled, add key material and cipherAlg into Asic */
1426 /* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */
1427 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
1428 pAd->StaCfg.DefaultKeyId = 0; /* always be zero */
1430 NdisZeroMemory(&pAd->SharedKey[BSS0][0],
1431 sizeof(struct rt_cipher_key));
1432 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1433 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key,
1434 pAd->StaCfg.PMK, LEN_TKIP_EK);
1436 if (pAd->StaCfg.PairCipher ==
1437 Ndis802_11Encryption2Enabled) {
1438 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic,
1439 &pAd->StaCfg.PMK[16],
1440 LEN_TKIP_RXMICK);
1441 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic,
1442 &pAd->StaCfg.PMK[16],
1443 LEN_TKIP_TXMICK);
1445 /* Decide its ChiperAlg */
1446 if (pAd->StaCfg.PairCipher ==
1447 Ndis802_11Encryption2Enabled)
1448 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1449 else if (pAd->StaCfg.PairCipher ==
1450 Ndis802_11Encryption3Enabled)
1451 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1452 else {
1453 DBGPRINT(RT_DEBUG_TRACE,
1454 ("Unknow Cipher (=%d), set Cipher to AES\n",
1455 pAd->StaCfg.PairCipher));
1456 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1459 /* Set key material and cipherAlg to Asic */
1460 AsicAddSharedKeyEntry(pAd,
1461 BSS0,
1463 pAd->SharedKey[BSS0][0].CipherAlg,
1464 pAd->SharedKey[BSS0][0].Key,
1465 pAd->SharedKey[BSS0][0].TxMic,
1466 pAd->SharedKey[BSS0][0].RxMic);
1468 /* Update WCID attribute table and IVEIV table for this group key table */
1469 RTMPAddWcidAttributeEntry(pAd, BSS0, 0,
1470 pAd->SharedKey[BSS0][0].
1471 CipherAlg, NULL);
1475 } else /* BSS_INFRA */
1477 /* Check the new SSID with last SSID */
1478 while (Cancelled == TRUE) {
1479 if (pAd->CommonCfg.LastSsidLen ==
1480 pAd->CommonCfg.SsidLen) {
1481 if (RTMPCompareMemory
1482 (pAd->CommonCfg.LastSsid,
1483 pAd->CommonCfg.Ssid,
1484 pAd->CommonCfg.LastSsidLen) == 0) {
1485 /* Link to the old one no linkdown is required. */
1486 break;
1489 /* Send link down event before set to link up */
1490 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1491 RTMP_IndicateMediaState(pAd);
1492 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1493 DBGPRINT(RT_DEBUG_TRACE,
1494 ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1495 break;
1498 /* */
1499 /* On WPA mode, Remove All Keys if not connect to the last BSSID */
1500 /* Key will be set after 4-way handshake. */
1501 /* */
1502 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
1503 unsigned long IV;
1505 /* Remove all WPA keys */
1506 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1507 RTMPWPARemoveAllKeys(pAd);
1508 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1509 pAd->StaCfg.PrivacyFilter =
1510 Ndis802_11PrivFilter8021xWEP;
1512 /* Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP */
1513 /* If IV related values are too large in GroupMsg2, AP would ignore this message. */
1514 IV = 1;
1515 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1516 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1518 /* NOTE: */
1519 /* the decision of using "short slot time" or not may change dynamically due to */
1520 /* new STA association to the AP. so we have to decide that upon parsing BEACON, not here */
1522 /* NOTE: */
1523 /* the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically */
1524 /* due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here */
1526 ComposePsPoll(pAd);
1527 ComposeNullFrame(pAd);
1529 AsicEnableBssSync(pAd);
1531 /* Add BSSID to WCID search table */
1532 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1534 /* If WEP is enabled, add pairwise and shared key */
1535 if (((pAd->StaCfg.WpaSupplicantUP) &&
1536 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1537 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1538 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) &&
1539 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled))) {
1540 u8 *Key;
1541 u8 CipherAlg;
1543 for (idx = 0; idx < SHARE_KEY_NUM; idx++) {
1544 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1545 Key = pAd->SharedKey[BSS0][idx].Key;
1547 if (pAd->SharedKey[BSS0][idx].KeyLen > 0) {
1548 /* Set key material and cipherAlg to Asic */
1549 AsicAddSharedKeyEntry(pAd, BSS0, idx,
1550 CipherAlg, Key,
1551 NULL, NULL);
1553 if (idx == pAd->StaCfg.DefaultKeyId) {
1554 /* Assign group key info */
1555 RTMPAddWcidAttributeEntry(pAd,
1556 BSS0,
1557 idx,
1558 CipherAlg,
1559 NULL);
1561 pEntry->Aid = BSSID_WCID;
1562 /* Assign pairwise key info */
1563 RTMPAddWcidAttributeEntry(pAd,
1564 BSS0,
1565 idx,
1566 CipherAlg,
1567 pEntry);
1572 /* only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode */
1573 /* should wait until at least 2 active nodes in this BSSID. */
1574 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1576 /* For GUI ++ */
1577 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) {
1578 pAd->IndicateMediaState = NdisMediaStateConnected;
1579 pAd->ExtraInfo = GENERAL_LINK_UP;
1580 RTMP_IndicateMediaState(pAd);
1581 } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1582 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1584 if (pAd->StaCfg.WpaSupplicantUP ==
1585 WPA_SUPPLICANT_DISABLE)
1586 RTMPSetTimer(&pAd->Mlme.LinkDownTimer,
1587 LINK_DOWN_TIMEOUT);
1589 /* -- */
1591 /* Add BSSID in my MAC Table. */
1592 NdisAcquireSpinLock(&pAd->MacTabLock);
1593 /* add this MAC entry into HASH table */
1594 if (pEntry) {
1595 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1596 if (pAd->MacTab.Hash[HashIdx] == NULL) {
1597 pAd->MacTab.Hash[HashIdx] = pEntry;
1598 } else {
1599 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1600 while (pCurrEntry->pNext != NULL) {
1601 pCurrEntry = pCurrEntry->pNext;
1603 pCurrEntry->pNext = pEntry;
1606 RTMPMoveMemory(pEntry->Addr, pAd->CommonCfg.Bssid,
1607 MAC_ADDR_LEN);
1608 pEntry->Aid = BSSID_WCID;
1609 pEntry->pAd = pAd;
1610 pEntry->ValidAsCLI = TRUE; /*Although this is bssid..still set ValidAsCl */
1611 pAd->MacTab.Size = 1; /* infra mode always set MACtab size =1. */
1612 pEntry->Sst = SST_ASSOC;
1613 pEntry->AuthState = SST_ASSOC;
1614 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1615 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1616 if (pEntry->AuthMode < Ndis802_11AuthModeWPA) {
1617 pEntry->WpaState = AS_NOTUSE;
1618 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1619 } else {
1620 pEntry->WpaState = AS_PTKSTART;
1621 pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1623 NdisReleaseSpinLock(&pAd->MacTabLock);
1625 DBGPRINT(RT_DEBUG_TRACE,
1626 ("LINK UP! ClientStatusFlags=%lx)\n",
1627 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1629 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1630 MlmeUpdateHtTxRates(pAd, BSS0);
1631 DBGPRINT(RT_DEBUG_TRACE,
1632 ("LINK UP! (StaActive.bHtEnable =%d, )\n",
1633 pAd->StaActive.SupportedPhyInfo.bHtEnable));
1635 if (pAd->CommonCfg.bAggregationCapable) {
1636 if ((pAd->CommonCfg.bPiggyBackCapable)
1637 && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3) {
1638 OPSTATUS_SET_FLAG(pAd,
1639 fOP_STATUS_PIGGYBACK_INUSED);
1640 OPSTATUS_SET_FLAG(pAd,
1641 fOP_STATUS_AGGREGATION_INUSED);
1642 CLIENT_STATUS_SET_FLAG(pEntry,
1643 fCLIENT_STATUS_AGGREGATION_CAPABLE);
1644 CLIENT_STATUS_SET_FLAG(pEntry,
1645 fCLIENT_STATUS_PIGGYBACK_CAPABLE);
1646 RTMPSetPiggyBack(pAd, TRUE);
1647 DBGPRINT(RT_DEBUG_TRACE,
1648 ("Turn on Piggy-Back\n"));
1649 } else if (pAd->MlmeAux.APRalinkIe & 0x00000001) {
1650 OPSTATUS_SET_FLAG(pAd,
1651 fOP_STATUS_AGGREGATION_INUSED);
1652 CLIENT_STATUS_SET_FLAG(pEntry,
1653 fCLIENT_STATUS_AGGREGATION_CAPABLE);
1654 DBGPRINT(RT_DEBUG_TRACE,
1655 ("Ralink Aggregation\n"));
1659 if (pAd->MlmeAux.APRalinkIe != 0x0) {
1660 if (CLIENT_STATUS_TEST_FLAG
1661 (pEntry, fCLIENT_STATUS_RDG_CAPABLE)) {
1662 AsicEnableRDG(pAd);
1664 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1665 CLIENT_STATUS_SET_FLAG(pEntry,
1666 fCLIENT_STATUS_RALINK_CHIPSET);
1667 } else {
1668 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1669 CLIENT_STATUS_CLEAR_FLAG(pEntry,
1670 fCLIENT_STATUS_RALINK_CHIPSET);
1674 DBGPRINT(RT_DEBUG_TRACE,
1675 ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n",
1676 pAd->CommonCfg.BACapability.word,
1677 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1679 /* Set LED */
1680 RTMPSetLED(pAd, LED_LINK_UP);
1682 pAd->Mlme.PeriodicRound = 0;
1683 pAd->Mlme.OneSecPeriodicRound = 0;
1684 pAd->bConfigChanged = FALSE; /* Reset config flag */
1685 pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information after link is up */
1687 /* Set basic auto fall back */
1689 u8 *pTable;
1690 u8 TableSize = 0;
1692 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID],
1693 &pTable, &TableSize,
1694 &pAd->CommonCfg.TxRateIndex);
1695 AsicUpdateAutoFallBackTable(pAd, pTable);
1698 NdisAcquireSpinLock(&pAd->MacTabLock);
1699 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1700 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1701 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE) {
1702 pEntry->bAutoTxRateSwitch = FALSE;
1704 if (pEntry->HTPhyMode.field.MCS == 32)
1705 pEntry->HTPhyMode.field.ShortGI = GI_800;
1707 if ((pEntry->HTPhyMode.field.MCS > MCS_7)
1708 || (pEntry->HTPhyMode.field.MCS == 32))
1709 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1711 /* If the legacy mode is set, overwrite the transmit setting of this entry. */
1712 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1713 RTMPUpdateLegacyTxSetting((u8)pAd->StaCfg.
1714 DesiredTransmitSetting.field.
1715 FixedTxMode, pEntry);
1716 } else
1717 pEntry->bAutoTxRateSwitch = TRUE;
1718 NdisReleaseSpinLock(&pAd->MacTabLock);
1720 /* Let Link Status Page display first initial rate. */
1721 pAd->LastTxRate = (u16)(pEntry->HTPhyMode.word);
1722 /* Select DAC according to HT or Legacy */
1723 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00) {
1724 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1725 Value &= (~0x18);
1726 if (pAd->Antenna.field.TxPath == 2) {
1727 Value |= 0x10;
1729 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1730 } else {
1731 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1732 Value &= (~0x18);
1733 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1736 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) {
1737 } else if (pEntry->MaxRAmpduFactor == 0) {
1738 /* If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0. */
1739 /* Because our Init value is 1 at MACRegTable. */
1740 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1742 /* Patch for Marvel AP to gain high throughput */
1743 /* Need to set as following, */
1744 /* 1. Set txop in register-EDCA_AC0_CFG as 0x60 */
1745 /* 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero */
1746 /* 3. PBF_MAX_PCNT as 0x1F3FBF9F */
1747 /* 4. kick per two packets when dequeue */
1748 /* */
1749 /* Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable */
1750 /* */
1751 /* if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is. */
1752 if (!((pAd->CommonCfg.RxStream == 1) && (pAd->CommonCfg.TxStream == 1))
1753 && (pAd->StaCfg.bForceTxBurst == FALSE)
1755 (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1756 && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
1757 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)
1758 && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))) {
1759 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1760 Data &= 0xFFFFFF00;
1761 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1763 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1764 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1765 } else if (pAd->CommonCfg.bEnableTxBurst) {
1766 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1767 Data &= 0xFFFFFF00;
1768 Data |= 0x60;
1769 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1770 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1772 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1773 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1774 } else {
1775 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1776 Data &= 0xFFFFFF00;
1777 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1779 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1780 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1783 /* Re-check to turn on TX burst or not. */
1784 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE)
1785 && ((STA_WEP_ON(pAd)) || (STA_TKIP_ON(pAd)))) {
1786 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1787 if (pAd->CommonCfg.bEnableTxBurst) {
1788 u32 MACValue = 0;
1789 /* Force disable TXOP value in this case. The same action in MLMEUpdateProtect too. */
1790 /* I didn't change PBF_MAX_PCNT setting. */
1791 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1792 MACValue &= 0xFFFFFF00;
1793 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1794 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1796 } else {
1797 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1800 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1801 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1802 DBGPRINT(RT_DEBUG_TRACE,
1803 ("pAd->bNextDisableRxBA= %d \n",
1804 pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1805 /* BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap */
1806 /* Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver. */
1807 /* Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same. */
1809 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled) {
1810 if (pAd->StaCfg.WpaSupplicantUP &&
1811 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1812 (pAd->StaCfg.IEEE8021X == TRUE)) ;
1813 else {
1814 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1815 pAd->StaCfg.PrivacyFilter =
1816 Ndis802_11PrivFilterAcceptAll;
1820 NdisAcquireSpinLock(&pAd->MacTabLock);
1821 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1822 NdisReleaseSpinLock(&pAd->MacTabLock);
1824 /* */
1825 /* Patch Atheros AP TX will breakdown issue. */
1826 /* AP Model: DLink DWL-8200AP */
1827 /* */
1828 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)
1829 && STA_TKIP_ON(pAd)) {
1830 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1831 } else {
1832 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1835 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1837 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1841 ==========================================================================
1843 Routine Description:
1844 Disconnect current BSSID
1846 Arguments:
1847 pAd - Pointer to our adapter
1848 IsReqFromAP - Request from AP
1850 Return Value:
1851 None
1853 IRQL = DISPATCH_LEVEL
1855 Note:
1856 We need more information to know it's this requst from AP.
1857 If yes! we need to do extra handling, for example, remove the WPA key.
1858 Otherwise on 4-way handshaking will fail, since the WPA key didn't get
1859 removed while auto reconnect.
1860 Disconnect request from AP, it means we will start afresh 4-way handshaking
1861 on WPA mode.
1863 ==========================================================================
1865 void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP)
1867 u8 i, ByteValue = 0;
1869 /* Do nothing if monitor mode is on */
1870 if (MONITOR_ON(pAd))
1871 return;
1873 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1874 /* Comment the codes, because the line 2291 call the same function. */
1875 /* RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); */
1876 /* Not allowed go to sleep within the linkdown function. */
1877 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1879 if (pAd->CommonCfg.bWirelessEvent) {
1880 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
1881 pAd->MacTab.Content[BSSID_WCID].Addr,
1882 BSS0, 0);
1885 DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN!\n"));
1886 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1888 #ifdef RTMP_MAC_PCI
1889 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
1890 BOOLEAN Cancelled;
1891 pAd->Mlme.bPsPollTimerRunning = FALSE;
1892 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1895 pAd->bPCIclkOff = FALSE;
1896 #endif /* RTMP_MAC_PCI // */
1898 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
1899 || RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)
1900 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) {
1901 AUTO_WAKEUP_STRUC AutoWakeupCfg;
1902 AsicForceWakeup(pAd, TRUE);
1903 AutoWakeupCfg.word = 0;
1904 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1905 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1907 #ifdef RTMP_MAC_PCI
1908 pAd->bPCIclkOff = FALSE;
1909 #endif /* RTMP_MAC_PCI // */
1911 if (ADHOC_ON(pAd)) /* Adhoc mode link down */
1913 DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 1!\n"));
1915 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1916 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1917 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1918 RTMP_IndicateMediaState(pAd);
1919 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1920 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid,
1921 pAd->CommonCfg.Channel);
1922 DBGPRINT(RT_DEBUG_TRACE,
1923 (" MacTab.Size=%d !\n", pAd->MacTab.Size));
1924 } else /* Infra structure mode */
1926 DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 2!\n"));
1928 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1929 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1931 /* Saved last SSID for linkup comparison */
1932 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1933 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid,
1934 pAd->CommonCfg.LastSsidLen);
1935 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1936 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE) {
1937 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1938 RTMP_IndicateMediaState(pAd);
1939 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1940 DBGPRINT(RT_DEBUG_TRACE,
1941 ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1942 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1943 } else {
1944 /* */
1945 /* If disassociation request is from NDIS, then we don't need to delete BSSID from entry. */
1946 /* Otherwise lost beacon or receive De-Authentication from AP, */
1947 /* then we should delete BSSID from BssTable. */
1948 /* If we don't delete from entry, roaming will fail. */
1949 /* */
1950 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid,
1951 pAd->CommonCfg.Channel);
1954 /* restore back to - */
1955 /* 1. long slot (20 us) or short slot (9 us) time */
1956 /* 2. turn on/off RTS/CTS and/or CTS-to-self protection */
1957 /* 3. short preamble */
1958 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1962 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
1963 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1964 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid,
1965 pAd->MacTab.Content[i].Addr);
1968 AsicSetSlotTime(pAd, TRUE); /*FALSE); */
1969 AsicSetEdcaParm(pAd, NULL);
1971 /* Set LED */
1972 RTMPSetLED(pAd, LED_LINK_DOWN);
1973 pAd->LedIndicatorStrength = 0xF0;
1974 RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, firmware has not done it. */
1976 AsicDisableSync(pAd);
1978 pAd->Mlme.PeriodicRound = 0;
1979 pAd->Mlme.OneSecPeriodicRound = 0;
1981 if (pAd->StaCfg.BssType == BSS_INFRA) {
1982 /* Remove StaCfg Information after link down */
1983 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1984 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1985 pAd->CommonCfg.SsidLen = 0;
1988 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(struct rt_ht_capability_ie));
1989 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(struct rt_add_ht_info_ie));
1990 pAd->MlmeAux.HtCapabilityLen = 0;
1991 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1993 /* Reset WPA-PSK state. Only reset when supplicant enabled */
1994 if (pAd->StaCfg.WpaState != SS_NOTUSE) {
1995 pAd->StaCfg.WpaState = SS_START;
1996 /* Clear Replay counter */
1997 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2000 /* */
2001 /* if link down come from AP, we need to remove all WPA keys on WPA mode. */
2002 /* otherwise will cause 4-way handshaking failed, since the WPA key not empty. */
2003 /* */
2004 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)) {
2005 /* Remove all WPA keys */
2006 RTMPWPARemoveAllKeys(pAd);
2008 /* 802.1x port control */
2010 /* Prevent clear PortSecured here with static WEP */
2011 /* NetworkManger set security policy first then set SSID to connect AP. */
2012 if (pAd->StaCfg.WpaSupplicantUP &&
2013 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
2014 (pAd->StaCfg.IEEE8021X == FALSE)) {
2015 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2016 } else {
2017 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2018 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2021 NdisAcquireSpinLock(&pAd->MacTabLock);
2022 NdisZeroMemory(&pAd->MacTab, sizeof(struct rt_mac_table));
2023 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2024 NdisReleaseSpinLock(&pAd->MacTabLock);
2026 pAd->StaCfg.MicErrCnt = 0;
2028 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2029 /* Update extra information to link is up */
2030 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2032 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2034 #ifdef RTMP_MAC_USB
2035 pAd->bUsbTxBulkAggre = FALSE;
2036 #endif /* RTMP_MAC_USB // */
2038 /* Clean association information */
2039 NdisZeroMemory(&pAd->StaCfg.AssocInfo,
2040 sizeof(struct rt_ndis_802_11_association_information));
2041 pAd->StaCfg.AssocInfo.Length =
2042 sizeof(struct rt_ndis_802_11_association_information);
2043 pAd->StaCfg.ReqVarIELen = 0;
2044 pAd->StaCfg.ResVarIELen = 0;
2046 /* */
2047 /* Reset RSSI value after link down */
2048 /* */
2049 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2050 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2051 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2052 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2053 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2054 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2056 /* Restore MlmeRate */
2057 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2058 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2060 /* */
2061 /* After Link down, reset piggy-back setting in ASIC. Disable RDG. */
2062 /* */
2063 if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
2064 pAd->CommonCfg.BBPCurrentBW = BW_20;
2065 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2066 ByteValue &= (~0x18);
2067 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2069 /* Reset DAC */
2070 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2071 ByteValue &= (~0x18);
2072 if (pAd->Antenna.field.TxPath == 2) {
2073 ByteValue |= 0x10;
2075 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2077 RTMPSetPiggyBack(pAd, FALSE);
2078 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2080 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2082 /* Restore all settings in the following. */
2083 AsicUpdateProtect(pAd, 0,
2084 (ALLN_SETPROTECT | CCKSETPROTECT | OFDMSETPROTECT),
2085 TRUE, FALSE);
2086 AsicDisableRDG(pAd);
2087 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2088 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2090 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2091 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2093 /* Allow go to sleep after linkdown steps. */
2094 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
2096 RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
2098 #ifdef RT30xx
2099 if ((IS_RT30xx(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd))
2100 && (pAd->Antenna.field.RxPath > 1 || pAd->Antenna.field.TxPath > 1)) {
2101 RTMP_ASIC_MMPS_DISABLE(pAd);
2103 #endif /* RT30xx // */
2107 ==========================================================================
2108 Description:
2110 IRQL = DISPATCH_LEVEL
2112 ==========================================================================
2114 void IterateOnBssTab(struct rt_rtmp_adapter *pAd)
2116 struct rt_mlme_start_req StartReq;
2117 struct rt_mlme_join_req JoinReq;
2118 unsigned long BssIdx;
2120 /* Change the wepstatus to original wepstatus */
2121 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2122 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2123 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2125 BssIdx = pAd->MlmeAux.BssIdx;
2126 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr) {
2127 /* Check cipher suite, AP must have more secured cipher than station setting */
2128 /* Set the Pairwise and Group cipher to match the intended AP setting */
2129 /* We can only connect to AP with less secured cipher setting */
2130 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
2131 || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) {
2132 pAd->StaCfg.GroupCipher =
2133 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
2134 GroupCipher;
2136 if (pAd->StaCfg.WepStatus ==
2137 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
2138 PairCipher)
2139 pAd->StaCfg.PairCipher =
2140 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
2141 WPA.PairCipher;
2142 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
2143 PairCipherAux != Ndis802_11WEPDisabled)
2144 pAd->StaCfg.PairCipher =
2145 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
2146 WPA.PairCipherAux;
2147 else /* There is no PairCipher Aux, downgrade our capability to TKIP */
2148 pAd->StaCfg.PairCipher =
2149 Ndis802_11Encryption2Enabled;
2150 } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
2151 || (pAd->StaCfg.AuthMode ==
2152 Ndis802_11AuthModeWPA2PSK)) {
2153 pAd->StaCfg.GroupCipher =
2154 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
2155 GroupCipher;
2157 if (pAd->StaCfg.WepStatus ==
2158 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
2159 PairCipher)
2160 pAd->StaCfg.PairCipher =
2161 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
2162 WPA2.PairCipher;
2163 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
2164 PairCipherAux != Ndis802_11WEPDisabled)
2165 pAd->StaCfg.PairCipher =
2166 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
2167 WPA2.PairCipherAux;
2168 else /* There is no PairCipher Aux, downgrade our capability to TKIP */
2169 pAd->StaCfg.PairCipher =
2170 Ndis802_11Encryption2Enabled;
2172 /* RSN capability */
2173 pAd->StaCfg.RsnCapability =
2174 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
2175 RsnCapability;
2177 /* Set Mix cipher flag */
2178 pAd->StaCfg.bMixCipher =
2179 (pAd->StaCfg.PairCipher ==
2180 pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2181 /*if (pAd->StaCfg.bMixCipher == TRUE)
2183 // If mix cipher, re-build RSNIE
2184 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2185 } */
2187 DBGPRINT(RT_DEBUG_TRACE,
2188 ("CNTL - iterate BSS %ld of %d\n", BssIdx,
2189 pAd->MlmeAux.SsidBssTab.BssNr));
2190 JoinParmFill(pAd, &JoinReq, BssIdx);
2191 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ,
2192 sizeof(struct rt_mlme_join_req), &JoinReq);
2193 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2194 } else if (pAd->StaCfg.BssType == BSS_ADHOC) {
2195 DBGPRINT(RT_DEBUG_TRACE,
2196 ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",
2197 pAd->MlmeAux.Ssid));
2198 StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid,
2199 pAd->MlmeAux.SsidLen);
2200 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
2201 sizeof(struct rt_mlme_start_req), &StartReq);
2202 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2203 } else /* no more BSS */
2207 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2208 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2209 DBGPRINT(RT_DEBUG_TRACE,
2210 ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",
2211 pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
2214 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2218 /* for re-association only */
2219 /* IRQL = DISPATCH_LEVEL */
2220 void IterateOnBssTab2(struct rt_rtmp_adapter *pAd)
2222 struct rt_mlme_assoc_req ReassocReq;
2223 unsigned long BssIdx;
2224 struct rt_bss_entry *pBss;
2226 BssIdx = pAd->MlmeAux.RoamIdx;
2227 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2229 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr) {
2230 DBGPRINT(RT_DEBUG_TRACE,
2231 ("CNTL - iterate BSS %ld of %d\n", BssIdx,
2232 pAd->MlmeAux.RoamTab.BssNr));
2234 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2235 AsicLockChannel(pAd, pBss->Channel);
2237 /* reassociate message has the same structure as associate message */
2238 AssocParmFill(pAd, &ReassocReq, pBss->Bssid,
2239 pBss->CapabilityInfo, ASSOC_TIMEOUT,
2240 pAd->StaCfg.DefaultListenCount);
2241 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2242 sizeof(struct rt_mlme_assoc_req), &ReassocReq);
2244 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2245 } else /* no more BSS */
2249 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2250 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2251 DBGPRINT(RT_DEBUG_TRACE,
2252 ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",
2253 pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
2256 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2261 ==========================================================================
2262 Description:
2264 IRQL = DISPATCH_LEVEL
2266 ==========================================================================
2268 void JoinParmFill(struct rt_rtmp_adapter *pAd,
2269 struct rt_mlme_join_req *JoinReq, unsigned long BssIdx)
2271 JoinReq->BssIdx = BssIdx;
2275 ==========================================================================
2276 Description:
2278 IRQL = DISPATCH_LEVEL
2280 ==========================================================================
2282 void ScanParmFill(struct rt_rtmp_adapter *pAd,
2283 struct rt_mlme_scan_req *ScanReq,
2284 char Ssid[],
2285 u8 SsidLen, u8 BssType, u8 ScanType)
2287 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2288 ScanReq->SsidLen = SsidLen;
2289 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2290 ScanReq->BssType = BssType;
2291 ScanReq->ScanType = ScanType;
2295 ==========================================================================
2296 Description:
2298 IRQL = DISPATCH_LEVEL
2300 ==========================================================================
2302 void StartParmFill(struct rt_rtmp_adapter *pAd,
2303 struct rt_mlme_start_req *StartReq,
2304 char Ssid[], u8 SsidLen)
2306 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2307 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2308 StartReq->SsidLen = SsidLen;
2312 ==========================================================================
2313 Description:
2315 IRQL = DISPATCH_LEVEL
2317 ==========================================================================
2319 void AuthParmFill(struct rt_rtmp_adapter *pAd,
2320 struct rt_mlme_auth_req *AuthReq,
2321 u8 *pAddr, u16 Alg)
2323 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2324 AuthReq->Alg = Alg;
2325 AuthReq->Timeout = AUTH_TIMEOUT;
2329 ==========================================================================
2330 Description:
2332 IRQL = DISPATCH_LEVEL
2334 ==========================================================================
2336 #ifdef RTMP_MAC_PCI
2337 void ComposePsPoll(struct rt_rtmp_adapter *pAd)
2339 NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
2340 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2341 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2342 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2343 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2344 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2347 /* IRQL = DISPATCH_LEVEL */
2348 void ComposeNullFrame(struct rt_rtmp_adapter *pAd)
2350 NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11));
2351 pAd->NullFrame.FC.Type = BTYPE_DATA;
2352 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2353 pAd->NullFrame.FC.ToDs = 1;
2354 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2355 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2356 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2358 #endif /* RTMP_MAC_PCI // */
2359 #ifdef RTMP_MAC_USB
2360 void MlmeCntlConfirm(struct rt_rtmp_adapter *pAd, unsigned long MsgType, u16 Msg)
2362 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(u16),
2363 &Msg);
2366 void ComposePsPoll(struct rt_rtmp_adapter *pAd)
2368 struct rt_txinfo *pTxInfo;
2369 struct rt_txwi * pTxWI;
2371 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2372 NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
2374 pAd->PsPollFrame.FC.PwrMgmt = 0;
2375 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2376 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2377 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2378 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2379 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2381 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.
2382 WirelessPacket[0], 100);
2383 pTxInfo =
2384 (struct rt_txinfo *)& pAd->PsPollContext.TransferBuffer->field.
2385 WirelessPacket[0];
2386 RTMPWriteTxInfo(pAd, pTxInfo,
2387 (u16)(sizeof(struct rt_pspoll_frame) + TXWI_SIZE), TRUE,
2388 EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2389 pTxWI =
2390 (struct rt_txwi *) & pAd->PsPollContext.TransferBuffer->field.
2391 WirelessPacket[TXINFO_SIZE];
2392 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0,
2393 BSSID_WCID, (sizeof(struct rt_pspoll_frame)), 0, 0,
2394 (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
2395 IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2396 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.
2397 WirelessPacket[TXWI_SIZE + TXINFO_SIZE],
2398 &pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
2399 /* Append 4 extra zero bytes. */
2400 pAd->PsPollContext.BulkOutSize =
2401 TXINFO_SIZE + TXWI_SIZE + sizeof(struct rt_pspoll_frame) + 4;
2404 /* IRQL = DISPATCH_LEVEL */
2405 void ComposeNullFrame(struct rt_rtmp_adapter *pAd)
2407 struct rt_txinfo *pTxInfo;
2408 struct rt_txwi * pTxWI;
2410 NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11));
2411 pAd->NullFrame.FC.Type = BTYPE_DATA;
2412 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2413 pAd->NullFrame.FC.ToDs = 1;
2414 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2415 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2416 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2417 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.
2418 WirelessPacket[0], 100);
2419 pTxInfo =
2420 (struct rt_txinfo *)& pAd->NullContext.TransferBuffer->field.
2421 WirelessPacket[0];
2422 RTMPWriteTxInfo(pAd, pTxInfo,
2423 (u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE), TRUE,
2424 EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2425 pTxWI =
2426 (struct rt_txwi *) & pAd->NullContext.TransferBuffer->field.
2427 WirelessPacket[TXINFO_SIZE];
2428 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0,
2429 BSSID_WCID, (sizeof(struct rt_header_802_11)), 0, 0,
2430 (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
2431 IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2432 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.
2433 WirelessPacket[TXWI_SIZE + TXINFO_SIZE], &pAd->NullFrame,
2434 sizeof(struct rt_header_802_11));
2435 pAd->NullContext.BulkOutSize =
2436 TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2438 #endif /* RTMP_MAC_USB // */
2441 ==========================================================================
2442 Description:
2443 Pre-build a BEACON frame in the shared memory
2445 IRQL = PASSIVE_LEVEL
2446 IRQL = DISPATCH_LEVEL
2448 ==========================================================================
2450 unsigned long MakeIbssBeacon(struct rt_rtmp_adapter *pAd)
2452 u8 DsLen = 1, IbssLen = 2;
2453 u8 LocalErpIe[3] = { IE_ERP, 1, 0x04 };
2454 struct rt_header_802_11 BcnHdr;
2455 u16 CapabilityInfo;
2456 LARGE_INTEGER FakeTimestamp;
2457 unsigned long FrameLen = 0;
2458 struct rt_txwi * pTxWI = &pAd->BeaconTxWI;
2459 u8 *pBeaconFrame = pAd->BeaconBuf;
2460 BOOLEAN Privacy;
2461 u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2462 u8 SupRateLen = 0;
2463 u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2464 u8 ExtRateLen = 0;
2465 u8 RSNIe = IE_WPA;
2467 if ((pAd->CommonCfg.PhyMode == PHY_11B)
2468 && (pAd->CommonCfg.Channel <= 14)) {
2469 SupRate[0] = 0x82; /* 1 mbps */
2470 SupRate[1] = 0x84; /* 2 mbps */
2471 SupRate[2] = 0x8b; /* 5.5 mbps */
2472 SupRate[3] = 0x96; /* 11 mbps */
2473 SupRateLen = 4;
2474 ExtRateLen = 0;
2475 } else if (pAd->CommonCfg.Channel > 14) {
2476 SupRate[0] = 0x8C; /* 6 mbps, in units of 0.5 Mbps, basic rate */
2477 SupRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */
2478 SupRate[2] = 0x98; /* 12 mbps, in units of 0.5 Mbps, basic rate */
2479 SupRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */
2480 SupRate[4] = 0xb0; /* 24 mbps, in units of 0.5 Mbps, basic rate */
2481 SupRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */
2482 SupRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */
2483 SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */
2484 SupRateLen = 8;
2485 ExtRateLen = 0;
2487 /* */
2488 /* Also Update MlmeRate & RtsRate for G only & A only */
2489 /* */
2490 pAd->CommonCfg.MlmeRate = RATE_6;
2491 pAd->CommonCfg.RtsRate = RATE_6;
2492 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2493 pAd->CommonCfg.MlmeTransmit.field.MCS =
2494 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2495 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
2496 MODE_OFDM;
2497 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
2498 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2499 } else {
2500 SupRate[0] = 0x82; /* 1 mbps */
2501 SupRate[1] = 0x84; /* 2 mbps */
2502 SupRate[2] = 0x8b; /* 5.5 mbps */
2503 SupRate[3] = 0x96; /* 11 mbps */
2504 SupRateLen = 4;
2506 ExtRate[0] = 0x0C; /* 6 mbps, in units of 0.5 Mbps, */
2507 ExtRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */
2508 ExtRate[2] = 0x18; /* 12 mbps, in units of 0.5 Mbps, */
2509 ExtRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */
2510 ExtRate[4] = 0x30; /* 24 mbps, in units of 0.5 Mbps, */
2511 ExtRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */
2512 ExtRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */
2513 ExtRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */
2514 ExtRateLen = 8;
2517 pAd->StaActive.SupRateLen = SupRateLen;
2518 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2519 pAd->StaActive.ExtRateLen = ExtRateLen;
2520 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2522 /* compose IBSS beacon frame */
2523 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR,
2524 pAd->CommonCfg.Bssid);
2525 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
2526 || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2527 || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2528 CapabilityInfo =
2529 CAP_GENERATE(0, 1, Privacy,
2530 (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort),
2531 0, 0);
2533 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2534 sizeof(struct rt_header_802_11), &BcnHdr,
2535 TIMESTAMP_LEN, &FakeTimestamp,
2536 2, &pAd->CommonCfg.BeaconPeriod,
2537 2, &CapabilityInfo,
2538 1, &SsidIe,
2539 1, &pAd->CommonCfg.SsidLen,
2540 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2541 1, &SupRateIe,
2542 1, &SupRateLen,
2543 SupRateLen, SupRate,
2544 1, &DsIe,
2545 1, &DsLen,
2546 1, &pAd->CommonCfg.Channel,
2547 1, &IbssIe,
2548 1, &IbssLen, 2, &pAd->StaActive.AtimWin, END_OF_ARGS);
2550 /* add ERP_IE and EXT_RAE IE of in 802.11g */
2551 if (ExtRateLen) {
2552 unsigned long tmp;
2554 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2555 3, LocalErpIe,
2556 1, &ExtRateIe,
2557 1, &ExtRateLen,
2558 ExtRateLen, ExtRate, END_OF_ARGS);
2559 FrameLen += tmp;
2561 /* If adhoc secruity is set for WPA-None, append the cipher suite IE */
2562 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
2563 unsigned long tmp;
2564 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus,
2565 BSS0);
2567 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2568 1, &RSNIe,
2569 1, &pAd->StaCfg.RSNIE_Len,
2570 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2571 END_OF_ARGS);
2572 FrameLen += tmp;
2575 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) {
2576 unsigned long TmpLen;
2577 u8 HtLen, HtLen1;
2579 /* add HT Capability IE */
2580 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2581 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2583 MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
2584 1, &HtCapIe,
2585 1, &HtLen,
2586 HtLen, &pAd->CommonCfg.HtCapability,
2587 1, &AddHtInfoIe,
2588 1, &HtLen1,
2589 HtLen1, &pAd->CommonCfg.AddHTInfo,
2590 END_OF_ARGS);
2592 FrameLen += TmpLen;
2594 /*beacon use reserved WCID 0xff */
2595 if (pAd->CommonCfg.Channel > 14) {
2596 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE,
2597 TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON,
2598 RATE_1, IFS_HTTXOP, FALSE,
2599 &pAd->CommonCfg.MlmeTransmit);
2600 } else {
2601 /* Set to use 1Mbps for Adhoc beacon. */
2602 HTTRANSMIT_SETTING Transmit;
2603 Transmit.word = 0;
2604 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE,
2605 TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON,
2606 RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2609 DBGPRINT(RT_DEBUG_TRACE,
2610 ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2611 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel,
2612 pAd->CommonCfg.PhyMode));
2613 return FrameLen;