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 //pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
539 //NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
541 // Add SSID into MlmeAux for site surey joining hidden SSID
542 //pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
543 //NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
545 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
546 // we just follow normal procedure. The reason of user doing this may because he/she changed
547 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
548 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
549 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
550 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
551 // connection when setting the same BSSID.
552 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
553 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
555 // already connected to the same BSSID, go back to idle state directly
556 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
557 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
560 union iwreq_data wrqu;
562 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
563 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
564 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
572 // disassoc from current AP first
573 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
574 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
575 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
576 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
578 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
584 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
585 LinkDown(pAd, FALSE);
586 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
587 pAd->IndicateMediaState = NdisMediaStateDisconnected;
588 RTMP_IndicateMediaState(pAd);
589 pAd->ExtraInfo = GENERAL_LINK_DOWN;
590 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
593 // Change the wepstatus to original wepstatus
594 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
595 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
596 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
598 // Check cipher suite, AP must have more secured cipher than station setting
599 // Set the Pairwise and Group cipher to match the intended AP setting
600 // We can only connect to AP with less secured cipher setting
601 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
603 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
605 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
606 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
607 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
608 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
609 else // There is no PairCipher Aux, downgrade our capability to TKIP
610 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
612 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
614 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
616 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
617 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
618 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
619 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
620 else // There is no PairCipher Aux, downgrade our capability to TKIP
621 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
624 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
627 // Set Mix cipher flag
628 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
629 if (pAd->StaCfg.bMixCipher == TRUE)
631 // If mix cipher, re-build RSNIE
632 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
634 // No active association, join the BSS immediately
635 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
636 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
638 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
639 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
641 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
646 // Roaming is the only external request triggering CNTL state machine
647 // despite of other "SET OID" operation. All "SET OID" related oerations
648 // happen in sequence, because no other SET OID will be sent to this device
649 // until the the previous SET operation is complete (successful o failed).
650 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
651 // or been corrupted by other "SET OID"?
653 // IRQL = DISPATCH_LEVEL
654 VOID CntlMlmeRoamingProc(
655 IN PRTMP_ADAPTER pAd,
656 IN MLME_QUEUE_ELEM *Elem)
659 // AP in different channel may show lower RSSI than actual value??
660 // should we add a weighting factor to compensate it?
661 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
663 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
664 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
666 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
667 pAd->MlmeAux.BssIdx = 0;
668 IterateOnBssTab(pAd);
672 ==========================================================================
675 IRQL = DISPATCH_LEVEL
677 ==========================================================================
679 VOID CntlWaitDisassocProc(
680 IN PRTMP_ADAPTER pAd,
681 IN MLME_QUEUE_ELEM *Elem)
683 MLME_START_REQ_STRUCT StartReq;
685 if (Elem->MsgType == MT2_DISASSOC_CONF)
687 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
689 if (pAd->CommonCfg.bWirelessEvent)
691 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
694 LinkDown(pAd, FALSE);
696 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
697 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
699 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
700 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
701 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
702 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
704 // case 2. try each matched BSS
707 pAd->MlmeAux.BssIdx = 0;
709 IterateOnBssTab(pAd);
715 ==========================================================================
718 IRQL = DISPATCH_LEVEL
720 ==========================================================================
722 VOID CntlWaitJoinProc(
723 IN PRTMP_ADAPTER pAd,
724 IN MLME_QUEUE_ELEM *Elem)
727 MLME_AUTH_REQ_STRUCT AuthReq;
729 if (Elem->MsgType == MT2_JOIN_CONF)
731 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
732 if (Reason == MLME_SUCCESS)
734 // 1. joined an IBSS, we are pretty much done here
735 if (pAd->MlmeAux.BssType == BSS_ADHOC)
738 // 5G bands rules of Japan:
739 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
741 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
742 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
745 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
746 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
750 LinkUp(pAd, BSS_ADHOC);
751 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
752 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
753 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
754 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
756 pAd->IndicateMediaState = NdisMediaStateConnected;
757 pAd->ExtraInfo = GENERAL_LINK_UP;
759 // 2. joined a new INFRA network, start from authentication
763 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
764 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
765 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
767 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
771 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
774 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
775 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
777 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
782 // 3. failed, try next BSS
783 pAd->MlmeAux.BssIdx++;
784 IterateOnBssTab(pAd);
791 ==========================================================================
794 IRQL = DISPATCH_LEVEL
796 ==========================================================================
798 VOID CntlWaitStartProc(
799 IN PRTMP_ADAPTER pAd,
800 IN MLME_QUEUE_ELEM *Elem)
804 if (Elem->MsgType == MT2_START_CONF)
806 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
807 if (Result == MLME_SUCCESS)
810 // 5G bands rules of Japan:
811 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
813 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
814 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
817 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
818 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
821 #ifdef DOT11_N_SUPPORT
822 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
826 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
827 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
828 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
829 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
830 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
831 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
833 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
834 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
836 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
838 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
839 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
841 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
845 #endif // DOT11_N_SUPPORT //
847 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
849 LinkUp(pAd, BSS_ADHOC);
850 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
851 // Before send beacon, driver need do radar detection
852 if ((pAd->CommonCfg.Channel > 14 )
853 && (pAd->CommonCfg.bIEEE80211H == 1)
854 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
856 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
857 pAd->CommonCfg.RadarDetect.RDCount = 0;
860 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
861 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
862 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
866 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
867 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
873 ==========================================================================
876 IRQL = DISPATCH_LEVEL
878 ==========================================================================
880 VOID CntlWaitAuthProc(
881 IN PRTMP_ADAPTER pAd,
882 IN MLME_QUEUE_ELEM *Elem)
885 MLME_ASSOC_REQ_STRUCT AssocReq;
886 MLME_AUTH_REQ_STRUCT AuthReq;
888 if (Elem->MsgType == MT2_AUTH_CONF)
890 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
891 if (Reason == MLME_SUCCESS)
893 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
894 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
895 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
898 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
899 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
901 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
906 // This fail may because of the AP already keep us in its MAC table without
907 // ageing-out. The previous authentication attempt must have let it remove us.
908 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
909 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
912 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
913 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
915 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
916 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
920 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
923 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
924 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
926 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
932 ==========================================================================
935 IRQL = DISPATCH_LEVEL
937 ==========================================================================
939 VOID CntlWaitAuthProc2(
940 IN PRTMP_ADAPTER pAd,
941 IN MLME_QUEUE_ELEM *Elem)
944 MLME_ASSOC_REQ_STRUCT AssocReq;
945 MLME_AUTH_REQ_STRUCT AuthReq;
947 if (Elem->MsgType == MT2_AUTH_CONF)
949 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
950 if (Reason == MLME_SUCCESS)
952 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
953 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
954 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
955 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
956 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
958 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
962 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
963 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
965 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
966 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
967 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
968 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
970 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
974 // not success, try next BSS
975 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
976 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
977 pAd->MlmeAux.BssIdx++;
978 IterateOnBssTab(pAd);
985 ==========================================================================
988 IRQL = DISPATCH_LEVEL
990 ==========================================================================
992 VOID CntlWaitAssocProc(
993 IN PRTMP_ADAPTER pAd,
994 IN MLME_QUEUE_ELEM *Elem)
998 if (Elem->MsgType == MT2_ASSOC_CONF)
1000 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1001 if (Reason == MLME_SUCCESS)
1003 LinkUp(pAd, BSS_INFRA);
1004 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1005 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1007 if (pAd->CommonCfg.bWirelessEvent)
1009 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1014 // not success, try next BSS
1015 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1016 pAd->MlmeAux.BssIdx++;
1017 IterateOnBssTab(pAd);
1023 ==========================================================================
1026 IRQL = DISPATCH_LEVEL
1028 ==========================================================================
1030 VOID CntlWaitReassocProc(
1031 IN PRTMP_ADAPTER pAd,
1032 IN MLME_QUEUE_ELEM *Elem)
1036 if (Elem->MsgType == MT2_REASSOC_CONF)
1038 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1039 if (Result == MLME_SUCCESS)
1042 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1044 LinkUp(pAd, BSS_INFRA);
1046 // send wireless event - for association
1047 if (pAd->CommonCfg.bWirelessEvent)
1048 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1050 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1051 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1055 // reassoc failed, try to pick next BSS in the BSS Table
1056 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1057 pAd->MlmeAux.RoamIdx++;
1058 IterateOnBssTab2(pAd);
1064 VOID AdhocTurnOnQos(
1065 IN PRTMP_ADAPTER pAd)
1067 #define AC0_DEF_TXOP 0
1068 #define AC1_DEF_TXOP 0
1069 #define AC2_DEF_TXOP 94
1070 #define AC3_DEF_TXOP 47
1072 // Turn on QOs if use HT rate.
1073 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1075 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1076 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1077 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1078 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1079 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1081 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1082 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1083 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1084 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1086 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1087 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1088 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1089 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1091 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1092 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1093 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1094 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1096 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1100 ==========================================================================
1103 IRQL = DISPATCH_LEVEL
1105 ==========================================================================
1108 IN PRTMP_ADAPTER pAd,
1114 UCHAR Value = 0, idx;
1115 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1117 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1120 // ASSOC - DisassocTimeoutAction
1121 // CNTL - Dis-associate successful
1122 // !!! LINK DOWN !!!
1123 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1125 // To prevent DisassocTimeoutAction to call Link down after we link up,
1126 // cancel the DisassocTimer no matter what it start or not.
1128 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1130 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1132 #ifdef DOT11_N_SUPPORT
1133 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1134 #endif // DOT11_N_SUPPORT //
1135 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1136 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1137 // to examine if cipher algorithm switching is required.
1138 //rt2860b. Don't know why need this
1139 SwitchBetweenWepAndCkip(pAd);
1142 if (BssType == BSS_ADHOC)
1144 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1145 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1147 #ifdef DOT11_N_SUPPORT
1148 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
1149 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
1151 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
1153 else if ((pAd->CommonCfg.Channel > 2) &&
1154 (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
1155 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
1157 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
1159 #endif // DOT11_N_SUPPORT //
1161 #ifdef DOT11_N_SUPPORT
1162 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1163 AdhocTurnOnQos(pAd);
1164 #endif // DOT11_N_SUPPORT //
1166 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1170 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1171 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1173 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1177 // reset Tx beamforming bit
1178 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1180 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1181 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1183 #ifdef DOT11_N_SUPPORT
1184 // Change to AP channel
1185 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1187 // Must using 40MHz.
1188 pAd->CommonCfg.BBPCurrentBW = BW_40;
1189 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1190 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1192 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1195 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1197 // RX : control channel at lower
1198 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1200 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1202 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1204 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1206 if (pAd->MACVersion == 0x28600100)
1208 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1209 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1210 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1211 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1214 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1216 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1218 // Must using 40MHz.
1219 pAd->CommonCfg.BBPCurrentBW = BW_40;
1220 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1221 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1223 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1226 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1228 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1230 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1232 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1234 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1236 if (pAd->MACVersion == 0x28600100)
1238 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1239 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1240 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1241 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1244 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1247 #endif // DOT11_N_SUPPORT //
1249 pAd->CommonCfg.BBPCurrentBW = BW_20;
1250 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1251 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1252 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1254 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1256 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1258 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1260 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1262 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1264 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1266 if (pAd->MACVersion == 0x28600100)
1268 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1269 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1270 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1271 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1274 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1277 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1279 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1281 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1283 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1284 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1286 #ifdef DOT11_N_SUPPORT
1287 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1288 #endif // DOT11_N_SUPPORT //
1290 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1292 AsicSetSlotTime(pAd, TRUE);
1293 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1295 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1296 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1298 #ifdef DOT11_N_SUPPORT
1299 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1301 // Update HT protectionfor based on AP's operating mode.
1302 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1304 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1307 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1309 #endif // DOT11_N_SUPPORT //
1311 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1313 NdisGetSystemUpTime(&Now);
1314 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1316 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1317 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1319 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1322 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1324 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1327 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1329 if (BssType == BSS_ADHOC)
1331 MakeIbssBeacon(pAd);
1332 if ((pAd->CommonCfg.Channel > 14)
1333 && (pAd->CommonCfg.bIEEE80211H == 1)
1334 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1340 AsicEnableIbssSync(pAd);
1343 // In ad hoc mode, use MAC table from index 1.
1344 // 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.
1345 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1346 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1348 // If WEP is enabled, add key material and cipherAlg into Asic
1349 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1351 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1356 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1358 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1359 Key = pAd->SharedKey[BSS0][idx].Key;
1361 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1363 // Set key material and cipherAlg to Asic
1364 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1366 if (idx == pAd->StaCfg.DefaultKeyId)
1368 // Update WCID attribute table and IVEIV table for this group key table
1369 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1376 // If WPANone is enabled, add key material and cipherAlg into Asic
1377 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1378 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1380 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1382 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1383 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1384 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1386 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1388 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1389 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1392 // Decide its ChiperAlg
1393 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1394 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1395 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1396 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1399 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1400 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1403 // Set key material and cipherAlg to Asic
1404 AsicAddSharedKeyEntry(pAd,
1407 pAd->SharedKey[BSS0][0].CipherAlg,
1408 pAd->SharedKey[BSS0][0].Key,
1409 pAd->SharedKey[BSS0][0].TxMic,
1410 pAd->SharedKey[BSS0][0].RxMic);
1412 // Update WCID attribute table and IVEIV table for this group key table
1413 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1420 // Check the new SSID with last SSID
1421 while (Cancelled == TRUE)
1423 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1425 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1427 // Link to the old one no linkdown is required.
1431 // Send link down event before set to link up
1432 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1433 RTMP_IndicateMediaState(pAd);
1434 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1435 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1440 // On WPA mode, Remove All Keys if not connect to the last BSSID
1441 // Key will be set after 4-way handshake.
1443 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1447 // Remove all WPA keys
1448 RTMPWPARemoveAllKeys(pAd);
1449 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1450 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1452 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1453 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1455 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1456 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1459 // the decision of using "short slot time" or not may change dynamically due to
1460 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1463 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1464 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1467 ComposeNullFrame(pAd);
1469 AsicEnableBssSync(pAd);
1471 // Add BSSID to WCID search table
1472 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1474 NdisAcquireSpinLock(&pAd->MacTabLock);
1475 // add this BSSID entry into HASH table
1479 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1480 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1481 if (pAd->MacTab.Hash[HashIdx] == NULL)
1483 pAd->MacTab.Hash[HashIdx] = pEntry;
1487 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1488 while (pCurrEntry->pNext != NULL)
1489 pCurrEntry = pCurrEntry->pNext;
1490 pCurrEntry->pNext = pEntry;
1493 NdisReleaseSpinLock(&pAd->MacTabLock);
1496 // If WEP is enabled, add paiewise and shared key
1497 if (((pAd->StaCfg.WpaSupplicantUP)&&
1498 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1499 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1500 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1501 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1506 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1508 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1509 Key = pAd->SharedKey[BSS0][idx].Key;
1511 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1513 // Set key material and cipherAlg to Asic
1514 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1516 if (idx == pAd->StaCfg.DefaultKeyId)
1518 // Assign group key info
1519 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1521 // Assign pairwise key info
1522 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1528 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1529 // should wait until at least 2 active nodes in this BSSID.
1530 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1533 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1535 pAd->IndicateMediaState = NdisMediaStateConnected;
1536 pAd->ExtraInfo = GENERAL_LINK_UP;
1537 RTMP_IndicateMediaState(pAd);
1541 // Add BSSID in my MAC Table.
1542 NdisAcquireSpinLock(&pAd->MacTabLock);
1543 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1544 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1545 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1546 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1547 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1548 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1549 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1550 pAd->MacTab.Content[BSSID_WCID].AuthMode = pAd->StaCfg.AuthMode;
1551 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1552 NdisReleaseSpinLock(&pAd->MacTabLock);
1554 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1555 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1557 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1558 #ifdef DOT11_N_SUPPORT
1559 MlmeUpdateHtTxRates(pAd, BSS0);
1560 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1561 #endif // DOT11_N_SUPPORT //
1563 if (pAd->CommonCfg.bAggregationCapable)
1565 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1568 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1569 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1570 RTMPSetPiggyBack(pAd, TRUE);
1571 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1573 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1575 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1579 if (pAd->MlmeAux.APRalinkIe != 0x0)
1581 #ifdef DOT11_N_SUPPORT
1582 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1586 #endif // DOT11_N_SUPPORT //
1587 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1588 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1592 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1593 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1597 #ifdef DOT11_N_SUPPORT
1598 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));
1599 #endif // DOT11_N_SUPPORT //
1602 RTMPSetLED(pAd, LED_LINK_UP);
1604 pAd->Mlme.PeriodicRound = 0;
1605 pAd->Mlme.OneSecPeriodicRound = 0;
1606 pAd->bConfigChanged = FALSE; // Reset config flag
1607 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1609 // Set asic auto fall back
1612 UCHAR TableSize = 0;
1614 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1615 AsicUpdateAutoFallBackTable(pAd, pTable);
1618 NdisAcquireSpinLock(&pAd->MacTabLock);
1619 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1620 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1621 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1623 pEntry->bAutoTxRateSwitch = FALSE;
1624 #ifdef DOT11_N_SUPPORT
1625 if (pEntry->HTPhyMode.field.MCS == 32)
1626 pEntry->HTPhyMode.field.ShortGI = GI_800;
1628 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1629 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1630 #endif // DOT11_N_SUPPORT //
1631 // If the legacy mode is set, overwrite the transmit setting of this entry.
1632 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1633 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1636 pEntry->bAutoTxRateSwitch = TRUE;
1637 NdisReleaseSpinLock(&pAd->MacTabLock);
1639 // Let Link Status Page display first initial rate.
1640 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1641 // Select DAC according to HT or Legacy
1642 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1644 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1646 if (pAd->Antenna.field.TxPath == 2)
1650 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1654 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1656 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1659 #ifdef DOT11_N_SUPPORT
1660 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1663 else if (pEntry->MaxRAmpduFactor == 0)
1665 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1666 // Because our Init value is 1 at MACRegTable.
1667 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1669 #endif // DOT11_N_SUPPORT //
1671 // Patch for Marvel AP to gain high throughput
1672 // Need to set as following,
1673 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1674 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1675 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1676 // 4. kick per two packets when dequeue
1678 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1680 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1681 #ifdef DOT11_N_SUPPORT
1682 // if ((!IS_RT30xx(pAd)) &&
1683 if (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) &&
1684 (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
1685 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))))
1687 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1689 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1691 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1692 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1695 #endif // DOT11_N_SUPPORT //
1696 if (pAd->CommonCfg.bEnableTxBurst)
1698 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1701 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1702 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1704 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1705 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1709 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1711 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1713 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1714 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1717 #ifdef DOT11_N_SUPPORT
1718 // Re-check to turn on TX burst or not.
1719 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1721 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1722 if (pAd->CommonCfg.bEnableTxBurst)
1724 UINT32 MACValue = 0;
1725 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1726 // I didn't change PBF_MAX_PCNT setting.
1727 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1728 MACValue &= 0xFFFFFF00;
1729 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1730 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1735 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1737 #endif // DOT11_N_SUPPORT //
1739 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1740 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1741 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1742 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1743 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1744 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1746 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1748 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1749 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1752 NdisAcquireSpinLock(&pAd->MacTabLock);
1753 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1754 NdisReleaseSpinLock(&pAd->MacTabLock);
1757 // Patch Atheros AP TX will breakdown issue.
1758 // AP Model: DLink DWL-8200AP
1760 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1762 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1766 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1769 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1773 ==========================================================================
1775 Routine Description:
1776 Disconnect current BSSID
1779 pAd - Pointer to our adapter
1780 IsReqFromAP - Request from AP
1785 IRQL = DISPATCH_LEVEL
1788 We need more information to know it's this requst from AP.
1789 If yes! we need to do extra handling, for example, remove the WPA key.
1790 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1791 remove while auto reconnect.
1792 Disconnect request from AP, it means we will start afresh 4-way handshaking
1795 ==========================================================================
1798 IN PRTMP_ADAPTER pAd,
1799 IN BOOLEAN IsReqFromAP)
1801 UCHAR i, ByteValue = 0;
1803 // Do nothing if monitor mode is on
1804 if (MONITOR_ON(pAd))
1807 if (pAd->CommonCfg.bWirelessEvent)
1809 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1812 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1813 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1815 if (ADHOC_ON(pAd)) // Adhoc mode link down
1817 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1819 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1820 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1821 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1822 RTMP_IndicateMediaState(pAd);
1823 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1824 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1825 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1827 else // Infra structure mode
1829 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1831 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1832 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1834 // Saved last SSID for linkup comparison
1835 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1836 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
1837 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1838 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
1840 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1841 RTMP_IndicateMediaState(pAd);
1842 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1843 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1844 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1849 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
1850 // Otherwise lost beacon or receive De-Authentication from AP,
1851 // then we should delete BSSID from BssTable.
1852 // If we don't delete from entry, roaming will fail.
1854 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1857 // restore back to -
1858 // 1. long slot (20 us) or short slot (9 us) time
1859 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1860 // 3. short preamble
1861 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1863 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
1866 // Record current AP's information.
1867 // for later used reporting Adjacent AP report.
1869 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
1870 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
1871 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
1872 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
1876 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
1878 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1879 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
1882 pAd->StaCfg.CCXQosECWMin = 4;
1883 pAd->StaCfg.CCXQosECWMax = 10;
1885 AsicSetSlotTime(pAd, TRUE); //FALSE);
1886 AsicSetEdcaParm(pAd, NULL);
1889 RTMPSetLED(pAd, LED_LINK_DOWN);
1890 pAd->LedIndicatorStregth = 0xF0;
1891 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
1893 AsicDisableSync(pAd);
1895 pAd->Mlme.PeriodicRound = 0;
1896 pAd->Mlme.OneSecPeriodicRound = 0;
1898 if (pAd->StaCfg.BssType == BSS_INFRA)
1900 // Remove StaCfg Information after link down
1901 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1902 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1903 pAd->CommonCfg.SsidLen = 0;
1905 #ifdef DOT11_N_SUPPORT
1906 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
1907 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
1908 pAd->MlmeAux.HtCapabilityLen = 0;
1909 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1910 #endif // DOT11_N_SUPPORT //
1912 // Reset WPA-PSK state. Only reset when supplicant enabled
1913 if (pAd->StaCfg.WpaState != SS_NOTUSE)
1915 pAd->StaCfg.WpaState = SS_START;
1916 // Clear Replay counter
1917 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1922 // if link down come from AP, we need to remove all WPA keys on WPA mode.
1923 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
1925 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1927 // Remove all WPA keys
1928 RTMPWPARemoveAllKeys(pAd);
1931 // 802.1x port control
1933 // Prevent clear PortSecured here with static WEP
1934 // NetworkManger set security policy first then set SSID to connect AP.
1935 if (pAd->StaCfg.WpaSupplicantUP &&
1936 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1937 (pAd->StaCfg.IEEE8021X == FALSE))
1939 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1943 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1944 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1947 NdisAcquireSpinLock(&pAd->MacTabLock);
1948 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
1949 NdisReleaseSpinLock(&pAd->MacTabLock);
1951 pAd->StaCfg.MicErrCnt = 0;
1953 // Turn off Ckip control flag
1954 pAd->StaCfg.bCkipOn = FALSE;
1955 pAd->StaCfg.CCXEnable = FALSE;
1957 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1958 // Update extra information to link is up
1959 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1961 //pAd->StaCfg.AdhocBOnlyJoined = FALSE;
1962 //pAd->StaCfg.AdhocBGJoined = FALSE;
1963 //pAd->StaCfg.Adhoc20NJoined = FALSE;
1964 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1966 // Reset the Current AP's IP address
1967 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
1969 pAd->bUsbTxBulkAggre = FALSE;
1972 // Clean association information
1973 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
1974 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
1975 pAd->StaCfg.ReqVarIELen = 0;
1976 pAd->StaCfg.ResVarIELen = 0;
1979 // Reset RSSI value after link down
1981 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
1982 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
1983 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
1984 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
1985 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
1986 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
1989 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
1990 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
1992 #ifdef DOT11_N_SUPPORT
1994 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
1996 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1998 pAd->CommonCfg.BBPCurrentBW = BW_20;
1999 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2000 ByteValue &= (~0x18);
2001 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2003 #endif // DOT11_N_SUPPORT //
2005 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2006 ByteValue &= (~0x18);
2007 if (pAd->Antenna.field.TxPath == 2)
2011 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2013 RTMPSetPiggyBack(pAd,FALSE);
2014 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2016 #ifdef DOT11_N_SUPPORT
2017 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2018 #endif // DOT11_N_SUPPORT //
2020 // Restore all settings in the following.
2021 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2022 AsicDisableRDG(pAd);
2023 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2024 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2026 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2027 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2030 union iwreq_data wrqu;
2031 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2032 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2039 // disable MMPS BBP control register
2040 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &ByteValue);
2041 ByteValue &= ~(0x04); //bit 2
2042 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, ByteValue);
2044 // disable MMPS MAC control register
2045 RTMP_IO_READ32(pAd, 0x1210, &macdata);
2046 macdata &= ~(0x09); //bit 0, 3
2047 RTMP_IO_WRITE32(pAd, 0x1210, macdata);
2054 ==========================================================================
2057 IRQL = DISPATCH_LEVEL
2059 ==========================================================================
2061 VOID IterateOnBssTab(
2062 IN PRTMP_ADAPTER pAd)
2064 MLME_START_REQ_STRUCT StartReq;
2065 MLME_JOIN_REQ_STRUCT JoinReq;
2068 // Change the wepstatus to original wepstatus
2069 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2070 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2071 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2073 BssIdx = pAd->MlmeAux.BssIdx;
2074 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2076 // Check cipher suite, AP must have more secured cipher than station setting
2077 // Set the Pairwise and Group cipher to match the intended AP setting
2078 // We can only connect to AP with less secured cipher setting
2079 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2081 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2083 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2084 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2085 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2086 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2087 else // There is no PairCipher Aux, downgrade our capability to TKIP
2088 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2090 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2092 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2094 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2095 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2096 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2097 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2098 else // There is no PairCipher Aux, downgrade our capability to TKIP
2099 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2102 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2105 // Set Mix cipher flag
2106 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2107 if (pAd->StaCfg.bMixCipher == TRUE)
2109 // If mix cipher, re-build RSNIE
2110 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2113 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2114 JoinParmFill(pAd, &JoinReq, BssIdx);
2115 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2117 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2119 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2121 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2122 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2123 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2124 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2128 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2129 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2130 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2131 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2135 // for re-association only
2136 // IRQL = DISPATCH_LEVEL
2137 VOID IterateOnBssTab2(
2138 IN PRTMP_ADAPTER pAd)
2140 MLME_REASSOC_REQ_STRUCT ReassocReq;
2144 BssIdx = pAd->MlmeAux.RoamIdx;
2145 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2147 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2149 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2151 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2152 AsicLockChannel(pAd, pBss->Channel);
2154 // reassociate message has the same structure as associate message
2155 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2156 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2157 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2158 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2160 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2164 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2165 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2166 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2167 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2172 ==========================================================================
2175 IRQL = DISPATCH_LEVEL
2177 ==========================================================================
2180 IN PRTMP_ADAPTER pAd,
2181 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2184 JoinReq->BssIdx = BssIdx;
2188 ==========================================================================
2191 IRQL = DISPATCH_LEVEL
2193 ==========================================================================
2196 IN PRTMP_ADAPTER pAd,
2197 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2203 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2204 ScanReq->SsidLen = SsidLen;
2205 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2206 ScanReq->BssType = BssType;
2207 ScanReq->ScanType = ScanType;
2211 ==========================================================================
2214 IRQL = DISPATCH_LEVEL
2216 ==========================================================================
2219 IN PRTMP_ADAPTER pAd,
2220 IN OUT MLME_START_REQ_STRUCT *StartReq,
2224 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2225 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2226 StartReq->SsidLen = SsidLen;
2230 ==========================================================================
2233 IRQL = DISPATCH_LEVEL
2235 ==========================================================================
2238 IN PRTMP_ADAPTER pAd,
2239 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2243 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2245 AuthReq->Timeout = AUTH_TIMEOUT;
2249 ==========================================================================
2252 IRQL = DISPATCH_LEVEL
2254 ==========================================================================
2260 VOID MlmeCntlConfirm(
2261 IN PRTMP_ADAPTER pAd,
2265 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
2269 IN PRTMP_ADAPTER pAd)
2271 PTXINFO_STRUC pTxInfo;
2274 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2275 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2277 pAd->PsPollFrame.FC.PwrMgmt = 0;
2278 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2279 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2280 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2281 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2282 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2284 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
2285 pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
2286 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2287 pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2288 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
2289 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2290 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2291 // Append 4 extra zero bytes.
2292 pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
2295 // IRQL = DISPATCH_LEVEL
2296 VOID ComposeNullFrame(
2297 IN PRTMP_ADAPTER pAd)
2299 PTXINFO_STRUC pTxInfo;
2302 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2303 pAd->NullFrame.FC.Type = BTYPE_DATA;
2304 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2305 pAd->NullFrame.FC.ToDs = 1;
2306 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2307 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2308 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2309 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
2310 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
2311 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2312 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2313 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
2314 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2315 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
2316 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2322 ==========================================================================
2324 Pre-build a BEACON frame in the shared memory
2326 IRQL = PASSIVE_LEVEL
2327 IRQL = DISPATCH_LEVEL
2329 ==========================================================================
2331 ULONG MakeIbssBeacon(
2332 IN PRTMP_ADAPTER pAd)
2334 UCHAR DsLen = 1, IbssLen = 2;
2335 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2336 HEADER_802_11 BcnHdr;
2337 USHORT CapabilityInfo;
2338 LARGE_INTEGER FakeTimestamp;
2340 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2341 CHAR *pBeaconFrame = pAd->BeaconBuf;
2343 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2344 UCHAR SupRateLen = 0;
2345 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2346 UCHAR ExtRateLen = 0;
2347 UCHAR RSNIe = IE_WPA;
2349 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2351 SupRate[0] = 0x82; // 1 mbps
2352 SupRate[1] = 0x84; // 2 mbps
2353 SupRate[2] = 0x8b; // 5.5 mbps
2354 SupRate[3] = 0x96; // 11 mbps
2358 else if (pAd->CommonCfg.Channel > 14)
2360 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2361 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2362 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2363 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2364 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2365 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2366 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2367 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2372 // Also Update MlmeRate & RtsRate for G only & A only
2374 pAd->CommonCfg.MlmeRate = RATE_6;
2375 pAd->CommonCfg.RtsRate = RATE_6;
2376 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2377 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2378 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2379 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2383 SupRate[0] = 0x82; // 1 mbps
2384 SupRate[1] = 0x84; // 2 mbps
2385 SupRate[2] = 0x8b; // 5.5 mbps
2386 SupRate[3] = 0x96; // 11 mbps
2389 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2390 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2391 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2392 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2393 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2394 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2395 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2396 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2400 pAd->StaActive.SupRateLen = SupRateLen;
2401 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2402 pAd->StaActive.ExtRateLen = ExtRateLen;
2403 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2405 // compose IBSS beacon frame
2406 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2407 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2408 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2409 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2410 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2412 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2413 sizeof(HEADER_802_11), &BcnHdr,
2414 TIMESTAMP_LEN, &FakeTimestamp,
2415 2, &pAd->CommonCfg.BeaconPeriod,
2418 1, &pAd->CommonCfg.SsidLen,
2419 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2422 SupRateLen, SupRate,
2425 1, &pAd->CommonCfg.Channel,
2428 2, &pAd->StaActive.AtimWin,
2431 // add ERP_IE and EXT_RAE IE of in 802.11g
2436 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2440 ExtRateLen, ExtRate,
2445 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2446 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2449 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2451 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2453 1, &pAd->StaCfg.RSNIE_Len,
2454 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2459 #ifdef DOT11_N_SUPPORT
2460 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2463 UCHAR HtLen, HtLen1;
2465 // add HT Capability IE
2466 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2467 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2469 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2472 HtLen, &pAd->CommonCfg.HtCapability,
2475 HtLen1, &pAd->CommonCfg.AddHTInfo,
2480 #endif // DOT11_N_SUPPORT //
2482 //beacon use reserved WCID 0xff
2483 if (pAd->CommonCfg.Channel > 14)
2485 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2486 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2490 // Set to use 1Mbps for Adhoc beacon.
2491 HTTRANSMIT_SETTING Transmit;
2493 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2494 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2497 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2498 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));