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;
959 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
960 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
961 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
965 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
966 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
972 ==========================================================================
975 IRQL = DISPATCH_LEVEL
977 ==========================================================================
979 VOID CntlWaitAuthProc(
980 IN PRTMP_ADAPTER pAd,
981 IN MLME_QUEUE_ELEM *Elem)
984 MLME_ASSOC_REQ_STRUCT AssocReq;
985 MLME_AUTH_REQ_STRUCT AuthReq;
987 if (Elem->MsgType == MT2_AUTH_CONF)
989 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
990 if (Reason == MLME_SUCCESS)
992 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
993 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
994 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
998 // Cisco Leap CCKM supported Re-association.
1000 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
1002 //if CCKM is turn on , that's mean Fast Reauthentication
1003 //Use CCKM Reassociation instead of normal association for Fast Roaming.
1004 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
1005 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1007 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
1010 #endif // LEAP_SUPPORT //
1012 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1013 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1015 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1020 // This fail may because of the AP already keep us in its MAC table without
1021 // ageing-out. The previous authentication attempt must have let it remove us.
1022 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
1023 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
1025 //Add AuthMode "LEAP" for CCX 1.X
1026 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1028 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
1031 #endif // LEAP_SUPPORT //
1033 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
1034 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
1036 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
1037 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
1041 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1044 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1045 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1047 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1053 ==========================================================================
1056 IRQL = DISPATCH_LEVEL
1058 ==========================================================================
1060 VOID CntlWaitAuthProc2(
1061 IN PRTMP_ADAPTER pAd,
1062 IN MLME_QUEUE_ELEM *Elem)
1065 MLME_ASSOC_REQ_STRUCT AssocReq;
1066 MLME_AUTH_REQ_STRUCT AuthReq;
1068 if (Elem->MsgType == MT2_AUTH_CONF)
1070 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1071 if (Reason == MLME_SUCCESS)
1073 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1074 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1075 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1076 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1077 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1079 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1084 // Process LEAP first, since it use different control variable
1085 // We don't want to affect other poven operation
1086 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1088 // LEAP Auth not success, try next BSS
1089 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
1090 DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
1091 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1092 pAd->MlmeAux.BssIdx++;
1093 IterateOnBssTab(pAd);
1096 #endif // LEAP_SUPPORT //
1097 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
1098 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
1100 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
1101 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1102 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1103 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1105 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1109 // not success, try next BSS
1110 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
1111 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
1112 pAd->MlmeAux.BssIdx++;
1113 IterateOnBssTab(pAd);
1120 ==========================================================================
1123 IRQL = DISPATCH_LEVEL
1125 ==========================================================================
1127 VOID CntlWaitAssocProc(
1128 IN PRTMP_ADAPTER pAd,
1129 IN MLME_QUEUE_ELEM *Elem)
1133 if (Elem->MsgType == MT2_ASSOC_CONF)
1135 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1136 if (Reason == MLME_SUCCESS)
1138 LinkUp(pAd, BSS_INFRA);
1139 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1140 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1142 if (pAd->CommonCfg.bWirelessEvent)
1144 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1149 // not success, try next BSS
1150 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1151 pAd->MlmeAux.BssIdx++;
1152 IterateOnBssTab(pAd);
1158 ==========================================================================
1161 IRQL = DISPATCH_LEVEL
1163 ==========================================================================
1165 VOID CntlWaitReassocProc(
1166 IN PRTMP_ADAPTER pAd,
1167 IN MLME_QUEUE_ELEM *Elem)
1171 if (Elem->MsgType == MT2_REASSOC_CONF)
1173 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1174 if (Result == MLME_SUCCESS)
1177 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1179 LinkUp(pAd, BSS_INFRA);
1181 // send wireless event - for association
1182 if (pAd->CommonCfg.bWirelessEvent)
1183 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1187 if (LEAP_CCKM_ON(pAd))
1189 STA_PORT_SECURED(pAd);
1190 pAd->StaCfg.WpaState = SS_FINISH;
1192 #endif // LEAP_SUPPORT //
1193 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1194 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1198 // reassoc failed, try to pick next BSS in the BSS Table
1199 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1200 pAd->MlmeAux.RoamIdx++;
1201 IterateOnBssTab2(pAd);
1207 ==========================================================================
1210 IRQL = DISPATCH_LEVEL
1212 ==========================================================================
1215 IN PRTMP_ADAPTER pAd,
1221 UCHAR Value = 0, idx;
1222 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1224 if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
1226 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
1227 RTMPusecDelay(6000);
1228 pAd->bPCIclkOff = FALSE;
1231 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1234 // ASSOC - DisassocTimeoutAction
1235 // CNTL - Dis-associate successful
1236 // !!! LINK DOWN !!!
1237 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1239 // To prevent DisassocTimeoutAction to call Link down after we link up,
1240 // cancel the DisassocTimer no matter what it start or not.
1242 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1244 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1246 #ifdef DOT11_N_SUPPORT
1247 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1248 #endif // DOT11_N_SUPPORT //
1249 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1250 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1251 // to examine if cipher algorithm switching is required.
1252 //rt2860b. Don't know why need this
1253 SwitchBetweenWepAndCkip(pAd);
1255 // Before power save before link up function, We will force use 1R.
1256 // So after link up, check Rx antenna # again.
1257 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1258 if(pAd->Antenna.field.RxPath == 3)
1262 else if(pAd->Antenna.field.RxPath == 2)
1266 else if(pAd->Antenna.field.RxPath == 1)
1270 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1271 pAd->StaCfg.BBPR3 = Value;
1273 if (BssType == BSS_ADHOC)
1275 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1276 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1278 #ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1279 // No carrier detection when adhoc
1280 // CarrierDetectionStop(pAd);
1281 pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
1282 #endif // CARRIER_DETECTION_SUPPORT //
1284 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1288 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1289 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1291 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1295 // reset Tx beamforming bit
1296 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1298 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1299 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1301 #ifdef DOT11_N_SUPPORT
1302 // Change to AP channel
1303 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1305 // Must using 40MHz.
1306 pAd->CommonCfg.BBPCurrentBW = BW_40;
1307 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1308 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1310 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1313 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1315 // RX : control channel at lower
1316 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1318 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1319 pAd->StaCfg.BBPR3 = Value;
1321 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1323 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1325 if (pAd->MACVersion == 0x28600100)
1327 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1328 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1329 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1330 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1333 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1335 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1337 // Must using 40MHz.
1338 pAd->CommonCfg.BBPCurrentBW = BW_40;
1339 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1340 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1342 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1345 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1347 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1349 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1351 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1353 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1354 pAd->StaCfg.BBPR3 = Value;
1356 if (pAd->MACVersion == 0x28600100)
1358 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1359 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1360 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1361 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1364 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1367 #endif // DOT11_N_SUPPORT //
1369 pAd->CommonCfg.BBPCurrentBW = BW_20;
1370 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1371 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1372 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1374 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1376 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1378 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1380 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1382 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1384 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1385 pAd->StaCfg.BBPR3 = Value;
1387 if (pAd->MACVersion == 0x28600100)
1389 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1390 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1391 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1392 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1395 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1398 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1400 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1402 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1404 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1405 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1407 #ifdef DOT11_N_SUPPORT
1408 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1409 #endif // DOT11_N_SUPPORT //
1411 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1413 AsicSetSlotTime(pAd, TRUE);
1414 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1416 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1417 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1419 #ifdef DOT11_N_SUPPORT
1420 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1422 // Update HT protectionfor based on AP's operating mode.
1423 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1425 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1428 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1430 #endif // DOT11_N_SUPPORT //
1432 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1434 NdisGetSystemUpTime(&Now);
1435 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1437 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1438 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1440 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1443 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1445 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1448 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1450 if (BssType == BSS_ADHOC)
1452 MakeIbssBeacon(pAd);
1453 if ((pAd->CommonCfg.Channel > 14)
1454 && (pAd->CommonCfg.bIEEE80211H == 1)
1455 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1461 AsicEnableIbssSync(pAd);
1464 // In ad hoc mode, use MAC table from index 1.
1465 // 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.
1466 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1467 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1469 // If WEP is enabled, add key material and cipherAlg into Asic
1470 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1472 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1477 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1479 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1480 Key = pAd->SharedKey[BSS0][idx].Key;
1482 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1484 // Set key material and cipherAlg to Asic
1485 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1487 if (idx == pAd->StaCfg.DefaultKeyId)
1489 // Update WCID attribute table and IVEIV table for this group key table
1490 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1497 // If WPANone is enabled, add key material and cipherAlg into Asic
1498 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1499 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1501 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1503 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1504 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1505 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1507 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1509 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1510 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1513 // Decide its ChiperAlg
1514 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1515 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1516 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1517 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1520 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1521 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1524 // Set key material and cipherAlg to Asic
1525 AsicAddSharedKeyEntry(pAd,
1528 pAd->SharedKey[BSS0][0].CipherAlg,
1529 pAd->SharedKey[BSS0][0].Key,
1530 pAd->SharedKey[BSS0][0].TxMic,
1531 pAd->SharedKey[BSS0][0].RxMic);
1533 // Update WCID attribute table and IVEIV table for this group key table
1534 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1541 // Check the new SSID with last SSID
1542 while (Cancelled == TRUE)
1544 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1546 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1548 // Link to the old one no linkdown is required.
1552 // Send link down event before set to link up
1553 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1554 RTMP_IndicateMediaState(pAd);
1555 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1556 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1561 // On WPA mode, Remove All Keys if not connect to the last BSSID
1562 // Key will be set after 4-way handshake.
1564 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1568 // Remove all WPA keys
1569 RTMPWPARemoveAllKeys(pAd);
1570 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1571 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1573 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1574 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1576 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1577 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1579 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1582 // the decision of using "short slot time" or not may change dynamically due to
1583 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1586 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1587 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1590 ComposeNullFrame(pAd);
1592 AsicEnableBssSync(pAd);
1594 // Add BSSID to WCID search table
1595 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1597 NdisAcquireSpinLock(&pAd->MacTabLock);
1598 // add this BSSID entry into HASH table
1602 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1603 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1604 if (pAd->MacTab.Hash[HashIdx] == NULL)
1606 pAd->MacTab.Hash[HashIdx] = pEntry;
1610 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1611 while (pCurrEntry->pNext != NULL)
1612 pCurrEntry = pCurrEntry->pNext;
1613 pCurrEntry->pNext = pEntry;
1616 NdisReleaseSpinLock(&pAd->MacTabLock);
1619 // If WEP is enabled, add paiewise and shared key
1620 #ifdef WPA_SUPPLICANT_SUPPORT
1621 if (((pAd->StaCfg.WpaSupplicantUP)&&
1622 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1623 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1624 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1625 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1627 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1628 #endif // WPA_SUPPLICANT_SUPPORT //
1633 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1635 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1636 Key = pAd->SharedKey[BSS0][idx].Key;
1638 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1640 // Set key material and cipherAlg to Asic
1641 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1643 if (idx == pAd->StaCfg.DefaultKeyId)
1645 // Assign group key info
1646 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1648 // Assign pairwise key info
1649 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1655 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1656 // should wait until at least 2 active nodes in this BSSID.
1657 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1660 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1662 pAd->IndicateMediaState = NdisMediaStateConnected;
1663 pAd->ExtraInfo = GENERAL_LINK_UP;
1666 RTMP_IndicateMediaState(pAd);
1668 // Add BSSID in my MAC Table.
1669 NdisAcquireSpinLock(&pAd->MacTabLock);
1670 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1671 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1672 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1673 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1674 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1675 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1676 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1677 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1678 NdisReleaseSpinLock(&pAd->MacTabLock);
1680 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1681 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1683 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1684 #ifdef DOT11_N_SUPPORT
1685 MlmeUpdateHtTxRates(pAd, BSS0);
1686 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1687 #endif // DOT11_N_SUPPORT //
1690 // Report Adjacent AP report.
1693 CCXAdjacentAPReport(pAd);
1694 #endif // LEAP_SUPPORT //
1696 if (pAd->CommonCfg.bAggregationCapable)
1698 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1701 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1702 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1703 RTMPSetPiggyBack(pAd, TRUE);
1704 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1706 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1708 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1712 if (pAd->MlmeAux.APRalinkIe != 0x0)
1714 #ifdef DOT11_N_SUPPORT
1715 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1719 #endif // DOT11_N_SUPPORT //
1720 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1721 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1725 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1726 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1730 #ifdef DOT11_N_SUPPORT
1731 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));
1732 #endif // DOT11_N_SUPPORT //
1735 RTMPSetLED(pAd, LED_LINK_UP);
1737 pAd->Mlme.PeriodicRound = 0;
1738 pAd->Mlme.OneSecPeriodicRound = 0;
1739 pAd->bConfigChanged = FALSE; // Reset config flag
1740 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1742 // Set asic auto fall back
1745 UCHAR TableSize = 0;
1747 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1748 AsicUpdateAutoFallBackTable(pAd, pTable);
1751 NdisAcquireSpinLock(&pAd->MacTabLock);
1752 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1753 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1754 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1756 pEntry->bAutoTxRateSwitch = FALSE;
1757 #ifdef DOT11_N_SUPPORT
1758 if (pEntry->HTPhyMode.field.MCS == 32)
1759 pEntry->HTPhyMode.field.ShortGI = GI_800;
1761 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1762 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1763 #endif // DOT11_N_SUPPORT //
1764 // If the legacy mode is set, overwrite the transmit setting of this entry.
1765 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1766 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1769 pEntry->bAutoTxRateSwitch = TRUE;
1770 NdisReleaseSpinLock(&pAd->MacTabLock);
1772 // Let Link Status Page display first initial rate.
1773 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1774 // Select DAC according to HT or Legacy
1775 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1777 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1779 if (pAd->Antenna.field.TxPath == 2)
1783 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1787 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1789 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1792 #ifdef DOT11_N_SUPPORT
1793 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1796 else if (pEntry->MaxRAmpduFactor == 0)
1798 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1799 // Because our Init value is 1 at MACRegTable.
1800 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1802 #endif // DOT11_N_SUPPORT //
1804 // Patch for Marvel AP to gain high throughput
1805 // Need to set as following,
1806 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1807 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1808 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1809 // 4. kick per two packets when dequeue
1811 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1813 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1814 #ifdef DOT11_N_SUPPORT
1815 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1816 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1818 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1820 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1822 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1823 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1826 #endif // DOT11_N_SUPPORT //
1827 if (pAd->CommonCfg.bEnableTxBurst)
1829 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1832 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1833 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1835 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1836 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1840 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1842 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1844 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1845 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1848 #ifdef DOT11_N_SUPPORT
1849 // Re-check to turn on TX burst or not.
1850 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1852 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1853 if (pAd->CommonCfg.bEnableTxBurst)
1855 UINT32 MACValue = 0;
1856 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1857 // I didn't change PBF_MAX_PCNT setting.
1858 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1859 MACValue &= 0xFFFFFF00;
1860 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1861 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1866 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1868 #endif // DOT11_N_SUPPORT //
1870 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1871 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1872 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1873 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1874 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1875 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1877 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1879 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1880 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1883 NdisAcquireSpinLock(&pAd->MacTabLock);
1884 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1885 NdisReleaseSpinLock(&pAd->MacTabLock);
1888 // Patch Atheros AP TX will breakdown issue.
1889 // AP Model: DLink DWL-8200AP
1891 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1893 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1897 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1900 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1901 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1903 #ifdef DOT11_N_SUPPORT
1904 #ifdef DOT11N_DRAFT3
1905 if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
1907 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
1908 BuildEffectedChannelList(pAd);
1910 #endif // DOT11N_DRAFT3 //
1911 #endif // DOT11_N_SUPPORT //
1915 ==========================================================================
1917 Routine Description:
1918 Disconnect current BSSID
1921 pAd - Pointer to our adapter
1922 IsReqFromAP - Request from AP
1927 IRQL = DISPATCH_LEVEL
1930 We need more information to know it's this requst from AP.
1931 If yes! we need to do extra handling, for example, remove the WPA key.
1932 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1933 remove while auto reconnect.
1934 Disconnect request from AP, it means we will start afresh 4-way handshaking
1937 ==========================================================================
1940 IN PRTMP_ADAPTER pAd,
1941 IN BOOLEAN IsReqFromAP)
1943 UCHAR i, ByteValue = 0;
1946 // Do nothing if monitor mode is on
1947 if (MONITOR_ON(pAd))
1950 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1951 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1953 // Not allow go to sleep within linkdown function.
1954 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1956 if (pAd->CommonCfg.bWirelessEvent)
1958 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1961 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1962 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1964 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1967 pAd->Mlme.bPsPollTimerRunning = FALSE;
1968 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1971 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
1972 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
1973 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
1975 AsicForceWakeup(pAd, RTMP_HALT);
1976 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1979 pAd->bPCIclkOff = FALSE;
1980 if (ADHOC_ON(pAd)) // Adhoc mode link down
1982 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1984 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1985 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1986 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1987 RTMP_IndicateMediaState(pAd);
1988 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1989 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1990 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1992 else // Infra structure mode
1994 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1996 #ifdef QOS_DLS_SUPPORT
1997 // DLS tear down frame must be sent before link down
1998 // send DLS-TEAR_DOWN message
1999 if (pAd->CommonCfg.bDLSCapable)
2001 // tear down local dls table entry
2002 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
2004 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2006 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2007 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2011 // tear down peer dls table entry
2012 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
2014 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2016 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2017 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2021 #endif // QOS_DLS_SUPPORT //
2023 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
2024 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2026 // Saved last SSID for linkup comparison
2027 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
2028 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
2029 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
2030 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
2032 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2033 RTMP_IndicateMediaState(pAd);
2034 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2035 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
2036 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
2041 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
2042 // Otherwise lost beacon or receive De-Authentication from AP,
2043 // then we should delete BSSID from BssTable.
2044 // If we don't delete from entry, roaming will fail.
2046 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2049 // restore back to -
2050 // 1. long slot (20 us) or short slot (9 us) time
2051 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
2052 // 3. short preamble
2053 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
2055 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
2058 // Record current AP's information.
2059 // for later used reporting Adjacent AP report.
2061 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
2062 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
2063 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
2064 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
2067 #ifdef EXT_BUILD_CHANNEL_LIST
2068 // Country IE of the AP will be evaluated and will be used.
2069 if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
2071 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
2072 pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
2073 BuildChannelListEx(pAd);
2075 #endif // EXT_BUILD_CHANNEL_LIST //
2079 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2081 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2082 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
2085 pAd->StaCfg.CCXQosECWMin = 4;
2086 pAd->StaCfg.CCXQosECWMax = 10;
2088 AsicSetSlotTime(pAd, TRUE); //FALSE);
2089 AsicSetEdcaParm(pAd, NULL);
2092 RTMPSetLED(pAd, LED_LINK_DOWN);
2093 pAd->LedIndicatorStregth = 0xF0;
2094 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
2096 AsicDisableSync(pAd);
2098 pAd->Mlme.PeriodicRound = 0;
2099 pAd->Mlme.OneSecPeriodicRound = 0;
2101 if (pAd->StaCfg.BssType == BSS_INFRA)
2103 // Remove StaCfg Information after link down
2104 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
2105 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
2106 pAd->CommonCfg.SsidLen = 0;
2108 #ifdef DOT11_N_SUPPORT
2109 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
2110 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
2111 pAd->MlmeAux.HtCapabilityLen = 0;
2112 pAd->MlmeAux.NewExtChannelOffset = 0xff;
2113 #endif // DOT11_N_SUPPORT //
2115 // Reset WPA-PSK state. Only reset when supplicant enabled
2116 if (pAd->StaCfg.WpaState != SS_NOTUSE)
2118 pAd->StaCfg.WpaState = SS_START;
2119 // Clear Replay counter
2120 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2122 #ifdef QOS_DLS_SUPPORT
2123 if (pAd->CommonCfg.bDLSCapable)
2124 NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
2125 #endif // QOS_DLS_SUPPORT //
2130 // if link down come from AP, we need to remove all WPA keys on WPA mode.
2131 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
2133 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
2135 // Remove all WPA keys
2136 RTMPWPARemoveAllKeys(pAd);
2139 // 802.1x port control
2140 #ifdef WPA_SUPPLICANT_SUPPORT
2141 // Prevent clear PortSecured here with static WEP
2142 // NetworkManger set security policy first then set SSID to connect AP.
2143 if (pAd->StaCfg.WpaSupplicantUP &&
2144 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
2145 (pAd->StaCfg.IEEE8021X == FALSE))
2147 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2150 #endif // WPA_SUPPLICANT_SUPPORT //
2152 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2153 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2156 NdisAcquireSpinLock(&pAd->MacTabLock);
2157 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2158 NdisReleaseSpinLock(&pAd->MacTabLock);
2160 pAd->StaCfg.MicErrCnt = 0;
2162 // Turn off Ckip control flag
2163 pAd->StaCfg.bCkipOn = FALSE;
2164 pAd->StaCfg.CCXEnable = FALSE;
2166 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2167 // Update extra information to link is up
2168 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2170 pAd->StaCfg.AdhocBOnlyJoined = FALSE;
2171 pAd->StaCfg.AdhocBGJoined = FALSE;
2172 pAd->StaCfg.Adhoc20NJoined = FALSE;
2173 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2175 // Reset the Current AP's IP address
2176 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
2178 // Clean association information
2179 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
2180 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
2181 pAd->StaCfg.ReqVarIELen = 0;
2182 pAd->StaCfg.ResVarIELen = 0;
2185 // Reset RSSI value after link down
2187 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2188 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2189 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2190 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2191 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2192 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2195 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2196 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2198 #ifdef DOT11_N_SUPPORT
2200 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
2202 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
2204 pAd->CommonCfg.BBPCurrentBW = BW_20;
2205 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2206 ByteValue &= (~0x18);
2207 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2209 #endif // DOT11_N_SUPPORT //
2211 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2212 ByteValue &= (~0x18);
2213 if (pAd->Antenna.field.TxPath == 2)
2217 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2219 RTMPSetPiggyBack(pAd,FALSE);
2220 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2222 #ifdef DOT11_N_SUPPORT
2223 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2224 #endif // DOT11_N_SUPPORT //
2226 // Restore all settings in the following.
2227 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2228 AsicDisableRDG(pAd);
2229 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2230 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2232 #ifdef DOT11_N_SUPPORT
2233 #ifdef DOT11N_DRAFT3
2234 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
2235 pAd->CommonCfg.BSSCoexist2040.word = 0;
2237 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
2239 pAd->ChannelList[i].bEffectedChannel = FALSE;
2241 #endif // DOT11N_DRAFT3 //
2242 #endif // DOT11_N_SUPPORT //
2244 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2245 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2247 // Allow go to sleep after linkdown steps.
2248 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
2250 #ifdef WPA_SUPPLICANT_SUPPORT
2251 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2252 if (pAd->StaCfg.WpaSupplicantUP) {
2253 union iwreq_data wrqu;
2254 //send disassociate event to wpa_supplicant
2255 memset(&wrqu, 0, sizeof(wrqu));
2256 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2257 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2259 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2260 #endif // WPA_SUPPLICANT_SUPPORT //
2262 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2264 union iwreq_data wrqu;
2265 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2266 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2268 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2272 ==========================================================================
2275 IRQL = DISPATCH_LEVEL
2277 ==========================================================================
2279 VOID IterateOnBssTab(
2280 IN PRTMP_ADAPTER pAd)
2282 MLME_START_REQ_STRUCT StartReq;
2283 MLME_JOIN_REQ_STRUCT JoinReq;
2286 // Change the wepstatus to original wepstatus
2287 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2288 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2289 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2291 BssIdx = pAd->MlmeAux.BssIdx;
2292 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2294 // Check cipher suite, AP must have more secured cipher than station setting
2295 // Set the Pairwise and Group cipher to match the intended AP setting
2296 // We can only connect to AP with less secured cipher setting
2297 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2299 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2301 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2302 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2303 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2304 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2305 else // There is no PairCipher Aux, downgrade our capability to TKIP
2306 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2308 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2310 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2312 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2313 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2314 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2315 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2316 else // There is no PairCipher Aux, downgrade our capability to TKIP
2317 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2320 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2323 // Set Mix cipher flag
2324 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2325 if (pAd->StaCfg.bMixCipher == TRUE)
2327 // If mix cipher, re-build RSNIE
2328 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2331 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2332 JoinParmFill(pAd, &JoinReq, BssIdx);
2333 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2335 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2337 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2339 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2340 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2341 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2342 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2346 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2347 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2348 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2349 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2353 // for re-association only
2354 // IRQL = DISPATCH_LEVEL
2355 VOID IterateOnBssTab2(
2356 IN PRTMP_ADAPTER pAd)
2358 MLME_REASSOC_REQ_STRUCT ReassocReq;
2362 BssIdx = pAd->MlmeAux.RoamIdx;
2363 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2365 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2367 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2369 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2370 AsicLockChannel(pAd, pBss->Channel);
2372 // reassociate message has the same structure as associate message
2373 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2374 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2375 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2376 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2378 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2382 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2383 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2384 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2385 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2390 ==========================================================================
2393 IRQL = DISPATCH_LEVEL
2395 ==========================================================================
2398 IN PRTMP_ADAPTER pAd,
2399 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2402 JoinReq->BssIdx = BssIdx;
2406 ==========================================================================
2409 IRQL = DISPATCH_LEVEL
2411 ==========================================================================
2414 IN PRTMP_ADAPTER pAd,
2415 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2421 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2422 ScanReq->SsidLen = SsidLen;
2423 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2424 ScanReq->BssType = BssType;
2425 ScanReq->ScanType = ScanType;
2428 #ifdef QOS_DLS_SUPPORT
2430 ==========================================================================
2433 IRQL = DISPATCH_LEVEL
2435 ==========================================================================
2438 IN PRTMP_ADAPTER pAd,
2439 IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
2440 IN PRT_802_11_DLS pDls,
2443 pDlsReq->pDLS = pDls;
2444 pDlsReq->Reason = reason;
2446 #endif // QOS_DLS_SUPPORT //
2449 ==========================================================================
2452 IRQL = DISPATCH_LEVEL
2454 ==========================================================================
2457 IN PRTMP_ADAPTER pAd,
2458 IN OUT MLME_START_REQ_STRUCT *StartReq,
2462 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2463 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2464 StartReq->SsidLen = SsidLen;
2468 ==========================================================================
2471 IRQL = DISPATCH_LEVEL
2473 ==========================================================================
2476 IN PRTMP_ADAPTER pAd,
2477 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2481 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2483 AuthReq->Timeout = AUTH_TIMEOUT;
2487 ==========================================================================
2490 IRQL = DISPATCH_LEVEL
2492 ==========================================================================
2495 IN PRTMP_ADAPTER pAd)
2497 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2498 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2499 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2500 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2501 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2502 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2505 // IRQL = DISPATCH_LEVEL
2506 VOID ComposeNullFrame(
2507 IN PRTMP_ADAPTER pAd)
2509 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2510 pAd->NullFrame.FC.Type = BTYPE_DATA;
2511 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2512 pAd->NullFrame.FC.ToDs = 1;
2513 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2514 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2515 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2522 ==========================================================================
2524 Pre-build a BEACON frame in the shared memory
2526 IRQL = PASSIVE_LEVEL
2527 IRQL = DISPATCH_LEVEL
2529 ==========================================================================
2531 ULONG MakeIbssBeacon(
2532 IN PRTMP_ADAPTER pAd)
2534 UCHAR DsLen = 1, IbssLen = 2;
2535 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2536 HEADER_802_11 BcnHdr;
2537 USHORT CapabilityInfo;
2538 LARGE_INTEGER FakeTimestamp;
2540 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2541 CHAR *pBeaconFrame = pAd->BeaconBuf;
2543 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2544 UCHAR SupRateLen = 0;
2545 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2546 UCHAR ExtRateLen = 0;
2547 UCHAR RSNIe = IE_WPA;
2549 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2551 SupRate[0] = 0x82; // 1 mbps
2552 SupRate[1] = 0x84; // 2 mbps
2553 SupRate[2] = 0x8b; // 5.5 mbps
2554 SupRate[3] = 0x96; // 11 mbps
2558 else if (pAd->CommonCfg.Channel > 14)
2560 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2561 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2562 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2563 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2564 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2565 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2566 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2567 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2572 // Also Update MlmeRate & RtsRate for G only & A only
2574 pAd->CommonCfg.MlmeRate = RATE_6;
2575 pAd->CommonCfg.RtsRate = RATE_6;
2576 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2577 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2578 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2579 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2583 SupRate[0] = 0x82; // 1 mbps
2584 SupRate[1] = 0x84; // 2 mbps
2585 SupRate[2] = 0x8b; // 5.5 mbps
2586 SupRate[3] = 0x96; // 11 mbps
2589 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2590 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2591 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2592 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2593 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2594 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2595 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2596 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2600 pAd->StaActive.SupRateLen = SupRateLen;
2601 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2602 pAd->StaActive.ExtRateLen = ExtRateLen;
2603 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2605 // compose IBSS beacon frame
2606 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2607 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2608 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2609 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2610 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2612 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2613 sizeof(HEADER_802_11), &BcnHdr,
2614 TIMESTAMP_LEN, &FakeTimestamp,
2615 2, &pAd->CommonCfg.BeaconPeriod,
2618 1, &pAd->CommonCfg.SsidLen,
2619 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2622 SupRateLen, SupRate,
2625 1, &pAd->CommonCfg.Channel,
2628 2, &pAd->StaActive.AtimWin,
2631 // add ERP_IE and EXT_RAE IE of in 802.11g
2636 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2640 ExtRateLen, ExtRate,
2645 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2646 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2649 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2651 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2653 1, &pAd->StaCfg.RSNIE_Len,
2654 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2659 #ifdef DOT11_N_SUPPORT
2660 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2663 UCHAR HtLen, HtLen1;
2665 #ifdef RT_BIG_ENDIAN
2666 HT_CAPABILITY_IE HtCapabilityTmp;
2667 ADD_HT_INFO_IE addHTInfoTmp;
2668 USHORT b2lTmp, b2lTmp2;
2671 // add HT Capability IE
2672 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2673 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2674 #ifndef RT_BIG_ENDIAN
2675 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2678 HtLen, &pAd->CommonCfg.HtCapability,
2681 HtLen1, &pAd->CommonCfg.AddHTInfo,
2684 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2685 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2686 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2688 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2689 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2690 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2692 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2695 HtLen, &HtCapabilityTmp,
2698 HtLen1, &addHTInfoTmp,
2703 #endif // DOT11_N_SUPPORT //
2705 //beacon use reserved WCID 0xff
2706 if (pAd->CommonCfg.Channel > 14)
2708 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2709 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2713 // Set to use 1Mbps for Adhoc beacon.
2714 HTTRANSMIT_SETTING Transmit;
2716 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2717 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2720 #ifdef RT_BIG_ENDIAN
2721 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2722 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2725 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2726 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));