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:
237 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
238 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
239 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
240 #ifdef WPA_SUPPLICANT_SUPPORT
241 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
242 #endif // WPA_SUPPLICANT_SUPPORT //
244 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
245 // Since calling this indicate user don't want to connect to that SSID anymore.
246 pAd->MlmeAux.AutoReconnectSsidLen= 32;
247 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
251 case MT2_MLME_ROAMING_REQ:
252 CntlMlmeRoamingProc(pAd, Elem);
255 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
256 WpaMicFailureReportFrame(pAd, Elem);
259 #ifdef QOS_DLS_SUPPORT
260 case RT_OID_802_11_SET_DLS_PARAM:
261 CntlOidDLSSetupProc(pAd, Elem);
263 #endif // QOS_DLS_SUPPORT //
266 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
271 VOID CntlOidScanProc(
272 IN PRTMP_ADAPTER pAd,
273 IN MLME_QUEUE_ELEM *Elem)
275 MLME_SCAN_REQ_STRUCT ScanReq;
276 ULONG BssIdx = BSS_NOT_FOUND;
279 // record current BSS if network is connected.
280 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
281 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
283 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
284 if (BssIdx != BSS_NOT_FOUND)
286 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
290 // clean up previous SCAN result, add current BSS back to table if any
291 BssTableInit(&pAd->ScanTab);
292 if (BssIdx != BSS_NOT_FOUND)
294 // DDK Note: If the NIC is associated with a particular BSSID and SSID
295 // that are not contained in the list of BSSIDs generated by this scan, the
296 // BSSID description of the currently associated BSSID and SSID should be
297 // appended to the list of BSSIDs in the NIC's database.
298 // To ensure this, we append this BSS as the first entry in SCAN result
299 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
300 pAd->ScanTab.BssNr = 1;
303 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
304 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
305 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
306 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
310 ==========================================================================
312 Before calling this routine, user desired SSID should already been
313 recorded in CommonCfg.Ssid[]
314 IRQL = DISPATCH_LEVEL
316 ==========================================================================
318 VOID CntlOidSsidProc(
319 IN PRTMP_ADAPTER pAd,
320 IN MLME_QUEUE_ELEM * Elem)
322 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
323 MLME_DISASSOC_REQ_STRUCT DisassocReq;
326 // BBP and RF are not accessible in PS mode, we has to wake them up first
327 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
328 AsicForceWakeup(pAd, RTMP_HALT);
330 // Step 1. record the desired user settings to MlmeAux
331 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
332 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
333 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
334 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
335 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
339 // Update Reconnect Ssid, that user desired to connect.
341 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
342 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
343 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
345 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
346 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
347 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
349 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
350 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
351 NdisGetSystemUpTime(&Now);
353 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
354 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
355 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
356 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
358 // Case 1. already connected with an AP who has the desired SSID
361 // Add checking Mode "LEAP" for CCX 1.0
362 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
363 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
364 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
365 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
367 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
368 #endif // LEAP_SUPPORT //
370 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
372 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
373 // connection process
374 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
375 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
376 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
377 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
378 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
380 else if (pAd->bConfigChanged == TRUE)
382 // case 1.2 Important Config has changed, we have to reconnect to the same AP
383 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
384 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
385 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
386 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
387 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
391 // case 1.3. already connected to the SSID with highest RSSI.
392 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
394 // (HCT 12.1) 1c_wlan_mediaevents required
395 // media connect events are indicated when associating with the same AP
400 // Since MediaState already is NdisMediaStateConnected
401 // We just indicate the connect event again to meet the WHQL required.
403 pAd->IndicateMediaState = NdisMediaStateConnected;
404 RTMP_IndicateMediaState(pAd);
405 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
408 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
409 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
411 union iwreq_data wrqu;
413 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
414 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
415 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
418 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
421 else if (INFRA_ON(pAd))
425 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
426 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
427 // But media status is connected, so the SSID not report correctly.
429 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
432 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
434 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
436 // case 2. active INFRA association existent
437 // roaming is done within miniport driver, nothing to do with configuration
438 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
439 // disassociate with the current associated AP,
440 // then perform a new association with this new SSID, no matter the
441 // new/old SSID are the same or not.
442 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
443 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
444 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
445 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
446 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
452 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
453 LinkDown(pAd, FALSE);
454 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
455 pAd->IndicateMediaState = NdisMediaStateDisconnected;
456 RTMP_IndicateMediaState(pAd);
457 pAd->ExtraInfo = GENERAL_LINK_DOWN;
458 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
461 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
462 (pAd->StaCfg.bAutoReconnect == TRUE) &&
463 (pAd->MlmeAux.BssType == BSS_INFRA) &&
464 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
467 MLME_SCAN_REQ_STRUCT ScanReq;
469 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
470 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
471 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
472 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
473 // Reset Missed scan number
474 pAd->StaCfg.LastScanTime = Now;
478 pAd->MlmeAux.BssIdx = 0;
479 IterateOnBssTab(pAd);
486 ==========================================================================
489 IRQL = DISPATCH_LEVEL
491 ==========================================================================
493 VOID CntlOidRTBssidProc(
494 IN PRTMP_ADAPTER pAd,
495 IN MLME_QUEUE_ELEM * Elem)
498 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
499 MLME_DISASSOC_REQ_STRUCT DisassocReq;
500 MLME_JOIN_REQ_STRUCT JoinReq;
502 // record user desired settings
503 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
504 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
507 // Update Reconnect Ssid, that user desired to connect.
509 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
510 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
511 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
513 // find the desired BSS in the latest SCAN result table
514 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
515 if (BssIdx == BSS_NOT_FOUND)
517 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
518 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
522 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
523 // Because we need this entry to become the JOIN target in later on SYNC state machine
524 pAd->MlmeAux.BssIdx = 0;
525 pAd->MlmeAux.SsidBssTab.BssNr = 1;
526 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
528 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
529 // we just follow normal procedure. The reason of user doing this may because he/she changed
530 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
531 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
532 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
533 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
534 // connection when setting the same BSSID.
535 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
536 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
538 // already connected to the same BSSID, go back to idle state directly
539 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
540 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
541 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
543 union iwreq_data wrqu;
545 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
546 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
547 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
550 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
556 // disassoc from current AP first
557 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
558 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
559 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
560 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
562 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
568 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
569 LinkDown(pAd, FALSE);
570 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
571 pAd->IndicateMediaState = NdisMediaStateDisconnected;
572 RTMP_IndicateMediaState(pAd);
573 pAd->ExtraInfo = GENERAL_LINK_DOWN;
574 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
577 // Change the wepstatus to original wepstatus
578 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
579 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
580 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
582 // Check cipher suite, AP must have more secured cipher than station setting
583 // Set the Pairwise and Group cipher to match the intended AP setting
584 // We can only connect to AP with less secured cipher setting
585 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
587 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
589 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
590 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
591 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
592 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
593 else // There is no PairCipher Aux, downgrade our capability to TKIP
594 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
596 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
598 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
600 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
601 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
602 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
603 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
604 else // There is no PairCipher Aux, downgrade our capability to TKIP
605 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
608 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
611 // Set Mix cipher flag
612 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
613 if (pAd->StaCfg.bMixCipher == TRUE)
615 // If mix cipher, re-build RSNIE
616 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
618 // No active association, join the BSS immediately
619 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
620 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
622 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
623 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
625 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
630 // Roaming is the only external request triggering CNTL state machine
631 // despite of other "SET OID" operation. All "SET OID" related oerations
632 // happen in sequence, because no other SET OID will be sent to this device
633 // until the the previous SET operation is complete (successful o failed).
634 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
635 // or been corrupted by other "SET OID"?
637 // IRQL = DISPATCH_LEVEL
638 VOID CntlMlmeRoamingProc(
639 IN PRTMP_ADAPTER pAd,
640 IN MLME_QUEUE_ELEM *Elem)
643 // AP in different channel may show lower RSSI than actual value??
644 // should we add a weighting factor to compensate it?
645 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
647 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
648 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
650 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
651 pAd->MlmeAux.BssIdx = 0;
652 IterateOnBssTab(pAd);
655 #ifdef QOS_DLS_SUPPORT
657 ==========================================================================
660 IRQL = DISPATCH_LEVEL
662 ==========================================================================
664 VOID CntlOidDLSSetupProc(
665 IN PRTMP_ADAPTER pAd,
666 IN MLME_QUEUE_ELEM *Elem)
668 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)Elem->Msg;
669 MLME_DLS_REQ_STRUCT MlmeDlsReq;
671 USHORT reason = REASON_UNSPECIFY;
673 DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n",
674 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5],
675 pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer));
677 if (!pAd->CommonCfg.bDLSCapable)
680 // DLS will not be supported when Adhoc mode
683 for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++)
685 if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
686 (pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
688 // 1. Same setting, just drop it
689 DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n"));
692 else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
693 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
695 // 2. Disable DLS link case, just tear down DLS link
696 reason = REASON_QOS_UNWANTED_MECHANISM;
697 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
698 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
699 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
700 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
701 DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n"));
704 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid)
706 // 3. Enable case, start DLS setup procedure
707 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
709 //Update countdown timer
710 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
711 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
712 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
713 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n"));
716 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
717 (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
719 // 4. update mac case, tear down old DLS and setup new DLS
720 reason = REASON_QOS_UNWANTED_MECHANISM;
721 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
722 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
723 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
724 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
725 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
726 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
727 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
728 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS tear down and restart case\n"));
731 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
732 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr) && (pAd->StaCfg.DLSEntry[i].TimeOut != pDLS->TimeOut))
734 // 5. update timeout case, start DLS setup procedure (no tear down)
735 pAd->StaCfg.DLSEntry[i].TimeOut = pDLS->TimeOut;
736 //Update countdown timer
737 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
738 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
739 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
740 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS update timeout case\n"));
743 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
744 (pAd->StaCfg.DLSEntry[i].Status != DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
746 // 6. re-setup case, start DLS setup procedure (no tear down)
747 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
748 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
749 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS retry setup procedure\n"));
754 DBGPRINT(RT_DEBUG_WARN,("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n",
755 i, pAd->StaCfg.DLSEntry[i].Valid, pAd->StaCfg.DLSEntry[i].Status, pAd->StaCfg.DLSEntry[i].TimeOut));
760 #endif // QOS_DLS_SUPPORT //
763 ==========================================================================
766 IRQL = DISPATCH_LEVEL
768 ==========================================================================
770 VOID CntlWaitDisassocProc(
771 IN PRTMP_ADAPTER pAd,
772 IN MLME_QUEUE_ELEM *Elem)
774 MLME_START_REQ_STRUCT StartReq;
776 if (Elem->MsgType == MT2_DISASSOC_CONF)
778 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
780 if (pAd->CommonCfg.bWirelessEvent)
782 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
785 LinkDown(pAd, FALSE);
787 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
788 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
790 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
791 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
792 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
793 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
795 // case 2. try each matched BSS
798 pAd->MlmeAux.BssIdx = 0;
800 IterateOnBssTab(pAd);
806 ==========================================================================
809 IRQL = DISPATCH_LEVEL
811 ==========================================================================
813 VOID CntlWaitJoinProc(
814 IN PRTMP_ADAPTER pAd,
815 IN MLME_QUEUE_ELEM *Elem)
818 MLME_AUTH_REQ_STRUCT AuthReq;
820 if (Elem->MsgType == MT2_JOIN_CONF)
822 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
823 if (Reason == MLME_SUCCESS)
825 // 1. joined an IBSS, we are pretty much done here
826 if (pAd->MlmeAux.BssType == BSS_ADHOC)
829 // 5G bands rules of Japan:
830 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
832 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
833 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
836 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
837 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
841 LinkUp(pAd, BSS_ADHOC);
842 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
843 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
844 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
845 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
847 pAd->IndicateMediaState = NdisMediaStateConnected;
848 pAd->ExtraInfo = GENERAL_LINK_UP;
850 // 2. joined a new INFRA network, start from authentication
854 // Add AuthMode "LEAP" for CCX 1.X
855 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
857 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
860 #endif // LEAP_SUPPORT //
862 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
863 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
864 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
866 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
870 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
873 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
874 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
876 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
881 // 3. failed, try next BSS
882 pAd->MlmeAux.BssIdx++;
883 IterateOnBssTab(pAd);
890 ==========================================================================
893 IRQL = DISPATCH_LEVEL
895 ==========================================================================
897 VOID CntlWaitStartProc(
898 IN PRTMP_ADAPTER pAd,
899 IN MLME_QUEUE_ELEM *Elem)
903 if (Elem->MsgType == MT2_START_CONF)
905 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
906 if (Result == MLME_SUCCESS)
909 // 5G bands rules of Japan:
910 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
912 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
913 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
916 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
917 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
920 #ifdef DOT11_N_SUPPORT
921 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
925 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
926 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
927 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
928 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
929 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
930 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
932 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
933 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
935 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
937 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
938 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
940 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
944 #endif // DOT11_N_SUPPORT //
946 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
948 LinkUp(pAd, BSS_ADHOC);
949 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
950 // Before send beacon, driver need do radar detection
951 if ((pAd->CommonCfg.Channel > 14 )
952 && (pAd->CommonCfg.bIEEE80211H == 1)
953 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
955 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
956 pAd->CommonCfg.RadarDetect.RDCount = 0;
958 BbpRadarDetectionStart(pAd);
959 #endif // DFS_SUPPORT //
962 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
963 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
964 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
968 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
969 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
975 ==========================================================================
978 IRQL = DISPATCH_LEVEL
980 ==========================================================================
982 VOID CntlWaitAuthProc(
983 IN PRTMP_ADAPTER pAd,
984 IN MLME_QUEUE_ELEM *Elem)
987 MLME_ASSOC_REQ_STRUCT AssocReq;
988 MLME_AUTH_REQ_STRUCT AuthReq;
990 if (Elem->MsgType == MT2_AUTH_CONF)
992 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
993 if (Reason == MLME_SUCCESS)
995 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
996 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
997 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1001 // Cisco Leap CCKM supported Re-association.
1003 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
1005 //if CCKM is turn on , that's mean Fast Reauthentication
1006 //Use CCKM Reassociation instead of normal association for Fast Roaming.
1007 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
1008 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1010 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
1013 #endif // LEAP_SUPPORT //
1015 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1016 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1018 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1023 // This fail may because of the AP already keep us in its MAC table without
1024 // ageing-out. The previous authentication attempt must have let it remove us.
1025 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
1026 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
1028 //Add AuthMode "LEAP" for CCX 1.X
1029 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1031 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
1034 #endif // LEAP_SUPPORT //
1036 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
1037 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
1039 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
1040 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
1044 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1047 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1048 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1050 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1056 ==========================================================================
1059 IRQL = DISPATCH_LEVEL
1061 ==========================================================================
1063 VOID CntlWaitAuthProc2(
1064 IN PRTMP_ADAPTER pAd,
1065 IN MLME_QUEUE_ELEM *Elem)
1068 MLME_ASSOC_REQ_STRUCT AssocReq;
1069 MLME_AUTH_REQ_STRUCT AuthReq;
1071 if (Elem->MsgType == MT2_AUTH_CONF)
1073 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1074 if (Reason == MLME_SUCCESS)
1076 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1077 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1078 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1079 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1080 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1082 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1087 // Process LEAP first, since it use different control variable
1088 // We don't want to affect other poven operation
1089 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1091 // LEAP Auth not success, try next BSS
1092 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
1093 DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
1094 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1095 pAd->MlmeAux.BssIdx++;
1096 IterateOnBssTab(pAd);
1099 #endif // LEAP_SUPPORT //
1100 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
1101 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
1103 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
1104 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1105 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1106 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1108 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1112 // not success, try next BSS
1113 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
1114 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
1115 pAd->MlmeAux.BssIdx++;
1116 IterateOnBssTab(pAd);
1123 ==========================================================================
1126 IRQL = DISPATCH_LEVEL
1128 ==========================================================================
1130 VOID CntlWaitAssocProc(
1131 IN PRTMP_ADAPTER pAd,
1132 IN MLME_QUEUE_ELEM *Elem)
1136 if (Elem->MsgType == MT2_ASSOC_CONF)
1138 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1139 if (Reason == MLME_SUCCESS)
1141 LinkUp(pAd, BSS_INFRA);
1142 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1143 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1145 if (pAd->CommonCfg.bWirelessEvent)
1147 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1152 // not success, try next BSS
1153 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1154 pAd->MlmeAux.BssIdx++;
1155 IterateOnBssTab(pAd);
1161 ==========================================================================
1164 IRQL = DISPATCH_LEVEL
1166 ==========================================================================
1168 VOID CntlWaitReassocProc(
1169 IN PRTMP_ADAPTER pAd,
1170 IN MLME_QUEUE_ELEM *Elem)
1174 if (Elem->MsgType == MT2_REASSOC_CONF)
1176 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1177 if (Result == MLME_SUCCESS)
1180 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1182 LinkUp(pAd, BSS_INFRA);
1184 // send wireless event - for association
1185 if (pAd->CommonCfg.bWirelessEvent)
1186 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1190 if (LEAP_CCKM_ON(pAd))
1192 STA_PORT_SECURED(pAd);
1193 pAd->StaCfg.WpaState = SS_FINISH;
1195 #endif // LEAP_SUPPORT //
1196 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1197 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1201 // reassoc failed, try to pick next BSS in the BSS Table
1202 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1203 pAd->MlmeAux.RoamIdx++;
1204 IterateOnBssTab2(pAd);
1210 ==========================================================================
1213 IRQL = DISPATCH_LEVEL
1215 ==========================================================================
1218 IN PRTMP_ADAPTER pAd,
1224 UCHAR Value = 0, idx;
1225 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1227 if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
1229 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
1230 RTMPusecDelay(6000);
1231 pAd->bPCIclkOff = FALSE;
1234 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1237 // ASSOC - DisassocTimeoutAction
1238 // CNTL - Dis-associate successful
1239 // !!! LINK DOWN !!!
1240 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1242 // To prevent DisassocTimeoutAction to call Link down after we link up,
1243 // cancel the DisassocTimer no matter what it start or not.
1245 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1247 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1249 #ifdef DOT11_N_SUPPORT
1250 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1251 #endif // DOT11_N_SUPPORT //
1252 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1253 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1254 // to examine if cipher algorithm switching is required.
1255 //rt2860b. Don't know why need this
1256 SwitchBetweenWepAndCkip(pAd);
1258 // Before power save before link up function, We will force use 1R.
1259 // So after link up, check Rx antenna # again.
1260 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1261 if(pAd->Antenna.field.RxPath == 3)
1265 else if(pAd->Antenna.field.RxPath == 2)
1269 else if(pAd->Antenna.field.RxPath == 1)
1273 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1274 pAd->StaCfg.BBPR3 = Value;
1276 if (BssType == BSS_ADHOC)
1278 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1279 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1281 #ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1282 // No carrier detection when adhoc
1283 // CarrierDetectionStop(pAd);
1284 pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
1285 #endif // CARRIER_DETECTION_SUPPORT //
1287 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1291 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1292 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1294 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1298 // reset Tx beamforming bit
1299 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1301 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1302 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1304 #ifdef DOT11_N_SUPPORT
1305 // Change to AP channel
1306 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1308 // Must using 40MHz.
1309 pAd->CommonCfg.BBPCurrentBW = BW_40;
1310 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1311 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1313 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1316 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1318 // RX : control channel at lower
1319 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1321 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1322 pAd->StaCfg.BBPR3 = Value;
1324 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1326 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1328 if (pAd->MACVersion == 0x28600100)
1330 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1331 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1332 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1333 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1336 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1338 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1340 // Must using 40MHz.
1341 pAd->CommonCfg.BBPCurrentBW = BW_40;
1342 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1343 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1345 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1348 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1350 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1352 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1354 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1356 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1357 pAd->StaCfg.BBPR3 = Value;
1359 if (pAd->MACVersion == 0x28600100)
1361 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1362 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1363 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1364 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1367 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1370 #endif // DOT11_N_SUPPORT //
1372 pAd->CommonCfg.BBPCurrentBW = BW_20;
1373 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1374 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1375 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1377 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1379 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1381 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1383 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1385 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1387 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1388 pAd->StaCfg.BBPR3 = Value;
1390 if (pAd->MACVersion == 0x28600100)
1392 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1393 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1394 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1395 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1398 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1401 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1403 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1405 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1407 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1408 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1410 #ifdef DOT11_N_SUPPORT
1411 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1412 #endif // DOT11_N_SUPPORT //
1414 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1416 AsicSetSlotTime(pAd, TRUE);
1417 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1419 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1420 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1422 #ifdef DOT11_N_SUPPORT
1423 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1425 // Update HT protectionfor based on AP's operating mode.
1426 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1428 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1431 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1433 #endif // DOT11_N_SUPPORT //
1435 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1437 NdisGetSystemUpTime(&Now);
1438 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1440 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1441 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1443 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1446 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1448 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1451 RadarDetectionStop(pAd);
1452 #endif // DFS_SUPPORT //
1454 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1456 if (BssType == BSS_ADHOC)
1458 MakeIbssBeacon(pAd);
1459 if ((pAd->CommonCfg.Channel > 14)
1460 && (pAd->CommonCfg.bIEEE80211H == 1)
1461 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1467 AsicEnableIbssSync(pAd);
1470 // In ad hoc mode, use MAC table from index 1.
1471 // 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.
1472 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1473 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1475 // If WEP is enabled, add key material and cipherAlg into Asic
1476 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1478 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1483 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1485 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1486 Key = pAd->SharedKey[BSS0][idx].Key;
1488 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1490 // Set key material and cipherAlg to Asic
1491 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1493 if (idx == pAd->StaCfg.DefaultKeyId)
1495 // Update WCID attribute table and IVEIV table for this group key table
1496 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1503 // If WPANone is enabled, add key material and cipherAlg into Asic
1504 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1505 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1507 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1509 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1510 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1511 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1513 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1515 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1516 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1519 // Decide its ChiperAlg
1520 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1521 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1522 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1523 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1526 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1527 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1530 // Set key material and cipherAlg to Asic
1531 AsicAddSharedKeyEntry(pAd,
1534 pAd->SharedKey[BSS0][0].CipherAlg,
1535 pAd->SharedKey[BSS0][0].Key,
1536 pAd->SharedKey[BSS0][0].TxMic,
1537 pAd->SharedKey[BSS0][0].RxMic);
1539 // Update WCID attribute table and IVEIV table for this group key table
1540 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1547 // Check the new SSID with last SSID
1548 while (Cancelled == TRUE)
1550 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1552 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1554 // Link to the old one no linkdown is required.
1558 // Send link down event before set to link up
1559 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1560 RTMP_IndicateMediaState(pAd);
1561 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1562 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1567 // On WPA mode, Remove All Keys if not connect to the last BSSID
1568 // Key will be set after 4-way handshake.
1570 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1574 // Remove all WPA keys
1575 RTMPWPARemoveAllKeys(pAd);
1576 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1577 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1579 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1580 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1582 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1583 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1585 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1588 // the decision of using "short slot time" or not may change dynamically due to
1589 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1592 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1593 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1596 ComposeNullFrame(pAd);
1598 AsicEnableBssSync(pAd);
1600 // Add BSSID to WCID search table
1601 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1603 NdisAcquireSpinLock(&pAd->MacTabLock);
1604 // add this BSSID entry into HASH table
1608 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1609 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1610 if (pAd->MacTab.Hash[HashIdx] == NULL)
1612 pAd->MacTab.Hash[HashIdx] = pEntry;
1616 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1617 while (pCurrEntry->pNext != NULL)
1618 pCurrEntry = pCurrEntry->pNext;
1619 pCurrEntry->pNext = pEntry;
1622 NdisReleaseSpinLock(&pAd->MacTabLock);
1625 // If WEP is enabled, add paiewise and shared key
1626 #ifdef WPA_SUPPLICANT_SUPPORT
1627 if (((pAd->StaCfg.WpaSupplicantUP)&&
1628 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1629 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1630 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1631 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1633 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1634 #endif // WPA_SUPPLICANT_SUPPORT //
1639 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1641 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1642 Key = pAd->SharedKey[BSS0][idx].Key;
1644 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1646 // Set key material and cipherAlg to Asic
1647 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1649 if (idx == pAd->StaCfg.DefaultKeyId)
1651 // Assign group key info
1652 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1654 // Assign pairwise key info
1655 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1661 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1662 // should wait until at least 2 active nodes in this BSSID.
1663 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1666 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1668 pAd->IndicateMediaState = NdisMediaStateConnected;
1669 pAd->ExtraInfo = GENERAL_LINK_UP;
1672 RTMP_IndicateMediaState(pAd);
1674 // Add BSSID in my MAC Table.
1675 NdisAcquireSpinLock(&pAd->MacTabLock);
1676 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1677 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1678 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1679 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1680 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1681 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1682 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1683 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1684 NdisReleaseSpinLock(&pAd->MacTabLock);
1686 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1687 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1689 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1690 #ifdef DOT11_N_SUPPORT
1691 MlmeUpdateHtTxRates(pAd, BSS0);
1692 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1693 #endif // DOT11_N_SUPPORT //
1696 // Report Adjacent AP report.
1699 CCXAdjacentAPReport(pAd);
1700 #endif // LEAP_SUPPORT //
1702 if (pAd->CommonCfg.bAggregationCapable)
1704 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1707 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1708 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1709 RTMPSetPiggyBack(pAd, TRUE);
1710 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1712 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1714 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1718 if (pAd->MlmeAux.APRalinkIe != 0x0)
1720 #ifdef DOT11_N_SUPPORT
1721 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1725 #endif // DOT11_N_SUPPORT //
1726 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1727 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1731 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1732 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1736 #ifdef DOT11_N_SUPPORT
1737 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));
1738 #endif // DOT11_N_SUPPORT //
1741 RTMPSetLED(pAd, LED_LINK_UP);
1743 pAd->Mlme.PeriodicRound = 0;
1744 pAd->Mlme.OneSecPeriodicRound = 0;
1745 pAd->bConfigChanged = FALSE; // Reset config flag
1746 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1748 // Set asic auto fall back
1751 UCHAR TableSize = 0;
1753 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1754 AsicUpdateAutoFallBackTable(pAd, pTable);
1757 NdisAcquireSpinLock(&pAd->MacTabLock);
1758 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1759 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1760 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1762 pEntry->bAutoTxRateSwitch = FALSE;
1763 #ifdef DOT11_N_SUPPORT
1764 if (pEntry->HTPhyMode.field.MCS == 32)
1765 pEntry->HTPhyMode.field.ShortGI = GI_800;
1767 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1768 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1769 #endif // DOT11_N_SUPPORT //
1770 // If the legacy mode is set, overwrite the transmit setting of this entry.
1771 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1772 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1775 pEntry->bAutoTxRateSwitch = TRUE;
1776 NdisReleaseSpinLock(&pAd->MacTabLock);
1778 // Let Link Status Page display first initial rate.
1779 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1780 // Select DAC according to HT or Legacy
1781 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1783 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1785 if (pAd->Antenna.field.TxPath == 2)
1789 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1793 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1795 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1798 #ifdef DOT11_N_SUPPORT
1799 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1802 else if (pEntry->MaxRAmpduFactor == 0)
1804 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1805 // Because our Init value is 1 at MACRegTable.
1806 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1808 #endif // DOT11_N_SUPPORT //
1810 // Patch for Marvel AP to gain high throughput
1811 // Need to set as following,
1812 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1813 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1814 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1815 // 4. kick per two packets when dequeue
1817 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1819 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1820 #ifdef DOT11_N_SUPPORT
1821 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1822 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1824 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1826 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1828 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1829 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1832 #endif // DOT11_N_SUPPORT //
1833 if (pAd->CommonCfg.bEnableTxBurst)
1835 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1838 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1839 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1841 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1842 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1846 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1848 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1850 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1851 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1854 #ifdef DOT11_N_SUPPORT
1855 // Re-check to turn on TX burst or not.
1856 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1858 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1859 if (pAd->CommonCfg.bEnableTxBurst)
1861 UINT32 MACValue = 0;
1862 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1863 // I didn't change PBF_MAX_PCNT setting.
1864 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1865 MACValue &= 0xFFFFFF00;
1866 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1867 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1872 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1874 #endif // DOT11_N_SUPPORT //
1876 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1877 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1878 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1879 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1880 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1881 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1883 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1885 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1886 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1889 NdisAcquireSpinLock(&pAd->MacTabLock);
1890 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1891 NdisReleaseSpinLock(&pAd->MacTabLock);
1894 // Patch Atheros AP TX will breakdown issue.
1895 // AP Model: DLink DWL-8200AP
1897 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1899 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1903 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1906 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1907 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1909 #ifdef DOT11_N_SUPPORT
1910 #ifdef DOT11N_DRAFT3
1911 if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
1913 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
1914 BuildEffectedChannelList(pAd);
1916 #endif // DOT11N_DRAFT3 //
1917 #endif // DOT11_N_SUPPORT //
1921 ==========================================================================
1923 Routine Description:
1924 Disconnect current BSSID
1927 pAd - Pointer to our adapter
1928 IsReqFromAP - Request from AP
1933 IRQL = DISPATCH_LEVEL
1936 We need more information to know it's this requst from AP.
1937 If yes! we need to do extra handling, for example, remove the WPA key.
1938 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1939 remove while auto reconnect.
1940 Disconnect request from AP, it means we will start afresh 4-way handshaking
1943 ==========================================================================
1946 IN PRTMP_ADAPTER pAd,
1947 IN BOOLEAN IsReqFromAP)
1949 UCHAR i, ByteValue = 0;
1952 // Do nothing if monitor mode is on
1953 if (MONITOR_ON(pAd))
1956 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1957 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1959 // Not allow go to sleep within linkdown function.
1960 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1962 if (pAd->CommonCfg.bWirelessEvent)
1964 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1967 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1968 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1970 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1973 pAd->Mlme.bPsPollTimerRunning = FALSE;
1974 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1977 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
1978 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
1979 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
1981 AsicForceWakeup(pAd, RTMP_HALT);
1982 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1985 pAd->bPCIclkOff = FALSE;
1986 if (ADHOC_ON(pAd)) // Adhoc mode link down
1988 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1990 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1991 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1992 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1993 RTMP_IndicateMediaState(pAd);
1994 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1995 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1996 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1998 else // Infra structure mode
2000 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
2002 #ifdef QOS_DLS_SUPPORT
2003 // DLS tear down frame must be sent before link down
2004 // send DLS-TEAR_DOWN message
2005 if (pAd->CommonCfg.bDLSCapable)
2007 // tear down local dls table entry
2008 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
2010 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2012 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2013 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2017 // tear down peer dls table entry
2018 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
2020 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2022 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2023 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2027 #endif // QOS_DLS_SUPPORT //
2029 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
2030 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2032 // Saved last SSID for linkup comparison
2033 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
2034 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
2035 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
2036 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
2038 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2039 RTMP_IndicateMediaState(pAd);
2040 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2041 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
2042 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
2047 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
2048 // Otherwise lost beacon or receive De-Authentication from AP,
2049 // then we should delete BSSID from BssTable.
2050 // If we don't delete from entry, roaming will fail.
2052 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2055 // restore back to -
2056 // 1. long slot (20 us) or short slot (9 us) time
2057 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
2058 // 3. short preamble
2059 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
2061 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
2064 // Record current AP's information.
2065 // for later used reporting Adjacent AP report.
2067 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
2068 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
2069 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
2070 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
2073 #ifdef EXT_BUILD_CHANNEL_LIST
2074 // Country IE of the AP will be evaluated and will be used.
2075 if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
2077 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
2078 pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
2079 BuildChannelListEx(pAd);
2081 #endif // EXT_BUILD_CHANNEL_LIST //
2085 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2087 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2088 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
2091 pAd->StaCfg.CCXQosECWMin = 4;
2092 pAd->StaCfg.CCXQosECWMax = 10;
2094 AsicSetSlotTime(pAd, TRUE); //FALSE);
2095 AsicSetEdcaParm(pAd, NULL);
2098 RTMPSetLED(pAd, LED_LINK_DOWN);
2099 pAd->LedIndicatorStregth = 0xF0;
2100 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
2102 AsicDisableSync(pAd);
2104 pAd->Mlme.PeriodicRound = 0;
2105 pAd->Mlme.OneSecPeriodicRound = 0;
2107 if (pAd->StaCfg.BssType == BSS_INFRA)
2109 // Remove StaCfg Information after link down
2110 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
2111 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
2112 pAd->CommonCfg.SsidLen = 0;
2114 #ifdef DOT11_N_SUPPORT
2115 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
2116 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
2117 pAd->MlmeAux.HtCapabilityLen = 0;
2118 pAd->MlmeAux.NewExtChannelOffset = 0xff;
2119 #endif // DOT11_N_SUPPORT //
2121 // Reset WPA-PSK state. Only reset when supplicant enabled
2122 if (pAd->StaCfg.WpaState != SS_NOTUSE)
2124 pAd->StaCfg.WpaState = SS_START;
2125 // Clear Replay counter
2126 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2128 #ifdef QOS_DLS_SUPPORT
2129 if (pAd->CommonCfg.bDLSCapable)
2130 NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
2131 #endif // QOS_DLS_SUPPORT //
2136 // if link down come from AP, we need to remove all WPA keys on WPA mode.
2137 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
2139 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
2141 // Remove all WPA keys
2142 RTMPWPARemoveAllKeys(pAd);
2145 // 802.1x port control
2146 #ifdef WPA_SUPPLICANT_SUPPORT
2147 // Prevent clear PortSecured here with static WEP
2148 // NetworkManger set security policy first then set SSID to connect AP.
2149 if (pAd->StaCfg.WpaSupplicantUP &&
2150 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
2151 (pAd->StaCfg.IEEE8021X == FALSE))
2153 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2156 #endif // WPA_SUPPLICANT_SUPPORT //
2158 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2159 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2162 NdisAcquireSpinLock(&pAd->MacTabLock);
2163 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2164 NdisReleaseSpinLock(&pAd->MacTabLock);
2166 pAd->StaCfg.MicErrCnt = 0;
2168 // Turn off Ckip control flag
2169 pAd->StaCfg.bCkipOn = FALSE;
2170 pAd->StaCfg.CCXEnable = FALSE;
2172 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2173 // Update extra information to link is up
2174 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2176 pAd->StaCfg.AdhocBOnlyJoined = FALSE;
2177 pAd->StaCfg.AdhocBGJoined = FALSE;
2178 pAd->StaCfg.Adhoc20NJoined = FALSE;
2179 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2181 // Reset the Current AP's IP address
2182 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
2184 // Clean association information
2185 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
2186 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
2187 pAd->StaCfg.ReqVarIELen = 0;
2188 pAd->StaCfg.ResVarIELen = 0;
2191 // Reset RSSI value after link down
2193 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2194 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2195 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2196 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2197 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2198 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2201 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2202 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2204 #ifdef DOT11_N_SUPPORT
2206 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
2208 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
2210 pAd->CommonCfg.BBPCurrentBW = BW_20;
2211 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2212 ByteValue &= (~0x18);
2213 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2215 #endif // DOT11_N_SUPPORT //
2217 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2218 ByteValue &= (~0x18);
2219 if (pAd->Antenna.field.TxPath == 2)
2223 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2225 RTMPSetPiggyBack(pAd,FALSE);
2226 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2228 #ifdef DOT11_N_SUPPORT
2229 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2230 #endif // DOT11_N_SUPPORT //
2232 // Restore all settings in the following.
2233 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2234 AsicDisableRDG(pAd);
2235 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2236 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2238 #ifdef DOT11_N_SUPPORT
2239 #ifdef DOT11N_DRAFT3
2240 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
2241 pAd->CommonCfg.BSSCoexist2040.word = 0;
2243 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
2245 pAd->ChannelList[i].bEffectedChannel = FALSE;
2247 #endif // DOT11N_DRAFT3 //
2248 #endif // DOT11_N_SUPPORT //
2250 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2251 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2253 // Allow go to sleep after linkdown steps.
2254 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
2256 #ifdef WPA_SUPPLICANT_SUPPORT
2257 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2258 if (pAd->StaCfg.WpaSupplicantUP) {
2259 union iwreq_data wrqu;
2260 //send disassociate event to wpa_supplicant
2261 memset(&wrqu, 0, sizeof(wrqu));
2262 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2263 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2265 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2266 #endif // WPA_SUPPLICANT_SUPPORT //
2268 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2270 union iwreq_data wrqu;
2271 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2272 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2274 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2278 ==========================================================================
2281 IRQL = DISPATCH_LEVEL
2283 ==========================================================================
2285 VOID IterateOnBssTab(
2286 IN PRTMP_ADAPTER pAd)
2288 MLME_START_REQ_STRUCT StartReq;
2289 MLME_JOIN_REQ_STRUCT JoinReq;
2292 // Change the wepstatus to original wepstatus
2293 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2294 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2295 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2297 BssIdx = pAd->MlmeAux.BssIdx;
2298 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2300 // Check cipher suite, AP must have more secured cipher than station setting
2301 // Set the Pairwise and Group cipher to match the intended AP setting
2302 // We can only connect to AP with less secured cipher setting
2303 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2305 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2307 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2308 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2309 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2310 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2311 else // There is no PairCipher Aux, downgrade our capability to TKIP
2312 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2314 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2316 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2318 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2319 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2320 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2321 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2322 else // There is no PairCipher Aux, downgrade our capability to TKIP
2323 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2326 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2329 // Set Mix cipher flag
2330 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2331 if (pAd->StaCfg.bMixCipher == TRUE)
2333 // If mix cipher, re-build RSNIE
2334 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2337 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2338 JoinParmFill(pAd, &JoinReq, BssIdx);
2339 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2341 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2343 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2345 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2346 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2347 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2348 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2352 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2353 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2354 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2355 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2359 // for re-association only
2360 // IRQL = DISPATCH_LEVEL
2361 VOID IterateOnBssTab2(
2362 IN PRTMP_ADAPTER pAd)
2364 MLME_REASSOC_REQ_STRUCT ReassocReq;
2368 BssIdx = pAd->MlmeAux.RoamIdx;
2369 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2371 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2373 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2375 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2376 AsicLockChannel(pAd, pBss->Channel);
2378 // reassociate message has the same structure as associate message
2379 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2380 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2381 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2382 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2384 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2388 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to 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;
2396 ==========================================================================
2399 IRQL = DISPATCH_LEVEL
2401 ==========================================================================
2404 IN PRTMP_ADAPTER pAd,
2405 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2408 JoinReq->BssIdx = BssIdx;
2412 ==========================================================================
2415 IRQL = DISPATCH_LEVEL
2417 ==========================================================================
2420 IN PRTMP_ADAPTER pAd,
2421 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2427 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2428 ScanReq->SsidLen = SsidLen;
2429 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2430 ScanReq->BssType = BssType;
2431 ScanReq->ScanType = ScanType;
2434 #ifdef QOS_DLS_SUPPORT
2436 ==========================================================================
2439 IRQL = DISPATCH_LEVEL
2441 ==========================================================================
2444 IN PRTMP_ADAPTER pAd,
2445 IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
2446 IN PRT_802_11_DLS pDls,
2449 pDlsReq->pDLS = pDls;
2450 pDlsReq->Reason = reason;
2452 #endif // QOS_DLS_SUPPORT //
2455 ==========================================================================
2458 IRQL = DISPATCH_LEVEL
2460 ==========================================================================
2463 IN PRTMP_ADAPTER pAd,
2464 IN OUT MLME_START_REQ_STRUCT *StartReq,
2468 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2469 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2470 StartReq->SsidLen = SsidLen;
2474 ==========================================================================
2477 IRQL = DISPATCH_LEVEL
2479 ==========================================================================
2482 IN PRTMP_ADAPTER pAd,
2483 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2487 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2489 AuthReq->Timeout = AUTH_TIMEOUT;
2493 ==========================================================================
2496 IRQL = DISPATCH_LEVEL
2498 ==========================================================================
2501 IN PRTMP_ADAPTER pAd)
2503 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2504 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2505 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2506 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2507 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2508 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2511 // IRQL = DISPATCH_LEVEL
2512 VOID ComposeNullFrame(
2513 IN PRTMP_ADAPTER pAd)
2515 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2516 pAd->NullFrame.FC.Type = BTYPE_DATA;
2517 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2518 pAd->NullFrame.FC.ToDs = 1;
2519 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2520 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2521 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2528 ==========================================================================
2530 Pre-build a BEACON frame in the shared memory
2532 IRQL = PASSIVE_LEVEL
2533 IRQL = DISPATCH_LEVEL
2535 ==========================================================================
2537 ULONG MakeIbssBeacon(
2538 IN PRTMP_ADAPTER pAd)
2540 UCHAR DsLen = 1, IbssLen = 2;
2541 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2542 HEADER_802_11 BcnHdr;
2543 USHORT CapabilityInfo;
2544 LARGE_INTEGER FakeTimestamp;
2546 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2547 CHAR *pBeaconFrame = pAd->BeaconBuf;
2549 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2550 UCHAR SupRateLen = 0;
2551 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2552 UCHAR ExtRateLen = 0;
2553 UCHAR RSNIe = IE_WPA;
2555 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2557 SupRate[0] = 0x82; // 1 mbps
2558 SupRate[1] = 0x84; // 2 mbps
2559 SupRate[2] = 0x8b; // 5.5 mbps
2560 SupRate[3] = 0x96; // 11 mbps
2564 else if (pAd->CommonCfg.Channel > 14)
2566 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2567 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2568 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2569 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2570 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2571 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2572 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2573 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2578 // Also Update MlmeRate & RtsRate for G only & A only
2580 pAd->CommonCfg.MlmeRate = RATE_6;
2581 pAd->CommonCfg.RtsRate = RATE_6;
2582 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2583 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2584 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2585 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2589 SupRate[0] = 0x82; // 1 mbps
2590 SupRate[1] = 0x84; // 2 mbps
2591 SupRate[2] = 0x8b; // 5.5 mbps
2592 SupRate[3] = 0x96; // 11 mbps
2595 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2596 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2597 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2598 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2599 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2600 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2601 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2602 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2606 pAd->StaActive.SupRateLen = SupRateLen;
2607 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2608 pAd->StaActive.ExtRateLen = ExtRateLen;
2609 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2611 // compose IBSS beacon frame
2612 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2613 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2614 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2615 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2616 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2618 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2619 sizeof(HEADER_802_11), &BcnHdr,
2620 TIMESTAMP_LEN, &FakeTimestamp,
2621 2, &pAd->CommonCfg.BeaconPeriod,
2624 1, &pAd->CommonCfg.SsidLen,
2625 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2628 SupRateLen, SupRate,
2631 1, &pAd->CommonCfg.Channel,
2634 2, &pAd->StaActive.AtimWin,
2637 // add ERP_IE and EXT_RAE IE of in 802.11g
2642 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2646 ExtRateLen, ExtRate,
2651 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2652 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2655 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2657 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2659 1, &pAd->StaCfg.RSNIE_Len,
2660 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2665 #ifdef DOT11_N_SUPPORT
2666 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2669 UCHAR HtLen, HtLen1;
2671 #ifdef RT_BIG_ENDIAN
2672 HT_CAPABILITY_IE HtCapabilityTmp;
2673 ADD_HT_INFO_IE addHTInfoTmp;
2674 USHORT b2lTmp, b2lTmp2;
2677 // add HT Capability IE
2678 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2679 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2680 #ifndef RT_BIG_ENDIAN
2681 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2684 HtLen, &pAd->CommonCfg.HtCapability,
2687 HtLen1, &pAd->CommonCfg.AddHTInfo,
2690 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2691 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2692 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2694 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2695 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2696 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2698 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2701 HtLen, &HtCapabilityTmp,
2704 HtLen1, &addHTInfoTmp,
2709 #endif // DOT11_N_SUPPORT //
2711 //beacon use reserved WCID 0xff
2712 if (pAd->CommonCfg.Channel > 14)
2714 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2715 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2719 // Set to use 1Mbps for Adhoc beacon.
2720 HTTRANSMIT_SETTING Transmit;
2722 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2723 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2726 #ifdef RT_BIG_ENDIAN
2727 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2728 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2731 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2732 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));