2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 John 2004-08-08 Major modification from RT2560
37 #include "../rt_config.h"
39 UCHAR CipherSuiteWpaNoneTkip[] = {
40 0x00, 0x50, 0xf2, 0x01, // oui
41 0x01, 0x00, // Version
42 0x00, 0x50, 0xf2, 0x02, // Multicast
43 0x01, 0x00, // Number of unicast
44 0x00, 0x50, 0xf2, 0x02, // unicast
45 0x01, 0x00, // number of authentication method
46 0x00, 0x50, 0xf2, 0x00 // authentication
48 UCHAR CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
50 UCHAR CipherSuiteWpaNoneAes[] = {
51 0x00, 0x50, 0xf2, 0x01, // oui
52 0x01, 0x00, // Version
53 0x00, 0x50, 0xf2, 0x04, // Multicast
54 0x01, 0x00, // Number of unicast
55 0x00, 0x50, 0xf2, 0x04, // unicast
56 0x01, 0x00, // number of authentication method
57 0x00, 0x50, 0xf2, 0x00 // authentication
59 UCHAR CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
61 // The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS,
62 // or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS
63 // All settings successfuly negotiated furing MLME state machines become final settings
64 // and are copied to pAd->StaActive
65 #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
67 (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \
68 NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
69 COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \
70 (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel; \
71 (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel; \
72 (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid; \
73 (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin; \
74 (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo; \
75 (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod; \
76 (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration; \
77 (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod; \
78 (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen; \
79 NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
80 (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen; \
81 NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
82 NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\
83 NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\
84 NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\
85 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid); \
86 (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid; \
87 (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
88 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
89 (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
93 ==========================================================================
98 ==========================================================================
101 IN PRTMP_ADAPTER pAd,
103 OUT STATE_MACHINE_FUNC Trans[])
105 // Control state machine differs from other state machines, the interface
106 // follows the standard interface
107 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
111 ==========================================================================
114 IRQL = DISPATCH_LEVEL
116 ==========================================================================
118 VOID MlmeCntlMachinePerformAction(
119 IN PRTMP_ADAPTER pAd,
121 IN MLME_QUEUE_ELEM *Elem)
123 switch(pAd->Mlme.CntlMachine.CurrState)
127 CntlIdleProc(pAd, Elem);
130 case CNTL_WAIT_DISASSOC:
131 CntlWaitDisassocProc(pAd, Elem);
134 CntlWaitJoinProc(pAd, Elem);
137 // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
138 // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
139 // Therefore not protected by NDIS's "only one outstanding OID request"
140 // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
141 // Current approach is to block new SET request at RTMPSetInformation()
142 // when CntlMachine.CurrState is not CNTL_IDLE
143 case CNTL_WAIT_REASSOC:
144 CntlWaitReassocProc(pAd, Elem);
147 case CNTL_WAIT_START:
148 CntlWaitStartProc(pAd, Elem);
151 CntlWaitAuthProc(pAd, Elem);
153 case CNTL_WAIT_AUTH2:
154 CntlWaitAuthProc2(pAd, Elem);
156 case CNTL_WAIT_ASSOC:
157 CntlWaitAssocProc(pAd, Elem);
160 case CNTL_WAIT_OID_LIST_SCAN:
161 if(Elem->MsgType == MT2_SCAN_CONF)
163 // Resume TxRing after SCANING complete. We hope the out-of-service time
164 // won't be too long to let upper layer time-out the waiting frames
165 RTMPResumeMsduTransmission(pAd);
166 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
168 // Cisco scan request is finished, prepare beacon report
169 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
171 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
174 // Set LED status to previous status.
176 if (pAd->bLedOnScanning)
178 pAd->bLedOnScanning = FALSE;
179 RTMPSetLED(pAd, pAd->LedStatus);
184 case CNTL_WAIT_OID_DISASSOC:
185 if (Elem->MsgType == MT2_DISASSOC_CONF)
187 LinkDown(pAd, FALSE);
188 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
193 // This state is for that we want to connect to an AP but
194 // it didn't find on BSS List table. So we need to scan the air first,
195 // after that we can try to connect to the desired AP if available.
197 case CNTL_WAIT_SCAN_FOR_CONNECT:
198 if(Elem->MsgType == MT2_SCAN_CONF)
200 // Resume TxRing after SCANING complete. We hope the out-of-service time
201 // won't be too long to let upper layer time-out the waiting frames
202 RTMPResumeMsduTransmission(pAd);
204 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
206 // Cisco scan request is finished, prepare beacon report
207 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
209 #endif // CCX_SUPPORT //
210 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
213 // Check if we can connect to.
215 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
216 if (pAd->MlmeAux.SsidBssTab.BssNr > 0)
218 MlmeAutoReconnectLastSSID(pAd);
224 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
231 ==========================================================================
234 IRQL = DISPATCH_LEVEL
236 ==========================================================================
239 IN PRTMP_ADAPTER pAd,
240 IN MLME_QUEUE_ELEM *Elem)
242 MLME_DISASSOC_REQ_STRUCT DisassocReq;
244 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
247 switch(Elem->MsgType)
249 case OID_802_11_SSID:
250 CntlOidSsidProc(pAd, Elem);
253 case OID_802_11_BSSID:
254 CntlOidRTBssidProc(pAd,Elem);
257 case OID_802_11_BSSID_LIST_SCAN:
258 CntlOidScanProc(pAd,Elem);
261 case OID_802_11_DISASSOCIATE:
262 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
263 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
264 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
266 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
268 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
269 // Since calling this indicate user don't want to connect to that SSID anymore.
270 pAd->MlmeAux.AutoReconnectSsidLen= 32;
271 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
275 case MT2_MLME_ROAMING_REQ:
276 CntlMlmeRoamingProc(pAd, Elem);
279 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
280 WpaMicFailureReportFrame(pAd, Elem);
284 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
289 VOID CntlOidScanProc(
290 IN PRTMP_ADAPTER pAd,
291 IN MLME_QUEUE_ELEM *Elem)
293 MLME_SCAN_REQ_STRUCT ScanReq;
294 ULONG BssIdx = BSS_NOT_FOUND;
297 // record current BSS if network is connected.
298 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
299 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
301 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
302 if (BssIdx != BSS_NOT_FOUND)
304 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
308 // clean up previous SCAN result, add current BSS back to table if any
309 BssTableInit(&pAd->ScanTab);
310 if (BssIdx != BSS_NOT_FOUND)
312 // DDK Note: If the NIC is associated with a particular BSSID and SSID
313 // that are not contained in the list of BSSIDs generated by this scan, the
314 // BSSID description of the currently associated BSSID and SSID should be
315 // appended to the list of BSSIDs in the NIC's database.
316 // To ensure this, we append this BSS as the first entry in SCAN result
317 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
318 pAd->ScanTab.BssNr = 1;
321 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
322 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
323 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
324 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
328 ==========================================================================
330 Before calling this routine, user desired SSID should already been
331 recorded in CommonCfg.Ssid[]
332 IRQL = DISPATCH_LEVEL
334 ==========================================================================
336 VOID CntlOidSsidProc(
337 IN PRTMP_ADAPTER pAd,
338 IN MLME_QUEUE_ELEM * Elem)
340 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
341 MLME_DISASSOC_REQ_STRUCT DisassocReq;
344 // Step 1. record the desired user settings to MlmeAux
345 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
346 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
347 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
348 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
349 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
353 // Update Reconnect Ssid, that user desired to connect.
355 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
356 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
357 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
359 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
360 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
361 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
363 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
364 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
365 NdisGetSystemUpTime(&Now);
367 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
368 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
369 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
370 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
372 // Case 1. already connected with an AP who has the desired SSID
375 // Add checking Mode "LEAP" for CCX 1.0
376 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
377 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
378 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
379 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
381 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
383 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
384 // connection process
385 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
386 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
387 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
388 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
389 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
391 else if (pAd->bConfigChanged == TRUE)
393 // case 1.2 Important Config has changed, we have to reconnect to the same AP
394 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
395 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
396 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
397 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
398 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
402 // case 1.3. already connected to the SSID with highest RSSI.
403 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
405 // (HCT 12.1) 1c_wlan_mediaevents required
406 // media connect events are indicated when associating with the same AP
411 // Since MediaState already is NdisMediaStateConnected
412 // We just indicate the connect event again to meet the WHQL required.
414 pAd->IndicateMediaState = NdisMediaStateConnected;
415 RTMP_IndicateMediaState(pAd);
416 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
419 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
422 union iwreq_data wrqu;
424 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
425 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
426 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
431 else if (INFRA_ON(pAd))
435 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
436 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
437 // But media status is connected, so the SSID not report correctly.
439 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
442 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
444 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
446 // case 2. active INFRA association existent
447 // roaming is done within miniport driver, nothing to do with configuration
448 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
449 // disassociate with the current associated AP,
450 // then perform a new association with this new SSID, no matter the
451 // new/old SSID are the same or not.
452 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
453 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
454 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
455 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
456 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
462 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
463 LinkDown(pAd, FALSE);
464 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
465 pAd->IndicateMediaState = NdisMediaStateDisconnected;
466 RTMP_IndicateMediaState(pAd);
467 pAd->ExtraInfo = GENERAL_LINK_DOWN;
468 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
471 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
472 (pAd->StaCfg.bAutoReconnect == TRUE) &&
473 (pAd->MlmeAux.BssType == BSS_INFRA) &&
474 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
477 MLME_SCAN_REQ_STRUCT ScanReq;
479 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
480 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
481 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
482 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
483 // Reset Missed scan number
484 pAd->StaCfg.LastScanTime = Now;
488 pAd->MlmeAux.BssIdx = 0;
489 IterateOnBssTab(pAd);
496 ==========================================================================
499 IRQL = DISPATCH_LEVEL
501 ==========================================================================
503 VOID CntlOidRTBssidProc(
504 IN PRTMP_ADAPTER pAd,
505 IN MLME_QUEUE_ELEM * Elem)
508 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
509 MLME_DISASSOC_REQ_STRUCT DisassocReq;
510 MLME_JOIN_REQ_STRUCT JoinReq;
512 // record user desired settings
513 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
514 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
517 // Update Reconnect Ssid, that user desired to connect.
519 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
520 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
521 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
523 // find the desired BSS in the latest SCAN result table
524 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
525 if (BssIdx == BSS_NOT_FOUND)
527 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
528 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
532 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
533 // Because we need this entry to become the JOIN target in later on SYNC state machine
534 pAd->MlmeAux.BssIdx = 0;
535 pAd->MlmeAux.SsidBssTab.BssNr = 1;
536 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
538 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
539 // we just follow normal procedure. The reason of user doing this may because he/she changed
540 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
541 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
542 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
543 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
544 // connection when setting the same BSSID.
545 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
546 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
548 // already connected to the same BSSID, go back to idle state directly
549 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
550 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
553 union iwreq_data wrqu;
555 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
556 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
557 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
565 // disassoc from current AP first
566 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
567 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
568 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
569 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
571 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
577 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
578 LinkDown(pAd, FALSE);
579 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
580 pAd->IndicateMediaState = NdisMediaStateDisconnected;
581 RTMP_IndicateMediaState(pAd);
582 pAd->ExtraInfo = GENERAL_LINK_DOWN;
583 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
586 // Change the wepstatus to original wepstatus
587 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
588 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
589 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
591 // Check cipher suite, AP must have more secured cipher than station setting
592 // Set the Pairwise and Group cipher to match the intended AP setting
593 // We can only connect to AP with less secured cipher setting
594 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
596 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
598 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
599 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
600 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
601 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
602 else // There is no PairCipher Aux, downgrade our capability to TKIP
603 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
605 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
607 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
609 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
610 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
611 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
612 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
613 else // There is no PairCipher Aux, downgrade our capability to TKIP
614 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
617 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
620 // Set Mix cipher flag
621 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
622 if (pAd->StaCfg.bMixCipher == TRUE)
624 // If mix cipher, re-build RSNIE
625 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
627 // No active association, join the BSS immediately
628 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
629 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
631 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
632 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
634 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
639 // Roaming is the only external request triggering CNTL state machine
640 // despite of other "SET OID" operation. All "SET OID" related oerations
641 // happen in sequence, because no other SET OID will be sent to this device
642 // until the the previous SET operation is complete (successful o failed).
643 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
644 // or been corrupted by other "SET OID"?
646 // IRQL = DISPATCH_LEVEL
647 VOID CntlMlmeRoamingProc(
648 IN PRTMP_ADAPTER pAd,
649 IN MLME_QUEUE_ELEM *Elem)
652 // AP in different channel may show lower RSSI than actual value??
653 // should we add a weighting factor to compensate it?
654 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
656 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
657 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
659 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
660 pAd->MlmeAux.BssIdx = 0;
661 IterateOnBssTab(pAd);
665 ==========================================================================
668 IRQL = DISPATCH_LEVEL
670 ==========================================================================
672 VOID CntlWaitDisassocProc(
673 IN PRTMP_ADAPTER pAd,
674 IN MLME_QUEUE_ELEM *Elem)
676 MLME_START_REQ_STRUCT StartReq;
678 if (Elem->MsgType == MT2_DISASSOC_CONF)
680 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
682 if (pAd->CommonCfg.bWirelessEvent)
684 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
687 LinkDown(pAd, FALSE);
689 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
690 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
692 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
693 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
694 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
695 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
697 // case 2. try each matched BSS
700 pAd->MlmeAux.BssIdx = 0;
702 IterateOnBssTab(pAd);
708 ==========================================================================
711 IRQL = DISPATCH_LEVEL
713 ==========================================================================
715 VOID CntlWaitJoinProc(
716 IN PRTMP_ADAPTER pAd,
717 IN MLME_QUEUE_ELEM *Elem)
720 MLME_AUTH_REQ_STRUCT AuthReq;
722 if (Elem->MsgType == MT2_JOIN_CONF)
724 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
725 if (Reason == MLME_SUCCESS)
727 // 1. joined an IBSS, we are pretty much done here
728 if (pAd->MlmeAux.BssType == BSS_ADHOC)
731 // 5G bands rules of Japan:
732 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
734 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
735 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
738 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
739 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
743 LinkUp(pAd, BSS_ADHOC);
744 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
745 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
746 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
747 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
749 pAd->IndicateMediaState = NdisMediaStateConnected;
750 pAd->ExtraInfo = GENERAL_LINK_UP;
752 // 2. joined a new INFRA network, start from authentication
756 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
757 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
758 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
760 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
764 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
767 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
768 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
770 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
775 // 3. failed, try next BSS
776 pAd->MlmeAux.BssIdx++;
777 IterateOnBssTab(pAd);
784 ==========================================================================
787 IRQL = DISPATCH_LEVEL
789 ==========================================================================
791 VOID CntlWaitStartProc(
792 IN PRTMP_ADAPTER pAd,
793 IN MLME_QUEUE_ELEM *Elem)
797 if (Elem->MsgType == MT2_START_CONF)
799 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
800 if (Result == MLME_SUCCESS)
803 // 5G bands rules of Japan:
804 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
806 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
807 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
810 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
811 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
815 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
819 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
820 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
821 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
822 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
823 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
824 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
826 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
827 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
829 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
831 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
832 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
834 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
839 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
841 LinkUp(pAd, BSS_ADHOC);
842 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
843 // Before send beacon, driver need do radar detection
844 if ((pAd->CommonCfg.Channel > 14 )
845 && (pAd->CommonCfg.bIEEE80211H == 1)
846 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
848 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
849 pAd->CommonCfg.RadarDetect.RDCount = 0;
852 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
853 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
854 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
858 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
859 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
865 ==========================================================================
868 IRQL = DISPATCH_LEVEL
870 ==========================================================================
872 VOID CntlWaitAuthProc(
873 IN PRTMP_ADAPTER pAd,
874 IN MLME_QUEUE_ELEM *Elem)
877 MLME_ASSOC_REQ_STRUCT AssocReq;
878 MLME_AUTH_REQ_STRUCT AuthReq;
880 if (Elem->MsgType == MT2_AUTH_CONF)
882 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
883 if (Reason == MLME_SUCCESS)
885 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
886 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
887 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
890 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
891 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
893 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
898 // This fail may because of the AP already keep us in its MAC table without
899 // ageing-out. The previous authentication attempt must have let it remove us.
900 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
901 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
904 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
905 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
907 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
908 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
912 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
915 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
916 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
918 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
924 ==========================================================================
927 IRQL = DISPATCH_LEVEL
929 ==========================================================================
931 VOID CntlWaitAuthProc2(
932 IN PRTMP_ADAPTER pAd,
933 IN MLME_QUEUE_ELEM *Elem)
936 MLME_ASSOC_REQ_STRUCT AssocReq;
937 MLME_AUTH_REQ_STRUCT AuthReq;
939 if (Elem->MsgType == MT2_AUTH_CONF)
941 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
942 if (Reason == MLME_SUCCESS)
944 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
945 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
946 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
947 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
948 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
950 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
954 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
955 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
957 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
958 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
959 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
960 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
962 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
966 // not success, try next BSS
967 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
968 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
969 pAd->MlmeAux.BssIdx++;
970 IterateOnBssTab(pAd);
977 ==========================================================================
980 IRQL = DISPATCH_LEVEL
982 ==========================================================================
984 VOID CntlWaitAssocProc(
985 IN PRTMP_ADAPTER pAd,
986 IN MLME_QUEUE_ELEM *Elem)
990 if (Elem->MsgType == MT2_ASSOC_CONF)
992 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
993 if (Reason == MLME_SUCCESS)
995 LinkUp(pAd, BSS_INFRA);
996 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
997 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
999 if (pAd->CommonCfg.bWirelessEvent)
1001 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1006 // not success, try next BSS
1007 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1008 pAd->MlmeAux.BssIdx++;
1009 IterateOnBssTab(pAd);
1015 ==========================================================================
1018 IRQL = DISPATCH_LEVEL
1020 ==========================================================================
1022 VOID CntlWaitReassocProc(
1023 IN PRTMP_ADAPTER pAd,
1024 IN MLME_QUEUE_ELEM *Elem)
1028 if (Elem->MsgType == MT2_REASSOC_CONF)
1030 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1031 if (Result == MLME_SUCCESS)
1034 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1036 LinkUp(pAd, BSS_INFRA);
1038 // send wireless event - for association
1039 if (pAd->CommonCfg.bWirelessEvent)
1040 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1042 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1043 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1047 // reassoc failed, try to pick next BSS in the BSS Table
1048 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1049 pAd->MlmeAux.RoamIdx++;
1050 IterateOnBssTab2(pAd);
1056 VOID AdhocTurnOnQos(
1057 IN PRTMP_ADAPTER pAd)
1059 #define AC0_DEF_TXOP 0
1060 #define AC1_DEF_TXOP 0
1061 #define AC2_DEF_TXOP 94
1062 #define AC3_DEF_TXOP 47
1064 // Turn on QOs if use HT rate.
1065 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1067 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1068 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1069 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1070 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1071 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1073 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1074 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1075 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1076 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1078 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1079 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1080 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1081 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1083 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1084 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1085 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1086 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1088 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1092 ==========================================================================
1095 IRQL = DISPATCH_LEVEL
1097 ==========================================================================
1100 IN PRTMP_ADAPTER pAd,
1106 UCHAR Value = 0, idx;
1107 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1109 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1112 // ASSOC - DisassocTimeoutAction
1113 // CNTL - Dis-associate successful
1114 // !!! LINK DOWN !!!
1115 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1117 // To prevent DisassocTimeoutAction to call Link down after we link up,
1118 // cancel the DisassocTimer no matter what it start or not.
1120 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1122 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1124 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1126 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1127 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1128 // to examine if cipher algorithm switching is required.
1129 //rt2860b. Don't know why need this
1130 SwitchBetweenWepAndCkip(pAd);
1133 if (BssType == BSS_ADHOC)
1135 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1136 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1138 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
1139 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
1141 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
1143 else if ((pAd->CommonCfg.Channel > 2) &&
1144 (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
1145 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
1147 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;
1531 pAd->MacTab.Content[BSSID_WCID].AuthMode = pAd->StaCfg.AuthMode;
1532 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1533 NdisReleaseSpinLock(&pAd->MacTabLock);
1535 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1536 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1538 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1539 MlmeUpdateHtTxRates(pAd, BSS0);
1540 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1542 if (pAd->CommonCfg.bAggregationCapable)
1544 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1547 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1548 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1549 RTMPSetPiggyBack(pAd, TRUE);
1550 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1552 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1554 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1558 if (pAd->MlmeAux.APRalinkIe != 0x0)
1560 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1565 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1566 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1570 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1571 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1575 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));
1578 RTMPSetLED(pAd, LED_LINK_UP);
1580 pAd->Mlme.PeriodicRound = 0;
1581 pAd->Mlme.OneSecPeriodicRound = 0;
1582 pAd->bConfigChanged = FALSE; // Reset config flag
1583 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1585 // Set asic auto fall back
1588 UCHAR TableSize = 0;
1590 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1591 AsicUpdateAutoFallBackTable(pAd, pTable);
1594 NdisAcquireSpinLock(&pAd->MacTabLock);
1595 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1596 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1597 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1599 pEntry->bAutoTxRateSwitch = FALSE;
1601 if (pEntry->HTPhyMode.field.MCS == 32)
1602 pEntry->HTPhyMode.field.ShortGI = GI_800;
1604 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1605 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1607 // If the legacy mode is set, overwrite the transmit setting of this entry.
1608 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1609 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1612 pEntry->bAutoTxRateSwitch = TRUE;
1613 NdisReleaseSpinLock(&pAd->MacTabLock);
1615 // Let Link Status Page display first initial rate.
1616 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1617 // Select DAC according to HT or Legacy
1618 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1620 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1622 if (pAd->Antenna.field.TxPath == 2)
1626 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1630 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1632 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1635 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1638 else if (pEntry->MaxRAmpduFactor == 0)
1640 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1641 // Because our Init value is 1 at MACRegTable.
1642 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1645 // Patch for Marvel AP to gain high throughput
1646 // Need to set as following,
1647 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1648 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1649 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1650 // 4. kick per two packets when dequeue
1652 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1654 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1655 if (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) &&
1656 (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
1657 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))))
1659 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1661 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1663 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1664 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1667 if (pAd->CommonCfg.bEnableTxBurst)
1669 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1672 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1673 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1675 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1676 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1680 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1682 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1684 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1685 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1688 // Re-check to turn on TX burst or not.
1689 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1691 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1692 if (pAd->CommonCfg.bEnableTxBurst)
1694 UINT32 MACValue = 0;
1695 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1696 // I didn't change PBF_MAX_PCNT setting.
1697 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1698 MACValue &= 0xFFFFFF00;
1699 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1700 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1705 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1708 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1709 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1710 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1711 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1712 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1713 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1715 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1717 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1718 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1721 NdisAcquireSpinLock(&pAd->MacTabLock);
1722 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1723 NdisReleaseSpinLock(&pAd->MacTabLock);
1726 // Patch Atheros AP TX will breakdown issue.
1727 // AP Model: DLink DWL-8200AP
1729 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1731 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1735 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1738 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1742 ==========================================================================
1744 Routine Description:
1745 Disconnect current BSSID
1748 pAd - Pointer to our adapter
1749 IsReqFromAP - Request from AP
1754 IRQL = DISPATCH_LEVEL
1757 We need more information to know it's this requst from AP.
1758 If yes! we need to do extra handling, for example, remove the WPA key.
1759 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1760 remove while auto reconnect.
1761 Disconnect request from AP, it means we will start afresh 4-way handshaking
1764 ==========================================================================
1767 IN PRTMP_ADAPTER pAd,
1768 IN BOOLEAN IsReqFromAP)
1770 UCHAR i, ByteValue = 0;
1772 // Do nothing if monitor mode is on
1773 if (MONITOR_ON(pAd))
1776 if (pAd->CommonCfg.bWirelessEvent)
1778 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1781 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1782 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1784 if (ADHOC_ON(pAd)) // Adhoc mode link down
1786 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1788 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1789 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1790 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1791 RTMP_IndicateMediaState(pAd);
1792 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1793 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1794 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1796 else // Infra structure mode
1798 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1800 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1801 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1803 // Saved last SSID for linkup comparison
1804 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1805 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
1806 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1807 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
1809 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1810 RTMP_IndicateMediaState(pAd);
1811 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1812 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1813 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1818 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
1819 // Otherwise lost beacon or receive De-Authentication from AP,
1820 // then we should delete BSSID from BssTable.
1821 // If we don't delete from entry, roaming will fail.
1823 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1826 // restore back to -
1827 // 1. long slot (20 us) or short slot (9 us) time
1828 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1829 // 3. short preamble
1830 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1832 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
1835 // Record current AP's information.
1836 // for later used reporting Adjacent AP report.
1838 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
1839 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
1840 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
1841 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
1845 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
1847 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1848 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
1851 pAd->StaCfg.CCXQosECWMin = 4;
1852 pAd->StaCfg.CCXQosECWMax = 10;
1854 AsicSetSlotTime(pAd, TRUE); //FALSE);
1855 AsicSetEdcaParm(pAd, NULL);
1858 RTMPSetLED(pAd, LED_LINK_DOWN);
1859 pAd->LedIndicatorStregth = 0xF0;
1860 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
1862 AsicDisableSync(pAd);
1864 pAd->Mlme.PeriodicRound = 0;
1865 pAd->Mlme.OneSecPeriodicRound = 0;
1867 if (pAd->StaCfg.BssType == BSS_INFRA)
1869 // Remove StaCfg Information after link down
1870 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1871 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1872 pAd->CommonCfg.SsidLen = 0;
1875 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
1876 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
1877 pAd->MlmeAux.HtCapabilityLen = 0;
1878 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1880 // Reset WPA-PSK state. Only reset when supplicant enabled
1881 if (pAd->StaCfg.WpaState != SS_NOTUSE)
1883 pAd->StaCfg.WpaState = SS_START;
1884 // Clear Replay counter
1885 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1890 // if link down come from AP, we need to remove all WPA keys on WPA mode.
1891 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
1893 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1895 // Remove all WPA keys
1896 RTMPWPARemoveAllKeys(pAd);
1899 // 802.1x port control
1901 // Prevent clear PortSecured here with static WEP
1902 // NetworkManger set security policy first then set SSID to connect AP.
1903 if (pAd->StaCfg.WpaSupplicantUP &&
1904 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1905 (pAd->StaCfg.IEEE8021X == FALSE))
1907 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1911 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1912 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1915 NdisAcquireSpinLock(&pAd->MacTabLock);
1916 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
1917 NdisReleaseSpinLock(&pAd->MacTabLock);
1919 pAd->StaCfg.MicErrCnt = 0;
1921 // Turn off Ckip control flag
1922 pAd->StaCfg.bCkipOn = FALSE;
1923 pAd->StaCfg.CCXEnable = FALSE;
1925 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1926 // Update extra information to link is up
1927 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1929 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1931 // Reset the Current AP's IP address
1932 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
1934 pAd->bUsbTxBulkAggre = FALSE;
1937 // Clean association information
1938 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
1939 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
1940 pAd->StaCfg.ReqVarIELen = 0;
1941 pAd->StaCfg.ResVarIELen = 0;
1944 // Reset RSSI value after link down
1946 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
1947 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
1948 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
1949 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
1950 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
1951 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
1954 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
1955 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
1958 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
1960 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1962 pAd->CommonCfg.BBPCurrentBW = BW_20;
1963 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
1964 ByteValue &= (~0x18);
1965 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
1969 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
1970 ByteValue &= (~0x18);
1971 if (pAd->Antenna.field.TxPath == 2)
1975 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
1977 RTMPSetPiggyBack(pAd,FALSE);
1978 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1980 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
1982 // Restore all settings in the following.
1983 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
1984 AsicDisableRDG(pAd);
1985 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
1986 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1988 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
1989 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1992 union iwreq_data wrqu;
1993 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1994 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2001 // disable MMPS BBP control register
2002 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &ByteValue);
2003 ByteValue &= ~(0x04); //bit 2
2004 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, ByteValue);
2006 // disable MMPS MAC control register
2007 RTMP_IO_READ32(pAd, 0x1210, &macdata);
2008 macdata &= ~(0x09); //bit 0, 3
2009 RTMP_IO_WRITE32(pAd, 0x1210, macdata);
2016 ==========================================================================
2019 IRQL = DISPATCH_LEVEL
2021 ==========================================================================
2023 VOID IterateOnBssTab(
2024 IN PRTMP_ADAPTER pAd)
2026 MLME_START_REQ_STRUCT StartReq;
2027 MLME_JOIN_REQ_STRUCT JoinReq;
2030 // Change the wepstatus to original wepstatus
2031 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2032 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2033 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2035 BssIdx = pAd->MlmeAux.BssIdx;
2036 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2038 // Check cipher suite, AP must have more secured cipher than station setting
2039 // Set the Pairwise and Group cipher to match the intended AP setting
2040 // We can only connect to AP with less secured cipher setting
2041 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2043 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2045 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2046 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2047 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2048 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2049 else // There is no PairCipher Aux, downgrade our capability to TKIP
2050 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2052 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2054 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2056 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2057 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2058 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2059 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2060 else // There is no PairCipher Aux, downgrade our capability to TKIP
2061 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2064 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2067 // Set Mix cipher flag
2068 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2069 if (pAd->StaCfg.bMixCipher == TRUE)
2071 // If mix cipher, re-build RSNIE
2072 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2075 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2076 JoinParmFill(pAd, &JoinReq, BssIdx);
2077 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2079 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2081 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2083 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2084 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2085 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2086 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2090 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2091 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2092 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2093 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2097 // for re-association only
2098 // IRQL = DISPATCH_LEVEL
2099 VOID IterateOnBssTab2(
2100 IN PRTMP_ADAPTER pAd)
2102 MLME_REASSOC_REQ_STRUCT ReassocReq;
2106 BssIdx = pAd->MlmeAux.RoamIdx;
2107 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2109 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2111 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2113 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2114 AsicLockChannel(pAd, pBss->Channel);
2116 // reassociate message has the same structure as associate message
2117 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2118 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2119 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2120 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2122 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2126 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2127 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2128 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2129 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2134 ==========================================================================
2137 IRQL = DISPATCH_LEVEL
2139 ==========================================================================
2142 IN PRTMP_ADAPTER pAd,
2143 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2146 JoinReq->BssIdx = BssIdx;
2150 ==========================================================================
2153 IRQL = DISPATCH_LEVEL
2155 ==========================================================================
2158 IN PRTMP_ADAPTER pAd,
2159 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2165 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2166 ScanReq->SsidLen = SsidLen;
2167 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2168 ScanReq->BssType = BssType;
2169 ScanReq->ScanType = ScanType;
2173 ==========================================================================
2176 IRQL = DISPATCH_LEVEL
2178 ==========================================================================
2181 IN PRTMP_ADAPTER pAd,
2182 IN OUT MLME_START_REQ_STRUCT *StartReq,
2186 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2187 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2188 StartReq->SsidLen = SsidLen;
2192 ==========================================================================
2195 IRQL = DISPATCH_LEVEL
2197 ==========================================================================
2200 IN PRTMP_ADAPTER pAd,
2201 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2205 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2207 AuthReq->Timeout = AUTH_TIMEOUT;
2211 ==========================================================================
2214 IRQL = DISPATCH_LEVEL
2216 ==========================================================================
2222 VOID MlmeCntlConfirm(
2223 IN PRTMP_ADAPTER pAd,
2227 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
2231 IN PRTMP_ADAPTER pAd)
2233 PTXINFO_STRUC pTxInfo;
2236 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2237 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2239 pAd->PsPollFrame.FC.PwrMgmt = 0;
2240 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2241 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2242 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2243 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2244 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2246 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
2247 pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
2248 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2249 pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2250 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
2251 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2252 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2253 // Append 4 extra zero bytes.
2254 pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
2257 // IRQL = DISPATCH_LEVEL
2258 VOID ComposeNullFrame(
2259 IN PRTMP_ADAPTER pAd)
2261 PTXINFO_STRUC pTxInfo;
2264 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2265 pAd->NullFrame.FC.Type = BTYPE_DATA;
2266 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2267 pAd->NullFrame.FC.ToDs = 1;
2268 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2269 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2270 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2271 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
2272 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
2273 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2274 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2275 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
2276 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2277 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
2278 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2284 ==========================================================================
2286 Pre-build a BEACON frame in the shared memory
2288 IRQL = PASSIVE_LEVEL
2289 IRQL = DISPATCH_LEVEL
2291 ==========================================================================
2293 ULONG MakeIbssBeacon(
2294 IN PRTMP_ADAPTER pAd)
2296 UCHAR DsLen = 1, IbssLen = 2;
2297 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2298 HEADER_802_11 BcnHdr;
2299 USHORT CapabilityInfo;
2300 LARGE_INTEGER FakeTimestamp;
2302 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2303 CHAR *pBeaconFrame = pAd->BeaconBuf;
2305 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2306 UCHAR SupRateLen = 0;
2307 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2308 UCHAR ExtRateLen = 0;
2309 UCHAR RSNIe = IE_WPA;
2311 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2313 SupRate[0] = 0x82; // 1 mbps
2314 SupRate[1] = 0x84; // 2 mbps
2315 SupRate[2] = 0x8b; // 5.5 mbps
2316 SupRate[3] = 0x96; // 11 mbps
2320 else if (pAd->CommonCfg.Channel > 14)
2322 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2323 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2324 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2325 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2326 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2327 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2328 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2329 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2334 // Also Update MlmeRate & RtsRate for G only & A only
2336 pAd->CommonCfg.MlmeRate = RATE_6;
2337 pAd->CommonCfg.RtsRate = RATE_6;
2338 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2339 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2340 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2341 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2345 SupRate[0] = 0x82; // 1 mbps
2346 SupRate[1] = 0x84; // 2 mbps
2347 SupRate[2] = 0x8b; // 5.5 mbps
2348 SupRate[3] = 0x96; // 11 mbps
2351 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2352 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2353 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2354 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2355 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2356 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2357 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2358 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2362 pAd->StaActive.SupRateLen = SupRateLen;
2363 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2364 pAd->StaActive.ExtRateLen = ExtRateLen;
2365 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2367 // compose IBSS beacon frame
2368 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2369 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2370 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2371 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2372 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2374 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2375 sizeof(HEADER_802_11), &BcnHdr,
2376 TIMESTAMP_LEN, &FakeTimestamp,
2377 2, &pAd->CommonCfg.BeaconPeriod,
2380 1, &pAd->CommonCfg.SsidLen,
2381 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2384 SupRateLen, SupRate,
2387 1, &pAd->CommonCfg.Channel,
2390 2, &pAd->StaActive.AtimWin,
2393 // add ERP_IE and EXT_RAE IE of in 802.11g
2398 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2402 ExtRateLen, ExtRate,
2407 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2408 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2411 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2413 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2415 1, &pAd->StaCfg.RSNIE_Len,
2416 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2421 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2424 UCHAR HtLen, HtLen1;
2426 // add HT Capability IE
2427 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2428 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2430 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2433 HtLen, &pAd->CommonCfg.HtCapability,
2436 HtLen1, &pAd->CommonCfg.AddHTInfo,
2442 //beacon use reserved WCID 0xff
2443 if (pAd->CommonCfg.Channel > 14)
2445 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2446 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2450 // Set to use 1Mbps for Adhoc beacon.
2451 HTTRANSMIT_SETTING Transmit;
2453 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2454 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2457 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2458 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));