2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 John 2004-08-08 Major modification from RT2560
37 #include "../rt_config.h"
39 UCHAR CipherSuiteWpaNoneTkip[] = {
40 0x00, 0x50, 0xf2, 0x01, // oui
41 0x01, 0x00, // Version
42 0x00, 0x50, 0xf2, 0x02, // Multicast
43 0x01, 0x00, // Number of unicast
44 0x00, 0x50, 0xf2, 0x02, // unicast
45 0x01, 0x00, // number of authentication method
46 0x00, 0x50, 0xf2, 0x00 // authentication
48 UCHAR CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
50 UCHAR CipherSuiteWpaNoneAes[] = {
51 0x00, 0x50, 0xf2, 0x01, // oui
52 0x01, 0x00, // Version
53 0x00, 0x50, 0xf2, 0x04, // Multicast
54 0x01, 0x00, // Number of unicast
55 0x00, 0x50, 0xf2, 0x04, // unicast
56 0x01, 0x00, // number of authentication method
57 0x00, 0x50, 0xf2, 0x00 // authentication
59 UCHAR CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
61 // The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS,
62 // or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS
63 // All settings successfuly negotiated furing MLME state machines become final settings
64 // and are copied to pAd->StaActive
65 #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
67 (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \
68 NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
69 COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \
70 (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel; \
71 (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel; \
72 (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid; \
73 (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin; \
74 (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo; \
75 (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod; \
76 (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration; \
77 (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod; \
78 (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen; \
79 NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
80 (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen; \
81 NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
82 NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\
83 NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\
84 NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\
85 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid); \
86 (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid; \
87 (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
88 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
89 (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
93 ==========================================================================
98 ==========================================================================
101 IN PRTMP_ADAPTER pAd,
103 OUT STATE_MACHINE_FUNC Trans[])
105 // Control state machine differs from other state machines, the interface
106 // follows the standard interface
107 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
111 ==========================================================================
114 IRQL = DISPATCH_LEVEL
116 ==========================================================================
118 VOID MlmeCntlMachinePerformAction(
119 IN PRTMP_ADAPTER pAd,
121 IN MLME_QUEUE_ELEM *Elem)
123 switch(pAd->Mlme.CntlMachine.CurrState)
127 CntlIdleProc(pAd, Elem);
130 case CNTL_WAIT_DISASSOC:
131 CntlWaitDisassocProc(pAd, Elem);
134 CntlWaitJoinProc(pAd, Elem);
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);
147 case CNTL_WAIT_START:
148 CntlWaitStartProc(pAd, Elem);
151 CntlWaitAuthProc(pAd, Elem);
153 case CNTL_WAIT_AUTH2:
154 CntlWaitAuthProc2(pAd, Elem);
156 case CNTL_WAIT_ASSOC:
157 CntlWaitAssocProc(pAd, Elem);
160 case CNTL_WAIT_OID_LIST_SCAN:
161 if(Elem->MsgType == MT2_SCAN_CONF)
163 // Resume TxRing after SCANING complete. We hope the out-of-service time
164 // won't be too long to let upper layer time-out the waiting frames
165 RTMPResumeMsduTransmission(pAd);
166 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
168 // Cisco scan request is finished, prepare beacon report
169 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
171 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
174 // Set LED status to previous status.
176 if (pAd->bLedOnScanning)
178 pAd->bLedOnScanning = FALSE;
179 RTMPSetLED(pAd, pAd->LedStatus);
182 // AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone.
183 if (pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1)
185 Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
187 #endif // DOT11N_DRAFT3 //
191 case CNTL_WAIT_OID_DISASSOC:
192 if (Elem->MsgType == MT2_DISASSOC_CONF)
194 LinkDown(pAd, FALSE);
195 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
199 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
206 ==========================================================================
209 IRQL = DISPATCH_LEVEL
211 ==========================================================================
214 IN PRTMP_ADAPTER pAd,
215 IN MLME_QUEUE_ELEM *Elem)
217 MLME_DISASSOC_REQ_STRUCT DisassocReq;
219 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
222 switch(Elem->MsgType)
224 case OID_802_11_SSID:
225 CntlOidSsidProc(pAd, Elem);
228 case OID_802_11_BSSID:
229 CntlOidRTBssidProc(pAd,Elem);
232 case OID_802_11_BSSID_LIST_SCAN:
233 CntlOidScanProc(pAd,Elem);
236 case OID_802_11_DISASSOCIATE:
237 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
238 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
239 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
240 #ifdef WPA_SUPPLICANT_SUPPORT
241 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
242 #endif // WPA_SUPPLICANT_SUPPORT //
244 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
245 // Since calling this indicate user don't want to connect to that SSID anymore.
246 pAd->MlmeAux.AutoReconnectSsidLen= 32;
247 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
251 case MT2_MLME_ROAMING_REQ:
252 CntlMlmeRoamingProc(pAd, Elem);
255 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
256 WpaMicFailureReportFrame(pAd, Elem);
260 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
265 VOID CntlOidScanProc(
266 IN PRTMP_ADAPTER pAd,
267 IN MLME_QUEUE_ELEM *Elem)
269 MLME_SCAN_REQ_STRUCT ScanReq;
270 ULONG BssIdx = BSS_NOT_FOUND;
273 // record current BSS if network is connected.
274 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
275 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
277 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
278 if (BssIdx != BSS_NOT_FOUND)
280 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
284 // clean up previous SCAN result, add current BSS back to table if any
285 BssTableInit(&pAd->ScanTab);
286 if (BssIdx != BSS_NOT_FOUND)
288 // DDK Note: If the NIC is associated with a particular BSSID and SSID
289 // that are not contained in the list of BSSIDs generated by this scan, the
290 // BSSID description of the currently associated BSSID and SSID should be
291 // appended to the list of BSSIDs in the NIC's database.
292 // To ensure this, we append this BSS as the first entry in SCAN result
293 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
294 pAd->ScanTab.BssNr = 1;
297 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
298 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
299 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
300 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
304 ==========================================================================
306 Before calling this routine, user desired SSID should already been
307 recorded in CommonCfg.Ssid[]
308 IRQL = DISPATCH_LEVEL
310 ==========================================================================
312 VOID CntlOidSsidProc(
313 IN PRTMP_ADAPTER pAd,
314 IN MLME_QUEUE_ELEM * Elem)
316 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
317 MLME_DISASSOC_REQ_STRUCT DisassocReq;
320 // BBP and RF are not accessible in PS mode, we has to wake them up first
321 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
322 AsicForceWakeup(pAd, RTMP_HALT);
324 // Step 1. record the desired user settings to MlmeAux
325 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
326 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
327 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
328 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
329 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
333 // Update Reconnect Ssid, that user desired to connect.
335 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
336 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
337 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
339 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
340 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
341 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
343 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
344 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
345 NdisGetSystemUpTime(&Now);
347 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
348 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
349 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
350 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
352 // Case 1. already connected with an AP who has the desired SSID
355 // Add checking Mode "LEAP" for CCX 1.0
356 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
357 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
358 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
359 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
361 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
362 #endif // LEAP_SUPPORT //
364 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
366 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
367 // connection process
368 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
369 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
370 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
371 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
372 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
374 else if (pAd->bConfigChanged == TRUE)
376 // case 1.2 Important Config has changed, we have to reconnect to the same AP
377 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
378 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
379 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
380 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
381 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
385 // case 1.3. already connected to the SSID with highest RSSI.
386 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
388 // (HCT 12.1) 1c_wlan_mediaevents required
389 // media connect events are indicated when associating with the same AP
394 // Since MediaState already is NdisMediaStateConnected
395 // We just indicate the connect event again to meet the WHQL required.
397 pAd->IndicateMediaState = NdisMediaStateConnected;
398 RTMP_IndicateMediaState(pAd);
399 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
402 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
403 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
405 union iwreq_data wrqu;
407 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
408 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
409 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
412 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
415 else if (INFRA_ON(pAd))
419 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
420 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
421 // But media status is connected, so the SSID not report correctly.
423 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
426 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
428 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
430 // case 2. active INFRA association existent
431 // roaming is done within miniport driver, nothing to do with configuration
432 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
433 // disassociate with the current associated AP,
434 // then perform a new association with this new SSID, no matter the
435 // new/old SSID are the same or not.
436 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
437 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
438 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
439 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
440 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
446 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
447 LinkDown(pAd, FALSE);
448 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
449 pAd->IndicateMediaState = NdisMediaStateDisconnected;
450 RTMP_IndicateMediaState(pAd);
451 pAd->ExtraInfo = GENERAL_LINK_DOWN;
452 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
455 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
456 (pAd->StaCfg.bAutoReconnect == TRUE) &&
457 (pAd->MlmeAux.BssType == BSS_INFRA) &&
458 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
461 MLME_SCAN_REQ_STRUCT ScanReq;
463 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
464 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
465 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
466 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
467 // Reset Missed scan number
468 pAd->StaCfg.LastScanTime = Now;
472 pAd->MlmeAux.BssIdx = 0;
473 IterateOnBssTab(pAd);
480 ==========================================================================
483 IRQL = DISPATCH_LEVEL
485 ==========================================================================
487 VOID CntlOidRTBssidProc(
488 IN PRTMP_ADAPTER pAd,
489 IN MLME_QUEUE_ELEM * Elem)
492 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
493 MLME_DISASSOC_REQ_STRUCT DisassocReq;
494 MLME_JOIN_REQ_STRUCT JoinReq;
496 // record user desired settings
497 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
498 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
501 // Update Reconnect Ssid, that user desired to connect.
503 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
504 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
505 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
507 // find the desired BSS in the latest SCAN result table
508 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
509 if (BssIdx == BSS_NOT_FOUND)
511 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
512 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
516 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
517 // Because we need this entry to become the JOIN target in later on SYNC state machine
518 pAd->MlmeAux.BssIdx = 0;
519 pAd->MlmeAux.SsidBssTab.BssNr = 1;
520 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
522 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
523 // we just follow normal procedure. The reason of user doing this may because he/she changed
524 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
525 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
526 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
527 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
528 // connection when setting the same BSSID.
529 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
530 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
532 // already connected to the same BSSID, go back to idle state directly
533 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
534 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
535 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
537 union iwreq_data wrqu;
539 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
540 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
541 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
544 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
550 // disassoc from current AP first
551 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
552 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
553 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
554 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
556 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
562 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
563 LinkDown(pAd, FALSE);
564 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
565 pAd->IndicateMediaState = NdisMediaStateDisconnected;
566 RTMP_IndicateMediaState(pAd);
567 pAd->ExtraInfo = GENERAL_LINK_DOWN;
568 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
571 // Change the wepstatus to original wepstatus
572 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
573 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
574 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
576 // Check cipher suite, AP must have more secured cipher than station setting
577 // Set the Pairwise and Group cipher to match the intended AP setting
578 // We can only connect to AP with less secured cipher setting
579 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
581 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
583 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
584 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
585 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
586 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
587 else // There is no PairCipher Aux, downgrade our capability to TKIP
588 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
590 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
592 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
594 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
595 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
596 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
597 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
598 else // There is no PairCipher Aux, downgrade our capability to TKIP
599 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
602 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
605 // Set Mix cipher flag
606 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
607 if (pAd->StaCfg.bMixCipher == TRUE)
609 // If mix cipher, re-build RSNIE
610 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
612 // No active association, join the BSS immediately
613 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
614 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
616 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
617 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
619 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
624 // Roaming is the only external request triggering CNTL state machine
625 // despite of other "SET OID" operation. All "SET OID" related oerations
626 // happen in sequence, because no other SET OID will be sent to this device
627 // until the the previous SET operation is complete (successful o failed).
628 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
629 // or been corrupted by other "SET OID"?
631 // IRQL = DISPATCH_LEVEL
632 VOID CntlMlmeRoamingProc(
633 IN PRTMP_ADAPTER pAd,
634 IN MLME_QUEUE_ELEM *Elem)
637 // AP in different channel may show lower RSSI than actual value??
638 // should we add a weighting factor to compensate it?
639 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
641 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
642 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
644 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
645 pAd->MlmeAux.BssIdx = 0;
646 IterateOnBssTab(pAd);
650 ==========================================================================
653 IRQL = DISPATCH_LEVEL
655 ==========================================================================
657 VOID CntlWaitDisassocProc(
658 IN PRTMP_ADAPTER pAd,
659 IN MLME_QUEUE_ELEM *Elem)
661 MLME_START_REQ_STRUCT StartReq;
663 if (Elem->MsgType == MT2_DISASSOC_CONF)
665 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
667 if (pAd->CommonCfg.bWirelessEvent)
669 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
672 LinkDown(pAd, FALSE);
674 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
675 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
677 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
678 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
679 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
680 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
682 // case 2. try each matched BSS
685 pAd->MlmeAux.BssIdx = 0;
687 IterateOnBssTab(pAd);
693 ==========================================================================
696 IRQL = DISPATCH_LEVEL
698 ==========================================================================
700 VOID CntlWaitJoinProc(
701 IN PRTMP_ADAPTER pAd,
702 IN MLME_QUEUE_ELEM *Elem)
705 MLME_AUTH_REQ_STRUCT AuthReq;
707 if (Elem->MsgType == MT2_JOIN_CONF)
709 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
710 if (Reason == MLME_SUCCESS)
712 // 1. joined an IBSS, we are pretty much done here
713 if (pAd->MlmeAux.BssType == BSS_ADHOC)
716 // 5G bands rules of Japan:
717 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
719 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
720 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
723 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
724 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
728 LinkUp(pAd, BSS_ADHOC);
729 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
730 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
731 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
732 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
734 pAd->IndicateMediaState = NdisMediaStateConnected;
735 pAd->ExtraInfo = GENERAL_LINK_UP;
737 // 2. joined a new INFRA network, start from authentication
741 // Add AuthMode "LEAP" for CCX 1.X
742 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
744 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
747 #endif // LEAP_SUPPORT //
749 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
750 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
751 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
753 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
757 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
760 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
761 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
763 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
768 // 3. failed, try next BSS
769 pAd->MlmeAux.BssIdx++;
770 IterateOnBssTab(pAd);
777 ==========================================================================
780 IRQL = DISPATCH_LEVEL
782 ==========================================================================
784 VOID CntlWaitStartProc(
785 IN PRTMP_ADAPTER pAd,
786 IN MLME_QUEUE_ELEM *Elem)
790 if (Elem->MsgType == MT2_START_CONF)
792 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
793 if (Result == MLME_SUCCESS)
796 // 5G bands rules of Japan:
797 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
799 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
800 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
803 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
804 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
807 #ifdef DOT11_N_SUPPORT
808 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
812 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
813 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
814 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
815 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
816 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
817 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
819 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
820 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
822 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
824 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
825 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
827 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
831 #endif // DOT11_N_SUPPORT //
833 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
835 LinkUp(pAd, BSS_ADHOC);
836 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
837 // Before send beacon, driver need do radar detection
838 if ((pAd->CommonCfg.Channel > 14 )
839 && (pAd->CommonCfg.bIEEE80211H == 1)
840 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
842 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
843 pAd->CommonCfg.RadarDetect.RDCount = 0;
846 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
847 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
848 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
852 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
853 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
859 ==========================================================================
862 IRQL = DISPATCH_LEVEL
864 ==========================================================================
866 VOID CntlWaitAuthProc(
867 IN PRTMP_ADAPTER pAd,
868 IN MLME_QUEUE_ELEM *Elem)
871 MLME_ASSOC_REQ_STRUCT AssocReq;
872 MLME_AUTH_REQ_STRUCT AuthReq;
874 if (Elem->MsgType == MT2_AUTH_CONF)
876 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
877 if (Reason == MLME_SUCCESS)
879 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
880 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
881 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
885 // Cisco Leap CCKM supported Re-association.
887 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
889 //if CCKM is turn on , that's mean Fast Reauthentication
890 //Use CCKM Reassociation instead of normal association for Fast Roaming.
891 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
892 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
894 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
897 #endif // LEAP_SUPPORT //
899 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
900 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
902 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
907 // This fail may because of the AP already keep us in its MAC table without
908 // ageing-out. The previous authentication attempt must have let it remove us.
909 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
910 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
912 //Add AuthMode "LEAP" for CCX 1.X
913 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
915 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
918 #endif // LEAP_SUPPORT //
920 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
921 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
923 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
924 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
928 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
931 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
932 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
934 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
940 ==========================================================================
943 IRQL = DISPATCH_LEVEL
945 ==========================================================================
947 VOID CntlWaitAuthProc2(
948 IN PRTMP_ADAPTER pAd,
949 IN MLME_QUEUE_ELEM *Elem)
952 MLME_ASSOC_REQ_STRUCT AssocReq;
953 MLME_AUTH_REQ_STRUCT AuthReq;
955 if (Elem->MsgType == MT2_AUTH_CONF)
957 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
958 if (Reason == MLME_SUCCESS)
960 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
961 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
962 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
963 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
964 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
966 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
971 // Process LEAP first, since it use different control variable
972 // We don't want to affect other poven operation
973 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
975 // LEAP Auth not success, try next BSS
976 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
977 DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
978 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
979 pAd->MlmeAux.BssIdx++;
980 IterateOnBssTab(pAd);
983 #endif // LEAP_SUPPORT //
984 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
985 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
987 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
988 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
989 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
990 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
992 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
996 // not success, try next BSS
997 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
998 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
999 pAd->MlmeAux.BssIdx++;
1000 IterateOnBssTab(pAd);
1007 ==========================================================================
1010 IRQL = DISPATCH_LEVEL
1012 ==========================================================================
1014 VOID CntlWaitAssocProc(
1015 IN PRTMP_ADAPTER pAd,
1016 IN MLME_QUEUE_ELEM *Elem)
1020 if (Elem->MsgType == MT2_ASSOC_CONF)
1022 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1023 if (Reason == MLME_SUCCESS)
1025 LinkUp(pAd, BSS_INFRA);
1026 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1027 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1029 if (pAd->CommonCfg.bWirelessEvent)
1031 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1036 // not success, try next BSS
1037 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1038 pAd->MlmeAux.BssIdx++;
1039 IterateOnBssTab(pAd);
1045 ==========================================================================
1048 IRQL = DISPATCH_LEVEL
1050 ==========================================================================
1052 VOID CntlWaitReassocProc(
1053 IN PRTMP_ADAPTER pAd,
1054 IN MLME_QUEUE_ELEM *Elem)
1058 if (Elem->MsgType == MT2_REASSOC_CONF)
1060 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1061 if (Result == MLME_SUCCESS)
1064 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1066 LinkUp(pAd, BSS_INFRA);
1068 // send wireless event - for association
1069 if (pAd->CommonCfg.bWirelessEvent)
1070 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1074 if (LEAP_CCKM_ON(pAd))
1076 STA_PORT_SECURED(pAd);
1077 pAd->StaCfg.WpaState = SS_FINISH;
1079 #endif // LEAP_SUPPORT //
1080 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1081 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1085 // reassoc failed, try to pick next BSS in the BSS Table
1086 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1087 pAd->MlmeAux.RoamIdx++;
1088 IterateOnBssTab2(pAd);
1094 ==========================================================================
1097 IRQL = DISPATCH_LEVEL
1099 ==========================================================================
1102 IN PRTMP_ADAPTER pAd,
1108 UCHAR Value = 0, idx;
1109 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1111 if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
1113 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
1114 RTMPusecDelay(6000);
1115 pAd->bPCIclkOff = FALSE;
1118 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1121 // ASSOC - DisassocTimeoutAction
1122 // CNTL - Dis-associate successful
1123 // !!! LINK DOWN !!!
1124 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1126 // To prevent DisassocTimeoutAction to call Link down after we link up,
1127 // cancel the DisassocTimer no matter what it start or not.
1129 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1131 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1133 #ifdef DOT11_N_SUPPORT
1134 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1135 #endif // DOT11_N_SUPPORT //
1136 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1137 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1138 // to examine if cipher algorithm switching is required.
1139 //rt2860b. Don't know why need this
1140 SwitchBetweenWepAndCkip(pAd);
1142 // Before power save before link up function, We will force use 1R.
1143 // So after link up, check Rx antenna # again.
1144 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1145 if(pAd->Antenna.field.RxPath == 3)
1149 else if(pAd->Antenna.field.RxPath == 2)
1153 else if(pAd->Antenna.field.RxPath == 1)
1157 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1158 pAd->StaCfg.BBPR3 = Value;
1160 if (BssType == BSS_ADHOC)
1162 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1163 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1165 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1169 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1170 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1172 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1176 // reset Tx beamforming bit
1177 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1179 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1180 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1182 #ifdef DOT11_N_SUPPORT
1183 // Change to AP channel
1184 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1186 // Must using 40MHz.
1187 pAd->CommonCfg.BBPCurrentBW = BW_40;
1188 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1189 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1191 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1194 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1196 // RX : control channel at lower
1197 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1199 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1200 pAd->StaCfg.BBPR3 = Value;
1202 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1204 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1206 if (pAd->MACVersion == 0x28600100)
1208 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1209 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1210 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1211 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1214 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1216 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1218 // Must using 40MHz.
1219 pAd->CommonCfg.BBPCurrentBW = BW_40;
1220 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1221 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1223 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1226 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1228 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1230 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1232 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1234 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1235 pAd->StaCfg.BBPR3 = Value;
1237 if (pAd->MACVersion == 0x28600100)
1239 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1240 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1241 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1242 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1245 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1248 #endif // DOT11_N_SUPPORT //
1250 pAd->CommonCfg.BBPCurrentBW = BW_20;
1251 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1252 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1253 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1255 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1257 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1259 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1261 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1263 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1265 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1266 pAd->StaCfg.BBPR3 = Value;
1268 if (pAd->MACVersion == 0x28600100)
1270 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1271 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1272 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1273 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1276 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1279 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1281 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1283 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1285 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1286 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1288 #ifdef DOT11_N_SUPPORT
1289 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1290 #endif // DOT11_N_SUPPORT //
1292 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1294 AsicSetSlotTime(pAd, TRUE);
1295 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1297 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1298 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1300 #ifdef DOT11_N_SUPPORT
1301 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1303 // Update HT protectionfor based on AP's operating mode.
1304 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1306 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1309 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1311 #endif // DOT11_N_SUPPORT //
1313 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1315 NdisGetSystemUpTime(&Now);
1316 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1318 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1319 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1321 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1324 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1326 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1329 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1331 if (BssType == BSS_ADHOC)
1333 MakeIbssBeacon(pAd);
1334 if ((pAd->CommonCfg.Channel > 14)
1335 && (pAd->CommonCfg.bIEEE80211H == 1)
1336 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1342 AsicEnableIbssSync(pAd);
1345 // In ad hoc mode, use MAC table from index 1.
1346 // 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.
1347 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1348 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1350 // If WEP is enabled, add key material and cipherAlg into Asic
1351 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1353 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1358 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1360 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1361 Key = pAd->SharedKey[BSS0][idx].Key;
1363 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1365 // Set key material and cipherAlg to Asic
1366 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1368 if (idx == pAd->StaCfg.DefaultKeyId)
1370 // Update WCID attribute table and IVEIV table for this group key table
1371 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1378 // If WPANone is enabled, add key material and cipherAlg into Asic
1379 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1380 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1382 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1384 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1385 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1386 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1388 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1390 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1391 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1394 // Decide its ChiperAlg
1395 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1396 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1397 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1398 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1401 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1402 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1405 // Set key material and cipherAlg to Asic
1406 AsicAddSharedKeyEntry(pAd,
1409 pAd->SharedKey[BSS0][0].CipherAlg,
1410 pAd->SharedKey[BSS0][0].Key,
1411 pAd->SharedKey[BSS0][0].TxMic,
1412 pAd->SharedKey[BSS0][0].RxMic);
1414 // Update WCID attribute table and IVEIV table for this group key table
1415 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1422 // Check the new SSID with last SSID
1423 while (Cancelled == TRUE)
1425 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1427 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1429 // Link to the old one no linkdown is required.
1433 // Send link down event before set to link up
1434 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1435 RTMP_IndicateMediaState(pAd);
1436 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1437 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1442 // On WPA mode, Remove All Keys if not connect to the last BSSID
1443 // Key will be set after 4-way handshake.
1445 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1449 // Remove all WPA keys
1450 RTMPWPARemoveAllKeys(pAd);
1451 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1452 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1454 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1455 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1457 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1458 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1460 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1463 // the decision of using "short slot time" or not may change dynamically due to
1464 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1467 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1468 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1471 ComposeNullFrame(pAd);
1473 AsicEnableBssSync(pAd);
1475 // Add BSSID to WCID search table
1476 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1478 NdisAcquireSpinLock(&pAd->MacTabLock);
1479 // add this BSSID entry into HASH table
1483 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1484 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1485 if (pAd->MacTab.Hash[HashIdx] == NULL)
1487 pAd->MacTab.Hash[HashIdx] = pEntry;
1491 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1492 while (pCurrEntry->pNext != NULL)
1493 pCurrEntry = pCurrEntry->pNext;
1494 pCurrEntry->pNext = pEntry;
1497 NdisReleaseSpinLock(&pAd->MacTabLock);
1500 // If WEP is enabled, add paiewise and shared key
1501 #ifdef WPA_SUPPLICANT_SUPPORT
1502 if (((pAd->StaCfg.WpaSupplicantUP)&&
1503 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1504 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1505 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1506 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1508 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1509 #endif // WPA_SUPPLICANT_SUPPORT //
1514 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1516 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1517 Key = pAd->SharedKey[BSS0][idx].Key;
1519 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1521 // Set key material and cipherAlg to Asic
1522 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1524 if (idx == pAd->StaCfg.DefaultKeyId)
1526 // Assign group key info
1527 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1529 // Assign pairwise key info
1530 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1536 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1537 // should wait until at least 2 active nodes in this BSSID.
1538 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1541 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1543 pAd->IndicateMediaState = NdisMediaStateConnected;
1544 pAd->ExtraInfo = GENERAL_LINK_UP;
1547 RTMP_IndicateMediaState(pAd);
1549 // Add BSSID in my MAC Table.
1550 NdisAcquireSpinLock(&pAd->MacTabLock);
1551 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1552 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1553 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1554 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1555 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1556 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1557 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1558 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1559 NdisReleaseSpinLock(&pAd->MacTabLock);
1561 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1562 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1564 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1565 #ifdef DOT11_N_SUPPORT
1566 MlmeUpdateHtTxRates(pAd, BSS0);
1567 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1568 #endif // DOT11_N_SUPPORT //
1571 // Report Adjacent AP report.
1574 CCXAdjacentAPReport(pAd);
1575 #endif // LEAP_SUPPORT //
1577 if (pAd->CommonCfg.bAggregationCapable)
1579 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1582 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1583 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1584 RTMPSetPiggyBack(pAd, TRUE);
1585 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1587 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1589 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1593 if (pAd->MlmeAux.APRalinkIe != 0x0)
1595 #ifdef DOT11_N_SUPPORT
1596 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1600 #endif // DOT11_N_SUPPORT //
1601 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1602 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1606 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1607 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1611 #ifdef DOT11_N_SUPPORT
1612 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n", pAd->CommonCfg.BACapability.word, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1613 #endif // DOT11_N_SUPPORT //
1616 RTMPSetLED(pAd, LED_LINK_UP);
1618 pAd->Mlme.PeriodicRound = 0;
1619 pAd->Mlme.OneSecPeriodicRound = 0;
1620 pAd->bConfigChanged = FALSE; // Reset config flag
1621 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1623 // Set asic auto fall back
1626 UCHAR TableSize = 0;
1628 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1629 AsicUpdateAutoFallBackTable(pAd, pTable);
1632 NdisAcquireSpinLock(&pAd->MacTabLock);
1633 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1634 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1635 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1637 pEntry->bAutoTxRateSwitch = FALSE;
1638 #ifdef DOT11_N_SUPPORT
1639 if (pEntry->HTPhyMode.field.MCS == 32)
1640 pEntry->HTPhyMode.field.ShortGI = GI_800;
1642 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1643 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1644 #endif // DOT11_N_SUPPORT //
1645 // If the legacy mode is set, overwrite the transmit setting of this entry.
1646 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1647 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1650 pEntry->bAutoTxRateSwitch = TRUE;
1651 NdisReleaseSpinLock(&pAd->MacTabLock);
1653 // Let Link Status Page display first initial rate.
1654 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1655 // Select DAC according to HT or Legacy
1656 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1658 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1660 if (pAd->Antenna.field.TxPath == 2)
1664 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1668 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1670 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1673 #ifdef DOT11_N_SUPPORT
1674 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1677 else if (pEntry->MaxRAmpduFactor == 0)
1679 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1680 // Because our Init value is 1 at MACRegTable.
1681 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1683 #endif // DOT11_N_SUPPORT //
1685 // Patch for Marvel AP to gain high throughput
1686 // Need to set as following,
1687 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1688 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1689 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1690 // 4. kick per two packets when dequeue
1692 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1694 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1695 #ifdef DOT11_N_SUPPORT
1696 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1697 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1699 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1701 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1703 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1704 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1707 #endif // DOT11_N_SUPPORT //
1708 if (pAd->CommonCfg.bEnableTxBurst)
1710 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1713 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1714 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1716 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1717 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1721 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1723 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1725 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1726 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1729 #ifdef DOT11_N_SUPPORT
1730 // Re-check to turn on TX burst or not.
1731 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1733 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1734 if (pAd->CommonCfg.bEnableTxBurst)
1736 UINT32 MACValue = 0;
1737 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1738 // I didn't change PBF_MAX_PCNT setting.
1739 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1740 MACValue &= 0xFFFFFF00;
1741 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1742 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1747 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1749 #endif // DOT11_N_SUPPORT //
1751 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1752 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1753 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1754 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1755 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1756 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1758 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1760 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1761 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1764 NdisAcquireSpinLock(&pAd->MacTabLock);
1765 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1766 NdisReleaseSpinLock(&pAd->MacTabLock);
1769 // Patch Atheros AP TX will breakdown issue.
1770 // AP Model: DLink DWL-8200AP
1772 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1774 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1778 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1781 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1782 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1784 #ifdef DOT11_N_SUPPORT
1785 #ifdef DOT11N_DRAFT3
1786 if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
1788 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
1789 BuildEffectedChannelList(pAd);
1791 #endif // DOT11N_DRAFT3 //
1792 #endif // DOT11_N_SUPPORT //
1796 ==========================================================================
1798 Routine Description:
1799 Disconnect current BSSID
1802 pAd - Pointer to our adapter
1803 IsReqFromAP - Request from AP
1808 IRQL = DISPATCH_LEVEL
1811 We need more information to know it's this requst from AP.
1812 If yes! we need to do extra handling, for example, remove the WPA key.
1813 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1814 remove while auto reconnect.
1815 Disconnect request from AP, it means we will start afresh 4-way handshaking
1818 ==========================================================================
1821 IN PRTMP_ADAPTER pAd,
1822 IN BOOLEAN IsReqFromAP)
1824 UCHAR i, ByteValue = 0;
1827 // Do nothing if monitor mode is on
1828 if (MONITOR_ON(pAd))
1831 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1832 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1834 // Not allow go to sleep within linkdown function.
1835 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1837 if (pAd->CommonCfg.bWirelessEvent)
1839 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1842 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1843 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1845 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1848 pAd->Mlme.bPsPollTimerRunning = FALSE;
1849 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1852 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
1853 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
1854 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
1856 AsicForceWakeup(pAd, RTMP_HALT);
1857 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1860 pAd->bPCIclkOff = FALSE;
1861 if (ADHOC_ON(pAd)) // Adhoc mode link down
1863 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1865 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1866 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1867 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1868 RTMP_IndicateMediaState(pAd);
1869 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1870 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1871 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1873 else // Infra structure mode
1875 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1877 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1878 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1880 // Saved last SSID for linkup comparison
1881 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1882 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
1883 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1884 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
1886 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1887 RTMP_IndicateMediaState(pAd);
1888 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1889 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1890 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1895 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
1896 // Otherwise lost beacon or receive De-Authentication from AP,
1897 // then we should delete BSSID from BssTable.
1898 // If we don't delete from entry, roaming will fail.
1900 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1903 // restore back to -
1904 // 1. long slot (20 us) or short slot (9 us) time
1905 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1906 // 3. short preamble
1907 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1909 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
1912 // Record current AP's information.
1913 // for later used reporting Adjacent AP report.
1915 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
1916 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
1917 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
1918 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
1921 #ifdef EXT_BUILD_CHANNEL_LIST
1922 // Country IE of the AP will be evaluated and will be used.
1923 if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
1925 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
1926 pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
1927 BuildChannelListEx(pAd);
1929 #endif // EXT_BUILD_CHANNEL_LIST //
1933 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
1935 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1936 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
1939 pAd->StaCfg.CCXQosECWMin = 4;
1940 pAd->StaCfg.CCXQosECWMax = 10;
1942 AsicSetSlotTime(pAd, TRUE); //FALSE);
1943 AsicSetEdcaParm(pAd, NULL);
1946 RTMPSetLED(pAd, LED_LINK_DOWN);
1947 pAd->LedIndicatorStregth = 0xF0;
1948 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
1950 AsicDisableSync(pAd);
1952 pAd->Mlme.PeriodicRound = 0;
1953 pAd->Mlme.OneSecPeriodicRound = 0;
1955 if (pAd->StaCfg.BssType == BSS_INFRA)
1957 // Remove StaCfg Information after link down
1958 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1959 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1960 pAd->CommonCfg.SsidLen = 0;
1962 #ifdef DOT11_N_SUPPORT
1963 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
1964 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
1965 pAd->MlmeAux.HtCapabilityLen = 0;
1966 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1967 #endif // DOT11_N_SUPPORT //
1969 // Reset WPA-PSK state. Only reset when supplicant enabled
1970 if (pAd->StaCfg.WpaState != SS_NOTUSE)
1972 pAd->StaCfg.WpaState = SS_START;
1973 // Clear Replay counter
1974 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1979 // if link down come from AP, we need to remove all WPA keys on WPA mode.
1980 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
1982 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1984 // Remove all WPA keys
1985 RTMPWPARemoveAllKeys(pAd);
1988 // 802.1x port control
1989 #ifdef WPA_SUPPLICANT_SUPPORT
1990 // Prevent clear PortSecured here with static WEP
1991 // NetworkManger set security policy first then set SSID to connect AP.
1992 if (pAd->StaCfg.WpaSupplicantUP &&
1993 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1994 (pAd->StaCfg.IEEE8021X == FALSE))
1996 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1999 #endif // WPA_SUPPLICANT_SUPPORT //
2001 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2002 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2005 NdisAcquireSpinLock(&pAd->MacTabLock);
2006 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2007 NdisReleaseSpinLock(&pAd->MacTabLock);
2009 pAd->StaCfg.MicErrCnt = 0;
2011 // Turn off Ckip control flag
2012 pAd->StaCfg.bCkipOn = FALSE;
2013 pAd->StaCfg.CCXEnable = FALSE;
2015 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2016 // Update extra information to link is up
2017 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2019 pAd->StaCfg.AdhocBOnlyJoined = FALSE;
2020 pAd->StaCfg.AdhocBGJoined = FALSE;
2021 pAd->StaCfg.Adhoc20NJoined = FALSE;
2022 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2024 // Reset the Current AP's IP address
2025 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
2027 // Clean association information
2028 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
2029 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
2030 pAd->StaCfg.ReqVarIELen = 0;
2031 pAd->StaCfg.ResVarIELen = 0;
2034 // Reset RSSI value after link down
2036 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2037 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2038 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2039 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2040 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2041 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2044 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2045 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2047 #ifdef DOT11_N_SUPPORT
2049 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
2051 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
2053 pAd->CommonCfg.BBPCurrentBW = BW_20;
2054 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2055 ByteValue &= (~0x18);
2056 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2058 #endif // DOT11_N_SUPPORT //
2060 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2061 ByteValue &= (~0x18);
2062 if (pAd->Antenna.field.TxPath == 2)
2066 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2068 RTMPSetPiggyBack(pAd,FALSE);
2069 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2071 #ifdef DOT11_N_SUPPORT
2072 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2073 #endif // DOT11_N_SUPPORT //
2075 // Restore all settings in the following.
2076 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2077 AsicDisableRDG(pAd);
2078 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2079 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2081 #ifdef DOT11_N_SUPPORT
2082 #ifdef DOT11N_DRAFT3
2083 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
2084 pAd->CommonCfg.BSSCoexist2040.word = 0;
2086 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
2088 pAd->ChannelList[i].bEffectedChannel = FALSE;
2090 #endif // DOT11N_DRAFT3 //
2091 #endif // DOT11_N_SUPPORT //
2093 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2094 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2096 // Allow go to sleep after linkdown steps.
2097 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
2099 #ifdef WPA_SUPPLICANT_SUPPORT
2100 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2101 if (pAd->StaCfg.WpaSupplicantUP) {
2102 union iwreq_data wrqu;
2103 //send disassociate event to wpa_supplicant
2104 memset(&wrqu, 0, sizeof(wrqu));
2105 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2106 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2108 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2109 #endif // WPA_SUPPLICANT_SUPPORT //
2111 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2113 union iwreq_data wrqu;
2114 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2115 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2117 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2121 ==========================================================================
2124 IRQL = DISPATCH_LEVEL
2126 ==========================================================================
2128 VOID IterateOnBssTab(
2129 IN PRTMP_ADAPTER pAd)
2131 MLME_START_REQ_STRUCT StartReq;
2132 MLME_JOIN_REQ_STRUCT JoinReq;
2135 // Change the wepstatus to original wepstatus
2136 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2137 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2138 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2140 BssIdx = pAd->MlmeAux.BssIdx;
2141 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2143 // Check cipher suite, AP must have more secured cipher than station setting
2144 // Set the Pairwise and Group cipher to match the intended AP setting
2145 // We can only connect to AP with less secured cipher setting
2146 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2148 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2150 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2151 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2152 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2153 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2154 else // There is no PairCipher Aux, downgrade our capability to TKIP
2155 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2157 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2159 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2161 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2162 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2163 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2164 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2165 else // There is no PairCipher Aux, downgrade our capability to TKIP
2166 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2169 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2172 // Set Mix cipher flag
2173 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2174 if (pAd->StaCfg.bMixCipher == TRUE)
2176 // If mix cipher, re-build RSNIE
2177 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2180 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2181 JoinParmFill(pAd, &JoinReq, BssIdx);
2182 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2184 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2186 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2188 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2189 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2190 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2191 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2195 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2196 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2197 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2198 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2202 // for re-association only
2203 // IRQL = DISPATCH_LEVEL
2204 VOID IterateOnBssTab2(
2205 IN PRTMP_ADAPTER pAd)
2207 MLME_REASSOC_REQ_STRUCT ReassocReq;
2211 BssIdx = pAd->MlmeAux.RoamIdx;
2212 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2214 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2216 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2218 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2219 AsicLockChannel(pAd, pBss->Channel);
2221 // reassociate message has the same structure as associate message
2222 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2223 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2224 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2225 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2227 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2231 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2232 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2233 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2234 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2239 ==========================================================================
2242 IRQL = DISPATCH_LEVEL
2244 ==========================================================================
2247 IN PRTMP_ADAPTER pAd,
2248 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2251 JoinReq->BssIdx = BssIdx;
2255 ==========================================================================
2258 IRQL = DISPATCH_LEVEL
2260 ==========================================================================
2263 IN PRTMP_ADAPTER pAd,
2264 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2270 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2271 ScanReq->SsidLen = SsidLen;
2272 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2273 ScanReq->BssType = BssType;
2274 ScanReq->ScanType = ScanType;
2278 ==========================================================================
2281 IRQL = DISPATCH_LEVEL
2283 ==========================================================================
2286 IN PRTMP_ADAPTER pAd,
2287 IN OUT MLME_START_REQ_STRUCT *StartReq,
2291 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2292 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2293 StartReq->SsidLen = SsidLen;
2297 ==========================================================================
2300 IRQL = DISPATCH_LEVEL
2302 ==========================================================================
2305 IN PRTMP_ADAPTER pAd,
2306 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2310 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2312 AuthReq->Timeout = AUTH_TIMEOUT;
2316 ==========================================================================
2319 IRQL = DISPATCH_LEVEL
2321 ==========================================================================
2324 IN PRTMP_ADAPTER pAd)
2326 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2327 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2328 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2329 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2330 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2331 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2334 // IRQL = DISPATCH_LEVEL
2335 VOID ComposeNullFrame(
2336 IN PRTMP_ADAPTER pAd)
2338 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2339 pAd->NullFrame.FC.Type = BTYPE_DATA;
2340 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2341 pAd->NullFrame.FC.ToDs = 1;
2342 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2343 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2344 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2351 ==========================================================================
2353 Pre-build a BEACON frame in the shared memory
2355 IRQL = PASSIVE_LEVEL
2356 IRQL = DISPATCH_LEVEL
2358 ==========================================================================
2360 ULONG MakeIbssBeacon(
2361 IN PRTMP_ADAPTER pAd)
2363 UCHAR DsLen = 1, IbssLen = 2;
2364 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2365 HEADER_802_11 BcnHdr;
2366 USHORT CapabilityInfo;
2367 LARGE_INTEGER FakeTimestamp;
2369 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2370 CHAR *pBeaconFrame = pAd->BeaconBuf;
2372 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2373 UCHAR SupRateLen = 0;
2374 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2375 UCHAR ExtRateLen = 0;
2376 UCHAR RSNIe = IE_WPA;
2378 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2380 SupRate[0] = 0x82; // 1 mbps
2381 SupRate[1] = 0x84; // 2 mbps
2382 SupRate[2] = 0x8b; // 5.5 mbps
2383 SupRate[3] = 0x96; // 11 mbps
2387 else if (pAd->CommonCfg.Channel > 14)
2389 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2390 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2391 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2392 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2393 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2394 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2395 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2396 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2401 // Also Update MlmeRate & RtsRate for G only & A only
2403 pAd->CommonCfg.MlmeRate = RATE_6;
2404 pAd->CommonCfg.RtsRate = RATE_6;
2405 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2406 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2407 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2408 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2412 SupRate[0] = 0x82; // 1 mbps
2413 SupRate[1] = 0x84; // 2 mbps
2414 SupRate[2] = 0x8b; // 5.5 mbps
2415 SupRate[3] = 0x96; // 11 mbps
2418 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2419 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2420 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2421 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2422 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2423 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2424 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2425 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2429 pAd->StaActive.SupRateLen = SupRateLen;
2430 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2431 pAd->StaActive.ExtRateLen = ExtRateLen;
2432 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2434 // compose IBSS beacon frame
2435 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2436 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2437 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2438 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2439 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2441 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2442 sizeof(HEADER_802_11), &BcnHdr,
2443 TIMESTAMP_LEN, &FakeTimestamp,
2444 2, &pAd->CommonCfg.BeaconPeriod,
2447 1, &pAd->CommonCfg.SsidLen,
2448 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2451 SupRateLen, SupRate,
2454 1, &pAd->CommonCfg.Channel,
2457 2, &pAd->StaActive.AtimWin,
2460 // add ERP_IE and EXT_RAE IE of in 802.11g
2465 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2469 ExtRateLen, ExtRate,
2474 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2475 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2478 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2480 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2482 1, &pAd->StaCfg.RSNIE_Len,
2483 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2488 #ifdef DOT11_N_SUPPORT
2489 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2492 UCHAR HtLen, HtLen1;
2494 #ifdef RT_BIG_ENDIAN
2495 HT_CAPABILITY_IE HtCapabilityTmp;
2496 ADD_HT_INFO_IE addHTInfoTmp;
2497 USHORT b2lTmp, b2lTmp2;
2500 // add HT Capability IE
2501 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2502 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2503 #ifndef RT_BIG_ENDIAN
2504 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2507 HtLen, &pAd->CommonCfg.HtCapability,
2510 HtLen1, &pAd->CommonCfg.AddHTInfo,
2513 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2514 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2515 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2517 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2518 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2519 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2521 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2524 HtLen, &HtCapabilityTmp,
2527 HtLen1, &addHTInfoTmp,
2532 #endif // DOT11_N_SUPPORT //
2534 //beacon use reserved WCID 0xff
2535 if (pAd->CommonCfg.Channel > 14)
2537 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2538 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2542 // Set to use 1Mbps for Adhoc beacon.
2543 HTTRANSMIT_SETTING Transmit;
2545 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2546 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2549 #ifdef RT_BIG_ENDIAN
2550 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2551 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2554 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2555 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));