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;
264 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
266 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
267 // Since calling this indicate user don't want to connect to that SSID anymore.
268 pAd->MlmeAux.AutoReconnectSsidLen= 32;
269 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
273 case MT2_MLME_ROAMING_REQ:
274 CntlMlmeRoamingProc(pAd, Elem);
277 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
278 WpaMicFailureReportFrame(pAd, Elem);
282 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
287 VOID CntlOidScanProc(
288 IN PRTMP_ADAPTER pAd,
289 IN MLME_QUEUE_ELEM *Elem)
291 MLME_SCAN_REQ_STRUCT ScanReq;
292 ULONG BssIdx = BSS_NOT_FOUND;
295 // record current BSS if network is connected.
296 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
297 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
299 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
300 if (BssIdx != BSS_NOT_FOUND)
302 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
306 // clean up previous SCAN result, add current BSS back to table if any
307 BssTableInit(&pAd->ScanTab);
308 if (BssIdx != BSS_NOT_FOUND)
310 // DDK Note: If the NIC is associated with a particular BSSID and SSID
311 // that are not contained in the list of BSSIDs generated by this scan, the
312 // BSSID description of the currently associated BSSID and SSID should be
313 // appended to the list of BSSIDs in the NIC's database.
314 // To ensure this, we append this BSS as the first entry in SCAN result
315 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
316 pAd->ScanTab.BssNr = 1;
319 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
320 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
321 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
322 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
326 ==========================================================================
328 Before calling this routine, user desired SSID should already been
329 recorded in CommonCfg.Ssid[]
330 IRQL = DISPATCH_LEVEL
332 ==========================================================================
334 VOID CntlOidSsidProc(
335 IN PRTMP_ADAPTER pAd,
336 IN MLME_QUEUE_ELEM * Elem)
338 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
339 MLME_DISASSOC_REQ_STRUCT DisassocReq;
342 // Step 1. record the desired user settings to MlmeAux
343 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
344 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
345 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
346 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
347 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
351 // Update Reconnect Ssid, that user desired to connect.
353 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
354 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
355 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
357 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
358 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
359 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
361 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
362 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
363 NdisGetSystemUpTime(&Now);
365 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
366 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
367 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
368 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
370 // Case 1. already connected with an AP who has the desired SSID
373 // Add checking Mode "LEAP" for CCX 1.0
374 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
375 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
376 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
377 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
379 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
381 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
382 // connection process
383 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
384 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
385 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
386 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
387 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
389 else if (pAd->bConfigChanged == TRUE)
391 // case 1.2 Important Config has changed, we have to reconnect to the same AP
392 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
393 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
394 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
395 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
396 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
400 // case 1.3. already connected to the SSID with highest RSSI.
401 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
403 // (HCT 12.1) 1c_wlan_mediaevents required
404 // media connect events are indicated when associating with the same AP
409 // Since MediaState already is NdisMediaStateConnected
410 // We just indicate the connect event again to meet the WHQL required.
412 pAd->IndicateMediaState = NdisMediaStateConnected;
413 RTMP_IndicateMediaState(pAd);
414 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
417 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
420 union iwreq_data wrqu;
422 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
423 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
424 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
429 else if (INFRA_ON(pAd))
433 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
434 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
435 // But media status is connected, so the SSID not report correctly.
437 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
440 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
442 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
444 // case 2. active INFRA association existent
445 // roaming is done within miniport driver, nothing to do with configuration
446 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
447 // disassociate with the current associated AP,
448 // then perform a new association with this new SSID, no matter the
449 // new/old SSID are the same or not.
450 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
451 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
452 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
453 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
454 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
460 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
461 LinkDown(pAd, FALSE);
462 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
463 pAd->IndicateMediaState = NdisMediaStateDisconnected;
464 RTMP_IndicateMediaState(pAd);
465 pAd->ExtraInfo = GENERAL_LINK_DOWN;
466 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
469 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
470 (pAd->StaCfg.bAutoReconnect == TRUE) &&
471 (pAd->MlmeAux.BssType == BSS_INFRA) &&
472 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
475 MLME_SCAN_REQ_STRUCT ScanReq;
477 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
478 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
479 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
480 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
481 // Reset Missed scan number
482 pAd->StaCfg.LastScanTime = Now;
486 pAd->MlmeAux.BssIdx = 0;
487 IterateOnBssTab(pAd);
494 ==========================================================================
497 IRQL = DISPATCH_LEVEL
499 ==========================================================================
501 VOID CntlOidRTBssidProc(
502 IN PRTMP_ADAPTER pAd,
503 IN MLME_QUEUE_ELEM * Elem)
506 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
507 MLME_DISASSOC_REQ_STRUCT DisassocReq;
508 MLME_JOIN_REQ_STRUCT JoinReq;
510 // record user desired settings
511 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
512 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
515 // Update Reconnect Ssid, that user desired to connect.
517 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
518 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
519 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
521 // find the desired BSS in the latest SCAN result table
522 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
523 if (BssIdx == BSS_NOT_FOUND)
525 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
526 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
530 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
531 // Because we need this entry to become the JOIN target in later on SYNC state machine
532 pAd->MlmeAux.BssIdx = 0;
533 pAd->MlmeAux.SsidBssTab.BssNr = 1;
534 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
536 //pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
537 //NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
539 // Add SSID into MlmeAux for site surey joining hidden SSID
540 //pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
541 //NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
543 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
544 // we just follow normal procedure. The reason of user doing this may because he/she changed
545 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
546 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
547 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
548 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
549 // connection when setting the same BSSID.
550 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
551 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
553 // already connected to the same BSSID, go back to idle state directly
554 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
555 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
558 union iwreq_data wrqu;
560 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
561 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
562 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
570 // disassoc from current AP first
571 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
572 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
573 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
574 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
576 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
582 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
583 LinkDown(pAd, FALSE);
584 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
585 pAd->IndicateMediaState = NdisMediaStateDisconnected;
586 RTMP_IndicateMediaState(pAd);
587 pAd->ExtraInfo = GENERAL_LINK_DOWN;
588 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
591 // Change the wepstatus to original wepstatus
592 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
593 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
594 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
596 // Check cipher suite, AP must have more secured cipher than station setting
597 // Set the Pairwise and Group cipher to match the intended AP setting
598 // We can only connect to AP with less secured cipher setting
599 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
601 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
603 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
604 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
605 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
606 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
607 else // There is no PairCipher Aux, downgrade our capability to TKIP
608 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
610 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
612 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
614 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
615 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
616 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
617 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
618 else // There is no PairCipher Aux, downgrade our capability to TKIP
619 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
622 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
625 // Set Mix cipher flag
626 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
627 if (pAd->StaCfg.bMixCipher == TRUE)
629 // If mix cipher, re-build RSNIE
630 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
632 // No active association, join the BSS immediately
633 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
634 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
636 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
637 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
639 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
644 // Roaming is the only external request triggering CNTL state machine
645 // despite of other "SET OID" operation. All "SET OID" related oerations
646 // happen in sequence, because no other SET OID will be sent to this device
647 // until the the previous SET operation is complete (successful o failed).
648 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
649 // or been corrupted by other "SET OID"?
651 // IRQL = DISPATCH_LEVEL
652 VOID CntlMlmeRoamingProc(
653 IN PRTMP_ADAPTER pAd,
654 IN MLME_QUEUE_ELEM *Elem)
657 // AP in different channel may show lower RSSI than actual value??
658 // should we add a weighting factor to compensate it?
659 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
661 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
662 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
664 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
665 pAd->MlmeAux.BssIdx = 0;
666 IterateOnBssTab(pAd);
670 ==========================================================================
673 IRQL = DISPATCH_LEVEL
675 ==========================================================================
677 VOID CntlWaitDisassocProc(
678 IN PRTMP_ADAPTER pAd,
679 IN MLME_QUEUE_ELEM *Elem)
681 MLME_START_REQ_STRUCT StartReq;
683 if (Elem->MsgType == MT2_DISASSOC_CONF)
685 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
687 if (pAd->CommonCfg.bWirelessEvent)
689 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
692 LinkDown(pAd, FALSE);
694 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
695 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
697 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
698 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
699 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
700 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
702 // case 2. try each matched BSS
705 pAd->MlmeAux.BssIdx = 0;
707 IterateOnBssTab(pAd);
713 ==========================================================================
716 IRQL = DISPATCH_LEVEL
718 ==========================================================================
720 VOID CntlWaitJoinProc(
721 IN PRTMP_ADAPTER pAd,
722 IN MLME_QUEUE_ELEM *Elem)
725 MLME_AUTH_REQ_STRUCT AuthReq;
727 if (Elem->MsgType == MT2_JOIN_CONF)
729 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
730 if (Reason == MLME_SUCCESS)
732 // 1. joined an IBSS, we are pretty much done here
733 if (pAd->MlmeAux.BssType == BSS_ADHOC)
736 // 5G bands rules of Japan:
737 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
739 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
740 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
743 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
744 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
748 LinkUp(pAd, BSS_ADHOC);
749 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
750 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
751 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
752 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
754 pAd->IndicateMediaState = NdisMediaStateConnected;
755 pAd->ExtraInfo = GENERAL_LINK_UP;
757 // 2. joined a new INFRA network, start from authentication
761 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
762 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
763 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
765 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
769 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
772 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
773 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
775 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
780 // 3. failed, try next BSS
781 pAd->MlmeAux.BssIdx++;
782 IterateOnBssTab(pAd);
789 ==========================================================================
792 IRQL = DISPATCH_LEVEL
794 ==========================================================================
796 VOID CntlWaitStartProc(
797 IN PRTMP_ADAPTER pAd,
798 IN MLME_QUEUE_ELEM *Elem)
802 if (Elem->MsgType == MT2_START_CONF)
804 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
805 if (Result == MLME_SUCCESS)
808 // 5G bands rules of Japan:
809 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
811 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
812 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
815 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
816 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
819 #ifdef DOT11_N_SUPPORT
820 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
824 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
825 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
826 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
827 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
828 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
829 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
831 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
832 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
834 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
836 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
837 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
839 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
843 #endif // DOT11_N_SUPPORT //
845 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
847 LinkUp(pAd, BSS_ADHOC);
848 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
849 // Before send beacon, driver need do radar detection
850 if ((pAd->CommonCfg.Channel > 14 )
851 && (pAd->CommonCfg.bIEEE80211H == 1)
852 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
854 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
855 pAd->CommonCfg.RadarDetect.RDCount = 0;
858 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
859 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
860 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
864 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
865 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
871 ==========================================================================
874 IRQL = DISPATCH_LEVEL
876 ==========================================================================
878 VOID CntlWaitAuthProc(
879 IN PRTMP_ADAPTER pAd,
880 IN MLME_QUEUE_ELEM *Elem)
883 MLME_ASSOC_REQ_STRUCT AssocReq;
884 MLME_AUTH_REQ_STRUCT AuthReq;
886 if (Elem->MsgType == MT2_AUTH_CONF)
888 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
889 if (Reason == MLME_SUCCESS)
891 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
892 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
893 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
896 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
897 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
899 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
904 // This fail may because of the AP already keep us in its MAC table without
905 // ageing-out. The previous authentication attempt must have let it remove us.
906 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
907 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
910 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
911 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
913 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
914 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
918 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
921 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
922 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
924 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
930 ==========================================================================
933 IRQL = DISPATCH_LEVEL
935 ==========================================================================
937 VOID CntlWaitAuthProc2(
938 IN PRTMP_ADAPTER pAd,
939 IN MLME_QUEUE_ELEM *Elem)
942 MLME_ASSOC_REQ_STRUCT AssocReq;
943 MLME_AUTH_REQ_STRUCT AuthReq;
945 if (Elem->MsgType == MT2_AUTH_CONF)
947 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
948 if (Reason == MLME_SUCCESS)
950 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
951 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
952 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
953 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
954 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
956 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
960 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
961 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
963 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
964 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
965 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
966 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
968 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
972 // not success, try next BSS
973 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
974 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
975 pAd->MlmeAux.BssIdx++;
976 IterateOnBssTab(pAd);
983 ==========================================================================
986 IRQL = DISPATCH_LEVEL
988 ==========================================================================
990 VOID CntlWaitAssocProc(
991 IN PRTMP_ADAPTER pAd,
992 IN MLME_QUEUE_ELEM *Elem)
996 if (Elem->MsgType == MT2_ASSOC_CONF)
998 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
999 if (Reason == MLME_SUCCESS)
1001 LinkUp(pAd, BSS_INFRA);
1002 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1003 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1005 if (pAd->CommonCfg.bWirelessEvent)
1007 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1012 // not success, try next BSS
1013 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1014 pAd->MlmeAux.BssIdx++;
1015 IterateOnBssTab(pAd);
1021 ==========================================================================
1024 IRQL = DISPATCH_LEVEL
1026 ==========================================================================
1028 VOID CntlWaitReassocProc(
1029 IN PRTMP_ADAPTER pAd,
1030 IN MLME_QUEUE_ELEM *Elem)
1034 if (Elem->MsgType == MT2_REASSOC_CONF)
1036 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1037 if (Result == MLME_SUCCESS)
1040 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1042 LinkUp(pAd, BSS_INFRA);
1044 // send wireless event - for association
1045 if (pAd->CommonCfg.bWirelessEvent)
1046 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1048 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1049 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1053 // reassoc failed, try to pick next BSS in the BSS Table
1054 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1055 pAd->MlmeAux.RoamIdx++;
1056 IterateOnBssTab2(pAd);
1062 VOID AdhocTurnOnQos(
1063 IN PRTMP_ADAPTER pAd)
1065 #define AC0_DEF_TXOP 0
1066 #define AC1_DEF_TXOP 0
1067 #define AC2_DEF_TXOP 94
1068 #define AC3_DEF_TXOP 47
1070 // Turn on QOs if use HT rate.
1071 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1073 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1074 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1075 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1076 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1077 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1079 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1080 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1081 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1082 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1084 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1085 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1086 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1087 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1089 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1090 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1091 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1092 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1094 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1098 ==========================================================================
1101 IRQL = DISPATCH_LEVEL
1103 ==========================================================================
1106 IN PRTMP_ADAPTER pAd,
1112 UCHAR Value = 0, idx;
1113 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1115 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1118 // ASSOC - DisassocTimeoutAction
1119 // CNTL - Dis-associate successful
1120 // !!! LINK DOWN !!!
1121 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1123 // To prevent DisassocTimeoutAction to call Link down after we link up,
1124 // cancel the DisassocTimer no matter what it start or not.
1126 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1128 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1130 #ifdef DOT11_N_SUPPORT
1131 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1132 #endif // DOT11_N_SUPPORT //
1133 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1134 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1135 // to examine if cipher algorithm switching is required.
1136 //rt2860b. Don't know why need this
1137 SwitchBetweenWepAndCkip(pAd);
1140 if (BssType == BSS_ADHOC)
1142 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1143 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1145 #ifdef DOT11_N_SUPPORT
1146 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1147 AdhocTurnOnQos(pAd);
1148 #endif // DOT11_N_SUPPORT //
1150 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1154 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1155 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1157 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1161 // reset Tx beamforming bit
1162 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1164 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1165 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1167 #ifdef DOT11_N_SUPPORT
1168 // Change to AP channel
1169 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1171 // Must using 40MHz.
1172 pAd->CommonCfg.BBPCurrentBW = BW_40;
1173 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1174 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1176 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1179 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1181 // RX : control channel at lower
1182 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1184 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1186 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1188 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1190 if (pAd->MACVersion == 0x28600100)
1192 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1193 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1194 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1195 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1198 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1200 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1202 // Must using 40MHz.
1203 pAd->CommonCfg.BBPCurrentBW = BW_40;
1204 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1205 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1207 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1210 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1212 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1214 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1216 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1218 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1220 if (pAd->MACVersion == 0x28600100)
1222 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1223 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1224 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1225 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1228 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1231 #endif // DOT11_N_SUPPORT //
1233 pAd->CommonCfg.BBPCurrentBW = BW_20;
1234 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1235 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1236 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1238 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1240 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1242 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1244 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1246 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1248 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1250 if (pAd->MACVersion == 0x28600100)
1252 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1253 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1254 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1255 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1258 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1261 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1263 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1265 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1267 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1268 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1270 #ifdef DOT11_N_SUPPORT
1271 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1272 #endif // DOT11_N_SUPPORT //
1274 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1276 AsicSetSlotTime(pAd, TRUE);
1277 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1279 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1280 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1282 #ifdef DOT11_N_SUPPORT
1283 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1285 // Update HT protectionfor based on AP's operating mode.
1286 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1288 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1291 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1293 #endif // DOT11_N_SUPPORT //
1295 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1297 NdisGetSystemUpTime(&Now);
1298 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1300 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1301 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1303 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1306 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1308 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1311 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1313 if (BssType == BSS_ADHOC)
1315 MakeIbssBeacon(pAd);
1316 if ((pAd->CommonCfg.Channel > 14)
1317 && (pAd->CommonCfg.bIEEE80211H == 1)
1318 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1324 AsicEnableIbssSync(pAd);
1327 // In ad hoc mode, use MAC table from index 1.
1328 // 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.
1329 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1330 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1332 // If WEP is enabled, add key material and cipherAlg into Asic
1333 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1335 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1340 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1342 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1343 Key = pAd->SharedKey[BSS0][idx].Key;
1345 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1347 // Set key material and cipherAlg to Asic
1348 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1350 if (idx == pAd->StaCfg.DefaultKeyId)
1352 // Update WCID attribute table and IVEIV table for this group key table
1353 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1360 // If WPANone is enabled, add key material and cipherAlg into Asic
1361 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1362 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1364 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1366 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1367 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1368 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1370 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1372 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1373 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1376 // Decide its ChiperAlg
1377 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1378 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1379 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1380 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1383 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1384 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1387 // Set key material and cipherAlg to Asic
1388 AsicAddSharedKeyEntry(pAd,
1391 pAd->SharedKey[BSS0][0].CipherAlg,
1392 pAd->SharedKey[BSS0][0].Key,
1393 pAd->SharedKey[BSS0][0].TxMic,
1394 pAd->SharedKey[BSS0][0].RxMic);
1396 // Update WCID attribute table and IVEIV table for this group key table
1397 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1404 // Check the new SSID with last SSID
1405 while (Cancelled == TRUE)
1407 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1409 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1411 // Link to the old one no linkdown is required.
1415 // Send link down event before set to link up
1416 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1417 RTMP_IndicateMediaState(pAd);
1418 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1419 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1424 // On WPA mode, Remove All Keys if not connect to the last BSSID
1425 // Key will be set after 4-way handshake.
1427 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1431 // Remove all WPA keys
1432 RTMPWPARemoveAllKeys(pAd);
1433 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1434 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1436 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1437 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1439 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1440 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1443 // the decision of using "short slot time" or not may change dynamically due to
1444 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1447 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1448 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1451 ComposeNullFrame(pAd);
1453 AsicEnableBssSync(pAd);
1455 // Add BSSID to WCID search table
1456 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1458 NdisAcquireSpinLock(&pAd->MacTabLock);
1459 // add this BSSID entry into HASH table
1463 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1464 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1465 if (pAd->MacTab.Hash[HashIdx] == NULL)
1467 pAd->MacTab.Hash[HashIdx] = pEntry;
1471 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1472 while (pCurrEntry->pNext != NULL)
1473 pCurrEntry = pCurrEntry->pNext;
1474 pCurrEntry->pNext = pEntry;
1477 NdisReleaseSpinLock(&pAd->MacTabLock);
1480 // If WEP is enabled, add paiewise and shared key
1481 if (((pAd->StaCfg.WpaSupplicantUP)&&
1482 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1483 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1484 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1485 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1490 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1492 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1493 Key = pAd->SharedKey[BSS0][idx].Key;
1495 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1497 // Set key material and cipherAlg to Asic
1498 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1500 if (idx == pAd->StaCfg.DefaultKeyId)
1502 // Assign group key info
1503 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1505 // Assign pairwise key info
1506 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1512 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1513 // should wait until at least 2 active nodes in this BSSID.
1514 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1517 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1519 pAd->IndicateMediaState = NdisMediaStateConnected;
1520 pAd->ExtraInfo = GENERAL_LINK_UP;
1521 RTMP_IndicateMediaState(pAd);
1525 // Add BSSID in my MAC Table.
1526 NdisAcquireSpinLock(&pAd->MacTabLock);
1527 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1528 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1529 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1530 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1531 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1532 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1533 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1534 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1535 NdisReleaseSpinLock(&pAd->MacTabLock);
1537 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1538 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1540 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1541 #ifdef DOT11_N_SUPPORT
1542 MlmeUpdateHtTxRates(pAd, BSS0);
1543 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1544 #endif // DOT11_N_SUPPORT //
1546 if (pAd->CommonCfg.bAggregationCapable)
1548 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1551 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1552 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1553 RTMPSetPiggyBack(pAd, TRUE);
1554 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1556 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1558 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1562 if (pAd->MlmeAux.APRalinkIe != 0x0)
1564 #ifdef DOT11_N_SUPPORT
1565 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1569 #endif // DOT11_N_SUPPORT //
1570 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1571 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1575 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1576 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1580 #ifdef DOT11_N_SUPPORT
1581 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));
1582 #endif // DOT11_N_SUPPORT //
1585 RTMPSetLED(pAd, LED_LINK_UP);
1587 pAd->Mlme.PeriodicRound = 0;
1588 pAd->Mlme.OneSecPeriodicRound = 0;
1589 pAd->bConfigChanged = FALSE; // Reset config flag
1590 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1592 // Set asic auto fall back
1595 UCHAR TableSize = 0;
1597 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1598 AsicUpdateAutoFallBackTable(pAd, pTable);
1601 NdisAcquireSpinLock(&pAd->MacTabLock);
1602 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1603 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1604 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1606 pEntry->bAutoTxRateSwitch = FALSE;
1607 #ifdef DOT11_N_SUPPORT
1608 if (pEntry->HTPhyMode.field.MCS == 32)
1609 pEntry->HTPhyMode.field.ShortGI = GI_800;
1611 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1612 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1613 #endif // DOT11_N_SUPPORT //
1614 // If the legacy mode is set, overwrite the transmit setting of this entry.
1615 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1616 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1619 pEntry->bAutoTxRateSwitch = TRUE;
1620 NdisReleaseSpinLock(&pAd->MacTabLock);
1622 // Let Link Status Page display first initial rate.
1623 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1624 // Select DAC according to HT or Legacy
1625 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1627 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1629 if (pAd->Antenna.field.TxPath == 2)
1633 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1637 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1639 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1642 #ifdef DOT11_N_SUPPORT
1643 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1646 else if (pEntry->MaxRAmpduFactor == 0)
1648 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1649 // Because our Init value is 1 at MACRegTable.
1650 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1652 #endif // DOT11_N_SUPPORT //
1654 // Patch for Marvel AP to gain high throughput
1655 // Need to set as following,
1656 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1657 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1658 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1659 // 4. kick per two packets when dequeue
1661 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1663 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1664 #ifdef DOT11_N_SUPPORT
1665 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1666 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1668 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1670 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1672 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1673 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1676 #endif // DOT11_N_SUPPORT //
1677 if (pAd->CommonCfg.bEnableTxBurst)
1679 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1682 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1683 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1685 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1686 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1690 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1692 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1694 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1695 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1698 #ifdef DOT11_N_SUPPORT
1699 // Re-check to turn on TX burst or not.
1700 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1702 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1703 if (pAd->CommonCfg.bEnableTxBurst)
1705 UINT32 MACValue = 0;
1706 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1707 // I didn't change PBF_MAX_PCNT setting.
1708 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1709 MACValue &= 0xFFFFFF00;
1710 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1711 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1716 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1718 #endif // DOT11_N_SUPPORT //
1720 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1721 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1722 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1723 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1724 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1725 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1727 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1729 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1730 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1733 NdisAcquireSpinLock(&pAd->MacTabLock);
1734 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1735 NdisReleaseSpinLock(&pAd->MacTabLock);
1738 // Patch Atheros AP TX will breakdown issue.
1739 // AP Model: DLink DWL-8200AP
1741 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1743 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1747 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1750 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1754 ==========================================================================
1756 Routine Description:
1757 Disconnect current BSSID
1760 pAd - Pointer to our adapter
1761 IsReqFromAP - Request from AP
1766 IRQL = DISPATCH_LEVEL
1769 We need more information to know it's this requst from AP.
1770 If yes! we need to do extra handling, for example, remove the WPA key.
1771 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1772 remove while auto reconnect.
1773 Disconnect request from AP, it means we will start afresh 4-way handshaking
1776 ==========================================================================
1779 IN PRTMP_ADAPTER pAd,
1780 IN BOOLEAN IsReqFromAP)
1782 UCHAR i, ByteValue = 0;
1784 // Do nothing if monitor mode is on
1785 if (MONITOR_ON(pAd))
1788 if (pAd->CommonCfg.bWirelessEvent)
1790 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1793 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1794 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1796 if (ADHOC_ON(pAd)) // Adhoc mode link down
1798 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1800 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1801 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1802 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1803 RTMP_IndicateMediaState(pAd);
1804 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1805 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1806 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1808 else // Infra structure mode
1810 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1812 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1813 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1815 // Saved last SSID for linkup comparison
1816 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1817 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
1818 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1819 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
1821 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1822 RTMP_IndicateMediaState(pAd);
1823 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1824 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1825 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1830 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
1831 // Otherwise lost beacon or receive De-Authentication from AP,
1832 // then we should delete BSSID from BssTable.
1833 // If we don't delete from entry, roaming will fail.
1835 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1838 // restore back to -
1839 // 1. long slot (20 us) or short slot (9 us) time
1840 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1841 // 3. short preamble
1842 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1844 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
1847 // Record current AP's information.
1848 // for later used reporting Adjacent AP report.
1850 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
1851 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
1852 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
1853 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
1857 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
1859 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1860 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
1863 pAd->StaCfg.CCXQosECWMin = 4;
1864 pAd->StaCfg.CCXQosECWMax = 10;
1866 AsicSetSlotTime(pAd, TRUE); //FALSE);
1867 AsicSetEdcaParm(pAd, NULL);
1870 RTMPSetLED(pAd, LED_LINK_DOWN);
1871 pAd->LedIndicatorStregth = 0xF0;
1872 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
1874 AsicDisableSync(pAd);
1876 pAd->Mlme.PeriodicRound = 0;
1877 pAd->Mlme.OneSecPeriodicRound = 0;
1879 if (pAd->StaCfg.BssType == BSS_INFRA)
1881 // Remove StaCfg Information after link down
1882 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1883 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1884 pAd->CommonCfg.SsidLen = 0;
1886 #ifdef DOT11_N_SUPPORT
1887 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
1888 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
1889 pAd->MlmeAux.HtCapabilityLen = 0;
1890 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1891 #endif // DOT11_N_SUPPORT //
1893 // Reset WPA-PSK state. Only reset when supplicant enabled
1894 if (pAd->StaCfg.WpaState != SS_NOTUSE)
1896 pAd->StaCfg.WpaState = SS_START;
1897 // Clear Replay counter
1898 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1903 // if link down come from AP, we need to remove all WPA keys on WPA mode.
1904 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
1906 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1908 // Remove all WPA keys
1909 RTMPWPARemoveAllKeys(pAd);
1912 // 802.1x port control
1914 // Prevent clear PortSecured here with static WEP
1915 // NetworkManger set security policy first then set SSID to connect AP.
1916 if (pAd->StaCfg.WpaSupplicantUP &&
1917 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1918 (pAd->StaCfg.IEEE8021X == FALSE))
1920 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1924 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1925 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1928 NdisAcquireSpinLock(&pAd->MacTabLock);
1929 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
1930 NdisReleaseSpinLock(&pAd->MacTabLock);
1932 pAd->StaCfg.MicErrCnt = 0;
1934 // Turn off Ckip control flag
1935 pAd->StaCfg.bCkipOn = FALSE;
1936 pAd->StaCfg.CCXEnable = FALSE;
1938 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1939 // Update extra information to link is up
1940 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1942 //pAd->StaCfg.AdhocBOnlyJoined = FALSE;
1943 //pAd->StaCfg.AdhocBGJoined = FALSE;
1944 //pAd->StaCfg.Adhoc20NJoined = FALSE;
1945 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1947 // Reset the Current AP's IP address
1948 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
1950 pAd->bUsbTxBulkAggre = FALSE;
1953 // Clean association information
1954 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
1955 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
1956 pAd->StaCfg.ReqVarIELen = 0;
1957 pAd->StaCfg.ResVarIELen = 0;
1960 // Reset RSSI value after link down
1962 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
1963 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
1964 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
1965 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
1966 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
1967 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
1970 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
1971 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
1973 #ifdef DOT11_N_SUPPORT
1975 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
1977 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1979 pAd->CommonCfg.BBPCurrentBW = BW_20;
1980 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
1981 ByteValue &= (~0x18);
1982 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
1984 #endif // DOT11_N_SUPPORT //
1986 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
1987 ByteValue &= (~0x18);
1988 if (pAd->Antenna.field.TxPath == 2)
1992 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
1994 RTMPSetPiggyBack(pAd,FALSE);
1995 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1997 #ifdef DOT11_N_SUPPORT
1998 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
1999 #endif // DOT11_N_SUPPORT //
2001 // Restore all settings in the following.
2002 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2003 AsicDisableRDG(pAd);
2004 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2005 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2007 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2008 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2011 union iwreq_data wrqu;
2012 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2013 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2018 ==========================================================================
2021 IRQL = DISPATCH_LEVEL
2023 ==========================================================================
2025 VOID IterateOnBssTab(
2026 IN PRTMP_ADAPTER pAd)
2028 MLME_START_REQ_STRUCT StartReq;
2029 MLME_JOIN_REQ_STRUCT JoinReq;
2032 // Change the wepstatus to original wepstatus
2033 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2034 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2035 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2037 BssIdx = pAd->MlmeAux.BssIdx;
2038 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2040 // Check cipher suite, AP must have more secured cipher than station setting
2041 // Set the Pairwise and Group cipher to match the intended AP setting
2042 // We can only connect to AP with less secured cipher setting
2043 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2045 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2047 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2048 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2049 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2050 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2051 else // There is no PairCipher Aux, downgrade our capability to TKIP
2052 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2054 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2056 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2058 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2059 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2060 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2061 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2062 else // There is no PairCipher Aux, downgrade our capability to TKIP
2063 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2066 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2069 // Set Mix cipher flag
2070 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2071 if (pAd->StaCfg.bMixCipher == TRUE)
2073 // If mix cipher, re-build RSNIE
2074 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2077 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2078 JoinParmFill(pAd, &JoinReq, BssIdx);
2079 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2081 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2083 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2085 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2086 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2087 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2088 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2092 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2093 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2094 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2095 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2099 // for re-association only
2100 // IRQL = DISPATCH_LEVEL
2101 VOID IterateOnBssTab2(
2102 IN PRTMP_ADAPTER pAd)
2104 MLME_REASSOC_REQ_STRUCT ReassocReq;
2108 BssIdx = pAd->MlmeAux.RoamIdx;
2109 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2111 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2113 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2115 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2116 AsicLockChannel(pAd, pBss->Channel);
2118 // reassociate message has the same structure as associate message
2119 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2120 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2121 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2122 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2124 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2128 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2129 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2130 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2131 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2136 ==========================================================================
2139 IRQL = DISPATCH_LEVEL
2141 ==========================================================================
2144 IN PRTMP_ADAPTER pAd,
2145 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2148 JoinReq->BssIdx = BssIdx;
2152 ==========================================================================
2155 IRQL = DISPATCH_LEVEL
2157 ==========================================================================
2160 IN PRTMP_ADAPTER pAd,
2161 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2167 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2168 ScanReq->SsidLen = SsidLen;
2169 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2170 ScanReq->BssType = BssType;
2171 ScanReq->ScanType = ScanType;
2175 ==========================================================================
2178 IRQL = DISPATCH_LEVEL
2180 ==========================================================================
2183 IN PRTMP_ADAPTER pAd,
2184 IN OUT MLME_START_REQ_STRUCT *StartReq,
2188 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2189 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2190 StartReq->SsidLen = SsidLen;
2194 ==========================================================================
2197 IRQL = DISPATCH_LEVEL
2199 ==========================================================================
2202 IN PRTMP_ADAPTER pAd,
2203 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2207 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2209 AuthReq->Timeout = AUTH_TIMEOUT;
2213 ==========================================================================
2216 IRQL = DISPATCH_LEVEL
2218 ==========================================================================
2224 VOID MlmeCntlConfirm(
2225 IN PRTMP_ADAPTER pAd,
2229 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
2233 IN PRTMP_ADAPTER pAd)
2235 PTXINFO_STRUC pTxInfo;
2238 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2239 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2241 pAd->PsPollFrame.FC.PwrMgmt = 0;
2242 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2243 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2244 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2245 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2246 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2248 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
2249 pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
2250 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2251 pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2252 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
2253 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2254 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2255 // Append 4 extra zero bytes.
2256 pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
2259 // IRQL = DISPATCH_LEVEL
2260 VOID ComposeNullFrame(
2261 IN PRTMP_ADAPTER pAd)
2263 PTXINFO_STRUC pTxInfo;
2266 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2267 pAd->NullFrame.FC.Type = BTYPE_DATA;
2268 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2269 pAd->NullFrame.FC.ToDs = 1;
2270 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2271 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2272 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2273 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
2274 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
2275 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2276 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2277 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
2278 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2279 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
2280 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2286 ==========================================================================
2288 Pre-build a BEACON frame in the shared memory
2290 IRQL = PASSIVE_LEVEL
2291 IRQL = DISPATCH_LEVEL
2293 ==========================================================================
2295 ULONG MakeIbssBeacon(
2296 IN PRTMP_ADAPTER pAd)
2298 UCHAR DsLen = 1, IbssLen = 2;
2299 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2300 HEADER_802_11 BcnHdr;
2301 USHORT CapabilityInfo;
2302 LARGE_INTEGER FakeTimestamp;
2304 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2305 CHAR *pBeaconFrame = pAd->BeaconBuf;
2307 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2308 UCHAR SupRateLen = 0;
2309 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2310 UCHAR ExtRateLen = 0;
2311 UCHAR RSNIe = IE_WPA;
2313 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2315 SupRate[0] = 0x82; // 1 mbps
2316 SupRate[1] = 0x84; // 2 mbps
2317 SupRate[2] = 0x8b; // 5.5 mbps
2318 SupRate[3] = 0x96; // 11 mbps
2322 else if (pAd->CommonCfg.Channel > 14)
2324 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2325 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2326 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2327 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2328 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2329 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2330 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2331 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2336 // Also Update MlmeRate & RtsRate for G only & A only
2338 pAd->CommonCfg.MlmeRate = RATE_6;
2339 pAd->CommonCfg.RtsRate = RATE_6;
2340 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2341 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2342 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2343 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2347 SupRate[0] = 0x82; // 1 mbps
2348 SupRate[1] = 0x84; // 2 mbps
2349 SupRate[2] = 0x8b; // 5.5 mbps
2350 SupRate[3] = 0x96; // 11 mbps
2353 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2354 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2355 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2356 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2357 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2358 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2359 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2360 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2364 pAd->StaActive.SupRateLen = SupRateLen;
2365 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2366 pAd->StaActive.ExtRateLen = ExtRateLen;
2367 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2369 // compose IBSS beacon frame
2370 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2371 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2372 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2373 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2374 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2376 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2377 sizeof(HEADER_802_11), &BcnHdr,
2378 TIMESTAMP_LEN, &FakeTimestamp,
2379 2, &pAd->CommonCfg.BeaconPeriod,
2382 1, &pAd->CommonCfg.SsidLen,
2383 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2386 SupRateLen, SupRate,
2389 1, &pAd->CommonCfg.Channel,
2392 2, &pAd->StaActive.AtimWin,
2395 // add ERP_IE and EXT_RAE IE of in 802.11g
2400 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2404 ExtRateLen, ExtRate,
2409 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2410 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2413 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2415 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2417 1, &pAd->StaCfg.RSNIE_Len,
2418 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2423 #ifdef DOT11_N_SUPPORT
2424 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2427 UCHAR HtLen, HtLen1;
2429 // add HT Capability IE
2430 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2431 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2433 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2436 HtLen, &pAd->CommonCfg.HtCapability,
2439 HtLen1, &pAd->CommonCfg.AddHTInfo,
2444 #endif // DOT11_N_SUPPORT //
2446 //beacon use reserved WCID 0xff
2447 if (pAd->CommonCfg.Channel > 14)
2449 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2450 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2454 // Set to use 1Mbps for Adhoc beacon.
2455 HTTRANSMIT_SETTING Transmit;
2457 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2458 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2461 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2462 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));