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;
199 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
206 ==========================================================================
209 IRQL = DISPATCH_LEVEL
211 ==========================================================================
214 IN PRTMP_ADAPTER pAd,
215 IN MLME_QUEUE_ELEM *Elem)
217 MLME_DISASSOC_REQ_STRUCT DisassocReq;
219 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
222 switch(Elem->MsgType)
224 case OID_802_11_SSID:
225 CntlOidSsidProc(pAd, Elem);
228 case OID_802_11_BSSID:
229 CntlOidRTBssidProc(pAd,Elem);
232 case OID_802_11_BSSID_LIST_SCAN:
233 CntlOidScanProc(pAd,Elem);
236 case OID_802_11_DISASSOCIATE:
240 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
243 #endif // RALINK_ATE //
244 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
245 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
246 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
247 #ifdef WPA_SUPPLICANT_SUPPORT
248 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
249 #endif // WPA_SUPPLICANT_SUPPORT //
251 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
252 // Since calling this indicate user don't want to connect to that SSID anymore.
253 pAd->MlmeAux.AutoReconnectSsidLen= 32;
254 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
258 case MT2_MLME_ROAMING_REQ:
259 CntlMlmeRoamingProc(pAd, Elem);
262 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
263 WpaMicFailureReportFrame(pAd, Elem);
266 #ifdef QOS_DLS_SUPPORT
267 case RT_OID_802_11_SET_DLS_PARAM:
268 CntlOidDLSSetupProc(pAd, Elem);
270 #endif // QOS_DLS_SUPPORT //
273 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
278 VOID CntlOidScanProc(
279 IN PRTMP_ADAPTER pAd,
280 IN MLME_QUEUE_ELEM *Elem)
282 MLME_SCAN_REQ_STRUCT ScanReq;
283 ULONG BssIdx = BSS_NOT_FOUND;
287 /* Disable scanning when ATE is running. */
290 #endif // RALINK_ATE //
293 // record current BSS if network is connected.
294 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
295 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
297 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
298 if (BssIdx != BSS_NOT_FOUND)
300 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
304 // clean up previous SCAN result, add current BSS back to table if any
305 BssTableInit(&pAd->ScanTab);
306 if (BssIdx != BSS_NOT_FOUND)
308 // DDK Note: If the NIC is associated with a particular BSSID and SSID
309 // that are not contained in the list of BSSIDs generated by this scan, the
310 // BSSID description of the currently associated BSSID and SSID should be
311 // appended to the list of BSSIDs in the NIC's database.
312 // To ensure this, we append this BSS as the first entry in SCAN result
313 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
314 pAd->ScanTab.BssNr = 1;
317 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
318 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
319 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
320 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
324 ==========================================================================
326 Before calling this routine, user desired SSID should already been
327 recorded in CommonCfg.Ssid[]
328 IRQL = DISPATCH_LEVEL
330 ==========================================================================
332 VOID CntlOidSsidProc(
333 IN PRTMP_ADAPTER pAd,
334 IN MLME_QUEUE_ELEM * Elem)
336 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
337 MLME_DISASSOC_REQ_STRUCT DisassocReq;
340 // BBP and RF are not accessible in PS mode, we has to wake them up first
341 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
342 AsicForceWakeup(pAd, RTMP_HALT);
344 // Step 1. record the desired user settings to MlmeAux
345 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
346 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
347 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
348 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
349 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
353 // Update Reconnect Ssid, that user desired to connect.
355 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
356 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
357 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
359 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
360 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
361 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
363 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
364 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
365 NdisGetSystemUpTime(&Now);
367 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
368 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
369 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
370 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
372 // Case 1. already connected with an AP who has the desired SSID
375 // Add checking Mode "LEAP" for CCX 1.0
376 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
377 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
378 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
379 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
381 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
382 #endif // LEAP_SUPPORT //
384 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
386 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
387 // connection process
388 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
389 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
390 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
391 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
392 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
394 else if (pAd->bConfigChanged == TRUE)
396 // case 1.2 Important Config has changed, we have to reconnect to the same AP
397 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
398 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
399 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
400 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
401 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
405 // case 1.3. already connected to the SSID with highest RSSI.
406 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
408 // (HCT 12.1) 1c_wlan_mediaevents required
409 // media connect events are indicated when associating with the same AP
414 // Since MediaState already is NdisMediaStateConnected
415 // We just indicate the connect event again to meet the WHQL required.
417 pAd->IndicateMediaState = NdisMediaStateConnected;
418 RTMP_IndicateMediaState(pAd);
419 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
422 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
423 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
425 union iwreq_data wrqu;
427 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
428 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
429 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
432 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
435 else if (INFRA_ON(pAd))
439 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
440 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
441 // But media status is connected, so the SSID not report correctly.
443 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
446 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
448 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
450 // case 2. active INFRA association existent
451 // roaming is done within miniport driver, nothing to do with configuration
452 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
453 // disassociate with the current associated AP,
454 // then perform a new association with this new SSID, no matter the
455 // new/old SSID are the same or not.
456 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
457 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
458 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
459 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
460 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
466 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
467 LinkDown(pAd, FALSE);
468 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
469 pAd->IndicateMediaState = NdisMediaStateDisconnected;
470 RTMP_IndicateMediaState(pAd);
471 pAd->ExtraInfo = GENERAL_LINK_DOWN;
472 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
475 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
476 (pAd->StaCfg.bAutoReconnect == TRUE) &&
477 (pAd->MlmeAux.BssType == BSS_INFRA) &&
478 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
481 MLME_SCAN_REQ_STRUCT ScanReq;
483 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
484 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
485 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
486 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
487 // Reset Missed scan number
488 pAd->StaCfg.LastScanTime = Now;
492 pAd->MlmeAux.BssIdx = 0;
493 IterateOnBssTab(pAd);
500 ==========================================================================
503 IRQL = DISPATCH_LEVEL
505 ==========================================================================
507 VOID CntlOidRTBssidProc(
508 IN PRTMP_ADAPTER pAd,
509 IN MLME_QUEUE_ELEM * Elem)
512 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
513 MLME_DISASSOC_REQ_STRUCT DisassocReq;
514 MLME_JOIN_REQ_STRUCT JoinReq;
517 /* No need to perform this routine when ATE is running. */
520 #endif // RALINK_ATE //
522 // record user desired settings
523 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
524 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
527 // Update Reconnect Ssid, that user desired to connect.
529 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
530 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
531 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
533 // find the desired BSS in the latest SCAN result table
534 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
535 if (BssIdx == BSS_NOT_FOUND)
537 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
538 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
542 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
543 // Because we need this entry to become the JOIN target in later on SYNC state machine
544 pAd->MlmeAux.BssIdx = 0;
545 pAd->MlmeAux.SsidBssTab.BssNr = 1;
546 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
548 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
549 // we just follow normal procedure. The reason of user doing this may because he/she changed
550 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
551 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
552 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
553 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
554 // connection when setting the same BSSID.
555 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
556 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
558 // already connected to the same BSSID, go back to idle state directly
559 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
560 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
561 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
563 union iwreq_data wrqu;
565 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
566 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
567 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
570 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
576 // disassoc from current AP first
577 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
578 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
579 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
580 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
582 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
588 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
589 LinkDown(pAd, FALSE);
590 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
591 pAd->IndicateMediaState = NdisMediaStateDisconnected;
592 RTMP_IndicateMediaState(pAd);
593 pAd->ExtraInfo = GENERAL_LINK_DOWN;
594 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
597 // Change the wepstatus to original wepstatus
598 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
599 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
600 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
602 // Check cipher suite, AP must have more secured cipher than station setting
603 // Set the Pairwise and Group cipher to match the intended AP setting
604 // We can only connect to AP with less secured cipher setting
605 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
607 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
609 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
610 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
611 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
612 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
613 else // There is no PairCipher Aux, downgrade our capability to TKIP
614 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
616 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
618 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
620 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
621 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
622 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
623 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
624 else // There is no PairCipher Aux, downgrade our capability to TKIP
625 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
628 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
631 // Set Mix cipher flag
632 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
633 if (pAd->StaCfg.bMixCipher == TRUE)
635 // If mix cipher, re-build RSNIE
636 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
638 // No active association, join the BSS immediately
639 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
640 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
642 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
643 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
645 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
650 // Roaming is the only external request triggering CNTL state machine
651 // despite of other "SET OID" operation. All "SET OID" related oerations
652 // happen in sequence, because no other SET OID will be sent to this device
653 // until the the previous SET operation is complete (successful o failed).
654 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
655 // or been corrupted by other "SET OID"?
657 // IRQL = DISPATCH_LEVEL
658 VOID CntlMlmeRoamingProc(
659 IN PRTMP_ADAPTER pAd,
660 IN MLME_QUEUE_ELEM *Elem)
663 // AP in different channel may show lower RSSI than actual value??
664 // should we add a weighting factor to compensate it?
665 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
667 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
668 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
670 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
671 pAd->MlmeAux.BssIdx = 0;
672 IterateOnBssTab(pAd);
675 #ifdef QOS_DLS_SUPPORT
677 ==========================================================================
680 IRQL = DISPATCH_LEVEL
682 ==========================================================================
684 VOID CntlOidDLSSetupProc(
685 IN PRTMP_ADAPTER pAd,
686 IN MLME_QUEUE_ELEM *Elem)
688 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)Elem->Msg;
689 MLME_DLS_REQ_STRUCT MlmeDlsReq;
691 USHORT reason = REASON_UNSPECIFY;
693 DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n",
694 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5],
695 pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer));
697 if (!pAd->CommonCfg.bDLSCapable)
700 // DLS will not be supported when Adhoc mode
703 for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++)
705 if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
706 (pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
708 // 1. Same setting, just drop it
709 DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n"));
712 else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
713 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
715 // 2. Disable DLS link case, just tear down DLS link
716 reason = REASON_QOS_UNWANTED_MECHANISM;
717 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
718 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
719 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
720 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
721 DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n"));
724 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid)
726 // 3. Enable case, start DLS setup procedure
727 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
729 //Update countdown timer
730 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
731 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
732 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
733 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n"));
736 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
737 (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
739 // 4. update mac case, tear down old DLS and setup new DLS
740 reason = REASON_QOS_UNWANTED_MECHANISM;
741 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
742 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
743 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
744 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
745 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
746 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
747 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
748 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS tear down and restart case\n"));
751 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
752 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr) && (pAd->StaCfg.DLSEntry[i].TimeOut != pDLS->TimeOut))
754 // 5. update timeout case, start DLS setup procedure (no tear down)
755 pAd->StaCfg.DLSEntry[i].TimeOut = pDLS->TimeOut;
756 //Update countdown timer
757 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
758 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
759 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
760 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS update timeout case\n"));
763 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
764 (pAd->StaCfg.DLSEntry[i].Status != DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
766 // 6. re-setup case, start DLS setup procedure (no tear down)
767 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
768 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
769 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS retry setup procedure\n"));
774 DBGPRINT(RT_DEBUG_WARN,("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n",
775 i, pAd->StaCfg.DLSEntry[i].Valid, pAd->StaCfg.DLSEntry[i].Status, pAd->StaCfg.DLSEntry[i].TimeOut));
780 #endif // QOS_DLS_SUPPORT //
783 ==========================================================================
786 IRQL = DISPATCH_LEVEL
788 ==========================================================================
790 VOID CntlWaitDisassocProc(
791 IN PRTMP_ADAPTER pAd,
792 IN MLME_QUEUE_ELEM *Elem)
794 MLME_START_REQ_STRUCT StartReq;
796 if (Elem->MsgType == MT2_DISASSOC_CONF)
798 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
800 if (pAd->CommonCfg.bWirelessEvent)
802 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
805 LinkDown(pAd, FALSE);
807 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
808 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
810 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
811 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
812 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
813 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
815 // case 2. try each matched BSS
818 pAd->MlmeAux.BssIdx = 0;
820 IterateOnBssTab(pAd);
826 ==========================================================================
829 IRQL = DISPATCH_LEVEL
831 ==========================================================================
833 VOID CntlWaitJoinProc(
834 IN PRTMP_ADAPTER pAd,
835 IN MLME_QUEUE_ELEM *Elem)
838 MLME_AUTH_REQ_STRUCT AuthReq;
840 if (Elem->MsgType == MT2_JOIN_CONF)
842 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
843 if (Reason == MLME_SUCCESS)
845 // 1. joined an IBSS, we are pretty much done here
846 if (pAd->MlmeAux.BssType == BSS_ADHOC)
849 // 5G bands rules of Japan:
850 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
852 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
853 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
856 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
857 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
861 LinkUp(pAd, BSS_ADHOC);
862 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
863 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
864 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
865 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
867 pAd->IndicateMediaState = NdisMediaStateConnected;
868 pAd->ExtraInfo = GENERAL_LINK_UP;
870 // 2. joined a new INFRA network, start from authentication
874 // Add AuthMode "LEAP" for CCX 1.X
875 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
877 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
880 #endif // LEAP_SUPPORT //
882 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
883 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
884 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
886 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
890 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
893 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
894 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
896 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
901 // 3. failed, try next BSS
902 pAd->MlmeAux.BssIdx++;
903 IterateOnBssTab(pAd);
910 ==========================================================================
913 IRQL = DISPATCH_LEVEL
915 ==========================================================================
917 VOID CntlWaitStartProc(
918 IN PRTMP_ADAPTER pAd,
919 IN MLME_QUEUE_ELEM *Elem)
923 if (Elem->MsgType == MT2_START_CONF)
925 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
926 if (Result == MLME_SUCCESS)
929 // 5G bands rules of Japan:
930 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
932 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
933 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
936 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
937 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
940 #ifdef DOT11_N_SUPPORT
941 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
945 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
946 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
947 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
948 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
949 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
950 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
952 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
953 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
955 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
957 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
958 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
960 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
964 #endif // DOT11_N_SUPPORT //
966 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
968 LinkUp(pAd, BSS_ADHOC);
969 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
970 // Before send beacon, driver need do radar detection
971 if ((pAd->CommonCfg.Channel > 14 )
972 && (pAd->CommonCfg.bIEEE80211H == 1)
973 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
975 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
976 pAd->CommonCfg.RadarDetect.RDCount = 0;
978 BbpRadarDetectionStart(pAd);
979 #endif // DFS_SUPPORT //
982 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
983 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
984 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
988 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
989 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
995 ==========================================================================
998 IRQL = DISPATCH_LEVEL
1000 ==========================================================================
1002 VOID CntlWaitAuthProc(
1003 IN PRTMP_ADAPTER pAd,
1004 IN MLME_QUEUE_ELEM *Elem)
1007 MLME_ASSOC_REQ_STRUCT AssocReq;
1008 MLME_AUTH_REQ_STRUCT AuthReq;
1010 if (Elem->MsgType == MT2_AUTH_CONF)
1012 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1013 if (Reason == MLME_SUCCESS)
1015 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1016 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1017 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1021 // Cisco Leap CCKM supported Re-association.
1023 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
1025 //if CCKM is turn on , that's mean Fast Reauthentication
1026 //Use CCKM Reassociation instead of normal association for Fast Roaming.
1027 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
1028 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1030 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
1033 #endif // LEAP_SUPPORT //
1035 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1036 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1038 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1043 // This fail may because of the AP already keep us in its MAC table without
1044 // ageing-out. The previous authentication attempt must have let it remove us.
1045 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
1046 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
1048 //Add AuthMode "LEAP" for CCX 1.X
1049 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1051 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
1054 #endif // LEAP_SUPPORT //
1056 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
1057 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
1059 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
1060 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
1064 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1067 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1068 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1070 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1076 ==========================================================================
1079 IRQL = DISPATCH_LEVEL
1081 ==========================================================================
1083 VOID CntlWaitAuthProc2(
1084 IN PRTMP_ADAPTER pAd,
1085 IN MLME_QUEUE_ELEM *Elem)
1088 MLME_ASSOC_REQ_STRUCT AssocReq;
1089 MLME_AUTH_REQ_STRUCT AuthReq;
1091 if (Elem->MsgType == MT2_AUTH_CONF)
1093 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1094 if (Reason == MLME_SUCCESS)
1096 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1097 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1098 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1099 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1100 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1102 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1107 // Process LEAP first, since it use different control variable
1108 // We don't want to affect other poven operation
1109 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1111 // LEAP Auth not success, try next BSS
1112 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
1113 DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
1114 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1115 pAd->MlmeAux.BssIdx++;
1116 IterateOnBssTab(pAd);
1119 #endif // LEAP_SUPPORT //
1120 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
1121 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
1123 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
1124 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1125 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1126 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1128 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1132 // not success, try next BSS
1133 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
1134 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
1135 pAd->MlmeAux.BssIdx++;
1136 IterateOnBssTab(pAd);
1143 ==========================================================================
1146 IRQL = DISPATCH_LEVEL
1148 ==========================================================================
1150 VOID CntlWaitAssocProc(
1151 IN PRTMP_ADAPTER pAd,
1152 IN MLME_QUEUE_ELEM *Elem)
1156 if (Elem->MsgType == MT2_ASSOC_CONF)
1158 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1159 if (Reason == MLME_SUCCESS)
1161 LinkUp(pAd, BSS_INFRA);
1162 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1163 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1165 if (pAd->CommonCfg.bWirelessEvent)
1167 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1172 // not success, try next BSS
1173 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1174 pAd->MlmeAux.BssIdx++;
1175 IterateOnBssTab(pAd);
1181 ==========================================================================
1184 IRQL = DISPATCH_LEVEL
1186 ==========================================================================
1188 VOID CntlWaitReassocProc(
1189 IN PRTMP_ADAPTER pAd,
1190 IN MLME_QUEUE_ELEM *Elem)
1194 if (Elem->MsgType == MT2_REASSOC_CONF)
1196 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1197 if (Result == MLME_SUCCESS)
1200 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1202 LinkUp(pAd, BSS_INFRA);
1204 // send wireless event - for association
1205 if (pAd->CommonCfg.bWirelessEvent)
1206 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1210 if (LEAP_CCKM_ON(pAd))
1212 STA_PORT_SECURED(pAd);
1213 pAd->StaCfg.WpaState = SS_FINISH;
1215 #endif // LEAP_SUPPORT //
1216 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1217 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1221 // reassoc failed, try to pick next BSS in the BSS Table
1222 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1223 pAd->MlmeAux.RoamIdx++;
1224 IterateOnBssTab2(pAd);
1230 ==========================================================================
1233 IRQL = DISPATCH_LEVEL
1235 ==========================================================================
1238 IN PRTMP_ADAPTER pAd,
1244 UCHAR Value = 0, idx;
1245 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1247 if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
1249 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
1250 RTMPusecDelay(6000);
1251 pAd->bPCIclkOff = FALSE;
1254 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1257 // ASSOC - DisassocTimeoutAction
1258 // CNTL - Dis-associate successful
1259 // !!! LINK DOWN !!!
1260 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1262 // To prevent DisassocTimeoutAction to call Link down after we link up,
1263 // cancel the DisassocTimer no matter what it start or not.
1265 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1267 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1269 #ifdef DOT11_N_SUPPORT
1270 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1271 #endif // DOT11_N_SUPPORT //
1272 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1273 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1274 // to examine if cipher algorithm switching is required.
1275 //rt2860b. Don't know why need this
1276 SwitchBetweenWepAndCkip(pAd);
1279 // Before power save before link up function, We will force use 1R.
1280 // So after link up, check Rx antenna # again.
1281 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1282 if(pAd->Antenna.field.RxPath == 3)
1286 else if(pAd->Antenna.field.RxPath == 2)
1290 else if(pAd->Antenna.field.RxPath == 1)
1294 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1295 pAd->StaCfg.BBPR3 = Value;
1298 if (BssType == BSS_ADHOC)
1300 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1301 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1303 #ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1304 // No carrier detection when adhoc
1305 // CarrierDetectionStop(pAd);
1306 pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
1307 #endif // CARRIER_DETECTION_SUPPORT //
1309 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1313 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1314 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1316 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1320 // reset Tx beamforming bit
1321 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1323 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1324 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1326 #ifdef DOT11_N_SUPPORT
1327 // Change to AP channel
1328 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1330 // Must using 40MHz.
1331 pAd->CommonCfg.BBPCurrentBW = BW_40;
1332 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1333 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1335 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1338 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1340 // RX : control channel at lower
1341 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1343 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1345 pAd->StaCfg.BBPR3 = Value;
1348 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1350 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1352 if (pAd->MACVersion == 0x28600100)
1354 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1355 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1356 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1357 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1360 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1362 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1364 // Must using 40MHz.
1365 pAd->CommonCfg.BBPCurrentBW = BW_40;
1366 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1367 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1369 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1372 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1374 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1376 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1378 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1380 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1382 pAd->StaCfg.BBPR3 = Value;
1385 if (pAd->MACVersion == 0x28600100)
1387 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1388 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1389 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1390 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1393 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1396 #endif // DOT11_N_SUPPORT //
1398 pAd->CommonCfg.BBPCurrentBW = BW_20;
1399 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1400 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1401 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1403 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1405 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1407 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1409 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1411 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1413 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1415 pAd->StaCfg.BBPR3 = Value;
1418 if (pAd->MACVersion == 0x28600100)
1420 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1421 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1422 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1423 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1426 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1429 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1431 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1433 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1435 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1436 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1438 #ifdef DOT11_N_SUPPORT
1439 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1440 #endif // DOT11_N_SUPPORT //
1442 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1444 AsicSetSlotTime(pAd, TRUE);
1445 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1447 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1448 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1450 #ifdef DOT11_N_SUPPORT
1451 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1453 // Update HT protectionfor based on AP's operating mode.
1454 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1456 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1459 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1461 #endif // DOT11_N_SUPPORT //
1463 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1465 NdisGetSystemUpTime(&Now);
1466 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1468 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1469 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1471 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1474 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1476 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1479 RadarDetectionStop(pAd);
1480 #endif // DFS_SUPPORT //
1482 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1484 if (BssType == BSS_ADHOC)
1486 MakeIbssBeacon(pAd);
1487 if ((pAd->CommonCfg.Channel > 14)
1488 && (pAd->CommonCfg.bIEEE80211H == 1)
1489 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1495 AsicEnableIbssSync(pAd);
1498 // In ad hoc mode, use MAC table from index 1.
1499 // 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.
1500 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1501 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1503 // If WEP is enabled, add key material and cipherAlg into Asic
1504 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1506 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1511 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1513 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1514 Key = pAd->SharedKey[BSS0][idx].Key;
1516 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1518 // Set key material and cipherAlg to Asic
1519 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1521 if (idx == pAd->StaCfg.DefaultKeyId)
1523 // Update WCID attribute table and IVEIV table for this group key table
1524 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1531 // If WPANone is enabled, add key material and cipherAlg into Asic
1532 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1533 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1535 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1537 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1538 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1539 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1541 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1543 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1544 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1547 // Decide its ChiperAlg
1548 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1549 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1550 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1551 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1554 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1555 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1558 // Set key material and cipherAlg to Asic
1559 AsicAddSharedKeyEntry(pAd,
1562 pAd->SharedKey[BSS0][0].CipherAlg,
1563 pAd->SharedKey[BSS0][0].Key,
1564 pAd->SharedKey[BSS0][0].TxMic,
1565 pAd->SharedKey[BSS0][0].RxMic);
1567 // Update WCID attribute table and IVEIV table for this group key table
1568 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1575 // Check the new SSID with last SSID
1576 while (Cancelled == TRUE)
1578 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1580 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1582 // Link to the old one no linkdown is required.
1586 // Send link down event before set to link up
1587 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1588 RTMP_IndicateMediaState(pAd);
1589 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1590 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1595 // On WPA mode, Remove All Keys if not connect to the last BSSID
1596 // Key will be set after 4-way handshake.
1598 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1602 // Remove all WPA keys
1603 RTMPWPARemoveAllKeys(pAd);
1604 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1605 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1607 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1608 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1610 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1611 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1613 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1616 // the decision of using "short slot time" or not may change dynamically due to
1617 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1620 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1621 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1624 ComposeNullFrame(pAd);
1626 AsicEnableBssSync(pAd);
1628 // Add BSSID to WCID search table
1629 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1631 NdisAcquireSpinLock(&pAd->MacTabLock);
1632 // add this BSSID entry into HASH table
1636 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1637 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1638 if (pAd->MacTab.Hash[HashIdx] == NULL)
1640 pAd->MacTab.Hash[HashIdx] = pEntry;
1644 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1645 while (pCurrEntry->pNext != NULL)
1646 pCurrEntry = pCurrEntry->pNext;
1647 pCurrEntry->pNext = pEntry;
1650 NdisReleaseSpinLock(&pAd->MacTabLock);
1653 // If WEP is enabled, add paiewise and shared key
1654 #ifdef WPA_SUPPLICANT_SUPPORT
1655 if (((pAd->StaCfg.WpaSupplicantUP)&&
1656 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1657 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1658 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1659 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1661 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1662 #endif // WPA_SUPPLICANT_SUPPORT //
1667 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1669 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1670 Key = pAd->SharedKey[BSS0][idx].Key;
1672 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1674 // Set key material and cipherAlg to Asic
1675 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1677 if (idx == pAd->StaCfg.DefaultKeyId)
1679 // Assign group key info
1680 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1682 // Assign pairwise key info
1683 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1689 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1690 // should wait until at least 2 active nodes in this BSSID.
1691 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1694 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1696 pAd->IndicateMediaState = NdisMediaStateConnected;
1697 pAd->ExtraInfo = GENERAL_LINK_UP;
1700 RTMP_IndicateMediaState(pAd);
1702 // Add BSSID in my MAC Table.
1703 NdisAcquireSpinLock(&pAd->MacTabLock);
1704 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1705 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1706 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1707 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1708 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1709 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1710 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1711 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1712 NdisReleaseSpinLock(&pAd->MacTabLock);
1714 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1715 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1717 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1718 #ifdef DOT11_N_SUPPORT
1719 MlmeUpdateHtTxRates(pAd, BSS0);
1720 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1721 #endif // DOT11_N_SUPPORT //
1724 // Report Adjacent AP report.
1727 CCXAdjacentAPReport(pAd);
1728 #endif // LEAP_SUPPORT //
1730 if (pAd->CommonCfg.bAggregationCapable)
1732 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1735 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1736 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1737 RTMPSetPiggyBack(pAd, TRUE);
1738 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1740 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1742 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1746 if (pAd->MlmeAux.APRalinkIe != 0x0)
1748 #ifdef DOT11_N_SUPPORT
1749 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1753 #endif // DOT11_N_SUPPORT //
1754 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1755 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1759 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1760 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1764 #ifdef DOT11_N_SUPPORT
1765 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));
1766 #endif // DOT11_N_SUPPORT //
1769 RTMPSetLED(pAd, LED_LINK_UP);
1771 pAd->Mlme.PeriodicRound = 0;
1772 pAd->Mlme.OneSecPeriodicRound = 0;
1773 pAd->bConfigChanged = FALSE; // Reset config flag
1774 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1776 // Set asic auto fall back
1779 UCHAR TableSize = 0;
1781 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1782 AsicUpdateAutoFallBackTable(pAd, pTable);
1785 NdisAcquireSpinLock(&pAd->MacTabLock);
1786 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1787 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1788 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1790 pEntry->bAutoTxRateSwitch = FALSE;
1791 #ifdef DOT11_N_SUPPORT
1792 if (pEntry->HTPhyMode.field.MCS == 32)
1793 pEntry->HTPhyMode.field.ShortGI = GI_800;
1795 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1796 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1797 #endif // DOT11_N_SUPPORT //
1798 // If the legacy mode is set, overwrite the transmit setting of this entry.
1799 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1800 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1803 pEntry->bAutoTxRateSwitch = TRUE;
1804 NdisReleaseSpinLock(&pAd->MacTabLock);
1806 // Let Link Status Page display first initial rate.
1807 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1808 // Select DAC according to HT or Legacy
1809 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1811 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1813 if (pAd->Antenna.field.TxPath == 2)
1817 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1821 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1823 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1826 #ifdef DOT11_N_SUPPORT
1827 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1830 else if (pEntry->MaxRAmpduFactor == 0)
1832 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1833 // Because our Init value is 1 at MACRegTable.
1834 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1836 #endif // DOT11_N_SUPPORT //
1838 // Patch for Marvel AP to gain high throughput
1839 // Need to set as following,
1840 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1841 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1842 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1843 // 4. kick per two packets when dequeue
1845 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1847 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1848 #ifdef DOT11_N_SUPPORT
1849 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1850 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1852 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1854 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1856 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1857 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1860 #endif // DOT11_N_SUPPORT //
1861 if (pAd->CommonCfg.bEnableTxBurst)
1863 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1866 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1867 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1869 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1870 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1874 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1876 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1878 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1879 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1882 #ifdef DOT11_N_SUPPORT
1883 // Re-check to turn on TX burst or not.
1884 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1886 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1887 if (pAd->CommonCfg.bEnableTxBurst)
1889 UINT32 MACValue = 0;
1890 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1891 // I didn't change PBF_MAX_PCNT setting.
1892 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1893 MACValue &= 0xFFFFFF00;
1894 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1895 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1900 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1902 #endif // DOT11_N_SUPPORT //
1904 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1905 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1906 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1907 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1908 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1909 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1911 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1913 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1914 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1917 NdisAcquireSpinLock(&pAd->MacTabLock);
1918 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1919 NdisReleaseSpinLock(&pAd->MacTabLock);
1922 // Patch Atheros AP TX will breakdown issue.
1923 // AP Model: DLink DWL-8200AP
1925 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1927 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1931 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1934 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1935 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1937 #ifdef DOT11_N_SUPPORT
1938 #ifdef DOT11N_DRAFT3
1939 if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
1941 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
1942 BuildEffectedChannelList(pAd);
1944 #endif // DOT11N_DRAFT3 //
1945 #endif // DOT11_N_SUPPORT //
1949 ==========================================================================
1951 Routine Description:
1952 Disconnect current BSSID
1955 pAd - Pointer to our adapter
1956 IsReqFromAP - Request from AP
1961 IRQL = DISPATCH_LEVEL
1964 We need more information to know it's this requst from AP.
1965 If yes! we need to do extra handling, for example, remove the WPA key.
1966 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1967 remove while auto reconnect.
1968 Disconnect request from AP, it means we will start afresh 4-way handshaking
1971 ==========================================================================
1974 IN PRTMP_ADAPTER pAd,
1975 IN BOOLEAN IsReqFromAP)
1977 UCHAR i, ByteValue = 0;
1980 // Do nothing if monitor mode is on
1981 if (MONITOR_ON(pAd))
1985 // Nothing to do in ATE mode.
1988 #endif // RALINK_ATE //
1990 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1991 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1993 // Not allow go to sleep within linkdown function.
1994 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1996 if (pAd->CommonCfg.bWirelessEvent)
1998 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
2001 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
2002 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
2005 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
2008 pAd->Mlme.bPsPollTimerRunning = FALSE;
2009 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
2012 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
2013 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
2014 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
2016 AsicForceWakeup(pAd, RTMP_HALT);
2017 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
2020 pAd->bPCIclkOff = FALSE;
2022 if (ADHOC_ON(pAd)) // Adhoc mode link down
2024 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
2026 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
2027 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2028 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2029 RTMP_IndicateMediaState(pAd);
2030 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2031 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2032 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
2034 else // Infra structure mode
2036 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
2038 #ifdef QOS_DLS_SUPPORT
2039 // DLS tear down frame must be sent before link down
2040 // send DLS-TEAR_DOWN message
2041 if (pAd->CommonCfg.bDLSCapable)
2043 // tear down local dls table entry
2044 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
2046 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2048 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2049 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2053 // tear down peer dls table entry
2054 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
2056 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2058 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2059 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2063 #endif // QOS_DLS_SUPPORT //
2065 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
2066 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2068 // Saved last SSID for linkup comparison
2069 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
2070 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
2071 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
2072 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
2074 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2075 RTMP_IndicateMediaState(pAd);
2076 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2077 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
2078 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
2083 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
2084 // Otherwise lost beacon or receive De-Authentication from AP,
2085 // then we should delete BSSID from BssTable.
2086 // If we don't delete from entry, roaming will fail.
2088 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2091 // restore back to -
2092 // 1. long slot (20 us) or short slot (9 us) time
2093 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
2094 // 3. short preamble
2095 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
2097 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
2100 // Record current AP's information.
2101 // for later used reporting Adjacent AP report.
2103 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
2104 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
2105 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
2106 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
2109 #ifdef EXT_BUILD_CHANNEL_LIST
2110 // Country IE of the AP will be evaluated and will be used.
2111 if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
2113 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
2114 pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
2115 BuildChannelListEx(pAd);
2117 #endif // EXT_BUILD_CHANNEL_LIST //
2121 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2123 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2124 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
2127 pAd->StaCfg.CCXQosECWMin = 4;
2128 pAd->StaCfg.CCXQosECWMax = 10;
2130 AsicSetSlotTime(pAd, TRUE); //FALSE);
2131 AsicSetEdcaParm(pAd, NULL);
2134 RTMPSetLED(pAd, LED_LINK_DOWN);
2135 pAd->LedIndicatorStregth = 0xF0;
2136 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
2138 AsicDisableSync(pAd);
2140 pAd->Mlme.PeriodicRound = 0;
2141 pAd->Mlme.OneSecPeriodicRound = 0;
2143 if (pAd->StaCfg.BssType == BSS_INFRA)
2145 // Remove StaCfg Information after link down
2146 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
2147 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
2148 pAd->CommonCfg.SsidLen = 0;
2150 #ifdef DOT11_N_SUPPORT
2151 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
2152 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
2153 pAd->MlmeAux.HtCapabilityLen = 0;
2154 pAd->MlmeAux.NewExtChannelOffset = 0xff;
2155 #endif // DOT11_N_SUPPORT //
2157 // Reset WPA-PSK state. Only reset when supplicant enabled
2158 if (pAd->StaCfg.WpaState != SS_NOTUSE)
2160 pAd->StaCfg.WpaState = SS_START;
2161 // Clear Replay counter
2162 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2164 #ifdef QOS_DLS_SUPPORT
2165 if (pAd->CommonCfg.bDLSCapable)
2166 NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
2167 #endif // QOS_DLS_SUPPORT //
2172 // if link down come from AP, we need to remove all WPA keys on WPA mode.
2173 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
2175 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
2177 // Remove all WPA keys
2178 RTMPWPARemoveAllKeys(pAd);
2181 // 802.1x port control
2182 #ifdef WPA_SUPPLICANT_SUPPORT
2183 // Prevent clear PortSecured here with static WEP
2184 // NetworkManger set security policy first then set SSID to connect AP.
2185 if (pAd->StaCfg.WpaSupplicantUP &&
2186 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
2187 (pAd->StaCfg.IEEE8021X == FALSE))
2189 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2192 #endif // WPA_SUPPLICANT_SUPPORT //
2194 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2195 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2198 NdisAcquireSpinLock(&pAd->MacTabLock);
2199 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2200 NdisReleaseSpinLock(&pAd->MacTabLock);
2202 pAd->StaCfg.MicErrCnt = 0;
2204 // Turn off Ckip control flag
2205 pAd->StaCfg.bCkipOn = FALSE;
2206 pAd->StaCfg.CCXEnable = FALSE;
2208 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2209 // Update extra information to link is up
2210 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2212 pAd->StaCfg.AdhocBOnlyJoined = FALSE;
2213 pAd->StaCfg.AdhocBGJoined = FALSE;
2214 pAd->StaCfg.Adhoc20NJoined = FALSE;
2215 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2217 // Reset the Current AP's IP address
2218 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
2220 // Clean association information
2221 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
2222 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
2223 pAd->StaCfg.ReqVarIELen = 0;
2224 pAd->StaCfg.ResVarIELen = 0;
2227 // Reset RSSI value after link down
2229 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2230 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2231 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2232 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2233 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2234 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2237 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2238 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2240 #ifdef DOT11_N_SUPPORT
2242 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
2244 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
2246 pAd->CommonCfg.BBPCurrentBW = BW_20;
2247 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2248 ByteValue &= (~0x18);
2249 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2251 #endif // DOT11_N_SUPPORT //
2253 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2254 ByteValue &= (~0x18);
2255 if (pAd->Antenna.field.TxPath == 2)
2259 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2261 RTMPSetPiggyBack(pAd,FALSE);
2262 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2264 #ifdef DOT11_N_SUPPORT
2265 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2266 #endif // DOT11_N_SUPPORT //
2268 // Restore all settings in the following.
2269 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2270 AsicDisableRDG(pAd);
2271 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2272 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2274 #ifdef DOT11_N_SUPPORT
2275 #ifdef DOT11N_DRAFT3
2276 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
2277 pAd->CommonCfg.BSSCoexist2040.word = 0;
2279 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
2281 pAd->ChannelList[i].bEffectedChannel = FALSE;
2283 #endif // DOT11N_DRAFT3 //
2284 #endif // DOT11_N_SUPPORT //
2286 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2287 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2289 // Allow go to sleep after linkdown steps.
2290 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
2292 #ifdef WPA_SUPPLICANT_SUPPORT
2293 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2294 if (pAd->StaCfg.WpaSupplicantUP) {
2295 union iwreq_data wrqu;
2296 //send disassociate event to wpa_supplicant
2297 memset(&wrqu, 0, sizeof(wrqu));
2298 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2299 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2301 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2302 #endif // WPA_SUPPLICANT_SUPPORT //
2304 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2306 union iwreq_data wrqu;
2307 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2308 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2310 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2314 ==========================================================================
2317 IRQL = DISPATCH_LEVEL
2319 ==========================================================================
2321 VOID IterateOnBssTab(
2322 IN PRTMP_ADAPTER pAd)
2324 MLME_START_REQ_STRUCT StartReq;
2325 MLME_JOIN_REQ_STRUCT JoinReq;
2328 // Change the wepstatus to original wepstatus
2329 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2330 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2331 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2333 BssIdx = pAd->MlmeAux.BssIdx;
2334 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2336 // Check cipher suite, AP must have more secured cipher than station setting
2337 // Set the Pairwise and Group cipher to match the intended AP setting
2338 // We can only connect to AP with less secured cipher setting
2339 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2341 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2343 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2344 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2345 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2346 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2347 else // There is no PairCipher Aux, downgrade our capability to TKIP
2348 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2350 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2352 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2354 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2355 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2356 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2357 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2358 else // There is no PairCipher Aux, downgrade our capability to TKIP
2359 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2362 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2365 // Set Mix cipher flag
2366 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2367 if (pAd->StaCfg.bMixCipher == TRUE)
2369 // If mix cipher, re-build RSNIE
2370 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2373 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2374 JoinParmFill(pAd, &JoinReq, BssIdx);
2375 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2377 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2379 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2381 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2382 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2383 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2384 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2388 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2389 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2390 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2391 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2395 // for re-association only
2396 // IRQL = DISPATCH_LEVEL
2397 VOID IterateOnBssTab2(
2398 IN PRTMP_ADAPTER pAd)
2400 MLME_REASSOC_REQ_STRUCT ReassocReq;
2404 BssIdx = pAd->MlmeAux.RoamIdx;
2405 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2407 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2409 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2411 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2412 AsicLockChannel(pAd, pBss->Channel);
2414 // reassociate message has the same structure as associate message
2415 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2416 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2417 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2418 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2420 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2424 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2425 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2426 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2427 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2432 ==========================================================================
2435 IRQL = DISPATCH_LEVEL
2437 ==========================================================================
2440 IN PRTMP_ADAPTER pAd,
2441 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2444 JoinReq->BssIdx = BssIdx;
2448 ==========================================================================
2451 IRQL = DISPATCH_LEVEL
2453 ==========================================================================
2456 IN PRTMP_ADAPTER pAd,
2457 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2463 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2464 ScanReq->SsidLen = SsidLen;
2465 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2466 ScanReq->BssType = BssType;
2467 ScanReq->ScanType = ScanType;
2470 #ifdef QOS_DLS_SUPPORT
2472 ==========================================================================
2475 IRQL = DISPATCH_LEVEL
2477 ==========================================================================
2480 IN PRTMP_ADAPTER pAd,
2481 IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
2482 IN PRT_802_11_DLS pDls,
2485 pDlsReq->pDLS = pDls;
2486 pDlsReq->Reason = reason;
2488 #endif // QOS_DLS_SUPPORT //
2491 ==========================================================================
2494 IRQL = DISPATCH_LEVEL
2496 ==========================================================================
2499 IN PRTMP_ADAPTER pAd,
2500 IN OUT MLME_START_REQ_STRUCT *StartReq,
2504 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2505 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2506 StartReq->SsidLen = SsidLen;
2510 ==========================================================================
2513 IRQL = DISPATCH_LEVEL
2515 ==========================================================================
2518 IN PRTMP_ADAPTER pAd,
2519 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2523 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2525 AuthReq->Timeout = AUTH_TIMEOUT;
2529 ==========================================================================
2532 IRQL = DISPATCH_LEVEL
2534 ==========================================================================
2538 IN PRTMP_ADAPTER pAd)
2540 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2541 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2542 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2543 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2544 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2545 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2548 // IRQL = DISPATCH_LEVEL
2549 VOID ComposeNullFrame(
2550 IN PRTMP_ADAPTER pAd)
2552 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2553 pAd->NullFrame.FC.Type = BTYPE_DATA;
2554 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2555 pAd->NullFrame.FC.ToDs = 1;
2556 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2557 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2558 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2566 ==========================================================================
2568 Pre-build a BEACON frame in the shared memory
2570 IRQL = PASSIVE_LEVEL
2571 IRQL = DISPATCH_LEVEL
2573 ==========================================================================
2575 ULONG MakeIbssBeacon(
2576 IN PRTMP_ADAPTER pAd)
2578 UCHAR DsLen = 1, IbssLen = 2;
2579 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2580 HEADER_802_11 BcnHdr;
2581 USHORT CapabilityInfo;
2582 LARGE_INTEGER FakeTimestamp;
2584 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2585 CHAR *pBeaconFrame = pAd->BeaconBuf;
2587 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2588 UCHAR SupRateLen = 0;
2589 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2590 UCHAR ExtRateLen = 0;
2591 UCHAR RSNIe = IE_WPA;
2593 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2595 SupRate[0] = 0x82; // 1 mbps
2596 SupRate[1] = 0x84; // 2 mbps
2597 SupRate[2] = 0x8b; // 5.5 mbps
2598 SupRate[3] = 0x96; // 11 mbps
2602 else if (pAd->CommonCfg.Channel > 14)
2604 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2605 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2606 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2607 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2608 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2609 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2610 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2611 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2616 // Also Update MlmeRate & RtsRate for G only & A only
2618 pAd->CommonCfg.MlmeRate = RATE_6;
2619 pAd->CommonCfg.RtsRate = RATE_6;
2620 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2621 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2622 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2623 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2627 SupRate[0] = 0x82; // 1 mbps
2628 SupRate[1] = 0x84; // 2 mbps
2629 SupRate[2] = 0x8b; // 5.5 mbps
2630 SupRate[3] = 0x96; // 11 mbps
2633 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2634 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2635 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2636 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2637 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2638 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2639 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2640 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2644 pAd->StaActive.SupRateLen = SupRateLen;
2645 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2646 pAd->StaActive.ExtRateLen = ExtRateLen;
2647 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2649 // compose IBSS beacon frame
2650 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2651 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2652 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2653 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2654 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2656 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2657 sizeof(HEADER_802_11), &BcnHdr,
2658 TIMESTAMP_LEN, &FakeTimestamp,
2659 2, &pAd->CommonCfg.BeaconPeriod,
2662 1, &pAd->CommonCfg.SsidLen,
2663 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2666 SupRateLen, SupRate,
2669 1, &pAd->CommonCfg.Channel,
2672 2, &pAd->StaActive.AtimWin,
2675 // add ERP_IE and EXT_RAE IE of in 802.11g
2680 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2684 ExtRateLen, ExtRate,
2689 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2690 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2693 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2695 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2697 1, &pAd->StaCfg.RSNIE_Len,
2698 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2703 #ifdef DOT11_N_SUPPORT
2704 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2707 UCHAR HtLen, HtLen1;
2709 #ifdef RT_BIG_ENDIAN
2710 HT_CAPABILITY_IE HtCapabilityTmp;
2711 ADD_HT_INFO_IE addHTInfoTmp;
2712 USHORT b2lTmp, b2lTmp2;
2715 // add HT Capability IE
2716 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2717 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2718 #ifndef RT_BIG_ENDIAN
2719 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2722 HtLen, &pAd->CommonCfg.HtCapability,
2725 HtLen1, &pAd->CommonCfg.AddHTInfo,
2728 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2729 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2730 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2732 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2733 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2734 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2736 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2739 HtLen, &HtCapabilityTmp,
2742 HtLen1, &addHTInfoTmp,
2747 #endif // DOT11_N_SUPPORT //
2749 //beacon use reserved WCID 0xff
2750 if (pAd->CommonCfg.Channel > 14)
2752 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2753 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2757 // Set to use 1Mbps for Adhoc beacon.
2758 HTTRANSMIT_SETTING Transmit;
2760 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2761 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2764 #ifdef RT_BIG_ENDIAN
2765 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2766 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2769 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2770 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));