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;
192 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
199 ==========================================================================
202 IRQL = DISPATCH_LEVEL
204 ==========================================================================
207 IN PRTMP_ADAPTER pAd,
208 IN MLME_QUEUE_ELEM *Elem)
210 MLME_DISASSOC_REQ_STRUCT DisassocReq;
212 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
215 switch(Elem->MsgType)
217 case OID_802_11_SSID:
218 CntlOidSsidProc(pAd, Elem);
221 case OID_802_11_BSSID:
222 CntlOidRTBssidProc(pAd,Elem);
225 case OID_802_11_BSSID_LIST_SCAN:
226 CntlOidScanProc(pAd,Elem);
229 case OID_802_11_DISASSOCIATE:
230 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
231 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
232 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
234 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
236 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
237 // Since calling this indicate user don't want to connect to that SSID anymore.
238 pAd->MlmeAux.AutoReconnectSsidLen= 32;
239 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
243 case MT2_MLME_ROAMING_REQ:
244 CntlMlmeRoamingProc(pAd, Elem);
247 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
248 WpaMicFailureReportFrame(pAd, Elem);
252 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
257 VOID CntlOidScanProc(
258 IN PRTMP_ADAPTER pAd,
259 IN MLME_QUEUE_ELEM *Elem)
261 MLME_SCAN_REQ_STRUCT ScanReq;
262 ULONG BssIdx = BSS_NOT_FOUND;
265 // record current BSS if network is connected.
266 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
267 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
269 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
270 if (BssIdx != BSS_NOT_FOUND)
272 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
276 // clean up previous SCAN result, add current BSS back to table if any
277 BssTableInit(&pAd->ScanTab);
278 if (BssIdx != BSS_NOT_FOUND)
280 // DDK Note: If the NIC is associated with a particular BSSID and SSID
281 // that are not contained in the list of BSSIDs generated by this scan, the
282 // BSSID description of the currently associated BSSID and SSID should be
283 // appended to the list of BSSIDs in the NIC's database.
284 // To ensure this, we append this BSS as the first entry in SCAN result
285 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
286 pAd->ScanTab.BssNr = 1;
289 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
290 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
291 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
292 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
296 ==========================================================================
298 Before calling this routine, user desired SSID should already been
299 recorded in CommonCfg.Ssid[]
300 IRQL = DISPATCH_LEVEL
302 ==========================================================================
304 VOID CntlOidSsidProc(
305 IN PRTMP_ADAPTER pAd,
306 IN MLME_QUEUE_ELEM * Elem)
308 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
309 MLME_DISASSOC_REQ_STRUCT DisassocReq;
312 // BBP and RF are not accessible in PS mode, we has to wake them up first
313 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
314 AsicForceWakeup(pAd, RTMP_HALT);
316 // Step 1. record the desired user settings to MlmeAux
317 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
318 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
319 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
320 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
321 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
325 // Update Reconnect Ssid, that user desired to connect.
327 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
328 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
329 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
331 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
332 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
333 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
335 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
336 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
337 NdisGetSystemUpTime(&Now);
339 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
340 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
341 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
342 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
344 // Case 1. already connected with an AP who has the desired SSID
347 // Add checking Mode "LEAP" for CCX 1.0
348 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
349 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
350 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
351 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
353 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
355 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
356 // connection process
357 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
358 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
359 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
360 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
361 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
363 else if (pAd->bConfigChanged == TRUE)
365 // case 1.2 Important Config has changed, we have to reconnect to the same AP
366 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
367 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
368 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
369 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
370 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
374 // case 1.3. already connected to the SSID with highest RSSI.
375 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
377 // (HCT 12.1) 1c_wlan_mediaevents required
378 // media connect events are indicated when associating with the same AP
383 // Since MediaState already is NdisMediaStateConnected
384 // We just indicate the connect event again to meet the WHQL required.
386 pAd->IndicateMediaState = NdisMediaStateConnected;
387 RTMP_IndicateMediaState(pAd);
388 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
391 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
394 union iwreq_data wrqu;
396 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
397 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
398 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
403 else if (INFRA_ON(pAd))
407 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
408 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
409 // But media status is connected, so the SSID not report correctly.
411 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
414 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
416 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
418 // case 2. active INFRA association existent
419 // roaming is done within miniport driver, nothing to do with configuration
420 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
421 // disassociate with the current associated AP,
422 // then perform a new association with this new SSID, no matter the
423 // new/old SSID are the same or not.
424 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
425 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
426 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
427 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
428 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
434 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
435 LinkDown(pAd, FALSE);
436 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
437 pAd->IndicateMediaState = NdisMediaStateDisconnected;
438 RTMP_IndicateMediaState(pAd);
439 pAd->ExtraInfo = GENERAL_LINK_DOWN;
440 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
443 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
444 (pAd->StaCfg.bAutoReconnect == TRUE) &&
445 (pAd->MlmeAux.BssType == BSS_INFRA) &&
446 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
449 MLME_SCAN_REQ_STRUCT ScanReq;
451 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
452 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
453 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
454 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
455 // Reset Missed scan number
456 pAd->StaCfg.LastScanTime = Now;
460 pAd->MlmeAux.BssIdx = 0;
461 IterateOnBssTab(pAd);
468 ==========================================================================
471 IRQL = DISPATCH_LEVEL
473 ==========================================================================
475 VOID CntlOidRTBssidProc(
476 IN PRTMP_ADAPTER pAd,
477 IN MLME_QUEUE_ELEM * Elem)
480 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
481 MLME_DISASSOC_REQ_STRUCT DisassocReq;
482 MLME_JOIN_REQ_STRUCT JoinReq;
484 // record user desired settings
485 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
486 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
489 // Update Reconnect Ssid, that user desired to connect.
491 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
492 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
493 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
495 // find the desired BSS in the latest SCAN result table
496 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
497 if (BssIdx == BSS_NOT_FOUND)
499 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
500 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
504 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
505 // Because we need this entry to become the JOIN target in later on SYNC state machine
506 pAd->MlmeAux.BssIdx = 0;
507 pAd->MlmeAux.SsidBssTab.BssNr = 1;
508 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
510 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
511 // we just follow normal procedure. The reason of user doing this may because he/she changed
512 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
513 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
514 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
515 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
516 // connection when setting the same BSSID.
517 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
518 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
520 // already connected to the same BSSID, go back to idle state directly
521 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
522 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
525 union iwreq_data wrqu;
527 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
528 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
529 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
537 // disassoc from current AP first
538 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
539 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
540 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
541 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
543 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
549 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
550 LinkDown(pAd, FALSE);
551 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
552 pAd->IndicateMediaState = NdisMediaStateDisconnected;
553 RTMP_IndicateMediaState(pAd);
554 pAd->ExtraInfo = GENERAL_LINK_DOWN;
555 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
558 // Change the wepstatus to original wepstatus
559 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
560 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
561 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
563 // Check cipher suite, AP must have more secured cipher than station setting
564 // Set the Pairwise and Group cipher to match the intended AP setting
565 // We can only connect to AP with less secured cipher setting
566 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
568 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
570 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
571 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
572 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
573 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
574 else // There is no PairCipher Aux, downgrade our capability to TKIP
575 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
577 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
579 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
581 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
582 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
583 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
584 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
585 else // There is no PairCipher Aux, downgrade our capability to TKIP
586 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
589 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
592 // Set Mix cipher flag
593 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
594 if (pAd->StaCfg.bMixCipher == TRUE)
596 // If mix cipher, re-build RSNIE
597 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
599 // No active association, join the BSS immediately
600 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
601 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
603 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
604 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
606 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
611 // Roaming is the only external request triggering CNTL state machine
612 // despite of other "SET OID" operation. All "SET OID" related oerations
613 // happen in sequence, because no other SET OID will be sent to this device
614 // until the the previous SET operation is complete (successful o failed).
615 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
616 // or been corrupted by other "SET OID"?
618 // IRQL = DISPATCH_LEVEL
619 VOID CntlMlmeRoamingProc(
620 IN PRTMP_ADAPTER pAd,
621 IN MLME_QUEUE_ELEM *Elem)
624 // AP in different channel may show lower RSSI than actual value??
625 // should we add a weighting factor to compensate it?
626 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
628 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
629 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
631 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
632 pAd->MlmeAux.BssIdx = 0;
633 IterateOnBssTab(pAd);
637 ==========================================================================
640 IRQL = DISPATCH_LEVEL
642 ==========================================================================
644 VOID CntlWaitDisassocProc(
645 IN PRTMP_ADAPTER pAd,
646 IN MLME_QUEUE_ELEM *Elem)
648 MLME_START_REQ_STRUCT StartReq;
650 if (Elem->MsgType == MT2_DISASSOC_CONF)
652 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
654 if (pAd->CommonCfg.bWirelessEvent)
656 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
659 LinkDown(pAd, FALSE);
661 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
662 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
664 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
665 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
666 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
667 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
669 // case 2. try each matched BSS
672 pAd->MlmeAux.BssIdx = 0;
674 IterateOnBssTab(pAd);
680 ==========================================================================
683 IRQL = DISPATCH_LEVEL
685 ==========================================================================
687 VOID CntlWaitJoinProc(
688 IN PRTMP_ADAPTER pAd,
689 IN MLME_QUEUE_ELEM *Elem)
692 MLME_AUTH_REQ_STRUCT AuthReq;
694 if (Elem->MsgType == MT2_JOIN_CONF)
696 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
697 if (Reason == MLME_SUCCESS)
699 // 1. joined an IBSS, we are pretty much done here
700 if (pAd->MlmeAux.BssType == BSS_ADHOC)
703 // 5G bands rules of Japan:
704 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
706 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
707 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
710 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
711 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
715 LinkUp(pAd, BSS_ADHOC);
716 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
717 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
718 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
719 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
721 pAd->IndicateMediaState = NdisMediaStateConnected;
722 pAd->ExtraInfo = GENERAL_LINK_UP;
724 // 2. joined a new INFRA network, start from authentication
728 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
729 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
730 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
732 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
736 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
739 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
740 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
742 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
747 // 3. failed, try next BSS
748 pAd->MlmeAux.BssIdx++;
749 IterateOnBssTab(pAd);
756 ==========================================================================
759 IRQL = DISPATCH_LEVEL
761 ==========================================================================
763 VOID CntlWaitStartProc(
764 IN PRTMP_ADAPTER pAd,
765 IN MLME_QUEUE_ELEM *Elem)
769 if (Elem->MsgType == MT2_START_CONF)
771 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
772 if (Result == MLME_SUCCESS)
775 // 5G bands rules of Japan:
776 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
778 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
779 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
782 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
783 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
786 #ifdef DOT11_N_SUPPORT
787 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
791 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
792 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
793 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
794 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
795 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
796 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
798 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
799 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
801 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
803 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
804 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
806 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
810 #endif // DOT11_N_SUPPORT //
812 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
814 LinkUp(pAd, BSS_ADHOC);
815 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
816 // Before send beacon, driver need do radar detection
817 if ((pAd->CommonCfg.Channel > 14 )
818 && (pAd->CommonCfg.bIEEE80211H == 1)
819 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
821 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
822 pAd->CommonCfg.RadarDetect.RDCount = 0;
825 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
826 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
827 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
831 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
832 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
838 ==========================================================================
841 IRQL = DISPATCH_LEVEL
843 ==========================================================================
845 VOID CntlWaitAuthProc(
846 IN PRTMP_ADAPTER pAd,
847 IN MLME_QUEUE_ELEM *Elem)
850 MLME_ASSOC_REQ_STRUCT AssocReq;
851 MLME_AUTH_REQ_STRUCT AuthReq;
853 if (Elem->MsgType == MT2_AUTH_CONF)
855 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
856 if (Reason == MLME_SUCCESS)
858 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
859 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
860 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
863 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
864 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
866 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
871 // This fail may because of the AP already keep us in its MAC table without
872 // ageing-out. The previous authentication attempt must have let it remove us.
873 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
874 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
877 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
878 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
880 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
881 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
885 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
888 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
889 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
891 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
897 ==========================================================================
900 IRQL = DISPATCH_LEVEL
902 ==========================================================================
904 VOID CntlWaitAuthProc2(
905 IN PRTMP_ADAPTER pAd,
906 IN MLME_QUEUE_ELEM *Elem)
909 MLME_ASSOC_REQ_STRUCT AssocReq;
910 MLME_AUTH_REQ_STRUCT AuthReq;
912 if (Elem->MsgType == MT2_AUTH_CONF)
914 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
915 if (Reason == MLME_SUCCESS)
917 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
918 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
919 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
920 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
921 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
923 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
927 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
928 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
930 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
931 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
932 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
933 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
935 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
939 // not success, try next BSS
940 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
941 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
942 pAd->MlmeAux.BssIdx++;
943 IterateOnBssTab(pAd);
950 ==========================================================================
953 IRQL = DISPATCH_LEVEL
955 ==========================================================================
957 VOID CntlWaitAssocProc(
958 IN PRTMP_ADAPTER pAd,
959 IN MLME_QUEUE_ELEM *Elem)
963 if (Elem->MsgType == MT2_ASSOC_CONF)
965 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
966 if (Reason == MLME_SUCCESS)
968 LinkUp(pAd, BSS_INFRA);
969 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
970 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
972 if (pAd->CommonCfg.bWirelessEvent)
974 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
979 // not success, try next BSS
980 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
981 pAd->MlmeAux.BssIdx++;
982 IterateOnBssTab(pAd);
988 ==========================================================================
991 IRQL = DISPATCH_LEVEL
993 ==========================================================================
995 VOID CntlWaitReassocProc(
996 IN PRTMP_ADAPTER pAd,
997 IN MLME_QUEUE_ELEM *Elem)
1001 if (Elem->MsgType == MT2_REASSOC_CONF)
1003 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1004 if (Result == MLME_SUCCESS)
1007 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1009 LinkUp(pAd, BSS_INFRA);
1011 // send wireless event - for association
1012 if (pAd->CommonCfg.bWirelessEvent)
1013 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1015 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1016 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1020 // reassoc failed, try to pick next BSS in the BSS Table
1021 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1022 pAd->MlmeAux.RoamIdx++;
1023 IterateOnBssTab2(pAd);
1029 ==========================================================================
1032 IRQL = DISPATCH_LEVEL
1034 ==========================================================================
1037 IN PRTMP_ADAPTER pAd,
1043 UCHAR Value = 0, idx;
1044 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1046 if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
1048 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
1049 RTMPusecDelay(6000);
1050 pAd->bPCIclkOff = FALSE;
1053 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1056 // ASSOC - DisassocTimeoutAction
1057 // CNTL - Dis-associate successful
1058 // !!! LINK DOWN !!!
1059 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1061 // To prevent DisassocTimeoutAction to call Link down after we link up,
1062 // cancel the DisassocTimer no matter what it start or not.
1064 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1066 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1068 #ifdef DOT11_N_SUPPORT
1069 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1070 #endif // DOT11_N_SUPPORT //
1071 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1072 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1073 // to examine if cipher algorithm switching is required.
1074 //rt2860b. Don't know why need this
1075 SwitchBetweenWepAndCkip(pAd);
1077 // Before power save before link up function, We will force use 1R.
1078 // So after link up, check Rx antenna # again.
1079 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1080 if(pAd->Antenna.field.RxPath == 3)
1084 else if(pAd->Antenna.field.RxPath == 2)
1088 else if(pAd->Antenna.field.RxPath == 1)
1092 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1093 pAd->StaCfg.BBPR3 = Value;
1095 if (BssType == BSS_ADHOC)
1097 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1098 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1100 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1104 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1105 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1107 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1111 // reset Tx beamforming bit
1112 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1114 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1115 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1117 #ifdef DOT11_N_SUPPORT
1118 // Change to AP channel
1119 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1121 // Must using 40MHz.
1122 pAd->CommonCfg.BBPCurrentBW = BW_40;
1123 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1124 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1126 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1129 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1131 // RX : control channel at lower
1132 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1134 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1135 pAd->StaCfg.BBPR3 = Value;
1137 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1139 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1141 if (pAd->MACVersion == 0x28600100)
1143 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1144 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1145 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1146 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1149 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1151 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1153 // Must using 40MHz.
1154 pAd->CommonCfg.BBPCurrentBW = BW_40;
1155 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1156 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1158 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1161 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1163 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1165 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1167 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1169 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1170 pAd->StaCfg.BBPR3 = Value;
1172 if (pAd->MACVersion == 0x28600100)
1174 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1175 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1176 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1177 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1180 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1183 #endif // DOT11_N_SUPPORT //
1185 pAd->CommonCfg.BBPCurrentBW = BW_20;
1186 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1187 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1188 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1190 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1192 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1194 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1196 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1198 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1200 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1201 pAd->StaCfg.BBPR3 = Value;
1203 if (pAd->MACVersion == 0x28600100)
1205 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1206 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1207 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1208 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1211 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1214 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1216 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1218 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1220 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1221 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1223 #ifdef DOT11_N_SUPPORT
1224 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1225 #endif // DOT11_N_SUPPORT //
1227 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1229 AsicSetSlotTime(pAd, TRUE);
1230 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1232 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1233 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1235 #ifdef DOT11_N_SUPPORT
1236 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1238 // Update HT protectionfor based on AP's operating mode.
1239 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1241 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1244 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1246 #endif // DOT11_N_SUPPORT //
1248 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1250 NdisGetSystemUpTime(&Now);
1251 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1253 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1254 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1256 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1259 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1261 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1264 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1266 if (BssType == BSS_ADHOC)
1268 MakeIbssBeacon(pAd);
1269 if ((pAd->CommonCfg.Channel > 14)
1270 && (pAd->CommonCfg.bIEEE80211H == 1)
1271 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1277 AsicEnableIbssSync(pAd);
1280 // In ad hoc mode, use MAC table from index 1.
1281 // 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.
1282 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1283 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1285 // If WEP is enabled, add key material and cipherAlg into Asic
1286 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1288 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1293 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1295 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1296 Key = pAd->SharedKey[BSS0][idx].Key;
1298 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1300 // Set key material and cipherAlg to Asic
1301 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1303 if (idx == pAd->StaCfg.DefaultKeyId)
1305 // Update WCID attribute table and IVEIV table for this group key table
1306 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1313 // If WPANone is enabled, add key material and cipherAlg into Asic
1314 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1315 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1317 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1319 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1320 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1321 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1323 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1325 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1326 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1329 // Decide its ChiperAlg
1330 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1331 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1332 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1333 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1336 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1337 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1340 // Set key material and cipherAlg to Asic
1341 AsicAddSharedKeyEntry(pAd,
1344 pAd->SharedKey[BSS0][0].CipherAlg,
1345 pAd->SharedKey[BSS0][0].Key,
1346 pAd->SharedKey[BSS0][0].TxMic,
1347 pAd->SharedKey[BSS0][0].RxMic);
1349 // Update WCID attribute table and IVEIV table for this group key table
1350 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1357 // Check the new SSID with last SSID
1358 while (Cancelled == TRUE)
1360 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1362 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1364 // Link to the old one no linkdown is required.
1368 // Send link down event before set to link up
1369 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1370 RTMP_IndicateMediaState(pAd);
1371 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1372 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1377 // On WPA mode, Remove All Keys if not connect to the last BSSID
1378 // Key will be set after 4-way handshake.
1380 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1384 // Remove all WPA keys
1385 RTMPWPARemoveAllKeys(pAd);
1386 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1387 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1389 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1390 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1392 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1393 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1395 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1398 // the decision of using "short slot time" or not may change dynamically due to
1399 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1402 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1403 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1406 ComposeNullFrame(pAd);
1408 AsicEnableBssSync(pAd);
1410 // Add BSSID to WCID search table
1411 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1413 NdisAcquireSpinLock(&pAd->MacTabLock);
1414 // add this BSSID entry into HASH table
1418 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1419 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1420 if (pAd->MacTab.Hash[HashIdx] == NULL)
1422 pAd->MacTab.Hash[HashIdx] = pEntry;
1426 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1427 while (pCurrEntry->pNext != NULL)
1428 pCurrEntry = pCurrEntry->pNext;
1429 pCurrEntry->pNext = pEntry;
1432 NdisReleaseSpinLock(&pAd->MacTabLock);
1435 // If WEP is enabled, add paiewise and shared key
1436 if (((pAd->StaCfg.WpaSupplicantUP)&&
1437 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1438 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1439 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1440 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1445 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1447 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1448 Key = pAd->SharedKey[BSS0][idx].Key;
1450 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1452 // Set key material and cipherAlg to Asic
1453 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1455 if (idx == pAd->StaCfg.DefaultKeyId)
1457 // Assign group key info
1458 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1460 // Assign pairwise key info
1461 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1467 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1468 // should wait until at least 2 active nodes in this BSSID.
1469 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1472 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1474 pAd->IndicateMediaState = NdisMediaStateConnected;
1475 pAd->ExtraInfo = GENERAL_LINK_UP;
1478 RTMP_IndicateMediaState(pAd);
1480 // Add BSSID in my MAC Table.
1481 NdisAcquireSpinLock(&pAd->MacTabLock);
1482 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1483 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1484 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1485 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1486 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1487 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1488 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1489 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1490 NdisReleaseSpinLock(&pAd->MacTabLock);
1492 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1493 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1495 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1496 #ifdef DOT11_N_SUPPORT
1497 MlmeUpdateHtTxRates(pAd, BSS0);
1498 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1499 #endif // DOT11_N_SUPPORT //
1501 if (pAd->CommonCfg.bAggregationCapable)
1503 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1506 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1507 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1508 RTMPSetPiggyBack(pAd, TRUE);
1509 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1511 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1513 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1517 if (pAd->MlmeAux.APRalinkIe != 0x0)
1519 #ifdef DOT11_N_SUPPORT
1520 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1524 #endif // DOT11_N_SUPPORT //
1525 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1526 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1530 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1531 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1535 #ifdef DOT11_N_SUPPORT
1536 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));
1537 #endif // DOT11_N_SUPPORT //
1540 RTMPSetLED(pAd, LED_LINK_UP);
1542 pAd->Mlme.PeriodicRound = 0;
1543 pAd->Mlme.OneSecPeriodicRound = 0;
1544 pAd->bConfigChanged = FALSE; // Reset config flag
1545 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1547 // Set asic auto fall back
1550 UCHAR TableSize = 0;
1552 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1553 AsicUpdateAutoFallBackTable(pAd, pTable);
1556 NdisAcquireSpinLock(&pAd->MacTabLock);
1557 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1558 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1559 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1561 pEntry->bAutoTxRateSwitch = FALSE;
1562 #ifdef DOT11_N_SUPPORT
1563 if (pEntry->HTPhyMode.field.MCS == 32)
1564 pEntry->HTPhyMode.field.ShortGI = GI_800;
1566 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1567 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1568 #endif // DOT11_N_SUPPORT //
1569 // If the legacy mode is set, overwrite the transmit setting of this entry.
1570 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1571 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1574 pEntry->bAutoTxRateSwitch = TRUE;
1575 NdisReleaseSpinLock(&pAd->MacTabLock);
1577 // Let Link Status Page display first initial rate.
1578 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1579 // Select DAC according to HT or Legacy
1580 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1582 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1584 if (pAd->Antenna.field.TxPath == 2)
1588 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1592 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1594 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1597 #ifdef DOT11_N_SUPPORT
1598 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1601 else if (pEntry->MaxRAmpduFactor == 0)
1603 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1604 // Because our Init value is 1 at MACRegTable.
1605 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1607 #endif // DOT11_N_SUPPORT //
1609 // Patch for Marvel AP to gain high throughput
1610 // Need to set as following,
1611 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1612 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1613 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1614 // 4. kick per two packets when dequeue
1616 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1618 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1619 #ifdef DOT11_N_SUPPORT
1620 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1621 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1623 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1625 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1627 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1628 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1631 #endif // DOT11_N_SUPPORT //
1632 if (pAd->CommonCfg.bEnableTxBurst)
1634 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1637 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1638 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1640 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1641 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1645 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1647 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1649 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1650 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1653 #ifdef DOT11_N_SUPPORT
1654 // Re-check to turn on TX burst or not.
1655 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1657 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1658 if (pAd->CommonCfg.bEnableTxBurst)
1660 UINT32 MACValue = 0;
1661 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1662 // I didn't change PBF_MAX_PCNT setting.
1663 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1664 MACValue &= 0xFFFFFF00;
1665 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1666 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1671 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1673 #endif // DOT11_N_SUPPORT //
1675 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1676 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1677 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1678 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1679 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1680 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1682 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1684 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1685 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1688 NdisAcquireSpinLock(&pAd->MacTabLock);
1689 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1690 NdisReleaseSpinLock(&pAd->MacTabLock);
1693 // Patch Atheros AP TX will breakdown issue.
1694 // AP Model: DLink DWL-8200AP
1696 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1698 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1702 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1705 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1706 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1710 ==========================================================================
1712 Routine Description:
1713 Disconnect current BSSID
1716 pAd - Pointer to our adapter
1717 IsReqFromAP - Request from AP
1722 IRQL = DISPATCH_LEVEL
1725 We need more information to know it's this requst from AP.
1726 If yes! we need to do extra handling, for example, remove the WPA key.
1727 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1728 remove while auto reconnect.
1729 Disconnect request from AP, it means we will start afresh 4-way handshaking
1732 ==========================================================================
1735 IN PRTMP_ADAPTER pAd,
1736 IN BOOLEAN IsReqFromAP)
1738 UCHAR i, ByteValue = 0;
1741 // Do nothing if monitor mode is on
1742 if (MONITOR_ON(pAd))
1745 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1746 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1748 // Not allow go to sleep within linkdown function.
1749 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1751 if (pAd->CommonCfg.bWirelessEvent)
1753 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1756 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1757 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1759 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1762 pAd->Mlme.bPsPollTimerRunning = FALSE;
1763 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1766 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
1767 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
1768 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
1770 AsicForceWakeup(pAd, RTMP_HALT);
1771 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1774 pAd->bPCIclkOff = FALSE;
1775 if (ADHOC_ON(pAd)) // Adhoc mode link down
1777 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1779 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1780 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1781 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1782 RTMP_IndicateMediaState(pAd);
1783 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1784 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1785 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1787 else // Infra structure mode
1789 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1791 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1792 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1794 // Saved last SSID for linkup comparison
1795 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1796 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
1797 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1798 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
1800 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1801 RTMP_IndicateMediaState(pAd);
1802 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1803 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1804 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1809 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
1810 // Otherwise lost beacon or receive De-Authentication from AP,
1811 // then we should delete BSSID from BssTable.
1812 // If we don't delete from entry, roaming will fail.
1814 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1817 // restore back to -
1818 // 1. long slot (20 us) or short slot (9 us) time
1819 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1820 // 3. short preamble
1821 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1823 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
1826 // Record current AP's information.
1827 // for later used reporting Adjacent AP report.
1829 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
1830 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
1831 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
1832 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
1836 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
1838 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1839 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
1842 pAd->StaCfg.CCXQosECWMin = 4;
1843 pAd->StaCfg.CCXQosECWMax = 10;
1845 AsicSetSlotTime(pAd, TRUE); //FALSE);
1846 AsicSetEdcaParm(pAd, NULL);
1849 RTMPSetLED(pAd, LED_LINK_DOWN);
1850 pAd->LedIndicatorStregth = 0xF0;
1851 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
1853 AsicDisableSync(pAd);
1855 pAd->Mlme.PeriodicRound = 0;
1856 pAd->Mlme.OneSecPeriodicRound = 0;
1858 if (pAd->StaCfg.BssType == BSS_INFRA)
1860 // Remove StaCfg Information after link down
1861 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1862 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1863 pAd->CommonCfg.SsidLen = 0;
1865 #ifdef DOT11_N_SUPPORT
1866 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
1867 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
1868 pAd->MlmeAux.HtCapabilityLen = 0;
1869 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1870 #endif // DOT11_N_SUPPORT //
1872 // Reset WPA-PSK state. Only reset when supplicant enabled
1873 if (pAd->StaCfg.WpaState != SS_NOTUSE)
1875 pAd->StaCfg.WpaState = SS_START;
1876 // Clear Replay counter
1877 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1882 // if link down come from AP, we need to remove all WPA keys on WPA mode.
1883 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
1885 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1887 // Remove all WPA keys
1888 RTMPWPARemoveAllKeys(pAd);
1891 // 802.1x port control
1893 // Prevent clear PortSecured here with static WEP
1894 // NetworkManger set security policy first then set SSID to connect AP.
1895 if (pAd->StaCfg.WpaSupplicantUP &&
1896 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1897 (pAd->StaCfg.IEEE8021X == FALSE))
1899 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1903 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1904 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1907 NdisAcquireSpinLock(&pAd->MacTabLock);
1908 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
1909 NdisReleaseSpinLock(&pAd->MacTabLock);
1911 pAd->StaCfg.MicErrCnt = 0;
1913 // Turn off Ckip control flag
1914 pAd->StaCfg.bCkipOn = FALSE;
1915 pAd->StaCfg.CCXEnable = FALSE;
1917 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1918 // Update extra information to link is up
1919 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1921 pAd->StaCfg.AdhocBOnlyJoined = FALSE;
1922 pAd->StaCfg.AdhocBGJoined = FALSE;
1923 pAd->StaCfg.Adhoc20NJoined = FALSE;
1924 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1926 // Reset the Current AP's IP address
1927 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
1929 // Clean association information
1930 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
1931 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
1932 pAd->StaCfg.ReqVarIELen = 0;
1933 pAd->StaCfg.ResVarIELen = 0;
1936 // Reset RSSI value after link down
1938 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
1939 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
1940 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
1941 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
1942 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
1943 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
1946 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
1947 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
1949 #ifdef DOT11_N_SUPPORT
1951 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
1953 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1955 pAd->CommonCfg.BBPCurrentBW = BW_20;
1956 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
1957 ByteValue &= (~0x18);
1958 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
1960 #endif // DOT11_N_SUPPORT //
1962 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
1963 ByteValue &= (~0x18);
1964 if (pAd->Antenna.field.TxPath == 2)
1968 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
1970 RTMPSetPiggyBack(pAd,FALSE);
1971 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1973 #ifdef DOT11_N_SUPPORT
1974 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
1975 #endif // DOT11_N_SUPPORT //
1977 // Restore all settings in the following.
1978 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
1979 AsicDisableRDG(pAd);
1980 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
1981 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1983 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
1984 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1986 // Allow go to sleep after linkdown steps.
1987 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1990 union iwreq_data wrqu;
1991 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1992 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1997 ==========================================================================
2000 IRQL = DISPATCH_LEVEL
2002 ==========================================================================
2004 VOID IterateOnBssTab(
2005 IN PRTMP_ADAPTER pAd)
2007 MLME_START_REQ_STRUCT StartReq;
2008 MLME_JOIN_REQ_STRUCT JoinReq;
2011 // Change the wepstatus to original wepstatus
2012 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2013 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2014 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2016 BssIdx = pAd->MlmeAux.BssIdx;
2017 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2019 // Check cipher suite, AP must have more secured cipher than station setting
2020 // Set the Pairwise and Group cipher to match the intended AP setting
2021 // We can only connect to AP with less secured cipher setting
2022 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2024 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2026 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2027 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2028 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2029 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2030 else // There is no PairCipher Aux, downgrade our capability to TKIP
2031 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2033 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2035 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2037 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2038 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2039 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2040 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2041 else // There is no PairCipher Aux, downgrade our capability to TKIP
2042 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2045 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2048 // Set Mix cipher flag
2049 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2050 if (pAd->StaCfg.bMixCipher == TRUE)
2052 // If mix cipher, re-build RSNIE
2053 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2056 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2057 JoinParmFill(pAd, &JoinReq, BssIdx);
2058 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2060 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2062 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2064 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2065 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2066 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2067 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2071 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2072 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2073 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2074 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2078 // for re-association only
2079 // IRQL = DISPATCH_LEVEL
2080 VOID IterateOnBssTab2(
2081 IN PRTMP_ADAPTER pAd)
2083 MLME_REASSOC_REQ_STRUCT ReassocReq;
2087 BssIdx = pAd->MlmeAux.RoamIdx;
2088 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2090 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2092 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2094 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2095 AsicLockChannel(pAd, pBss->Channel);
2097 // reassociate message has the same structure as associate message
2098 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2099 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2100 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2101 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2103 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2107 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2108 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2109 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2110 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2115 ==========================================================================
2118 IRQL = DISPATCH_LEVEL
2120 ==========================================================================
2123 IN PRTMP_ADAPTER pAd,
2124 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2127 JoinReq->BssIdx = BssIdx;
2131 ==========================================================================
2134 IRQL = DISPATCH_LEVEL
2136 ==========================================================================
2139 IN PRTMP_ADAPTER pAd,
2140 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2146 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2147 ScanReq->SsidLen = SsidLen;
2148 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2149 ScanReq->BssType = BssType;
2150 ScanReq->ScanType = ScanType;
2154 ==========================================================================
2157 IRQL = DISPATCH_LEVEL
2159 ==========================================================================
2162 IN PRTMP_ADAPTER pAd,
2163 IN OUT MLME_START_REQ_STRUCT *StartReq,
2167 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2168 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2169 StartReq->SsidLen = SsidLen;
2173 ==========================================================================
2176 IRQL = DISPATCH_LEVEL
2178 ==========================================================================
2181 IN PRTMP_ADAPTER pAd,
2182 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2186 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2188 AuthReq->Timeout = AUTH_TIMEOUT;
2192 ==========================================================================
2195 IRQL = DISPATCH_LEVEL
2197 ==========================================================================
2200 IN PRTMP_ADAPTER pAd)
2202 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2203 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2204 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2205 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2206 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2207 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2210 // IRQL = DISPATCH_LEVEL
2211 VOID ComposeNullFrame(
2212 IN PRTMP_ADAPTER pAd)
2214 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2215 pAd->NullFrame.FC.Type = BTYPE_DATA;
2216 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2217 pAd->NullFrame.FC.ToDs = 1;
2218 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2219 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2220 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2227 ==========================================================================
2229 Pre-build a BEACON frame in the shared memory
2231 IRQL = PASSIVE_LEVEL
2232 IRQL = DISPATCH_LEVEL
2234 ==========================================================================
2236 ULONG MakeIbssBeacon(
2237 IN PRTMP_ADAPTER pAd)
2239 UCHAR DsLen = 1, IbssLen = 2;
2240 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2241 HEADER_802_11 BcnHdr;
2242 USHORT CapabilityInfo;
2243 LARGE_INTEGER FakeTimestamp;
2245 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2246 CHAR *pBeaconFrame = pAd->BeaconBuf;
2248 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2249 UCHAR SupRateLen = 0;
2250 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2251 UCHAR ExtRateLen = 0;
2252 UCHAR RSNIe = IE_WPA;
2254 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2256 SupRate[0] = 0x82; // 1 mbps
2257 SupRate[1] = 0x84; // 2 mbps
2258 SupRate[2] = 0x8b; // 5.5 mbps
2259 SupRate[3] = 0x96; // 11 mbps
2263 else if (pAd->CommonCfg.Channel > 14)
2265 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2266 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2267 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2268 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2269 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2270 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2271 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2272 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2277 // Also Update MlmeRate & RtsRate for G only & A only
2279 pAd->CommonCfg.MlmeRate = RATE_6;
2280 pAd->CommonCfg.RtsRate = RATE_6;
2281 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2282 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2283 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2284 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2288 SupRate[0] = 0x82; // 1 mbps
2289 SupRate[1] = 0x84; // 2 mbps
2290 SupRate[2] = 0x8b; // 5.5 mbps
2291 SupRate[3] = 0x96; // 11 mbps
2294 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2295 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2296 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2297 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2298 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2299 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2300 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2301 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2305 pAd->StaActive.SupRateLen = SupRateLen;
2306 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2307 pAd->StaActive.ExtRateLen = ExtRateLen;
2308 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2310 // compose IBSS beacon frame
2311 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2312 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2313 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2314 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2315 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2317 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2318 sizeof(HEADER_802_11), &BcnHdr,
2319 TIMESTAMP_LEN, &FakeTimestamp,
2320 2, &pAd->CommonCfg.BeaconPeriod,
2323 1, &pAd->CommonCfg.SsidLen,
2324 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2327 SupRateLen, SupRate,
2330 1, &pAd->CommonCfg.Channel,
2333 2, &pAd->StaActive.AtimWin,
2336 // add ERP_IE and EXT_RAE IE of in 802.11g
2341 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2345 ExtRateLen, ExtRate,
2350 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2351 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2354 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2356 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2358 1, &pAd->StaCfg.RSNIE_Len,
2359 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2364 #ifdef DOT11_N_SUPPORT
2365 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2368 UCHAR HtLen, HtLen1;
2370 // add HT Capability IE
2371 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2372 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2374 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2377 HtLen, &pAd->CommonCfg.HtCapability,
2380 HtLen1, &pAd->CommonCfg.AddHTInfo,
2385 #endif // DOT11_N_SUPPORT //
2387 //beacon use reserved WCID 0xff
2388 if (pAd->CommonCfg.Channel > 14)
2390 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2391 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2395 // Set to use 1Mbps for Adhoc beacon.
2396 HTTRANSMIT_SETTING Transmit;
2398 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2399 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2402 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2403 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));