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);
182 // AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone.
183 if (pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1)
185 Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
187 #endif // DOT11N_DRAFT3 //
191 case CNTL_WAIT_OID_DISASSOC:
192 if (Elem->MsgType == MT2_DISASSOC_CONF)
194 LinkDown(pAd, FALSE);
195 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
200 // This state is for that we want to connect to an AP but
201 // it didn't find on BSS List table. So we need to scan the air first,
202 // after that we can try to connect to the desired AP if available.
204 case CNTL_WAIT_SCAN_FOR_CONNECT:
205 if(Elem->MsgType == MT2_SCAN_CONF)
207 // Resume TxRing after SCANING complete. We hope the out-of-service time
208 // won't be too long to let upper layer time-out the waiting frames
209 RTMPResumeMsduTransmission(pAd);
211 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
213 // Cisco scan request is finished, prepare beacon report
214 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
216 #endif // CCX_SUPPORT //
217 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
220 // Check if we can connect to.
222 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
223 if (pAd->MlmeAux.SsidBssTab.BssNr > 0)
225 MlmeAutoReconnectLastSSID(pAd);
231 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
238 ==========================================================================
241 IRQL = DISPATCH_LEVEL
243 ==========================================================================
246 IN PRTMP_ADAPTER pAd,
247 IN MLME_QUEUE_ELEM *Elem)
249 MLME_DISASSOC_REQ_STRUCT DisassocReq;
251 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
254 switch(Elem->MsgType)
256 case OID_802_11_SSID:
257 CntlOidSsidProc(pAd, Elem);
260 case OID_802_11_BSSID:
261 CntlOidRTBssidProc(pAd,Elem);
264 case OID_802_11_BSSID_LIST_SCAN:
265 CntlOidScanProc(pAd,Elem);
268 case OID_802_11_DISASSOCIATE:
272 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
275 #endif // RALINK_ATE //
276 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
277 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
278 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
279 #ifdef WPA_SUPPLICANT_SUPPORT
280 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
281 #endif // WPA_SUPPLICANT_SUPPORT //
283 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
284 // Since calling this indicate user don't want to connect to that SSID anymore.
285 pAd->MlmeAux.AutoReconnectSsidLen= 32;
286 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
290 case MT2_MLME_ROAMING_REQ:
291 CntlMlmeRoamingProc(pAd, Elem);
294 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
295 WpaMicFailureReportFrame(pAd, Elem);
298 #ifdef QOS_DLS_SUPPORT
299 case RT_OID_802_11_SET_DLS_PARAM:
300 CntlOidDLSSetupProc(pAd, Elem);
302 #endif // QOS_DLS_SUPPORT //
305 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
310 VOID CntlOidScanProc(
311 IN PRTMP_ADAPTER pAd,
312 IN MLME_QUEUE_ELEM *Elem)
314 MLME_SCAN_REQ_STRUCT ScanReq;
315 ULONG BssIdx = BSS_NOT_FOUND;
319 /* Disable scanning when ATE is running. */
322 #endif // RALINK_ATE //
325 // record current BSS if network is connected.
326 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
327 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
329 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
330 if (BssIdx != BSS_NOT_FOUND)
332 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
336 // clean up previous SCAN result, add current BSS back to table if any
337 BssTableInit(&pAd->ScanTab);
338 if (BssIdx != BSS_NOT_FOUND)
340 // DDK Note: If the NIC is associated with a particular BSSID and SSID
341 // that are not contained in the list of BSSIDs generated by this scan, the
342 // BSSID description of the currently associated BSSID and SSID should be
343 // appended to the list of BSSIDs in the NIC's database.
344 // To ensure this, we append this BSS as the first entry in SCAN result
345 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
346 pAd->ScanTab.BssNr = 1;
349 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
350 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
351 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
352 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
356 ==========================================================================
358 Before calling this routine, user desired SSID should already been
359 recorded in CommonCfg.Ssid[]
360 IRQL = DISPATCH_LEVEL
362 ==========================================================================
364 VOID CntlOidSsidProc(
365 IN PRTMP_ADAPTER pAd,
366 IN MLME_QUEUE_ELEM * Elem)
368 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
369 MLME_DISASSOC_REQ_STRUCT DisassocReq;
372 // Step 1. record the desired user settings to MlmeAux
373 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
374 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
375 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
376 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
377 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
381 // Update Reconnect Ssid, that user desired to connect.
383 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
384 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
385 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
387 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
388 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
389 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
391 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
392 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
393 NdisGetSystemUpTime(&Now);
395 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
396 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
397 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
398 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
400 // Case 1. already connected with an AP who has the desired SSID
403 // Add checking Mode "LEAP" for CCX 1.0
404 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
405 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
406 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
407 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
409 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
410 #endif // LEAP_SUPPORT //
412 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
414 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
415 // connection process
416 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
417 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
418 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
419 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
420 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
422 else if (pAd->bConfigChanged == TRUE)
424 // case 1.2 Important Config has changed, we have to reconnect to the same AP
425 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
426 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
427 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
428 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
429 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
433 // case 1.3. already connected to the SSID with highest RSSI.
434 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
436 // (HCT 12.1) 1c_wlan_mediaevents required
437 // media connect events are indicated when associating with the same AP
442 // Since MediaState already is NdisMediaStateConnected
443 // We just indicate the connect event again to meet the WHQL required.
445 pAd->IndicateMediaState = NdisMediaStateConnected;
446 RTMP_IndicateMediaState(pAd);
447 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
450 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
451 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
453 union iwreq_data wrqu;
455 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
456 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
457 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
460 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
463 else if (INFRA_ON(pAd))
467 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
468 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
469 // But media status is connected, so the SSID not report correctly.
471 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
474 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
476 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
478 // case 2. active INFRA association existent
479 // roaming is done within miniport driver, nothing to do with configuration
480 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
481 // disassociate with the current associated AP,
482 // then perform a new association with this new SSID, no matter the
483 // new/old SSID are the same or not.
484 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
485 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
486 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
487 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
488 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
494 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
495 LinkDown(pAd, FALSE);
496 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
497 pAd->IndicateMediaState = NdisMediaStateDisconnected;
498 RTMP_IndicateMediaState(pAd);
499 pAd->ExtraInfo = GENERAL_LINK_DOWN;
500 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
503 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
504 (pAd->StaCfg.bAutoReconnect == TRUE) &&
505 (pAd->MlmeAux.BssType == BSS_INFRA) &&
506 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
509 MLME_SCAN_REQ_STRUCT ScanReq;
511 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
512 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
513 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
514 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
515 // Reset Missed scan number
516 pAd->StaCfg.LastScanTime = Now;
520 pAd->MlmeAux.BssIdx = 0;
521 IterateOnBssTab(pAd);
528 ==========================================================================
531 IRQL = DISPATCH_LEVEL
533 ==========================================================================
535 VOID CntlOidRTBssidProc(
536 IN PRTMP_ADAPTER pAd,
537 IN MLME_QUEUE_ELEM * Elem)
540 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
541 MLME_DISASSOC_REQ_STRUCT DisassocReq;
542 MLME_JOIN_REQ_STRUCT JoinReq;
545 /* No need to perform this routine when ATE is running. */
548 #endif // RALINK_ATE //
550 // record user desired settings
551 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
552 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
555 // Update Reconnect Ssid, that user desired to connect.
557 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
558 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
559 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
561 // find the desired BSS in the latest SCAN result table
562 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
563 if (BssIdx == BSS_NOT_FOUND)
565 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
566 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
570 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
571 // Because we need this entry to become the JOIN target in later on SYNC state machine
572 pAd->MlmeAux.BssIdx = 0;
573 pAd->MlmeAux.SsidBssTab.BssNr = 1;
574 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
576 //pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
577 //NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
579 // Add SSID into MlmeAux for site surey joining hidden SSID
580 //pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
581 //NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
583 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
584 // we just follow normal procedure. The reason of user doing this may because he/she changed
585 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
586 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
587 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
588 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
589 // connection when setting the same BSSID.
590 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
591 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
593 // already connected to the same BSSID, go back to idle state directly
594 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
595 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
596 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
598 union iwreq_data wrqu;
600 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
601 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
602 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
605 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
611 // disassoc from current AP first
612 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
613 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
614 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
615 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
617 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
623 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
624 LinkDown(pAd, FALSE);
625 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
626 pAd->IndicateMediaState = NdisMediaStateDisconnected;
627 RTMP_IndicateMediaState(pAd);
628 pAd->ExtraInfo = GENERAL_LINK_DOWN;
629 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
632 // Change the wepstatus to original wepstatus
633 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
634 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
635 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
637 // Check cipher suite, AP must have more secured cipher than station setting
638 // Set the Pairwise and Group cipher to match the intended AP setting
639 // We can only connect to AP with less secured cipher setting
640 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
642 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
644 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
645 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
646 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
647 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
648 else // There is no PairCipher Aux, downgrade our capability to TKIP
649 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
651 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
653 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
655 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
656 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
657 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
658 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
659 else // There is no PairCipher Aux, downgrade our capability to TKIP
660 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
663 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
666 // Set Mix cipher flag
667 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
668 if (pAd->StaCfg.bMixCipher == TRUE)
670 // If mix cipher, re-build RSNIE
671 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
673 // No active association, join the BSS immediately
674 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
675 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
677 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
678 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
680 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
685 // Roaming is the only external request triggering CNTL state machine
686 // despite of other "SET OID" operation. All "SET OID" related oerations
687 // happen in sequence, because no other SET OID will be sent to this device
688 // until the the previous SET operation is complete (successful o failed).
689 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
690 // or been corrupted by other "SET OID"?
692 // IRQL = DISPATCH_LEVEL
693 VOID CntlMlmeRoamingProc(
694 IN PRTMP_ADAPTER pAd,
695 IN MLME_QUEUE_ELEM *Elem)
698 // AP in different channel may show lower RSSI than actual value??
699 // should we add a weighting factor to compensate it?
700 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
702 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
703 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
705 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
706 pAd->MlmeAux.BssIdx = 0;
707 IterateOnBssTab(pAd);
710 #ifdef QOS_DLS_SUPPORT
712 ==========================================================================
715 IRQL = DISPATCH_LEVEL
717 ==========================================================================
719 VOID CntlOidDLSSetupProc(
720 IN PRTMP_ADAPTER pAd,
721 IN MLME_QUEUE_ELEM *Elem)
723 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)Elem->Msg;
724 MLME_DLS_REQ_STRUCT MlmeDlsReq;
726 USHORT reason = REASON_UNSPECIFY;
728 DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n",
729 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5],
730 pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer));
732 if (!pAd->CommonCfg.bDLSCapable)
735 // DLS will not be supported when Adhoc mode
738 for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++)
740 if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
741 (pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
743 // 1. Same setting, just drop it
744 DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n"));
747 else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
748 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
750 // 2. Disable DLS link case, just tear down DLS link
751 reason = REASON_QOS_UNWANTED_MECHANISM;
752 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
753 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
754 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
755 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
756 DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n"));
759 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid)
761 // 3. Enable case, start DLS setup procedure
762 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
764 //Update countdown timer
765 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
766 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
767 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
768 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n"));
771 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
772 (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
774 // 4. update mac case, tear down old DLS and setup new DLS
775 reason = REASON_QOS_UNWANTED_MECHANISM;
776 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
777 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
778 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
779 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
780 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
781 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
782 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
783 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS tear down and restart case\n"));
786 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
787 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr) && (pAd->StaCfg.DLSEntry[i].TimeOut != pDLS->TimeOut))
789 // 5. update timeout case, start DLS setup procedure (no tear down)
790 pAd->StaCfg.DLSEntry[i].TimeOut = pDLS->TimeOut;
791 //Update countdown timer
792 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
793 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
794 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
795 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS update timeout case\n"));
798 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
799 (pAd->StaCfg.DLSEntry[i].Status != DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
801 // 6. re-setup case, start DLS setup procedure (no tear down)
802 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
803 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
804 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS retry setup procedure\n"));
809 DBGPRINT(RT_DEBUG_WARN,("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n",
810 i, pAd->StaCfg.DLSEntry[i].Valid, pAd->StaCfg.DLSEntry[i].Status, pAd->StaCfg.DLSEntry[i].TimeOut));
815 #endif // QOS_DLS_SUPPORT //
818 ==========================================================================
821 IRQL = DISPATCH_LEVEL
823 ==========================================================================
825 VOID CntlWaitDisassocProc(
826 IN PRTMP_ADAPTER pAd,
827 IN MLME_QUEUE_ELEM *Elem)
829 MLME_START_REQ_STRUCT StartReq;
831 if (Elem->MsgType == MT2_DISASSOC_CONF)
833 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
835 if (pAd->CommonCfg.bWirelessEvent)
837 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
840 LinkDown(pAd, FALSE);
842 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
843 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
845 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
846 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
847 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
848 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
850 // case 2. try each matched BSS
853 pAd->MlmeAux.BssIdx = 0;
855 IterateOnBssTab(pAd);
861 ==========================================================================
864 IRQL = DISPATCH_LEVEL
866 ==========================================================================
868 VOID CntlWaitJoinProc(
869 IN PRTMP_ADAPTER pAd,
870 IN MLME_QUEUE_ELEM *Elem)
873 MLME_AUTH_REQ_STRUCT AuthReq;
875 if (Elem->MsgType == MT2_JOIN_CONF)
877 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
878 if (Reason == MLME_SUCCESS)
880 // 1. joined an IBSS, we are pretty much done here
881 if (pAd->MlmeAux.BssType == BSS_ADHOC)
884 // 5G bands rules of Japan:
885 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
887 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
888 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
891 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
892 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
896 LinkUp(pAd, BSS_ADHOC);
897 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
898 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
899 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
900 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
902 pAd->IndicateMediaState = NdisMediaStateConnected;
903 pAd->ExtraInfo = GENERAL_LINK_UP;
905 // 2. joined a new INFRA network, start from authentication
909 // Add AuthMode "LEAP" for CCX 1.X
910 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
912 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
915 #endif // LEAP_SUPPORT //
917 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
918 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
919 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
921 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
925 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
928 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
929 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
931 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
936 // 3. failed, try next BSS
937 pAd->MlmeAux.BssIdx++;
938 IterateOnBssTab(pAd);
945 ==========================================================================
948 IRQL = DISPATCH_LEVEL
950 ==========================================================================
952 VOID CntlWaitStartProc(
953 IN PRTMP_ADAPTER pAd,
954 IN MLME_QUEUE_ELEM *Elem)
958 if (Elem->MsgType == MT2_START_CONF)
960 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
961 if (Result == MLME_SUCCESS)
964 // 5G bands rules of Japan:
965 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
967 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
968 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
971 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
972 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
975 #ifdef DOT11_N_SUPPORT
976 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
980 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
981 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
982 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
983 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
984 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
985 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
987 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
988 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
990 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
992 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
993 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
995 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
999 #endif // DOT11_N_SUPPORT //
1001 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1003 LinkUp(pAd, BSS_ADHOC);
1004 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1005 // Before send beacon, driver need do radar detection
1006 if ((pAd->CommonCfg.Channel > 14 )
1007 && (pAd->CommonCfg.bIEEE80211H == 1)
1008 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1010 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
1011 pAd->CommonCfg.RadarDetect.RDCount = 0;
1013 BbpRadarDetectionStart(pAd);
1014 #endif // DFS_SUPPORT //
1017 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
1018 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
1019 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
1023 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
1024 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1030 ==========================================================================
1033 IRQL = DISPATCH_LEVEL
1035 ==========================================================================
1037 VOID CntlWaitAuthProc(
1038 IN PRTMP_ADAPTER pAd,
1039 IN MLME_QUEUE_ELEM *Elem)
1042 MLME_ASSOC_REQ_STRUCT AssocReq;
1043 MLME_AUTH_REQ_STRUCT AuthReq;
1045 if (Elem->MsgType == MT2_AUTH_CONF)
1047 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1048 if (Reason == MLME_SUCCESS)
1050 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1051 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1052 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1056 // Cisco Leap CCKM supported Re-association.
1058 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
1060 //if CCKM is turn on , that's mean Fast Reauthentication
1061 //Use CCKM Reassociation instead of normal association for Fast Roaming.
1062 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
1063 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1065 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
1068 #endif // LEAP_SUPPORT //
1070 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1071 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1073 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1078 // This fail may because of the AP already keep us in its MAC table without
1079 // ageing-out. The previous authentication attempt must have let it remove us.
1080 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
1081 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
1083 //Add AuthMode "LEAP" for CCX 1.X
1084 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1086 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
1089 #endif // LEAP_SUPPORT //
1091 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
1092 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
1094 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
1095 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
1099 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1102 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1103 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1105 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1111 ==========================================================================
1114 IRQL = DISPATCH_LEVEL
1116 ==========================================================================
1118 VOID CntlWaitAuthProc2(
1119 IN PRTMP_ADAPTER pAd,
1120 IN MLME_QUEUE_ELEM *Elem)
1123 MLME_ASSOC_REQ_STRUCT AssocReq;
1124 MLME_AUTH_REQ_STRUCT AuthReq;
1126 if (Elem->MsgType == MT2_AUTH_CONF)
1128 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1129 if (Reason == MLME_SUCCESS)
1131 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1132 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1133 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1134 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1135 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1137 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1142 // Process LEAP first, since it use different control variable
1143 // We don't want to affect other poven operation
1144 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1146 // LEAP Auth not success, try next BSS
1147 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
1148 DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
1149 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1150 pAd->MlmeAux.BssIdx++;
1151 IterateOnBssTab(pAd);
1154 #endif // LEAP_SUPPORT //
1155 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
1156 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
1158 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
1159 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1160 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1161 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1163 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1167 // not success, try next BSS
1168 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
1169 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
1170 pAd->MlmeAux.BssIdx++;
1171 IterateOnBssTab(pAd);
1178 ==========================================================================
1181 IRQL = DISPATCH_LEVEL
1183 ==========================================================================
1185 VOID CntlWaitAssocProc(
1186 IN PRTMP_ADAPTER pAd,
1187 IN MLME_QUEUE_ELEM *Elem)
1191 if (Elem->MsgType == MT2_ASSOC_CONF)
1193 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1194 if (Reason == MLME_SUCCESS)
1196 LinkUp(pAd, BSS_INFRA);
1197 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1198 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1200 if (pAd->CommonCfg.bWirelessEvent)
1202 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1207 // not success, try next BSS
1208 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1209 pAd->MlmeAux.BssIdx++;
1210 IterateOnBssTab(pAd);
1216 ==========================================================================
1219 IRQL = DISPATCH_LEVEL
1221 ==========================================================================
1223 VOID CntlWaitReassocProc(
1224 IN PRTMP_ADAPTER pAd,
1225 IN MLME_QUEUE_ELEM *Elem)
1229 if (Elem->MsgType == MT2_REASSOC_CONF)
1231 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1232 if (Result == MLME_SUCCESS)
1235 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1237 LinkUp(pAd, BSS_INFRA);
1239 // send wireless event - for association
1240 if (pAd->CommonCfg.bWirelessEvent)
1241 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1245 if (LEAP_CCKM_ON(pAd))
1247 STA_PORT_SECURED(pAd);
1248 pAd->StaCfg.WpaState = SS_FINISH;
1250 #endif // LEAP_SUPPORT //
1251 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1252 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1256 // reassoc failed, try to pick next BSS in the BSS Table
1257 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1258 pAd->MlmeAux.RoamIdx++;
1259 IterateOnBssTab2(pAd);
1265 VOID AdhocTurnOnQos(
1266 IN PRTMP_ADAPTER pAd)
1268 #define AC0_DEF_TXOP 0
1269 #define AC1_DEF_TXOP 0
1270 #define AC2_DEF_TXOP 94
1271 #define AC3_DEF_TXOP 47
1273 // Turn on QOs if use HT rate.
1274 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1276 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1277 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1278 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1279 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1280 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1282 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1283 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1284 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1285 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1287 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1288 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1289 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1290 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1292 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1293 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1294 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1295 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1297 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1301 ==========================================================================
1304 IRQL = DISPATCH_LEVEL
1306 ==========================================================================
1309 IN PRTMP_ADAPTER pAd,
1315 UCHAR Value = 0, idx;
1316 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1318 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1321 // ASSOC - DisassocTimeoutAction
1322 // CNTL - Dis-associate successful
1323 // !!! LINK DOWN !!!
1324 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1326 // To prevent DisassocTimeoutAction to call Link down after we link up,
1327 // cancel the DisassocTimer no matter what it start or not.
1329 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1331 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1333 #ifdef DOT11_N_SUPPORT
1334 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1335 #endif // DOT11_N_SUPPORT //
1336 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1337 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1338 // to examine if cipher algorithm switching is required.
1339 //rt2860b. Don't know why need this
1340 SwitchBetweenWepAndCkip(pAd);
1343 if (BssType == BSS_ADHOC)
1345 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1346 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1348 #ifdef DOT11_N_SUPPORT
1349 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
1350 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
1352 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
1354 else if ((pAd->CommonCfg.Channel > 2) &&
1355 (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
1356 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
1358 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
1360 #endif // DOT11_N_SUPPORT //
1362 #ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1363 // No carrier detection when adhoc
1364 // CarrierDetectionStop(pAd);
1365 pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
1366 #endif // CARRIER_DETECTION_SUPPORT //
1368 #ifdef DOT11_N_SUPPORT
1369 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1370 AdhocTurnOnQos(pAd);
1371 #endif // DOT11_N_SUPPORT //
1373 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1377 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1378 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1380 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1384 // reset Tx beamforming bit
1385 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1387 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1388 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1390 #ifdef DOT11_N_SUPPORT
1391 // Change to AP channel
1392 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1394 // Must using 40MHz.
1395 pAd->CommonCfg.BBPCurrentBW = BW_40;
1396 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1397 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1399 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1402 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1404 // RX : control channel at lower
1405 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1407 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1409 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1411 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1413 if (pAd->MACVersion == 0x28600100)
1415 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1416 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1417 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1418 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1421 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1423 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1425 // Must using 40MHz.
1426 pAd->CommonCfg.BBPCurrentBW = BW_40;
1427 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1428 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1430 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1433 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1435 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1437 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1439 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1441 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1443 if (pAd->MACVersion == 0x28600100)
1445 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1446 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1447 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1448 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1451 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1454 #endif // DOT11_N_SUPPORT //
1456 pAd->CommonCfg.BBPCurrentBW = BW_20;
1457 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1458 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1459 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1461 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1463 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1465 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1467 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1469 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1471 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1473 if (pAd->MACVersion == 0x28600100)
1475 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1476 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1477 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1478 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1481 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1484 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1486 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1488 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1490 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1491 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1493 #ifdef DOT11_N_SUPPORT
1494 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1495 #endif // DOT11_N_SUPPORT //
1497 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1499 AsicSetSlotTime(pAd, TRUE);
1500 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1502 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1503 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1505 #ifdef DOT11_N_SUPPORT
1506 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1508 // Update HT protectionfor based on AP's operating mode.
1509 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1511 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1514 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1516 #endif // DOT11_N_SUPPORT //
1518 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1520 NdisGetSystemUpTime(&Now);
1521 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1523 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1524 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1526 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1529 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1531 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1534 RadarDetectionStop(pAd);
1535 #endif // DFS_SUPPORT //
1537 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1539 if (BssType == BSS_ADHOC)
1541 MakeIbssBeacon(pAd);
1542 if ((pAd->CommonCfg.Channel > 14)
1543 && (pAd->CommonCfg.bIEEE80211H == 1)
1544 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1550 AsicEnableIbssSync(pAd);
1553 // In ad hoc mode, use MAC table from index 1.
1554 // 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.
1555 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1556 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1558 // If WEP is enabled, add key material and cipherAlg into Asic
1559 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1561 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1566 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1568 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1569 Key = pAd->SharedKey[BSS0][idx].Key;
1571 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1573 // Set key material and cipherAlg to Asic
1574 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1576 if (idx == pAd->StaCfg.DefaultKeyId)
1578 // Update WCID attribute table and IVEIV table for this group key table
1579 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1586 // If WPANone is enabled, add key material and cipherAlg into Asic
1587 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1588 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1590 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1592 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1593 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1594 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1596 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1598 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1599 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1602 // Decide its ChiperAlg
1603 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1604 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1605 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1606 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1609 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1610 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1613 // Set key material and cipherAlg to Asic
1614 AsicAddSharedKeyEntry(pAd,
1617 pAd->SharedKey[BSS0][0].CipherAlg,
1618 pAd->SharedKey[BSS0][0].Key,
1619 pAd->SharedKey[BSS0][0].TxMic,
1620 pAd->SharedKey[BSS0][0].RxMic);
1622 // Update WCID attribute table and IVEIV table for this group key table
1623 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1630 // Check the new SSID with last SSID
1631 while (Cancelled == TRUE)
1633 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1635 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1637 // Link to the old one no linkdown is required.
1641 // Send link down event before set to link up
1642 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1643 RTMP_IndicateMediaState(pAd);
1644 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1645 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1650 // On WPA mode, Remove All Keys if not connect to the last BSSID
1651 // Key will be set after 4-way handshake.
1653 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1657 // Remove all WPA keys
1658 RTMPWPARemoveAllKeys(pAd);
1659 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1660 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1662 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1663 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1665 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1666 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1669 // the decision of using "short slot time" or not may change dynamically due to
1670 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1673 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1674 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1677 ComposeNullFrame(pAd);
1679 AsicEnableBssSync(pAd);
1681 // Add BSSID to WCID search table
1682 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1684 NdisAcquireSpinLock(&pAd->MacTabLock);
1685 // add this BSSID entry into HASH table
1689 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1690 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1691 if (pAd->MacTab.Hash[HashIdx] == NULL)
1693 pAd->MacTab.Hash[HashIdx] = pEntry;
1697 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1698 while (pCurrEntry->pNext != NULL)
1699 pCurrEntry = pCurrEntry->pNext;
1700 pCurrEntry->pNext = pEntry;
1703 NdisReleaseSpinLock(&pAd->MacTabLock);
1706 // If WEP is enabled, add paiewise and shared key
1707 #ifdef WPA_SUPPLICANT_SUPPORT
1708 if (((pAd->StaCfg.WpaSupplicantUP)&&
1709 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1710 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1711 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1712 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1714 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1715 #endif // WPA_SUPPLICANT_SUPPORT //
1720 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1722 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1723 Key = pAd->SharedKey[BSS0][idx].Key;
1725 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1727 // Set key material and cipherAlg to Asic
1728 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1730 if (idx == pAd->StaCfg.DefaultKeyId)
1732 // Assign group key info
1733 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1735 // Assign pairwise key info
1736 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1742 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1743 // should wait until at least 2 active nodes in this BSSID.
1744 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1747 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1749 pAd->IndicateMediaState = NdisMediaStateConnected;
1750 pAd->ExtraInfo = GENERAL_LINK_UP;
1751 RTMP_IndicateMediaState(pAd);
1755 // Add BSSID in my MAC Table.
1756 NdisAcquireSpinLock(&pAd->MacTabLock);
1757 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1758 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1759 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1760 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1761 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1762 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1763 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1764 pAd->MacTab.Content[BSSID_WCID].AuthMode = pAd->StaCfg.AuthMode;
1765 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1766 NdisReleaseSpinLock(&pAd->MacTabLock);
1768 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1769 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1771 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1772 #ifdef DOT11_N_SUPPORT
1773 MlmeUpdateHtTxRates(pAd, BSS0);
1774 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1775 #endif // DOT11_N_SUPPORT //
1778 // Report Adjacent AP report.
1781 CCXAdjacentAPReport(pAd);
1782 #endif // LEAP_SUPPORT //
1784 if (pAd->CommonCfg.bAggregationCapable)
1786 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1789 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1790 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1791 RTMPSetPiggyBack(pAd, TRUE);
1792 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1794 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1796 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1800 if (pAd->MlmeAux.APRalinkIe != 0x0)
1802 #ifdef DOT11_N_SUPPORT
1803 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1807 #endif // DOT11_N_SUPPORT //
1808 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1809 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1813 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1814 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1818 #ifdef DOT11_N_SUPPORT
1819 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));
1820 #endif // DOT11_N_SUPPORT //
1823 RTMPSetLED(pAd, LED_LINK_UP);
1825 pAd->Mlme.PeriodicRound = 0;
1826 pAd->Mlme.OneSecPeriodicRound = 0;
1827 pAd->bConfigChanged = FALSE; // Reset config flag
1828 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1830 // Set asic auto fall back
1833 UCHAR TableSize = 0;
1835 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1836 AsicUpdateAutoFallBackTable(pAd, pTable);
1839 NdisAcquireSpinLock(&pAd->MacTabLock);
1840 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1841 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1842 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1844 pEntry->bAutoTxRateSwitch = FALSE;
1845 #ifdef DOT11_N_SUPPORT
1846 if (pEntry->HTPhyMode.field.MCS == 32)
1847 pEntry->HTPhyMode.field.ShortGI = GI_800;
1849 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1850 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1851 #endif // DOT11_N_SUPPORT //
1852 // If the legacy mode is set, overwrite the transmit setting of this entry.
1853 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1854 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1857 pEntry->bAutoTxRateSwitch = TRUE;
1858 NdisReleaseSpinLock(&pAd->MacTabLock);
1860 // Let Link Status Page display first initial rate.
1861 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1862 // Select DAC according to HT or Legacy
1863 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1865 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1867 if (pAd->Antenna.field.TxPath == 2)
1871 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1875 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1877 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1880 #ifdef DOT11_N_SUPPORT
1881 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1884 else if (pEntry->MaxRAmpduFactor == 0)
1886 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1887 // Because our Init value is 1 at MACRegTable.
1888 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1890 #endif // DOT11_N_SUPPORT //
1892 // Patch for Marvel AP to gain high throughput
1893 // Need to set as following,
1894 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1895 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1896 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1897 // 4. kick per two packets when dequeue
1899 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1901 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1902 #ifdef DOT11_N_SUPPORT
1903 // if ((!IS_RT30xx(pAd)) &&
1904 if (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) &&
1905 (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
1906 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))))
1908 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1910 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1912 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1913 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1916 #endif // DOT11_N_SUPPORT //
1917 if (pAd->CommonCfg.bEnableTxBurst)
1919 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1922 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1923 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1925 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1926 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1930 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1932 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1934 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1935 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1938 #ifdef DOT11_N_SUPPORT
1939 // Re-check to turn on TX burst or not.
1940 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1942 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1943 if (pAd->CommonCfg.bEnableTxBurst)
1945 UINT32 MACValue = 0;
1946 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1947 // I didn't change PBF_MAX_PCNT setting.
1948 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1949 MACValue &= 0xFFFFFF00;
1950 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1951 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1956 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1958 #endif // DOT11_N_SUPPORT //
1960 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1961 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1962 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1963 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1964 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1965 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1967 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1969 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1970 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1973 NdisAcquireSpinLock(&pAd->MacTabLock);
1974 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1975 NdisReleaseSpinLock(&pAd->MacTabLock);
1978 // Patch Atheros AP TX will breakdown issue.
1979 // AP Model: DLink DWL-8200AP
1981 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1983 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1987 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1990 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1992 #ifdef DOT11_N_SUPPORT
1993 #ifdef DOT11N_DRAFT3
1994 if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
1996 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
1997 BuildEffectedChannelList(pAd);
1999 #endif // DOT11N_DRAFT3 //
2000 #endif // DOT11_N_SUPPORT //
2004 ==========================================================================
2006 Routine Description:
2007 Disconnect current BSSID
2010 pAd - Pointer to our adapter
2011 IsReqFromAP - Request from AP
2016 IRQL = DISPATCH_LEVEL
2019 We need more information to know it's this requst from AP.
2020 If yes! we need to do extra handling, for example, remove the WPA key.
2021 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
2022 remove while auto reconnect.
2023 Disconnect request from AP, it means we will start afresh 4-way handshaking
2026 ==========================================================================
2029 IN PRTMP_ADAPTER pAd,
2030 IN BOOLEAN IsReqFromAP)
2032 UCHAR i, ByteValue = 0;
2034 // Do nothing if monitor mode is on
2035 if (MONITOR_ON(pAd))
2039 // Nothing to do in ATE mode.
2042 #endif // RALINK_ATE //
2044 if (pAd->CommonCfg.bWirelessEvent)
2046 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
2049 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
2050 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
2052 if (ADHOC_ON(pAd)) // Adhoc mode link down
2054 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
2056 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
2057 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2058 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2059 RTMP_IndicateMediaState(pAd);
2060 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2061 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2062 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
2064 else // Infra structure mode
2066 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
2068 #ifdef QOS_DLS_SUPPORT
2069 // DLS tear down frame must be sent before link down
2070 // send DLS-TEAR_DOWN message
2071 if (pAd->CommonCfg.bDLSCapable)
2073 // tear down local dls table entry
2074 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
2076 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2078 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2079 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2083 // tear down peer dls table entry
2084 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
2086 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2088 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2089 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2093 #endif // QOS_DLS_SUPPORT //
2095 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
2096 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2098 // Saved last SSID for linkup comparison
2099 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
2100 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
2101 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
2102 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
2104 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2105 RTMP_IndicateMediaState(pAd);
2106 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2107 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
2108 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
2113 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
2114 // Otherwise lost beacon or receive De-Authentication from AP,
2115 // then we should delete BSSID from BssTable.
2116 // If we don't delete from entry, roaming will fail.
2118 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2121 // restore back to -
2122 // 1. long slot (20 us) or short slot (9 us) time
2123 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
2124 // 3. short preamble
2125 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
2127 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
2130 // Record current AP's information.
2131 // for later used reporting Adjacent AP report.
2133 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
2134 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
2135 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
2136 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
2139 #ifdef EXT_BUILD_CHANNEL_LIST
2140 // Country IE of the AP will be evaluated and will be used.
2141 if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
2143 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
2144 pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
2145 BuildChannelListEx(pAd);
2147 #endif // EXT_BUILD_CHANNEL_LIST //
2151 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2153 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2154 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
2157 pAd->StaCfg.CCXQosECWMin = 4;
2158 pAd->StaCfg.CCXQosECWMax = 10;
2160 AsicSetSlotTime(pAd, TRUE); //FALSE);
2161 AsicSetEdcaParm(pAd, NULL);
2164 RTMPSetLED(pAd, LED_LINK_DOWN);
2165 pAd->LedIndicatorStregth = 0xF0;
2166 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
2168 AsicDisableSync(pAd);
2170 pAd->Mlme.PeriodicRound = 0;
2171 pAd->Mlme.OneSecPeriodicRound = 0;
2173 if (pAd->StaCfg.BssType == BSS_INFRA)
2175 // Remove StaCfg Information after link down
2176 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
2177 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
2178 pAd->CommonCfg.SsidLen = 0;
2180 #ifdef DOT11_N_SUPPORT
2181 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
2182 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
2183 pAd->MlmeAux.HtCapabilityLen = 0;
2184 pAd->MlmeAux.NewExtChannelOffset = 0xff;
2185 #endif // DOT11_N_SUPPORT //
2187 // Reset WPA-PSK state. Only reset when supplicant enabled
2188 if (pAd->StaCfg.WpaState != SS_NOTUSE)
2190 pAd->StaCfg.WpaState = SS_START;
2191 // Clear Replay counter
2192 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2194 #ifdef QOS_DLS_SUPPORT
2195 if (pAd->CommonCfg.bDLSCapable)
2196 NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
2197 #endif // QOS_DLS_SUPPORT //
2202 // if link down come from AP, we need to remove all WPA keys on WPA mode.
2203 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
2205 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
2207 // Remove all WPA keys
2208 RTMPWPARemoveAllKeys(pAd);
2211 // 802.1x port control
2212 #ifdef WPA_SUPPLICANT_SUPPORT
2213 // Prevent clear PortSecured here with static WEP
2214 // NetworkManger set security policy first then set SSID to connect AP.
2215 if (pAd->StaCfg.WpaSupplicantUP &&
2216 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
2217 (pAd->StaCfg.IEEE8021X == FALSE))
2219 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2222 #endif // WPA_SUPPLICANT_SUPPORT //
2224 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2225 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2228 NdisAcquireSpinLock(&pAd->MacTabLock);
2229 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2230 NdisReleaseSpinLock(&pAd->MacTabLock);
2232 pAd->StaCfg.MicErrCnt = 0;
2234 // Turn off Ckip control flag
2235 pAd->StaCfg.bCkipOn = FALSE;
2236 pAd->StaCfg.CCXEnable = FALSE;
2238 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2239 // Update extra information to link is up
2240 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2242 //pAd->StaCfg.AdhocBOnlyJoined = FALSE;
2243 //pAd->StaCfg.AdhocBGJoined = FALSE;
2244 //pAd->StaCfg.Adhoc20NJoined = FALSE;
2245 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2247 // Reset the Current AP's IP address
2248 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
2250 pAd->bUsbTxBulkAggre = FALSE;
2253 // Clean association information
2254 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
2255 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
2256 pAd->StaCfg.ReqVarIELen = 0;
2257 pAd->StaCfg.ResVarIELen = 0;
2260 // Reset RSSI value after link down
2262 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2263 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2264 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2265 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2266 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2267 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2270 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2271 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2273 #ifdef DOT11_N_SUPPORT
2275 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
2277 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
2279 pAd->CommonCfg.BBPCurrentBW = BW_20;
2280 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2281 ByteValue &= (~0x18);
2282 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2284 #endif // DOT11_N_SUPPORT //
2286 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2287 ByteValue &= (~0x18);
2288 if (pAd->Antenna.field.TxPath == 2)
2292 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2294 RTMPSetPiggyBack(pAd,FALSE);
2295 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2297 #ifdef DOT11_N_SUPPORT
2298 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2299 #endif // DOT11_N_SUPPORT //
2301 // Restore all settings in the following.
2302 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2303 AsicDisableRDG(pAd);
2304 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2305 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2307 #ifdef DOT11_N_SUPPORT
2308 #ifdef DOT11N_DRAFT3
2309 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
2310 pAd->CommonCfg.BSSCoexist2040.word = 0;
2312 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
2314 pAd->ChannelList[i].bEffectedChannel = FALSE;
2316 #endif // DOT11N_DRAFT3 //
2317 #endif // DOT11_N_SUPPORT //
2319 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2320 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2322 #ifdef WPA_SUPPLICANT_SUPPORT
2323 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2324 if (pAd->StaCfg.WpaSupplicantUP) {
2325 union iwreq_data wrqu;
2326 //send disassociate event to wpa_supplicant
2327 memset(&wrqu, 0, sizeof(wrqu));
2328 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2329 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2331 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2332 #endif // WPA_SUPPLICANT_SUPPORT //
2334 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2336 union iwreq_data wrqu;
2337 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2338 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2340 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2346 // disable MMPS BBP control register
2347 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &ByteValue);
2348 ByteValue &= ~(0x04); //bit 2
2349 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, ByteValue);
2351 // disable MMPS MAC control register
2352 RTMP_IO_READ32(pAd, 0x1210, &macdata);
2353 macdata &= ~(0x09); //bit 0, 3
2354 RTMP_IO_WRITE32(pAd, 0x1210, macdata);
2361 ==========================================================================
2364 IRQL = DISPATCH_LEVEL
2366 ==========================================================================
2368 VOID IterateOnBssTab(
2369 IN PRTMP_ADAPTER pAd)
2371 MLME_START_REQ_STRUCT StartReq;
2372 MLME_JOIN_REQ_STRUCT JoinReq;
2375 // Change the wepstatus to original wepstatus
2376 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2377 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2378 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2380 BssIdx = pAd->MlmeAux.BssIdx;
2381 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2383 // Check cipher suite, AP must have more secured cipher than station setting
2384 // Set the Pairwise and Group cipher to match the intended AP setting
2385 // We can only connect to AP with less secured cipher setting
2386 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2388 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2390 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2391 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2392 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2393 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2394 else // There is no PairCipher Aux, downgrade our capability to TKIP
2395 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2397 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2399 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2401 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2402 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2403 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2404 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2405 else // There is no PairCipher Aux, downgrade our capability to TKIP
2406 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2409 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2412 // Set Mix cipher flag
2413 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2414 if (pAd->StaCfg.bMixCipher == TRUE)
2416 // If mix cipher, re-build RSNIE
2417 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2420 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2421 JoinParmFill(pAd, &JoinReq, BssIdx);
2422 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2424 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2426 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2428 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2429 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2430 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2431 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2435 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2436 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2437 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2438 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2442 // for re-association only
2443 // IRQL = DISPATCH_LEVEL
2444 VOID IterateOnBssTab2(
2445 IN PRTMP_ADAPTER pAd)
2447 MLME_REASSOC_REQ_STRUCT ReassocReq;
2451 BssIdx = pAd->MlmeAux.RoamIdx;
2452 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2454 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2456 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2458 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2459 AsicLockChannel(pAd, pBss->Channel);
2461 // reassociate message has the same structure as associate message
2462 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2463 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2464 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2465 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2467 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2471 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2472 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2473 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2474 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2479 ==========================================================================
2482 IRQL = DISPATCH_LEVEL
2484 ==========================================================================
2487 IN PRTMP_ADAPTER pAd,
2488 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2491 JoinReq->BssIdx = BssIdx;
2495 ==========================================================================
2498 IRQL = DISPATCH_LEVEL
2500 ==========================================================================
2503 IN PRTMP_ADAPTER pAd,
2504 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2510 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2511 ScanReq->SsidLen = SsidLen;
2512 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2513 ScanReq->BssType = BssType;
2514 ScanReq->ScanType = ScanType;
2517 #ifdef QOS_DLS_SUPPORT
2519 ==========================================================================
2522 IRQL = DISPATCH_LEVEL
2524 ==========================================================================
2527 IN PRTMP_ADAPTER pAd,
2528 IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
2529 IN PRT_802_11_DLS pDls,
2532 pDlsReq->pDLS = pDls;
2533 pDlsReq->Reason = reason;
2535 #endif // QOS_DLS_SUPPORT //
2538 ==========================================================================
2541 IRQL = DISPATCH_LEVEL
2543 ==========================================================================
2546 IN PRTMP_ADAPTER pAd,
2547 IN OUT MLME_START_REQ_STRUCT *StartReq,
2551 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2552 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2553 StartReq->SsidLen = SsidLen;
2557 ==========================================================================
2560 IRQL = DISPATCH_LEVEL
2562 ==========================================================================
2565 IN PRTMP_ADAPTER pAd,
2566 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2570 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2572 AuthReq->Timeout = AUTH_TIMEOUT;
2576 ==========================================================================
2579 IRQL = DISPATCH_LEVEL
2581 ==========================================================================
2587 VOID MlmeCntlConfirm(
2588 IN PRTMP_ADAPTER pAd,
2592 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
2596 IN PRTMP_ADAPTER pAd)
2598 PTXINFO_STRUC pTxInfo;
2601 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2602 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2604 pAd->PsPollFrame.FC.PwrMgmt = 0;
2605 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2606 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2607 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2608 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2609 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2611 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
2612 pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
2613 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2614 pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2615 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
2616 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2617 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2618 // Append 4 extra zero bytes.
2619 pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
2622 // IRQL = DISPATCH_LEVEL
2623 VOID ComposeNullFrame(
2624 IN PRTMP_ADAPTER pAd)
2626 PTXINFO_STRUC pTxInfo;
2629 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2630 pAd->NullFrame.FC.Type = BTYPE_DATA;
2631 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2632 pAd->NullFrame.FC.ToDs = 1;
2633 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2634 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2635 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2636 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
2637 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
2638 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2639 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2640 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
2641 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2642 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
2643 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2649 ==========================================================================
2651 Pre-build a BEACON frame in the shared memory
2653 IRQL = PASSIVE_LEVEL
2654 IRQL = DISPATCH_LEVEL
2656 ==========================================================================
2658 ULONG MakeIbssBeacon(
2659 IN PRTMP_ADAPTER pAd)
2661 UCHAR DsLen = 1, IbssLen = 2;
2662 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2663 HEADER_802_11 BcnHdr;
2664 USHORT CapabilityInfo;
2665 LARGE_INTEGER FakeTimestamp;
2667 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2668 CHAR *pBeaconFrame = pAd->BeaconBuf;
2670 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2671 UCHAR SupRateLen = 0;
2672 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2673 UCHAR ExtRateLen = 0;
2674 UCHAR RSNIe = IE_WPA;
2676 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2678 SupRate[0] = 0x82; // 1 mbps
2679 SupRate[1] = 0x84; // 2 mbps
2680 SupRate[2] = 0x8b; // 5.5 mbps
2681 SupRate[3] = 0x96; // 11 mbps
2685 else if (pAd->CommonCfg.Channel > 14)
2687 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2688 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2689 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2690 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2691 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2692 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2693 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2694 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2699 // Also Update MlmeRate & RtsRate for G only & A only
2701 pAd->CommonCfg.MlmeRate = RATE_6;
2702 pAd->CommonCfg.RtsRate = RATE_6;
2703 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2704 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2705 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2706 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2710 SupRate[0] = 0x82; // 1 mbps
2711 SupRate[1] = 0x84; // 2 mbps
2712 SupRate[2] = 0x8b; // 5.5 mbps
2713 SupRate[3] = 0x96; // 11 mbps
2716 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2717 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2718 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2719 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2720 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2721 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2722 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2723 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2727 pAd->StaActive.SupRateLen = SupRateLen;
2728 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2729 pAd->StaActive.ExtRateLen = ExtRateLen;
2730 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2732 // compose IBSS beacon frame
2733 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2734 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2735 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2736 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2737 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2739 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2740 sizeof(HEADER_802_11), &BcnHdr,
2741 TIMESTAMP_LEN, &FakeTimestamp,
2742 2, &pAd->CommonCfg.BeaconPeriod,
2745 1, &pAd->CommonCfg.SsidLen,
2746 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2749 SupRateLen, SupRate,
2752 1, &pAd->CommonCfg.Channel,
2755 2, &pAd->StaActive.AtimWin,
2758 // add ERP_IE and EXT_RAE IE of in 802.11g
2763 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2767 ExtRateLen, ExtRate,
2772 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2773 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2776 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2778 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2780 1, &pAd->StaCfg.RSNIE_Len,
2781 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2786 #ifdef DOT11_N_SUPPORT
2787 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2790 UCHAR HtLen, HtLen1;
2792 #ifdef RT_BIG_ENDIAN
2793 HT_CAPABILITY_IE HtCapabilityTmp;
2794 ADD_HT_INFO_IE addHTInfoTmp;
2795 USHORT b2lTmp, b2lTmp2;
2798 // add HT Capability IE
2799 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2800 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2801 #ifndef RT_BIG_ENDIAN
2802 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2805 HtLen, &pAd->CommonCfg.HtCapability,
2808 HtLen1, &pAd->CommonCfg.AddHTInfo,
2811 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2812 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2813 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2815 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2816 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2817 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2819 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2822 HtLen, &HtCapabilityTmp,
2825 HtLen1, &addHTInfoTmp,
2830 #endif // DOT11_N_SUPPORT //
2832 //beacon use reserved WCID 0xff
2833 if (pAd->CommonCfg.Channel > 14)
2835 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2836 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2840 // Set to use 1Mbps for Adhoc beacon.
2841 HTTRANSMIT_SETTING Transmit;
2843 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2844 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2847 #ifdef RT_BIG_ENDIAN
2848 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2849 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2852 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2853 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));