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 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
537 // we just follow normal procedure. The reason of user doing this may because he/she changed
538 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
539 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
540 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
541 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
542 // connection when setting the same BSSID.
543 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
544 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
546 // already connected to the same BSSID, go back to idle state directly
547 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
548 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
551 union iwreq_data wrqu;
553 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
554 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
555 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
563 // disassoc from current AP first
564 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
565 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
566 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
567 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
569 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
575 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
576 LinkDown(pAd, FALSE);
577 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
578 pAd->IndicateMediaState = NdisMediaStateDisconnected;
579 RTMP_IndicateMediaState(pAd);
580 pAd->ExtraInfo = GENERAL_LINK_DOWN;
581 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
584 // Change the wepstatus to original wepstatus
585 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
586 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
587 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
589 // Check cipher suite, AP must have more secured cipher than station setting
590 // Set the Pairwise and Group cipher to match the intended AP setting
591 // We can only connect to AP with less secured cipher setting
592 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
594 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
596 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
597 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
598 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
599 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
600 else // There is no PairCipher Aux, downgrade our capability to TKIP
601 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
603 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
605 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
607 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
608 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
609 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
610 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
611 else // There is no PairCipher Aux, downgrade our capability to TKIP
612 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
615 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
618 // Set Mix cipher flag
619 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
620 if (pAd->StaCfg.bMixCipher == TRUE)
622 // If mix cipher, re-build RSNIE
623 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
625 // No active association, join the BSS immediately
626 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
627 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
629 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
630 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
632 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
637 // Roaming is the only external request triggering CNTL state machine
638 // despite of other "SET OID" operation. All "SET OID" related oerations
639 // happen in sequence, because no other SET OID will be sent to this device
640 // until the the previous SET operation is complete (successful o failed).
641 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
642 // or been corrupted by other "SET OID"?
644 // IRQL = DISPATCH_LEVEL
645 VOID CntlMlmeRoamingProc(
646 IN PRTMP_ADAPTER pAd,
647 IN MLME_QUEUE_ELEM *Elem)
650 // AP in different channel may show lower RSSI than actual value??
651 // should we add a weighting factor to compensate it?
652 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
654 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
655 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
657 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
658 pAd->MlmeAux.BssIdx = 0;
659 IterateOnBssTab(pAd);
663 ==========================================================================
666 IRQL = DISPATCH_LEVEL
668 ==========================================================================
670 VOID CntlWaitDisassocProc(
671 IN PRTMP_ADAPTER pAd,
672 IN MLME_QUEUE_ELEM *Elem)
674 MLME_START_REQ_STRUCT StartReq;
676 if (Elem->MsgType == MT2_DISASSOC_CONF)
678 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
680 if (pAd->CommonCfg.bWirelessEvent)
682 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
685 LinkDown(pAd, FALSE);
687 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
688 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
690 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
691 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
692 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
693 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
695 // case 2. try each matched BSS
698 pAd->MlmeAux.BssIdx = 0;
700 IterateOnBssTab(pAd);
706 ==========================================================================
709 IRQL = DISPATCH_LEVEL
711 ==========================================================================
713 VOID CntlWaitJoinProc(
714 IN PRTMP_ADAPTER pAd,
715 IN MLME_QUEUE_ELEM *Elem)
718 MLME_AUTH_REQ_STRUCT AuthReq;
720 if (Elem->MsgType == MT2_JOIN_CONF)
722 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
723 if (Reason == MLME_SUCCESS)
725 // 1. joined an IBSS, we are pretty much done here
726 if (pAd->MlmeAux.BssType == BSS_ADHOC)
729 // 5G bands rules of Japan:
730 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
732 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
733 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
736 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
737 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
741 LinkUp(pAd, BSS_ADHOC);
742 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
743 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
744 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
745 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
747 pAd->IndicateMediaState = NdisMediaStateConnected;
748 pAd->ExtraInfo = GENERAL_LINK_UP;
750 // 2. joined a new INFRA network, start from authentication
754 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
755 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
756 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
758 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
762 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
765 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
766 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
768 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
773 // 3. failed, try next BSS
774 pAd->MlmeAux.BssIdx++;
775 IterateOnBssTab(pAd);
782 ==========================================================================
785 IRQL = DISPATCH_LEVEL
787 ==========================================================================
789 VOID CntlWaitStartProc(
790 IN PRTMP_ADAPTER pAd,
791 IN MLME_QUEUE_ELEM *Elem)
795 if (Elem->MsgType == MT2_START_CONF)
797 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
798 if (Result == MLME_SUCCESS)
801 // 5G bands rules of Japan:
802 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
804 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
805 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
808 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
809 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
813 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
817 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
818 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
819 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
820 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
821 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
822 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
824 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
825 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
827 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
829 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
830 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
832 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
837 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
839 LinkUp(pAd, BSS_ADHOC);
840 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
841 // Before send beacon, driver need do radar detection
842 if ((pAd->CommonCfg.Channel > 14 )
843 && (pAd->CommonCfg.bIEEE80211H == 1)
844 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
846 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
847 pAd->CommonCfg.RadarDetect.RDCount = 0;
850 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
851 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
852 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
856 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
857 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
863 ==========================================================================
866 IRQL = DISPATCH_LEVEL
868 ==========================================================================
870 VOID CntlWaitAuthProc(
871 IN PRTMP_ADAPTER pAd,
872 IN MLME_QUEUE_ELEM *Elem)
875 MLME_ASSOC_REQ_STRUCT AssocReq;
876 MLME_AUTH_REQ_STRUCT AuthReq;
878 if (Elem->MsgType == MT2_AUTH_CONF)
880 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
881 if (Reason == MLME_SUCCESS)
883 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
884 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
885 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
888 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
889 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
891 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
896 // This fail may because of the AP already keep us in its MAC table without
897 // ageing-out. The previous authentication attempt must have let it remove us.
898 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
899 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
902 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
903 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
905 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
906 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
910 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
913 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
914 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
916 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
922 ==========================================================================
925 IRQL = DISPATCH_LEVEL
927 ==========================================================================
929 VOID CntlWaitAuthProc2(
930 IN PRTMP_ADAPTER pAd,
931 IN MLME_QUEUE_ELEM *Elem)
934 MLME_ASSOC_REQ_STRUCT AssocReq;
935 MLME_AUTH_REQ_STRUCT AuthReq;
937 if (Elem->MsgType == MT2_AUTH_CONF)
939 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
940 if (Reason == MLME_SUCCESS)
942 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
943 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
944 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
945 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
946 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
948 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
952 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
953 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
955 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
956 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
957 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
958 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
960 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
964 // not success, try next BSS
965 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
966 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
967 pAd->MlmeAux.BssIdx++;
968 IterateOnBssTab(pAd);
975 ==========================================================================
978 IRQL = DISPATCH_LEVEL
980 ==========================================================================
982 VOID CntlWaitAssocProc(
983 IN PRTMP_ADAPTER pAd,
984 IN MLME_QUEUE_ELEM *Elem)
988 if (Elem->MsgType == MT2_ASSOC_CONF)
990 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
991 if (Reason == MLME_SUCCESS)
993 LinkUp(pAd, BSS_INFRA);
994 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
995 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
997 if (pAd->CommonCfg.bWirelessEvent)
999 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1004 // not success, try next BSS
1005 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1006 pAd->MlmeAux.BssIdx++;
1007 IterateOnBssTab(pAd);
1013 ==========================================================================
1016 IRQL = DISPATCH_LEVEL
1018 ==========================================================================
1020 VOID CntlWaitReassocProc(
1021 IN PRTMP_ADAPTER pAd,
1022 IN MLME_QUEUE_ELEM *Elem)
1026 if (Elem->MsgType == MT2_REASSOC_CONF)
1028 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1029 if (Result == MLME_SUCCESS)
1032 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1034 LinkUp(pAd, BSS_INFRA);
1036 // send wireless event - for association
1037 if (pAd->CommonCfg.bWirelessEvent)
1038 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1040 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1041 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1045 // reassoc failed, try to pick next BSS in the BSS Table
1046 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1047 pAd->MlmeAux.RoamIdx++;
1048 IterateOnBssTab2(pAd);
1054 VOID AdhocTurnOnQos(
1055 IN PRTMP_ADAPTER pAd)
1057 #define AC0_DEF_TXOP 0
1058 #define AC1_DEF_TXOP 0
1059 #define AC2_DEF_TXOP 94
1060 #define AC3_DEF_TXOP 47
1062 // Turn on QOs if use HT rate.
1063 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1065 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1066 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1067 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1068 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1069 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1071 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1072 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1073 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1074 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1076 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1077 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1078 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1079 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1081 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1082 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1083 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1084 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1086 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1090 ==========================================================================
1093 IRQL = DISPATCH_LEVEL
1095 ==========================================================================
1098 IN PRTMP_ADAPTER pAd,
1104 UCHAR Value = 0, idx;
1105 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1107 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1110 // ASSOC - DisassocTimeoutAction
1111 // CNTL - Dis-associate successful
1112 // !!! LINK DOWN !!!
1113 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1115 // To prevent DisassocTimeoutAction to call Link down after we link up,
1116 // cancel the DisassocTimer no matter what it start or not.
1118 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1120 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1122 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1124 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1125 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1126 // to examine if cipher algorithm switching is required.
1127 //rt2860b. Don't know why need this
1128 SwitchBetweenWepAndCkip(pAd);
1131 if (BssType == BSS_ADHOC)
1133 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1134 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1137 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
1138 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
1140 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
1142 else if ((pAd->CommonCfg.Channel > 2) &&
1143 (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
1144 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
1146 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
1150 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1151 AdhocTurnOnQos(pAd);
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 // Change to AP channel
1171 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1173 // Must using 40MHz.
1174 pAd->CommonCfg.BBPCurrentBW = BW_40;
1175 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1176 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1178 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1181 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1183 // RX : control channel at lower
1184 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1186 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1188 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1190 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1192 if (pAd->MACVersion == 0x28600100)
1194 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1195 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1196 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1197 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1200 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1202 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1204 // Must using 40MHz.
1205 pAd->CommonCfg.BBPCurrentBW = BW_40;
1206 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1207 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1209 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1212 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1214 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1216 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1218 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1220 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1222 if (pAd->MACVersion == 0x28600100)
1224 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1225 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1226 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1227 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1230 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1234 pAd->CommonCfg.BBPCurrentBW = BW_20;
1235 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1236 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1237 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1239 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1241 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1243 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1245 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1247 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1249 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1251 if (pAd->MACVersion == 0x28600100)
1253 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1254 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1255 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1256 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1259 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1262 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1264 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1266 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1268 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1269 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1271 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1273 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1275 AsicSetSlotTime(pAd, TRUE);
1276 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1278 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1279 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1281 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1283 // Update HT protectionfor based on AP's operating mode.
1284 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1286 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1289 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1292 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1294 NdisGetSystemUpTime(&Now);
1295 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1297 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1298 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1300 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1303 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1305 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1308 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1310 if (BssType == BSS_ADHOC)
1312 MakeIbssBeacon(pAd);
1313 if ((pAd->CommonCfg.Channel > 14)
1314 && (pAd->CommonCfg.bIEEE80211H == 1)
1315 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1321 AsicEnableIbssSync(pAd);
1324 // In ad hoc mode, use MAC table from index 1.
1325 // 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.
1326 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1327 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1329 // If WEP is enabled, add key material and cipherAlg into Asic
1330 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1332 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1337 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1339 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1340 Key = pAd->SharedKey[BSS0][idx].Key;
1342 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1344 // Set key material and cipherAlg to Asic
1345 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1347 if (idx == pAd->StaCfg.DefaultKeyId)
1349 // Update WCID attribute table and IVEIV table for this group key table
1350 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1357 // If WPANone is enabled, add key material and cipherAlg into Asic
1358 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1359 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1361 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1363 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1364 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1365 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1367 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1369 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1370 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1373 // Decide its ChiperAlg
1374 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1375 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1376 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1377 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1380 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1381 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1384 // Set key material and cipherAlg to Asic
1385 AsicAddSharedKeyEntry(pAd,
1388 pAd->SharedKey[BSS0][0].CipherAlg,
1389 pAd->SharedKey[BSS0][0].Key,
1390 pAd->SharedKey[BSS0][0].TxMic,
1391 pAd->SharedKey[BSS0][0].RxMic);
1393 // Update WCID attribute table and IVEIV table for this group key table
1394 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1401 // Check the new SSID with last SSID
1402 while (Cancelled == TRUE)
1404 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1406 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1408 // Link to the old one no linkdown is required.
1412 // Send link down event before set to link up
1413 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1414 RTMP_IndicateMediaState(pAd);
1415 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1416 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1421 // On WPA mode, Remove All Keys if not connect to the last BSSID
1422 // Key will be set after 4-way handshake.
1424 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1428 // Remove all WPA keys
1429 RTMPWPARemoveAllKeys(pAd);
1430 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1431 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1433 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1434 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1436 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1437 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1440 // the decision of using "short slot time" or not may change dynamically due to
1441 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1444 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1445 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1448 ComposeNullFrame(pAd);
1450 AsicEnableBssSync(pAd);
1452 // Add BSSID to WCID search table
1453 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1455 NdisAcquireSpinLock(&pAd->MacTabLock);
1456 // add this BSSID entry into HASH table
1460 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1461 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1462 if (pAd->MacTab.Hash[HashIdx] == NULL)
1464 pAd->MacTab.Hash[HashIdx] = pEntry;
1468 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1469 while (pCurrEntry->pNext != NULL)
1470 pCurrEntry = pCurrEntry->pNext;
1471 pCurrEntry->pNext = pEntry;
1474 NdisReleaseSpinLock(&pAd->MacTabLock);
1477 // If WEP is enabled, add paiewise and shared key
1478 if (((pAd->StaCfg.WpaSupplicantUP)&&
1479 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1480 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1481 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1482 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1487 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1489 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1490 Key = pAd->SharedKey[BSS0][idx].Key;
1492 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1494 // Set key material and cipherAlg to Asic
1495 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1497 if (idx == pAd->StaCfg.DefaultKeyId)
1499 // Assign group key info
1500 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1502 // Assign pairwise key info
1503 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1509 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1510 // should wait until at least 2 active nodes in this BSSID.
1511 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1514 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1516 pAd->IndicateMediaState = NdisMediaStateConnected;
1517 pAd->ExtraInfo = GENERAL_LINK_UP;
1518 RTMP_IndicateMediaState(pAd);
1522 // Add BSSID in my MAC Table.
1523 NdisAcquireSpinLock(&pAd->MacTabLock);
1524 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1525 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1526 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1527 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1528 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1529 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1530 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1532 pAd->MacTab.Content[BSSID_WCID].AuthMode = pAd->StaCfg.AuthMode;
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 MlmeUpdateHtTxRates(pAd, BSS0);
1542 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1544 if (pAd->CommonCfg.bAggregationCapable)
1546 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1549 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1550 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1551 RTMPSetPiggyBack(pAd, TRUE);
1552 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1554 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1556 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1560 if (pAd->MlmeAux.APRalinkIe != 0x0)
1562 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1567 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1568 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1572 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1573 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1577 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));
1580 RTMPSetLED(pAd, LED_LINK_UP);
1582 pAd->Mlme.PeriodicRound = 0;
1583 pAd->Mlme.OneSecPeriodicRound = 0;
1584 pAd->bConfigChanged = FALSE; // Reset config flag
1585 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1587 // Set asic auto fall back
1590 UCHAR TableSize = 0;
1592 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1593 AsicUpdateAutoFallBackTable(pAd, pTable);
1596 NdisAcquireSpinLock(&pAd->MacTabLock);
1597 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1598 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1599 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1601 pEntry->bAutoTxRateSwitch = FALSE;
1603 if (pEntry->HTPhyMode.field.MCS == 32)
1604 pEntry->HTPhyMode.field.ShortGI = GI_800;
1606 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1607 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1609 // If the legacy mode is set, overwrite the transmit setting of this entry.
1610 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1611 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1614 pEntry->bAutoTxRateSwitch = TRUE;
1615 NdisReleaseSpinLock(&pAd->MacTabLock);
1617 // Let Link Status Page display first initial rate.
1618 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1619 // Select DAC according to HT or Legacy
1620 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1622 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1624 if (pAd->Antenna.field.TxPath == 2)
1628 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1632 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1634 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1637 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1640 else if (pEntry->MaxRAmpduFactor == 0)
1642 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1643 // Because our Init value is 1 at MACRegTable.
1644 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1647 // Patch for Marvel AP to gain high throughput
1648 // Need to set as following,
1649 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1650 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1651 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1652 // 4. kick per two packets when dequeue
1654 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1656 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1658 if (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) &&
1659 (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
1660 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))))
1663 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1664 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1667 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1669 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1671 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1672 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1675 if (pAd->CommonCfg.bEnableTxBurst)
1677 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1680 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1681 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1683 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1684 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1688 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1690 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1692 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1693 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1696 // Re-check to turn on TX burst or not.
1697 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1699 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1700 if (pAd->CommonCfg.bEnableTxBurst)
1702 UINT32 MACValue = 0;
1703 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1704 // I didn't change PBF_MAX_PCNT setting.
1705 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1706 MACValue &= 0xFFFFFF00;
1707 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1708 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1713 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1716 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1717 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1718 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1719 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1720 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1721 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1723 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1725 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1726 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1729 NdisAcquireSpinLock(&pAd->MacTabLock);
1730 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1731 NdisReleaseSpinLock(&pAd->MacTabLock);
1734 // Patch Atheros AP TX will breakdown issue.
1735 // AP Model: DLink DWL-8200AP
1737 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1739 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1743 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1746 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1750 ==========================================================================
1752 Routine Description:
1753 Disconnect current BSSID
1756 pAd - Pointer to our adapter
1757 IsReqFromAP - Request from AP
1762 IRQL = DISPATCH_LEVEL
1765 We need more information to know it's this requst from AP.
1766 If yes! we need to do extra handling, for example, remove the WPA key.
1767 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1768 remove while auto reconnect.
1769 Disconnect request from AP, it means we will start afresh 4-way handshaking
1772 ==========================================================================
1775 IN PRTMP_ADAPTER pAd,
1776 IN BOOLEAN IsReqFromAP)
1778 UCHAR i, ByteValue = 0;
1780 // Do nothing if monitor mode is on
1781 if (MONITOR_ON(pAd))
1784 if (pAd->CommonCfg.bWirelessEvent)
1786 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1789 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1790 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1792 if (ADHOC_ON(pAd)) // Adhoc mode link down
1794 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1796 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1797 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1798 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1799 RTMP_IndicateMediaState(pAd);
1800 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1801 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1802 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1804 else // Infra structure mode
1806 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1808 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1809 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1811 // Saved last SSID for linkup comparison
1812 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1813 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
1814 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1815 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
1817 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1818 RTMP_IndicateMediaState(pAd);
1819 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1820 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1821 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1826 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
1827 // Otherwise lost beacon or receive De-Authentication from AP,
1828 // then we should delete BSSID from BssTable.
1829 // If we don't delete from entry, roaming will fail.
1831 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1834 // restore back to -
1835 // 1. long slot (20 us) or short slot (9 us) time
1836 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1837 // 3. short preamble
1838 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1840 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
1843 // Record current AP's information.
1844 // for later used reporting Adjacent AP report.
1846 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
1847 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
1848 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
1849 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
1853 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
1855 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1856 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
1859 pAd->StaCfg.CCXQosECWMin = 4;
1860 pAd->StaCfg.CCXQosECWMax = 10;
1862 AsicSetSlotTime(pAd, TRUE); //FALSE);
1863 AsicSetEdcaParm(pAd, NULL);
1866 RTMPSetLED(pAd, LED_LINK_DOWN);
1867 pAd->LedIndicatorStregth = 0xF0;
1868 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
1870 AsicDisableSync(pAd);
1872 pAd->Mlme.PeriodicRound = 0;
1873 pAd->Mlme.OneSecPeriodicRound = 0;
1875 if (pAd->StaCfg.BssType == BSS_INFRA)
1877 // Remove StaCfg Information after link down
1878 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1879 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1880 pAd->CommonCfg.SsidLen = 0;
1883 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
1884 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
1885 pAd->MlmeAux.HtCapabilityLen = 0;
1886 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1888 // Reset WPA-PSK state. Only reset when supplicant enabled
1889 if (pAd->StaCfg.WpaState != SS_NOTUSE)
1891 pAd->StaCfg.WpaState = SS_START;
1892 // Clear Replay counter
1893 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1898 // if link down come from AP, we need to remove all WPA keys on WPA mode.
1899 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
1901 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1903 // Remove all WPA keys
1904 RTMPWPARemoveAllKeys(pAd);
1907 // 802.1x port control
1909 // Prevent clear PortSecured here with static WEP
1910 // NetworkManger set security policy first then set SSID to connect AP.
1911 if (pAd->StaCfg.WpaSupplicantUP &&
1912 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1913 (pAd->StaCfg.IEEE8021X == FALSE))
1915 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1919 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1920 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1923 NdisAcquireSpinLock(&pAd->MacTabLock);
1924 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
1925 NdisReleaseSpinLock(&pAd->MacTabLock);
1927 pAd->StaCfg.MicErrCnt = 0;
1929 // Turn off Ckip control flag
1930 pAd->StaCfg.bCkipOn = FALSE;
1931 pAd->StaCfg.CCXEnable = FALSE;
1933 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1934 // Update extra information to link is up
1935 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1937 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1939 // Reset the Current AP's IP address
1940 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
1942 pAd->bUsbTxBulkAggre = FALSE;
1945 // Clean association information
1946 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
1947 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
1948 pAd->StaCfg.ReqVarIELen = 0;
1949 pAd->StaCfg.ResVarIELen = 0;
1952 // Reset RSSI value after link down
1954 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
1955 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
1956 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
1957 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
1958 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
1959 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
1962 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
1963 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
1966 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
1968 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1970 pAd->CommonCfg.BBPCurrentBW = BW_20;
1971 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
1972 ByteValue &= (~0x18);
1973 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
1977 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
1978 ByteValue &= (~0x18);
1979 if (pAd->Antenna.field.TxPath == 2)
1983 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
1985 RTMPSetPiggyBack(pAd,FALSE);
1986 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1988 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
1990 // Restore all settings in the following.
1991 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
1992 AsicDisableRDG(pAd);
1993 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
1994 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1996 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
1997 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2000 union iwreq_data wrqu;
2001 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2002 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2009 // disable MMPS BBP control register
2010 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &ByteValue);
2011 ByteValue &= ~(0x04); //bit 2
2012 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, ByteValue);
2014 // disable MMPS MAC control register
2015 RTMP_IO_READ32(pAd, 0x1210, &macdata);
2016 macdata &= ~(0x09); //bit 0, 3
2017 RTMP_IO_WRITE32(pAd, 0x1210, macdata);
2023 ==========================================================================
2026 IRQL = DISPATCH_LEVEL
2028 ==========================================================================
2030 VOID IterateOnBssTab(
2031 IN PRTMP_ADAPTER pAd)
2033 MLME_START_REQ_STRUCT StartReq;
2034 MLME_JOIN_REQ_STRUCT JoinReq;
2037 // Change the wepstatus to original wepstatus
2038 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2039 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2040 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2042 BssIdx = pAd->MlmeAux.BssIdx;
2043 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2045 // Check cipher suite, AP must have more secured cipher than station setting
2046 // Set the Pairwise and Group cipher to match the intended AP setting
2047 // We can only connect to AP with less secured cipher setting
2048 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2050 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2052 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2053 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2054 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2055 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2056 else // There is no PairCipher Aux, downgrade our capability to TKIP
2057 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2059 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2061 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2063 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2064 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2065 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2066 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2067 else // There is no PairCipher Aux, downgrade our capability to TKIP
2068 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2071 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2074 // Set Mix cipher flag
2075 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2076 if (pAd->StaCfg.bMixCipher == TRUE)
2078 // If mix cipher, re-build RSNIE
2079 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2082 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2083 JoinParmFill(pAd, &JoinReq, BssIdx);
2084 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2086 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2088 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2090 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2091 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2092 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2093 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2097 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2098 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2099 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2100 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2104 // for re-association only
2105 // IRQL = DISPATCH_LEVEL
2106 VOID IterateOnBssTab2(
2107 IN PRTMP_ADAPTER pAd)
2109 MLME_REASSOC_REQ_STRUCT ReassocReq;
2113 BssIdx = pAd->MlmeAux.RoamIdx;
2114 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2116 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2118 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2120 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2121 AsicLockChannel(pAd, pBss->Channel);
2123 // reassociate message has the same structure as associate message
2124 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2125 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2126 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2127 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2129 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2133 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2134 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2135 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2136 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2141 ==========================================================================
2144 IRQL = DISPATCH_LEVEL
2146 ==========================================================================
2149 IN PRTMP_ADAPTER pAd,
2150 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2153 JoinReq->BssIdx = BssIdx;
2157 ==========================================================================
2160 IRQL = DISPATCH_LEVEL
2162 ==========================================================================
2165 IN PRTMP_ADAPTER pAd,
2166 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2172 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2173 ScanReq->SsidLen = SsidLen;
2174 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2175 ScanReq->BssType = BssType;
2176 ScanReq->ScanType = ScanType;
2180 ==========================================================================
2183 IRQL = DISPATCH_LEVEL
2185 ==========================================================================
2188 IN PRTMP_ADAPTER pAd,
2189 IN OUT MLME_START_REQ_STRUCT *StartReq,
2193 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2194 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2195 StartReq->SsidLen = SsidLen;
2199 ==========================================================================
2202 IRQL = DISPATCH_LEVEL
2204 ==========================================================================
2207 IN PRTMP_ADAPTER pAd,
2208 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2212 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2214 AuthReq->Timeout = AUTH_TIMEOUT;
2218 ==========================================================================
2221 IRQL = DISPATCH_LEVEL
2223 ==========================================================================
2229 VOID MlmeCntlConfirm(
2230 IN PRTMP_ADAPTER pAd,
2234 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
2238 IN PRTMP_ADAPTER pAd)
2240 PTXINFO_STRUC pTxInfo;
2243 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2244 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2246 pAd->PsPollFrame.FC.PwrMgmt = 0;
2247 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2248 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2249 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2250 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2251 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2253 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
2254 pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
2255 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2256 pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2257 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
2258 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2259 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2260 // Append 4 extra zero bytes.
2261 pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
2264 // IRQL = DISPATCH_LEVEL
2265 VOID ComposeNullFrame(
2266 IN PRTMP_ADAPTER pAd)
2268 PTXINFO_STRUC pTxInfo;
2271 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2272 pAd->NullFrame.FC.Type = BTYPE_DATA;
2273 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2274 pAd->NullFrame.FC.ToDs = 1;
2275 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2276 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2277 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2278 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
2279 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
2280 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2281 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2282 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
2283 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2284 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
2285 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2291 ==========================================================================
2293 Pre-build a BEACON frame in the shared memory
2295 IRQL = PASSIVE_LEVEL
2296 IRQL = DISPATCH_LEVEL
2298 ==========================================================================
2300 ULONG MakeIbssBeacon(
2301 IN PRTMP_ADAPTER pAd)
2303 UCHAR DsLen = 1, IbssLen = 2;
2304 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2305 HEADER_802_11 BcnHdr;
2306 USHORT CapabilityInfo;
2307 LARGE_INTEGER FakeTimestamp;
2309 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2310 CHAR *pBeaconFrame = pAd->BeaconBuf;
2312 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2313 UCHAR SupRateLen = 0;
2314 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2315 UCHAR ExtRateLen = 0;
2316 UCHAR RSNIe = IE_WPA;
2318 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2320 SupRate[0] = 0x82; // 1 mbps
2321 SupRate[1] = 0x84; // 2 mbps
2322 SupRate[2] = 0x8b; // 5.5 mbps
2323 SupRate[3] = 0x96; // 11 mbps
2327 else if (pAd->CommonCfg.Channel > 14)
2329 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2330 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2331 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2332 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2333 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2334 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2335 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2336 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2341 // Also Update MlmeRate & RtsRate for G only & A only
2343 pAd->CommonCfg.MlmeRate = RATE_6;
2344 pAd->CommonCfg.RtsRate = RATE_6;
2345 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2346 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2347 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2348 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2352 SupRate[0] = 0x82; // 1 mbps
2353 SupRate[1] = 0x84; // 2 mbps
2354 SupRate[2] = 0x8b; // 5.5 mbps
2355 SupRate[3] = 0x96; // 11 mbps
2358 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2359 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2360 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2361 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2362 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2363 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2364 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2365 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2369 pAd->StaActive.SupRateLen = SupRateLen;
2370 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2371 pAd->StaActive.ExtRateLen = ExtRateLen;
2372 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2374 // compose IBSS beacon frame
2375 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2376 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2377 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2378 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2379 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2381 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2382 sizeof(HEADER_802_11), &BcnHdr,
2383 TIMESTAMP_LEN, &FakeTimestamp,
2384 2, &pAd->CommonCfg.BeaconPeriod,
2387 1, &pAd->CommonCfg.SsidLen,
2388 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2391 SupRateLen, SupRate,
2394 1, &pAd->CommonCfg.Channel,
2397 2, &pAd->StaActive.AtimWin,
2400 // add ERP_IE and EXT_RAE IE of in 802.11g
2405 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2409 ExtRateLen, ExtRate,
2414 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2415 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2418 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2420 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2422 1, &pAd->StaCfg.RSNIE_Len,
2423 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2428 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2431 UCHAR HtLen, HtLen1;
2433 // add HT Capability IE
2434 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2435 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2437 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2440 HtLen, &pAd->CommonCfg.HtCapability,
2443 HtLen1, &pAd->CommonCfg.AddHTInfo,
2449 //beacon use reserved WCID 0xff
2450 if (pAd->CommonCfg.Channel > 14)
2452 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2453 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2457 // Set to use 1Mbps for Adhoc beacon.
2458 HTTRANSMIT_SETTING Transmit;
2460 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2461 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2464 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2465 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));