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)
126 CntlIdleProc(pAd, Elem);
128 case CNTL_WAIT_DISASSOC:
129 CntlWaitDisassocProc(pAd, Elem);
132 CntlWaitJoinProc(pAd, Elem);
135 // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
136 // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
137 // Therefore not protected by NDIS's "only one outstanding OID request"
138 // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
139 // Current approach is to block new SET request at RTMPSetInformation()
140 // when CntlMachine.CurrState is not CNTL_IDLE
141 case CNTL_WAIT_REASSOC:
142 CntlWaitReassocProc(pAd, Elem);
145 case CNTL_WAIT_START:
146 CntlWaitStartProc(pAd, Elem);
149 CntlWaitAuthProc(pAd, Elem);
151 case CNTL_WAIT_AUTH2:
152 CntlWaitAuthProc2(pAd, Elem);
154 case CNTL_WAIT_ASSOC:
155 CntlWaitAssocProc(pAd, Elem);
158 case CNTL_WAIT_OID_LIST_SCAN:
159 if(Elem->MsgType == MT2_SCAN_CONF)
161 // Resume TxRing after SCANING complete. We hope the out-of-service time
162 // won't be too long to let upper layer time-out the waiting frames
163 RTMPResumeMsduTransmission(pAd);
164 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
166 // Cisco scan request is finished, prepare beacon report
167 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
169 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
172 // Set LED status to previous status.
174 if (pAd->bLedOnScanning)
176 pAd->bLedOnScanning = FALSE;
177 RTMPSetLED(pAd, pAd->LedStatus);
182 case CNTL_WAIT_OID_DISASSOC:
183 if (Elem->MsgType == MT2_DISASSOC_CONF)
185 LinkDown(pAd, FALSE);
186 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
191 // This state is for that we want to connect to an AP but
192 // it didn't find on BSS List table. So we need to scan the air first,
193 // after that we can try to connect to the desired AP if available.
195 case CNTL_WAIT_SCAN_FOR_CONNECT:
196 if(Elem->MsgType == MT2_SCAN_CONF)
198 // Resume TxRing after SCANING complete. We hope the out-of-service time
199 // won't be too long to let upper layer time-out the waiting frames
200 RTMPResumeMsduTransmission(pAd);
202 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
204 // Cisco scan request is finished, prepare beacon report
205 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
207 #endif // CCX_SUPPORT //
208 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
211 // Check if we can connect to.
213 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
214 if (pAd->MlmeAux.SsidBssTab.BssNr > 0)
216 MlmeAutoReconnectLastSSID(pAd);
222 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
229 ==========================================================================
232 IRQL = DISPATCH_LEVEL
234 ==========================================================================
237 IN PRTMP_ADAPTER pAd,
238 IN MLME_QUEUE_ELEM *Elem)
240 MLME_DISASSOC_REQ_STRUCT DisassocReq;
242 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
245 switch(Elem->MsgType)
247 case OID_802_11_SSID:
248 CntlOidSsidProc(pAd, Elem);
251 case OID_802_11_BSSID:
252 CntlOidRTBssidProc(pAd,Elem);
255 case OID_802_11_BSSID_LIST_SCAN:
256 CntlOidScanProc(pAd,Elem);
259 case OID_802_11_DISASSOCIATE:
260 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
261 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
262 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
263 #ifdef WPA_SUPPLICANT_SUPPORT
264 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
265 #endif // WPA_SUPPLICANT_SUPPORT //
267 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
268 // Since calling this indicate user don't want to connect to that SSID anymore.
269 pAd->MlmeAux.AutoReconnectSsidLen= 32;
270 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
274 case MT2_MLME_ROAMING_REQ:
275 CntlMlmeRoamingProc(pAd, Elem);
278 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
279 WpaMicFailureReportFrame(pAd, Elem);
283 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
288 VOID CntlOidScanProc(
289 IN PRTMP_ADAPTER pAd,
290 IN MLME_QUEUE_ELEM *Elem)
292 MLME_SCAN_REQ_STRUCT ScanReq;
293 ULONG BssIdx = BSS_NOT_FOUND;
296 // record current BSS if network is connected.
297 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
298 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
300 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
301 if (BssIdx != BSS_NOT_FOUND)
303 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
307 // clean up previous SCAN result, add current BSS back to table if any
308 BssTableInit(&pAd->ScanTab);
309 if (BssIdx != BSS_NOT_FOUND)
311 // DDK Note: If the NIC is associated with a particular BSSID and SSID
312 // that are not contained in the list of BSSIDs generated by this scan, the
313 // BSSID description of the currently associated BSSID and SSID should be
314 // appended to the list of BSSIDs in the NIC's database.
315 // To ensure this, we append this BSS as the first entry in SCAN result
316 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
317 pAd->ScanTab.BssNr = 1;
320 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
321 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
322 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
323 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
327 ==========================================================================
329 Before calling this routine, user desired SSID should already been
330 recorded in CommonCfg.Ssid[]
331 IRQL = DISPATCH_LEVEL
333 ==========================================================================
335 VOID CntlOidSsidProc(
336 IN PRTMP_ADAPTER pAd,
337 IN MLME_QUEUE_ELEM * Elem)
339 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
340 MLME_DISASSOC_REQ_STRUCT DisassocReq;
343 // Step 1. record the desired user settings to MlmeAux
344 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
345 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
346 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
347 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
348 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
352 // Update Reconnect Ssid, that user desired to connect.
354 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
355 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
356 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
358 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
359 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
360 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
362 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
363 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
364 NdisGetSystemUpTime(&Now);
366 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
367 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
368 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
369 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
371 // Case 1. already connected with an AP who has the desired SSID
374 // Add checking Mode "LEAP" for CCX 1.0
375 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
376 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
377 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
378 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
380 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
382 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
383 // connection process
384 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
385 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
386 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
387 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
388 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
390 else if (pAd->bConfigChanged == TRUE)
392 // case 1.2 Important Config has changed, we have to reconnect to the same AP
393 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
394 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
395 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
396 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
397 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
401 // case 1.3. already connected to the SSID with highest RSSI.
402 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
404 // (HCT 12.1) 1c_wlan_mediaevents required
405 // media connect events are indicated when associating with the same AP
410 // Since MediaState already is NdisMediaStateConnected
411 // We just indicate the connect event again to meet the WHQL required.
413 pAd->IndicateMediaState = NdisMediaStateConnected;
414 RTMP_IndicateMediaState(pAd);
415 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
418 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
419 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
421 union iwreq_data wrqu;
423 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
424 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
425 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
428 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
431 else if (INFRA_ON(pAd))
435 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
436 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
437 // But media status is connected, so the SSID not report correctly.
439 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
442 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
444 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
446 // case 2. active INFRA association existent
447 // roaming is done within miniport driver, nothing to do with configuration
448 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
449 // disassociate with the current associated AP,
450 // then perform a new association with this new SSID, no matter the
451 // new/old SSID are the same or not.
452 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
453 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
454 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
455 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
456 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
462 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
463 LinkDown(pAd, FALSE);
464 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
465 pAd->IndicateMediaState = NdisMediaStateDisconnected;
466 RTMP_IndicateMediaState(pAd);
467 pAd->ExtraInfo = GENERAL_LINK_DOWN;
468 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
471 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
472 (pAd->StaCfg.bAutoReconnect == TRUE) &&
473 (pAd->MlmeAux.BssType == BSS_INFRA) &&
474 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
477 MLME_SCAN_REQ_STRUCT ScanReq;
479 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
480 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
481 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
482 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
483 // Reset Missed scan number
484 pAd->StaCfg.LastScanTime = Now;
488 pAd->MlmeAux.BssIdx = 0;
489 IterateOnBssTab(pAd);
496 ==========================================================================
499 IRQL = DISPATCH_LEVEL
501 ==========================================================================
503 VOID CntlOidRTBssidProc(
504 IN PRTMP_ADAPTER pAd,
505 IN MLME_QUEUE_ELEM * Elem)
508 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
509 MLME_DISASSOC_REQ_STRUCT DisassocReq;
510 MLME_JOIN_REQ_STRUCT JoinReq;
512 // record user desired settings
513 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
514 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
517 // Update Reconnect Ssid, that user desired to connect.
519 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
520 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
521 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
523 // find the desired BSS in the latest SCAN result table
524 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
525 if (BssIdx == BSS_NOT_FOUND)
527 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
528 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
532 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
533 // Because we need this entry to become the JOIN target in later on SYNC state machine
534 pAd->MlmeAux.BssIdx = 0;
535 pAd->MlmeAux.SsidBssTab.BssNr = 1;
536 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
538 //pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
539 //NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
541 // Add SSID into MlmeAux for site surey joining hidden SSID
542 //pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
543 //NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
545 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
546 // we just follow normal procedure. The reason of user doing this may because he/she changed
547 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
548 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
549 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
550 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
551 // connection when setting the same BSSID.
552 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
553 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
555 // already connected to the same BSSID, go back to idle state directly
556 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
557 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
558 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
560 union iwreq_data wrqu;
562 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
563 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
564 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
567 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
573 // disassoc from current AP first
574 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
575 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
576 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
577 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
579 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
585 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
586 LinkDown(pAd, FALSE);
587 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
588 pAd->IndicateMediaState = NdisMediaStateDisconnected;
589 RTMP_IndicateMediaState(pAd);
590 pAd->ExtraInfo = GENERAL_LINK_DOWN;
591 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
594 // Change the wepstatus to original wepstatus
595 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
596 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
597 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
599 // Check cipher suite, AP must have more secured cipher than station setting
600 // Set the Pairwise and Group cipher to match the intended AP setting
601 // We can only connect to AP with less secured cipher setting
602 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
604 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
606 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
607 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
608 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
609 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
610 else // There is no PairCipher Aux, downgrade our capability to TKIP
611 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
613 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
615 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
617 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
618 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
619 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
620 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
621 else // There is no PairCipher Aux, downgrade our capability to TKIP
622 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
625 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
628 // Set Mix cipher flag
629 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
630 if (pAd->StaCfg.bMixCipher == TRUE)
632 // If mix cipher, re-build RSNIE
633 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
635 // No active association, join the BSS immediately
636 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
637 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
639 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
640 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
642 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
647 // Roaming is the only external request triggering CNTL state machine
648 // despite of other "SET OID" operation. All "SET OID" related oerations
649 // happen in sequence, because no other SET OID will be sent to this device
650 // until the the previous SET operation is complete (successful o failed).
651 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
652 // or been corrupted by other "SET OID"?
654 // IRQL = DISPATCH_LEVEL
655 VOID CntlMlmeRoamingProc(
656 IN PRTMP_ADAPTER pAd,
657 IN MLME_QUEUE_ELEM *Elem)
660 // AP in different channel may show lower RSSI than actual value??
661 // should we add a weighting factor to compensate it?
662 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
664 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
665 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
667 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
668 pAd->MlmeAux.BssIdx = 0;
669 IterateOnBssTab(pAd);
673 ==========================================================================
676 IRQL = DISPATCH_LEVEL
678 ==========================================================================
680 VOID CntlWaitDisassocProc(
681 IN PRTMP_ADAPTER pAd,
682 IN MLME_QUEUE_ELEM *Elem)
684 MLME_START_REQ_STRUCT StartReq;
686 if (Elem->MsgType == MT2_DISASSOC_CONF)
688 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
690 if (pAd->CommonCfg.bWirelessEvent)
692 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
695 LinkDown(pAd, FALSE);
697 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
698 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
700 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
701 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
702 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
703 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
705 // case 2. try each matched BSS
708 pAd->MlmeAux.BssIdx = 0;
710 IterateOnBssTab(pAd);
716 ==========================================================================
719 IRQL = DISPATCH_LEVEL
721 ==========================================================================
723 VOID CntlWaitJoinProc(
724 IN PRTMP_ADAPTER pAd,
725 IN MLME_QUEUE_ELEM *Elem)
728 MLME_AUTH_REQ_STRUCT AuthReq;
730 if (Elem->MsgType == MT2_JOIN_CONF)
732 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
733 if (Reason == MLME_SUCCESS)
735 // 1. joined an IBSS, we are pretty much done here
736 if (pAd->MlmeAux.BssType == BSS_ADHOC)
739 // 5G bands rules of Japan:
740 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
742 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
743 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
746 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
747 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
751 LinkUp(pAd, BSS_ADHOC);
752 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
753 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
754 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
755 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
757 pAd->IndicateMediaState = NdisMediaStateConnected;
758 pAd->ExtraInfo = GENERAL_LINK_UP;
760 // 2. joined a new INFRA network, start from authentication
764 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
765 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
766 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
768 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
772 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
775 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
776 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
778 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
783 // 3. failed, try next BSS
784 pAd->MlmeAux.BssIdx++;
785 IterateOnBssTab(pAd);
792 ==========================================================================
795 IRQL = DISPATCH_LEVEL
797 ==========================================================================
799 VOID CntlWaitStartProc(
800 IN PRTMP_ADAPTER pAd,
801 IN MLME_QUEUE_ELEM *Elem)
805 if (Elem->MsgType == MT2_START_CONF)
807 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
808 if (Result == MLME_SUCCESS)
811 // 5G bands rules of Japan:
812 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
814 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
815 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
818 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
819 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
822 #ifdef DOT11_N_SUPPORT
823 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
827 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
828 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
829 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
830 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
831 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
832 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
834 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
835 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
837 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
839 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
840 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
842 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
846 #endif // DOT11_N_SUPPORT //
848 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
850 LinkUp(pAd, BSS_ADHOC);
851 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
852 // Before send beacon, driver need do radar detection
853 if ((pAd->CommonCfg.Channel > 14 )
854 && (pAd->CommonCfg.bIEEE80211H == 1)
855 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
857 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
858 pAd->CommonCfg.RadarDetect.RDCount = 0;
861 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
862 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
863 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
867 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
868 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
874 ==========================================================================
877 IRQL = DISPATCH_LEVEL
879 ==========================================================================
881 VOID CntlWaitAuthProc(
882 IN PRTMP_ADAPTER pAd,
883 IN MLME_QUEUE_ELEM *Elem)
886 MLME_ASSOC_REQ_STRUCT AssocReq;
887 MLME_AUTH_REQ_STRUCT AuthReq;
889 if (Elem->MsgType == MT2_AUTH_CONF)
891 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
892 if (Reason == MLME_SUCCESS)
894 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
895 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
896 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
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"));
913 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
914 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
916 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
917 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
921 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
924 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
925 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
927 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
933 ==========================================================================
936 IRQL = DISPATCH_LEVEL
938 ==========================================================================
940 VOID CntlWaitAuthProc2(
941 IN PRTMP_ADAPTER pAd,
942 IN MLME_QUEUE_ELEM *Elem)
945 MLME_ASSOC_REQ_STRUCT AssocReq;
946 MLME_AUTH_REQ_STRUCT AuthReq;
948 if (Elem->MsgType == MT2_AUTH_CONF)
950 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
951 if (Reason == MLME_SUCCESS)
953 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
954 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
955 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
956 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
957 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
959 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
963 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
964 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
966 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
967 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
968 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
969 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
971 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
975 // not success, try next BSS
976 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
977 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
978 pAd->MlmeAux.BssIdx++;
979 IterateOnBssTab(pAd);
986 ==========================================================================
989 IRQL = DISPATCH_LEVEL
991 ==========================================================================
993 VOID CntlWaitAssocProc(
994 IN PRTMP_ADAPTER pAd,
995 IN MLME_QUEUE_ELEM *Elem)
999 if (Elem->MsgType == MT2_ASSOC_CONF)
1001 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1002 if (Reason == MLME_SUCCESS)
1004 LinkUp(pAd, BSS_INFRA);
1005 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1006 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1008 if (pAd->CommonCfg.bWirelessEvent)
1010 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1015 // not success, try next BSS
1016 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1017 pAd->MlmeAux.BssIdx++;
1018 IterateOnBssTab(pAd);
1024 ==========================================================================
1027 IRQL = DISPATCH_LEVEL
1029 ==========================================================================
1031 VOID CntlWaitReassocProc(
1032 IN PRTMP_ADAPTER pAd,
1033 IN MLME_QUEUE_ELEM *Elem)
1037 if (Elem->MsgType == MT2_REASSOC_CONF)
1039 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1040 if (Result == MLME_SUCCESS)
1043 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1045 LinkUp(pAd, BSS_INFRA);
1047 // send wireless event - for association
1048 if (pAd->CommonCfg.bWirelessEvent)
1049 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1051 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1052 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1056 // reassoc failed, try to pick next BSS in the BSS Table
1057 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1058 pAd->MlmeAux.RoamIdx++;
1059 IterateOnBssTab2(pAd);
1065 VOID AdhocTurnOnQos(
1066 IN PRTMP_ADAPTER pAd)
1068 #define AC0_DEF_TXOP 0
1069 #define AC1_DEF_TXOP 0
1070 #define AC2_DEF_TXOP 94
1071 #define AC3_DEF_TXOP 47
1073 // Turn on QOs if use HT rate.
1074 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1076 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1077 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1078 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1079 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1080 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1082 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1083 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1084 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1085 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1087 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1088 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1089 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1090 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1092 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1093 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1094 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1095 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1097 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1101 ==========================================================================
1104 IRQL = DISPATCH_LEVEL
1106 ==========================================================================
1109 IN PRTMP_ADAPTER pAd,
1115 UCHAR Value = 0, idx;
1116 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
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);
1143 if (BssType == BSS_ADHOC)
1145 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1146 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1148 #ifdef DOT11_N_SUPPORT
1149 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1150 AdhocTurnOnQos(pAd);
1151 #endif // DOT11_N_SUPPORT //
1153 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1157 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1158 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1160 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1164 // reset Tx beamforming bit
1165 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1167 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1168 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1170 #ifdef DOT11_N_SUPPORT
1171 // Change to AP channel
1172 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1174 // Must using 40MHz.
1175 pAd->CommonCfg.BBPCurrentBW = BW_40;
1176 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1177 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1179 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1182 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1184 // RX : control channel at lower
1185 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1187 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1189 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1191 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1193 if (pAd->MACVersion == 0x28600100)
1195 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1196 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1197 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1198 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1201 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1203 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1205 // Must using 40MHz.
1206 pAd->CommonCfg.BBPCurrentBW = BW_40;
1207 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1208 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1210 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1213 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1215 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1217 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1219 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1221 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1223 if (pAd->MACVersion == 0x28600100)
1225 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1226 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1227 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1228 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1231 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1234 #endif // DOT11_N_SUPPORT //
1236 pAd->CommonCfg.BBPCurrentBW = BW_20;
1237 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1238 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1239 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1241 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1243 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1245 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1247 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1249 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1251 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1253 if (pAd->MACVersion == 0x28600100)
1255 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1256 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1257 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1258 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1261 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1264 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1266 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1268 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1270 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1271 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1273 #ifdef DOT11_N_SUPPORT
1274 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1275 #endif // DOT11_N_SUPPORT //
1277 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1279 AsicSetSlotTime(pAd, TRUE);
1280 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1282 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1283 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1285 #ifdef DOT11_N_SUPPORT
1286 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1288 // Update HT protectionfor based on AP's operating mode.
1289 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1291 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1294 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1296 #endif // DOT11_N_SUPPORT //
1298 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1300 NdisGetSystemUpTime(&Now);
1301 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1303 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1304 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1306 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1309 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1311 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1314 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1316 if (BssType == BSS_ADHOC)
1318 MakeIbssBeacon(pAd);
1319 if ((pAd->CommonCfg.Channel > 14)
1320 && (pAd->CommonCfg.bIEEE80211H == 1)
1321 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1327 AsicEnableIbssSync(pAd);
1330 // In ad hoc mode, use MAC table from index 1.
1331 // 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.
1332 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1333 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1335 // If WEP is enabled, add key material and cipherAlg into Asic
1336 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1338 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1343 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1345 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1346 Key = pAd->SharedKey[BSS0][idx].Key;
1348 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1350 // Set key material and cipherAlg to Asic
1351 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1353 if (idx == pAd->StaCfg.DefaultKeyId)
1355 // Update WCID attribute table and IVEIV table for this group key table
1356 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1363 // If WPANone is enabled, add key material and cipherAlg into Asic
1364 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1365 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1367 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1369 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1370 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1371 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1373 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1375 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1376 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1379 // Decide its ChiperAlg
1380 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1381 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1382 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1383 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1386 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1387 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1390 // Set key material and cipherAlg to Asic
1391 AsicAddSharedKeyEntry(pAd,
1394 pAd->SharedKey[BSS0][0].CipherAlg,
1395 pAd->SharedKey[BSS0][0].Key,
1396 pAd->SharedKey[BSS0][0].TxMic,
1397 pAd->SharedKey[BSS0][0].RxMic);
1399 // Update WCID attribute table and IVEIV table for this group key table
1400 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1407 // Check the new SSID with last SSID
1408 while (Cancelled == TRUE)
1410 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1412 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1414 // Link to the old one no linkdown is required.
1418 // Send link down event before set to link up
1419 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1420 RTMP_IndicateMediaState(pAd);
1421 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1422 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1427 // On WPA mode, Remove All Keys if not connect to the last BSSID
1428 // Key will be set after 4-way handshake.
1430 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1434 // Remove all WPA keys
1435 RTMPWPARemoveAllKeys(pAd);
1436 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1437 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1439 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1440 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1442 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1443 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1446 // the decision of using "short slot time" or not may change dynamically due to
1447 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1450 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1451 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1454 ComposeNullFrame(pAd);
1456 AsicEnableBssSync(pAd);
1458 // Add BSSID to WCID search table
1459 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1461 NdisAcquireSpinLock(&pAd->MacTabLock);
1462 // add this BSSID entry into HASH table
1466 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1467 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1468 if (pAd->MacTab.Hash[HashIdx] == NULL)
1470 pAd->MacTab.Hash[HashIdx] = pEntry;
1474 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1475 while (pCurrEntry->pNext != NULL)
1476 pCurrEntry = pCurrEntry->pNext;
1477 pCurrEntry->pNext = pEntry;
1480 NdisReleaseSpinLock(&pAd->MacTabLock);
1483 // If WEP is enabled, add paiewise and shared key
1484 #ifdef WPA_SUPPLICANT_SUPPORT
1485 if (((pAd->StaCfg.WpaSupplicantUP)&&
1486 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1487 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1488 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1489 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1491 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1492 #endif // WPA_SUPPLICANT_SUPPORT //
1497 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1499 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1500 Key = pAd->SharedKey[BSS0][idx].Key;
1502 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1504 // Set key material and cipherAlg to Asic
1505 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1507 if (idx == pAd->StaCfg.DefaultKeyId)
1509 // Assign group key info
1510 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1512 // Assign pairwise key info
1513 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1519 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1520 // should wait until at least 2 active nodes in this BSSID.
1521 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1524 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1526 pAd->IndicateMediaState = NdisMediaStateConnected;
1527 pAd->ExtraInfo = GENERAL_LINK_UP;
1528 RTMP_IndicateMediaState(pAd);
1532 // Add BSSID in my MAC Table.
1533 NdisAcquireSpinLock(&pAd->MacTabLock);
1534 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1535 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1536 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1537 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1538 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1539 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1540 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1541 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1542 NdisReleaseSpinLock(&pAd->MacTabLock);
1544 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1545 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1547 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1548 #ifdef DOT11_N_SUPPORT
1549 MlmeUpdateHtTxRates(pAd, BSS0);
1550 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1551 #endif // DOT11_N_SUPPORT //
1553 if (pAd->CommonCfg.bAggregationCapable)
1555 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1558 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1559 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1560 RTMPSetPiggyBack(pAd, TRUE);
1561 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1563 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1565 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1569 if (pAd->MlmeAux.APRalinkIe != 0x0)
1571 #ifdef DOT11_N_SUPPORT
1572 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1576 #endif // DOT11_N_SUPPORT //
1577 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1578 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1582 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1583 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1587 #ifdef DOT11_N_SUPPORT
1588 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));
1589 #endif // DOT11_N_SUPPORT //
1592 RTMPSetLED(pAd, LED_LINK_UP);
1594 pAd->Mlme.PeriodicRound = 0;
1595 pAd->Mlme.OneSecPeriodicRound = 0;
1596 pAd->bConfigChanged = FALSE; // Reset config flag
1597 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1599 // Set asic auto fall back
1602 UCHAR TableSize = 0;
1604 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1605 AsicUpdateAutoFallBackTable(pAd, pTable);
1608 NdisAcquireSpinLock(&pAd->MacTabLock);
1609 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1610 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1611 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1613 pEntry->bAutoTxRateSwitch = FALSE;
1614 #ifdef DOT11_N_SUPPORT
1615 if (pEntry->HTPhyMode.field.MCS == 32)
1616 pEntry->HTPhyMode.field.ShortGI = GI_800;
1618 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1619 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1620 #endif // DOT11_N_SUPPORT //
1621 // If the legacy mode is set, overwrite the transmit setting of this entry.
1622 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1623 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1626 pEntry->bAutoTxRateSwitch = TRUE;
1627 NdisReleaseSpinLock(&pAd->MacTabLock);
1629 // Let Link Status Page display first initial rate.
1630 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1631 // Select DAC according to HT or Legacy
1632 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1634 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1636 if (pAd->Antenna.field.TxPath == 2)
1640 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1644 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1646 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1649 #ifdef DOT11_N_SUPPORT
1650 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1653 else if (pEntry->MaxRAmpduFactor == 0)
1655 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1656 // Because our Init value is 1 at MACRegTable.
1657 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1659 #endif // DOT11_N_SUPPORT //
1661 // Patch for Marvel AP to gain high throughput
1662 // Need to set as following,
1663 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1664 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1665 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1666 // 4. kick per two packets when dequeue
1668 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1670 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1671 #ifdef DOT11_N_SUPPORT
1672 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1673 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1675 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1677 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1679 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1680 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1683 #endif // DOT11_N_SUPPORT //
1684 if (pAd->CommonCfg.bEnableTxBurst)
1686 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1689 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1690 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1692 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1693 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1697 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1699 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1701 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1702 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1705 #ifdef DOT11_N_SUPPORT
1706 // Re-check to turn on TX burst or not.
1707 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1709 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1710 if (pAd->CommonCfg.bEnableTxBurst)
1712 UINT32 MACValue = 0;
1713 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1714 // I didn't change PBF_MAX_PCNT setting.
1715 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1716 MACValue &= 0xFFFFFF00;
1717 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1718 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1723 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1725 #endif // DOT11_N_SUPPORT //
1727 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1728 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1729 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1730 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1731 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1732 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1734 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1736 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1737 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1740 NdisAcquireSpinLock(&pAd->MacTabLock);
1741 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1742 NdisReleaseSpinLock(&pAd->MacTabLock);
1745 // Patch Atheros AP TX will breakdown issue.
1746 // AP Model: DLink DWL-8200AP
1748 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1750 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1754 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1757 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1761 ==========================================================================
1763 Routine Description:
1764 Disconnect current BSSID
1767 pAd - Pointer to our adapter
1768 IsReqFromAP - Request from AP
1773 IRQL = DISPATCH_LEVEL
1776 We need more information to know it's this requst from AP.
1777 If yes! we need to do extra handling, for example, remove the WPA key.
1778 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1779 remove while auto reconnect.
1780 Disconnect request from AP, it means we will start afresh 4-way handshaking
1783 ==========================================================================
1786 IN PRTMP_ADAPTER pAd,
1787 IN BOOLEAN IsReqFromAP)
1789 UCHAR i, ByteValue = 0;
1791 // Do nothing if monitor mode is on
1792 if (MONITOR_ON(pAd))
1795 if (pAd->CommonCfg.bWirelessEvent)
1797 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1800 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1801 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1803 if (ADHOC_ON(pAd)) // Adhoc mode link down
1805 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1807 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1808 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1809 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1810 RTMP_IndicateMediaState(pAd);
1811 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1812 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1813 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1815 else // Infra structure mode
1817 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1819 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1820 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1822 // Saved last SSID for linkup comparison
1823 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1824 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
1825 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1826 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
1828 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1829 RTMP_IndicateMediaState(pAd);
1830 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1831 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1832 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1837 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
1838 // Otherwise lost beacon or receive De-Authentication from AP,
1839 // then we should delete BSSID from BssTable.
1840 // If we don't delete from entry, roaming will fail.
1842 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1845 // restore back to -
1846 // 1. long slot (20 us) or short slot (9 us) time
1847 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1848 // 3. short preamble
1849 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1851 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
1854 // Record current AP's information.
1855 // for later used reporting Adjacent AP report.
1857 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
1858 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
1859 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
1860 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
1864 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
1866 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1867 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
1870 pAd->StaCfg.CCXQosECWMin = 4;
1871 pAd->StaCfg.CCXQosECWMax = 10;
1873 AsicSetSlotTime(pAd, TRUE); //FALSE);
1874 AsicSetEdcaParm(pAd, NULL);
1877 RTMPSetLED(pAd, LED_LINK_DOWN);
1878 pAd->LedIndicatorStregth = 0xF0;
1879 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
1881 AsicDisableSync(pAd);
1883 pAd->Mlme.PeriodicRound = 0;
1884 pAd->Mlme.OneSecPeriodicRound = 0;
1886 if (pAd->StaCfg.BssType == BSS_INFRA)
1888 // Remove StaCfg Information after link down
1889 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1890 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1891 pAd->CommonCfg.SsidLen = 0;
1893 #ifdef DOT11_N_SUPPORT
1894 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
1895 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
1896 pAd->MlmeAux.HtCapabilityLen = 0;
1897 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1898 #endif // DOT11_N_SUPPORT //
1900 // Reset WPA-PSK state. Only reset when supplicant enabled
1901 if (pAd->StaCfg.WpaState != SS_NOTUSE)
1903 pAd->StaCfg.WpaState = SS_START;
1904 // Clear Replay counter
1905 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1910 // if link down come from AP, we need to remove all WPA keys on WPA mode.
1911 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
1913 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1915 // Remove all WPA keys
1916 RTMPWPARemoveAllKeys(pAd);
1919 // 802.1x port control
1920 #ifdef WPA_SUPPLICANT_SUPPORT
1921 // Prevent clear PortSecured here with static WEP
1922 // NetworkManger set security policy first then set SSID to connect AP.
1923 if (pAd->StaCfg.WpaSupplicantUP &&
1924 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1925 (pAd->StaCfg.IEEE8021X == FALSE))
1927 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1930 #endif // WPA_SUPPLICANT_SUPPORT //
1932 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1933 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1936 NdisAcquireSpinLock(&pAd->MacTabLock);
1937 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
1938 NdisReleaseSpinLock(&pAd->MacTabLock);
1940 pAd->StaCfg.MicErrCnt = 0;
1942 // Turn off Ckip control flag
1943 pAd->StaCfg.bCkipOn = FALSE;
1944 pAd->StaCfg.CCXEnable = FALSE;
1946 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1947 // Update extra information to link is up
1948 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1950 //pAd->StaCfg.AdhocBOnlyJoined = FALSE;
1951 //pAd->StaCfg.AdhocBGJoined = FALSE;
1952 //pAd->StaCfg.Adhoc20NJoined = FALSE;
1953 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1955 // Reset the Current AP's IP address
1956 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
1958 pAd->bUsbTxBulkAggre = FALSE;
1961 // Clean association information
1962 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
1963 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
1964 pAd->StaCfg.ReqVarIELen = 0;
1965 pAd->StaCfg.ResVarIELen = 0;
1968 // Reset RSSI value after link down
1970 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
1971 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
1972 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
1973 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
1974 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
1975 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
1978 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
1979 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
1981 #ifdef DOT11_N_SUPPORT
1983 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
1985 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1987 pAd->CommonCfg.BBPCurrentBW = BW_20;
1988 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
1989 ByteValue &= (~0x18);
1990 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
1992 #endif // DOT11_N_SUPPORT //
1994 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
1995 ByteValue &= (~0x18);
1996 if (pAd->Antenna.field.TxPath == 2)
2000 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2002 RTMPSetPiggyBack(pAd,FALSE);
2003 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2005 #ifdef DOT11_N_SUPPORT
2006 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2007 #endif // DOT11_N_SUPPORT //
2009 // Restore all settings in the following.
2010 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2011 AsicDisableRDG(pAd);
2012 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2013 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2015 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2016 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2018 #ifdef WPA_SUPPLICANT_SUPPORT
2019 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2020 if (pAd->StaCfg.WpaSupplicantUP) {
2021 union iwreq_data wrqu;
2022 //send disassociate event to wpa_supplicant
2023 memset(&wrqu, 0, sizeof(wrqu));
2024 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2025 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2027 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2028 #endif // WPA_SUPPLICANT_SUPPORT //
2030 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2032 union iwreq_data wrqu;
2033 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2034 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2036 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2040 ==========================================================================
2043 IRQL = DISPATCH_LEVEL
2045 ==========================================================================
2047 VOID IterateOnBssTab(
2048 IN PRTMP_ADAPTER pAd)
2050 MLME_START_REQ_STRUCT StartReq;
2051 MLME_JOIN_REQ_STRUCT JoinReq;
2054 // Change the wepstatus to original wepstatus
2055 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2056 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2057 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2059 BssIdx = pAd->MlmeAux.BssIdx;
2060 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2062 // Check cipher suite, AP must have more secured cipher than station setting
2063 // Set the Pairwise and Group cipher to match the intended AP setting
2064 // We can only connect to AP with less secured cipher setting
2065 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2067 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2069 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2070 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2071 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2072 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2073 else // There is no PairCipher Aux, downgrade our capability to TKIP
2074 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2076 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2078 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2080 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2081 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2082 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2083 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2084 else // There is no PairCipher Aux, downgrade our capability to TKIP
2085 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2088 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2091 // Set Mix cipher flag
2092 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2093 if (pAd->StaCfg.bMixCipher == TRUE)
2095 // If mix cipher, re-build RSNIE
2096 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2099 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2100 JoinParmFill(pAd, &JoinReq, BssIdx);
2101 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2103 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2105 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2107 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2108 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2109 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2110 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2114 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2115 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2116 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2117 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2121 // for re-association only
2122 // IRQL = DISPATCH_LEVEL
2123 VOID IterateOnBssTab2(
2124 IN PRTMP_ADAPTER pAd)
2126 MLME_REASSOC_REQ_STRUCT ReassocReq;
2130 BssIdx = pAd->MlmeAux.RoamIdx;
2131 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2133 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2135 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2137 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2138 AsicLockChannel(pAd, pBss->Channel);
2140 // reassociate message has the same structure as associate message
2141 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2142 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2143 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2144 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2146 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2150 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2151 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2152 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2153 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2158 ==========================================================================
2161 IRQL = DISPATCH_LEVEL
2163 ==========================================================================
2166 IN PRTMP_ADAPTER pAd,
2167 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2170 JoinReq->BssIdx = BssIdx;
2174 ==========================================================================
2177 IRQL = DISPATCH_LEVEL
2179 ==========================================================================
2182 IN PRTMP_ADAPTER pAd,
2183 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2189 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2190 ScanReq->SsidLen = SsidLen;
2191 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2192 ScanReq->BssType = BssType;
2193 ScanReq->ScanType = ScanType;
2197 ==========================================================================
2200 IRQL = DISPATCH_LEVEL
2202 ==========================================================================
2205 IN PRTMP_ADAPTER pAd,
2206 IN OUT MLME_START_REQ_STRUCT *StartReq,
2210 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2211 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2212 StartReq->SsidLen = SsidLen;
2216 ==========================================================================
2219 IRQL = DISPATCH_LEVEL
2221 ==========================================================================
2224 IN PRTMP_ADAPTER pAd,
2225 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2229 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2231 AuthReq->Timeout = AUTH_TIMEOUT;
2235 ==========================================================================
2238 IRQL = DISPATCH_LEVEL
2240 ==========================================================================
2246 VOID MlmeCntlConfirm(
2247 IN PRTMP_ADAPTER pAd,
2251 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
2255 IN PRTMP_ADAPTER pAd)
2257 PTXINFO_STRUC pTxInfo;
2260 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2261 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2263 pAd->PsPollFrame.FC.PwrMgmt = 0;
2264 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2265 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2266 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2267 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2268 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2270 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
2271 pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
2272 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2273 pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2274 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
2275 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2276 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2277 // Append 4 extra zero bytes.
2278 pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
2281 // IRQL = DISPATCH_LEVEL
2282 VOID ComposeNullFrame(
2283 IN PRTMP_ADAPTER pAd)
2285 PTXINFO_STRUC pTxInfo;
2288 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2289 pAd->NullFrame.FC.Type = BTYPE_DATA;
2290 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2291 pAd->NullFrame.FC.ToDs = 1;
2292 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2293 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2294 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2295 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
2296 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
2297 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2298 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2299 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
2300 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2301 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
2302 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2308 ==========================================================================
2310 Pre-build a BEACON frame in the shared memory
2312 IRQL = PASSIVE_LEVEL
2313 IRQL = DISPATCH_LEVEL
2315 ==========================================================================
2317 ULONG MakeIbssBeacon(
2318 IN PRTMP_ADAPTER pAd)
2320 UCHAR DsLen = 1, IbssLen = 2;
2321 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2322 HEADER_802_11 BcnHdr;
2323 USHORT CapabilityInfo;
2324 LARGE_INTEGER FakeTimestamp;
2326 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2327 CHAR *pBeaconFrame = pAd->BeaconBuf;
2329 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2330 UCHAR SupRateLen = 0;
2331 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2332 UCHAR ExtRateLen = 0;
2333 UCHAR RSNIe = IE_WPA;
2335 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2337 SupRate[0] = 0x82; // 1 mbps
2338 SupRate[1] = 0x84; // 2 mbps
2339 SupRate[2] = 0x8b; // 5.5 mbps
2340 SupRate[3] = 0x96; // 11 mbps
2344 else if (pAd->CommonCfg.Channel > 14)
2346 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2347 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2348 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2349 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2350 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2351 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2352 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2353 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2358 // Also Update MlmeRate & RtsRate for G only & A only
2360 pAd->CommonCfg.MlmeRate = RATE_6;
2361 pAd->CommonCfg.RtsRate = RATE_6;
2362 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2363 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2364 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2365 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2369 SupRate[0] = 0x82; // 1 mbps
2370 SupRate[1] = 0x84; // 2 mbps
2371 SupRate[2] = 0x8b; // 5.5 mbps
2372 SupRate[3] = 0x96; // 11 mbps
2375 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2376 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2377 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2378 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2379 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2380 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2381 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2382 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2386 pAd->StaActive.SupRateLen = SupRateLen;
2387 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2388 pAd->StaActive.ExtRateLen = ExtRateLen;
2389 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2391 // compose IBSS beacon frame
2392 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2393 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2394 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2395 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2396 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2398 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2399 sizeof(HEADER_802_11), &BcnHdr,
2400 TIMESTAMP_LEN, &FakeTimestamp,
2401 2, &pAd->CommonCfg.BeaconPeriod,
2404 1, &pAd->CommonCfg.SsidLen,
2405 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2408 SupRateLen, SupRate,
2411 1, &pAd->CommonCfg.Channel,
2414 2, &pAd->StaActive.AtimWin,
2417 // add ERP_IE and EXT_RAE IE of in 802.11g
2422 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2426 ExtRateLen, ExtRate,
2431 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2432 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2435 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2437 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2439 1, &pAd->StaCfg.RSNIE_Len,
2440 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2445 #ifdef DOT11_N_SUPPORT
2446 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2449 UCHAR HtLen, HtLen1;
2451 #ifdef RT_BIG_ENDIAN
2452 HT_CAPABILITY_IE HtCapabilityTmp;
2453 ADD_HT_INFO_IE addHTInfoTmp;
2454 USHORT b2lTmp, b2lTmp2;
2457 // add HT Capability IE
2458 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2459 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2460 #ifndef RT_BIG_ENDIAN
2461 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2464 HtLen, &pAd->CommonCfg.HtCapability,
2467 HtLen1, &pAd->CommonCfg.AddHTInfo,
2470 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2471 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2472 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2474 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2475 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2476 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2478 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2481 HtLen, &HtCapabilityTmp,
2484 HtLen1, &addHTInfoTmp,
2489 #endif // DOT11_N_SUPPORT //
2491 //beacon use reserved WCID 0xff
2492 if (pAd->CommonCfg.Channel > 14)
2494 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2495 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2499 // Set to use 1Mbps for Adhoc beacon.
2500 HTTRANSMIT_SETTING Transmit;
2502 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2503 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2506 #ifdef RT_BIG_ENDIAN
2507 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2508 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2511 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2512 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));