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)
126 CntlIdleProc(pAd, Elem);
128 case CNTL_WAIT_DISASSOC:
129 CntlWaitDisassocProc(pAd, Elem);
132 CntlWaitJoinProc(pAd, Elem);
135 // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
136 // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
137 // Therefore not protected by NDIS's "only one outstanding OID request"
138 // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
139 // Current approach is to block new SET request at RTMPSetInformation()
140 // when CntlMachine.CurrState is not CNTL_IDLE
141 case CNTL_WAIT_REASSOC:
142 CntlWaitReassocProc(pAd, Elem);
145 case CNTL_WAIT_START:
146 CntlWaitStartProc(pAd, Elem);
149 CntlWaitAuthProc(pAd, Elem);
151 case CNTL_WAIT_AUTH2:
152 CntlWaitAuthProc2(pAd, Elem);
154 case CNTL_WAIT_ASSOC:
155 CntlWaitAssocProc(pAd, Elem);
158 case CNTL_WAIT_OID_LIST_SCAN:
159 if(Elem->MsgType == MT2_SCAN_CONF)
161 // Resume TxRing after SCANING complete. We hope the out-of-service time
162 // won't be too long to let upper layer time-out the waiting frames
163 RTMPResumeMsduTransmission(pAd);
164 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
166 // Cisco scan request is finished, prepare beacon report
167 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
169 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
172 // Set LED status to previous status.
174 if (pAd->bLedOnScanning)
176 pAd->bLedOnScanning = FALSE;
177 RTMPSetLED(pAd, pAd->LedStatus);
180 // AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone.
181 if (pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1)
183 Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
185 #endif // DOT11N_DRAFT3 //
189 case CNTL_WAIT_OID_DISASSOC:
190 if (Elem->MsgType == MT2_DISASSOC_CONF)
192 LinkDown(pAd, FALSE);
193 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
198 // This state is for that we want to connect to an AP but
199 // it didn't find on BSS List table. So we need to scan the air first,
200 // after that we can try to connect to the desired AP if available.
202 case CNTL_WAIT_SCAN_FOR_CONNECT:
203 if(Elem->MsgType == MT2_SCAN_CONF)
205 // Resume TxRing after SCANING complete. We hope the out-of-service time
206 // won't be too long to let upper layer time-out the waiting frames
207 RTMPResumeMsduTransmission(pAd);
209 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
211 // Cisco scan request is finished, prepare beacon report
212 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
214 #endif // CCX_SUPPORT //
215 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
218 // Check if we can connect to.
220 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
221 if (pAd->MlmeAux.SsidBssTab.BssNr > 0)
223 MlmeAutoReconnectLastSSID(pAd);
229 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
236 ==========================================================================
239 IRQL = DISPATCH_LEVEL
241 ==========================================================================
244 IN PRTMP_ADAPTER pAd,
245 IN MLME_QUEUE_ELEM *Elem)
247 MLME_DISASSOC_REQ_STRUCT DisassocReq;
249 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
252 switch(Elem->MsgType)
254 case OID_802_11_SSID:
255 CntlOidSsidProc(pAd, Elem);
258 case OID_802_11_BSSID:
259 CntlOidRTBssidProc(pAd,Elem);
262 case OID_802_11_BSSID_LIST_SCAN:
263 CntlOidScanProc(pAd,Elem);
266 case OID_802_11_DISASSOCIATE:
267 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
268 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
269 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
270 #ifdef WPA_SUPPLICANT_SUPPORT
271 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
272 #endif // WPA_SUPPLICANT_SUPPORT //
274 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
275 // Since calling this indicate user don't want to connect to that SSID anymore.
276 pAd->MlmeAux.AutoReconnectSsidLen= 32;
277 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
281 case MT2_MLME_ROAMING_REQ:
282 CntlMlmeRoamingProc(pAd, Elem);
285 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
286 WpaMicFailureReportFrame(pAd, Elem);
289 #ifdef QOS_DLS_SUPPORT
290 case RT_OID_802_11_SET_DLS_PARAM:
291 CntlOidDLSSetupProc(pAd, Elem);
293 #endif // QOS_DLS_SUPPORT //
296 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
301 VOID CntlOidScanProc(
302 IN PRTMP_ADAPTER pAd,
303 IN MLME_QUEUE_ELEM *Elem)
305 MLME_SCAN_REQ_STRUCT ScanReq;
306 ULONG BssIdx = BSS_NOT_FOUND;
309 // record current BSS if network is connected.
310 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
311 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
313 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
314 if (BssIdx != BSS_NOT_FOUND)
316 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
320 // clean up previous SCAN result, add current BSS back to table if any
321 BssTableInit(&pAd->ScanTab);
322 if (BssIdx != BSS_NOT_FOUND)
324 // DDK Note: If the NIC is associated with a particular BSSID and SSID
325 // that are not contained in the list of BSSIDs generated by this scan, the
326 // BSSID description of the currently associated BSSID and SSID should be
327 // appended to the list of BSSIDs in the NIC's database.
328 // To ensure this, we append this BSS as the first entry in SCAN result
329 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
330 pAd->ScanTab.BssNr = 1;
333 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
334 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
335 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
336 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
340 ==========================================================================
342 Before calling this routine, user desired SSID should already been
343 recorded in CommonCfg.Ssid[]
344 IRQL = DISPATCH_LEVEL
346 ==========================================================================
348 VOID CntlOidSsidProc(
349 IN PRTMP_ADAPTER pAd,
350 IN MLME_QUEUE_ELEM * Elem)
352 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
353 MLME_DISASSOC_REQ_STRUCT DisassocReq;
356 // Step 1. record the desired user settings to MlmeAux
357 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
358 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
359 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
360 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
361 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
365 // Update Reconnect Ssid, that user desired to connect.
367 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
368 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
369 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
371 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
372 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
373 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
375 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
376 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
377 NdisGetSystemUpTime(&Now);
379 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
380 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
381 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
382 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
384 // Case 1. already connected with an AP who has the desired SSID
387 // Add checking Mode "LEAP" for CCX 1.0
388 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
389 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
390 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
391 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
393 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
394 #endif // LEAP_SUPPORT //
396 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
398 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
399 // connection process
400 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
401 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
402 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
403 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
404 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
406 else if (pAd->bConfigChanged == TRUE)
408 // case 1.2 Important Config has changed, we have to reconnect to the same AP
409 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
410 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
411 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
412 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
413 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
417 // case 1.3. already connected to the SSID with highest RSSI.
418 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
420 // (HCT 12.1) 1c_wlan_mediaevents required
421 // media connect events are indicated when associating with the same AP
426 // Since MediaState already is NdisMediaStateConnected
427 // We just indicate the connect event again to meet the WHQL required.
429 pAd->IndicateMediaState = NdisMediaStateConnected;
430 RTMP_IndicateMediaState(pAd);
431 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
434 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
435 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
437 union iwreq_data wrqu;
439 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
440 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
441 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
444 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
447 else if (INFRA_ON(pAd))
451 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
452 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
453 // But media status is connected, so the SSID not report correctly.
455 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
458 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
460 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
462 // case 2. active INFRA association existent
463 // roaming is done within miniport driver, nothing to do with configuration
464 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
465 // disassociate with the current associated AP,
466 // then perform a new association with this new SSID, no matter the
467 // new/old SSID are the same or not.
468 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
469 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
470 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
471 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
472 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
478 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
479 LinkDown(pAd, FALSE);
480 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
481 pAd->IndicateMediaState = NdisMediaStateDisconnected;
482 RTMP_IndicateMediaState(pAd);
483 pAd->ExtraInfo = GENERAL_LINK_DOWN;
484 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
487 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
488 (pAd->StaCfg.bAutoReconnect == TRUE) &&
489 (pAd->MlmeAux.BssType == BSS_INFRA) &&
490 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
493 MLME_SCAN_REQ_STRUCT ScanReq;
495 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
496 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
497 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
498 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
499 // Reset Missed scan number
500 pAd->StaCfg.LastScanTime = Now;
504 pAd->MlmeAux.BssIdx = 0;
505 IterateOnBssTab(pAd);
512 ==========================================================================
515 IRQL = DISPATCH_LEVEL
517 ==========================================================================
519 VOID CntlOidRTBssidProc(
520 IN PRTMP_ADAPTER pAd,
521 IN MLME_QUEUE_ELEM * Elem)
524 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
525 MLME_DISASSOC_REQ_STRUCT DisassocReq;
526 MLME_JOIN_REQ_STRUCT JoinReq;
528 // record user desired settings
529 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
530 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
533 // Update Reconnect Ssid, that user desired to connect.
535 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
536 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
537 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
539 // find the desired BSS in the latest SCAN result table
540 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
541 if (BssIdx == BSS_NOT_FOUND)
543 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
544 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
548 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
549 // Because we need this entry to become the JOIN target in later on SYNC state machine
550 pAd->MlmeAux.BssIdx = 0;
551 pAd->MlmeAux.SsidBssTab.BssNr = 1;
552 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
554 //pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
555 //NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
557 // Add SSID into MlmeAux for site surey joining hidden SSID
558 //pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
559 //NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
561 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
562 // we just follow normal procedure. The reason of user doing this may because he/she changed
563 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
564 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
565 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
566 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
567 // connection when setting the same BSSID.
568 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
569 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
571 // already connected to the same BSSID, go back to idle state directly
572 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
573 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
574 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
576 union iwreq_data wrqu;
578 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
579 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
580 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
583 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
589 // disassoc from current AP first
590 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
591 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
592 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
593 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
595 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
601 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
602 LinkDown(pAd, FALSE);
603 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
604 pAd->IndicateMediaState = NdisMediaStateDisconnected;
605 RTMP_IndicateMediaState(pAd);
606 pAd->ExtraInfo = GENERAL_LINK_DOWN;
607 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
610 // Change the wepstatus to original wepstatus
611 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
612 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
613 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
615 // Check cipher suite, AP must have more secured cipher than station setting
616 // Set the Pairwise and Group cipher to match the intended AP setting
617 // We can only connect to AP with less secured cipher setting
618 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
620 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
622 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
623 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
624 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
625 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
626 else // There is no PairCipher Aux, downgrade our capability to TKIP
627 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
629 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
631 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
633 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
634 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
635 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
636 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
637 else // There is no PairCipher Aux, downgrade our capability to TKIP
638 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
641 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
644 // Set Mix cipher flag
645 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
646 if (pAd->StaCfg.bMixCipher == TRUE)
648 // If mix cipher, re-build RSNIE
649 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
651 // No active association, join the BSS immediately
652 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
653 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
655 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
656 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
658 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
663 // Roaming is the only external request triggering CNTL state machine
664 // despite of other "SET OID" operation. All "SET OID" related oerations
665 // happen in sequence, because no other SET OID will be sent to this device
666 // until the the previous SET operation is complete (successful o failed).
667 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
668 // or been corrupted by other "SET OID"?
670 // IRQL = DISPATCH_LEVEL
671 VOID CntlMlmeRoamingProc(
672 IN PRTMP_ADAPTER pAd,
673 IN MLME_QUEUE_ELEM *Elem)
676 // AP in different channel may show lower RSSI than actual value??
677 // should we add a weighting factor to compensate it?
678 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
680 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
681 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
683 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
684 pAd->MlmeAux.BssIdx = 0;
685 IterateOnBssTab(pAd);
688 #ifdef QOS_DLS_SUPPORT
690 ==========================================================================
693 IRQL = DISPATCH_LEVEL
695 ==========================================================================
697 VOID CntlOidDLSSetupProc(
698 IN PRTMP_ADAPTER pAd,
699 IN MLME_QUEUE_ELEM *Elem)
701 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)Elem->Msg;
702 MLME_DLS_REQ_STRUCT MlmeDlsReq;
704 USHORT reason = REASON_UNSPECIFY;
706 DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n",
707 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5],
708 pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer));
710 if (!pAd->CommonCfg.bDLSCapable)
713 // DLS will not be supported when Adhoc mode
716 for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++)
718 if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
719 (pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
721 // 1. Same setting, just drop it
722 DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n"));
725 else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
726 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
728 // 2. Disable DLS link case, just tear down DLS link
729 reason = REASON_QOS_UNWANTED_MECHANISM;
730 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
731 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
732 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
733 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
734 DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n"));
737 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid)
739 // 3. Enable case, start DLS setup procedure
740 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
742 //Update countdown timer
743 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
744 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
745 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
746 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n"));
749 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
750 (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
752 // 4. update mac case, tear down old DLS and setup new DLS
753 reason = REASON_QOS_UNWANTED_MECHANISM;
754 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
755 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
756 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
757 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
758 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
759 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
760 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
761 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS tear down and restart case\n"));
764 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
765 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr) && (pAd->StaCfg.DLSEntry[i].TimeOut != pDLS->TimeOut))
767 // 5. update timeout case, start DLS setup procedure (no tear down)
768 pAd->StaCfg.DLSEntry[i].TimeOut = pDLS->TimeOut;
769 //Update countdown timer
770 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
771 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
772 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
773 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS update timeout case\n"));
776 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
777 (pAd->StaCfg.DLSEntry[i].Status != DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
779 // 6. re-setup case, start DLS setup procedure (no tear down)
780 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
781 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
782 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS retry setup procedure\n"));
787 DBGPRINT(RT_DEBUG_WARN,("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n",
788 i, pAd->StaCfg.DLSEntry[i].Valid, pAd->StaCfg.DLSEntry[i].Status, pAd->StaCfg.DLSEntry[i].TimeOut));
793 #endif // QOS_DLS_SUPPORT //
796 ==========================================================================
799 IRQL = DISPATCH_LEVEL
801 ==========================================================================
803 VOID CntlWaitDisassocProc(
804 IN PRTMP_ADAPTER pAd,
805 IN MLME_QUEUE_ELEM *Elem)
807 MLME_START_REQ_STRUCT StartReq;
809 if (Elem->MsgType == MT2_DISASSOC_CONF)
811 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
813 if (pAd->CommonCfg.bWirelessEvent)
815 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
818 LinkDown(pAd, FALSE);
820 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
821 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
823 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
824 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
825 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
826 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
828 // case 2. try each matched BSS
831 pAd->MlmeAux.BssIdx = 0;
833 IterateOnBssTab(pAd);
839 ==========================================================================
842 IRQL = DISPATCH_LEVEL
844 ==========================================================================
846 VOID CntlWaitJoinProc(
847 IN PRTMP_ADAPTER pAd,
848 IN MLME_QUEUE_ELEM *Elem)
851 MLME_AUTH_REQ_STRUCT AuthReq;
853 if (Elem->MsgType == MT2_JOIN_CONF)
855 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
856 if (Reason == MLME_SUCCESS)
858 // 1. joined an IBSS, we are pretty much done here
859 if (pAd->MlmeAux.BssType == BSS_ADHOC)
862 // 5G bands rules of Japan:
863 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
865 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
866 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
869 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
870 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
874 LinkUp(pAd, BSS_ADHOC);
875 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
876 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
877 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
878 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
880 pAd->IndicateMediaState = NdisMediaStateConnected;
881 pAd->ExtraInfo = GENERAL_LINK_UP;
883 // 2. joined a new INFRA network, start from authentication
887 // Add AuthMode "LEAP" for CCX 1.X
888 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
890 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
893 #endif // LEAP_SUPPORT //
895 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
896 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
897 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
899 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
903 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
906 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
907 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
909 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
914 // 3. failed, try next BSS
915 pAd->MlmeAux.BssIdx++;
916 IterateOnBssTab(pAd);
923 ==========================================================================
926 IRQL = DISPATCH_LEVEL
928 ==========================================================================
930 VOID CntlWaitStartProc(
931 IN PRTMP_ADAPTER pAd,
932 IN MLME_QUEUE_ELEM *Elem)
936 if (Elem->MsgType == MT2_START_CONF)
938 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
939 if (Result == MLME_SUCCESS)
942 // 5G bands rules of Japan:
943 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
945 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
946 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
949 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
950 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
953 #ifdef DOT11_N_SUPPORT
954 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
958 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
959 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
960 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
961 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
962 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
963 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
965 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
966 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
968 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
970 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
971 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
973 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
977 #endif // DOT11_N_SUPPORT //
979 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
981 LinkUp(pAd, BSS_ADHOC);
982 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
983 // Before send beacon, driver need do radar detection
984 if ((pAd->CommonCfg.Channel > 14 )
985 && (pAd->CommonCfg.bIEEE80211H == 1)
986 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
988 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
989 pAd->CommonCfg.RadarDetect.RDCount = 0;
992 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
993 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
994 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
998 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
999 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1005 ==========================================================================
1008 IRQL = DISPATCH_LEVEL
1010 ==========================================================================
1012 VOID CntlWaitAuthProc(
1013 IN PRTMP_ADAPTER pAd,
1014 IN MLME_QUEUE_ELEM *Elem)
1017 MLME_ASSOC_REQ_STRUCT AssocReq;
1018 MLME_AUTH_REQ_STRUCT AuthReq;
1020 if (Elem->MsgType == MT2_AUTH_CONF)
1022 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1023 if (Reason == MLME_SUCCESS)
1025 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1026 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1027 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1031 // Cisco Leap CCKM supported Re-association.
1033 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
1035 //if CCKM is turn on , that's mean Fast Reauthentication
1036 //Use CCKM Reassociation instead of normal association for Fast Roaming.
1037 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
1038 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1040 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
1043 #endif // LEAP_SUPPORT //
1045 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1046 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1048 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1053 // This fail may because of the AP already keep us in its MAC table without
1054 // ageing-out. The previous authentication attempt must have let it remove us.
1055 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
1056 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
1058 //Add AuthMode "LEAP" for CCX 1.X
1059 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1061 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
1064 #endif // LEAP_SUPPORT //
1066 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
1067 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
1069 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
1070 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
1074 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1077 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1078 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1080 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1086 ==========================================================================
1089 IRQL = DISPATCH_LEVEL
1091 ==========================================================================
1093 VOID CntlWaitAuthProc2(
1094 IN PRTMP_ADAPTER pAd,
1095 IN MLME_QUEUE_ELEM *Elem)
1098 MLME_ASSOC_REQ_STRUCT AssocReq;
1099 MLME_AUTH_REQ_STRUCT AuthReq;
1101 if (Elem->MsgType == MT2_AUTH_CONF)
1103 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1104 if (Reason == MLME_SUCCESS)
1106 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1107 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1108 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1109 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1110 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1112 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1117 // Process LEAP first, since it use different control variable
1118 // We don't want to affect other poven operation
1119 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1121 // LEAP Auth not success, try next BSS
1122 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
1123 DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
1124 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1125 pAd->MlmeAux.BssIdx++;
1126 IterateOnBssTab(pAd);
1129 #endif // LEAP_SUPPORT //
1130 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
1131 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
1133 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
1134 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1135 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1136 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1138 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1142 // not success, try next BSS
1143 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
1144 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
1145 pAd->MlmeAux.BssIdx++;
1146 IterateOnBssTab(pAd);
1153 ==========================================================================
1156 IRQL = DISPATCH_LEVEL
1158 ==========================================================================
1160 VOID CntlWaitAssocProc(
1161 IN PRTMP_ADAPTER pAd,
1162 IN MLME_QUEUE_ELEM *Elem)
1166 if (Elem->MsgType == MT2_ASSOC_CONF)
1168 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1169 if (Reason == MLME_SUCCESS)
1171 LinkUp(pAd, BSS_INFRA);
1172 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1173 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1175 if (pAd->CommonCfg.bWirelessEvent)
1177 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1182 // not success, try next BSS
1183 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1184 pAd->MlmeAux.BssIdx++;
1185 IterateOnBssTab(pAd);
1191 ==========================================================================
1194 IRQL = DISPATCH_LEVEL
1196 ==========================================================================
1198 VOID CntlWaitReassocProc(
1199 IN PRTMP_ADAPTER pAd,
1200 IN MLME_QUEUE_ELEM *Elem)
1204 if (Elem->MsgType == MT2_REASSOC_CONF)
1206 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1207 if (Result == MLME_SUCCESS)
1210 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1212 LinkUp(pAd, BSS_INFRA);
1214 // send wireless event - for association
1215 if (pAd->CommonCfg.bWirelessEvent)
1216 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1220 if (LEAP_CCKM_ON(pAd))
1222 STA_PORT_SECURED(pAd);
1223 pAd->StaCfg.WpaState = SS_FINISH;
1225 #endif // LEAP_SUPPORT //
1226 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1227 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1231 // reassoc failed, try to pick next BSS in the BSS Table
1232 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1233 pAd->MlmeAux.RoamIdx++;
1234 IterateOnBssTab2(pAd);
1240 VOID AdhocTurnOnQos(
1241 IN PRTMP_ADAPTER pAd)
1243 #define AC0_DEF_TXOP 0
1244 #define AC1_DEF_TXOP 0
1245 #define AC2_DEF_TXOP 94
1246 #define AC3_DEF_TXOP 47
1248 // Turn on QOs if use HT rate.
1249 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1251 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1252 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1253 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1254 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1255 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1257 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1258 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1259 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1260 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1262 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1263 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1264 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1265 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1267 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1268 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1269 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1270 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1272 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1276 ==========================================================================
1279 IRQL = DISPATCH_LEVEL
1281 ==========================================================================
1284 IN PRTMP_ADAPTER pAd,
1290 UCHAR Value = 0, idx;
1291 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1293 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1296 // ASSOC - DisassocTimeoutAction
1297 // CNTL - Dis-associate successful
1298 // !!! LINK DOWN !!!
1299 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1301 // To prevent DisassocTimeoutAction to call Link down after we link up,
1302 // cancel the DisassocTimer no matter what it start or not.
1304 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1306 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1308 #ifdef DOT11_N_SUPPORT
1309 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1310 #endif // DOT11_N_SUPPORT //
1311 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1312 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1313 // to examine if cipher algorithm switching is required.
1314 //rt2860b. Don't know why need this
1315 SwitchBetweenWepAndCkip(pAd);
1318 if (BssType == BSS_ADHOC)
1320 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1321 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1323 #ifdef DOT11_N_SUPPORT
1324 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1325 AdhocTurnOnQos(pAd);
1326 #endif // DOT11_N_SUPPORT //
1328 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1332 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1333 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1335 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1339 // reset Tx beamforming bit
1340 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1342 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1343 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1345 #ifdef DOT11_N_SUPPORT
1346 // Change to AP channel
1347 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1349 // Must using 40MHz.
1350 pAd->CommonCfg.BBPCurrentBW = BW_40;
1351 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1352 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1354 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1357 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1359 // RX : control channel at lower
1360 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1362 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1364 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1366 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1368 if (pAd->MACVersion == 0x28600100)
1370 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1371 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1372 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1373 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1376 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1378 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1380 // Must using 40MHz.
1381 pAd->CommonCfg.BBPCurrentBW = BW_40;
1382 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1383 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1385 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1388 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1390 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1392 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1394 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1396 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1398 if (pAd->MACVersion == 0x28600100)
1400 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1401 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1402 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1403 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1406 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1409 #endif // DOT11_N_SUPPORT //
1411 pAd->CommonCfg.BBPCurrentBW = BW_20;
1412 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1413 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1414 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1416 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1418 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1420 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1422 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1424 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1426 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1428 if (pAd->MACVersion == 0x28600100)
1430 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1431 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1432 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1433 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1436 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1439 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1441 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1443 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1445 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1446 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1448 #ifdef DOT11_N_SUPPORT
1449 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1450 #endif // DOT11_N_SUPPORT //
1452 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1454 AsicSetSlotTime(pAd, TRUE);
1455 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1457 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1458 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1460 #ifdef DOT11_N_SUPPORT
1461 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1463 // Update HT protectionfor based on AP's operating mode.
1464 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1466 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1469 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1471 #endif // DOT11_N_SUPPORT //
1473 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1475 NdisGetSystemUpTime(&Now);
1476 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1478 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1479 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1481 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1484 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1486 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1489 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1491 if (BssType == BSS_ADHOC)
1493 MakeIbssBeacon(pAd);
1494 if ((pAd->CommonCfg.Channel > 14)
1495 && (pAd->CommonCfg.bIEEE80211H == 1)
1496 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1502 AsicEnableIbssSync(pAd);
1505 // In ad hoc mode, use MAC table from index 1.
1506 // 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.
1507 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1508 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1510 // If WEP is enabled, add key material and cipherAlg into Asic
1511 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1513 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1518 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1520 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1521 Key = pAd->SharedKey[BSS0][idx].Key;
1523 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1525 // Set key material and cipherAlg to Asic
1526 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1528 if (idx == pAd->StaCfg.DefaultKeyId)
1530 // Update WCID attribute table and IVEIV table for this group key table
1531 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1538 // If WPANone is enabled, add key material and cipherAlg into Asic
1539 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1540 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1542 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1544 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1545 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1546 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1548 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1550 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1551 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1554 // Decide its ChiperAlg
1555 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1556 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1557 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1558 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1561 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1562 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1565 // Set key material and cipherAlg to Asic
1566 AsicAddSharedKeyEntry(pAd,
1569 pAd->SharedKey[BSS0][0].CipherAlg,
1570 pAd->SharedKey[BSS0][0].Key,
1571 pAd->SharedKey[BSS0][0].TxMic,
1572 pAd->SharedKey[BSS0][0].RxMic);
1574 // Update WCID attribute table and IVEIV table for this group key table
1575 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1582 // Check the new SSID with last SSID
1583 while (Cancelled == TRUE)
1585 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1587 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1589 // Link to the old one no linkdown is required.
1593 // Send link down event before set to link up
1594 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1595 RTMP_IndicateMediaState(pAd);
1596 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1597 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1602 // On WPA mode, Remove All Keys if not connect to the last BSSID
1603 // Key will be set after 4-way handshake.
1605 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1609 // Remove all WPA keys
1610 RTMPWPARemoveAllKeys(pAd);
1611 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1612 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1614 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1615 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1617 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1618 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1621 // the decision of using "short slot time" or not may change dynamically due to
1622 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1625 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1626 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1629 ComposeNullFrame(pAd);
1631 AsicEnableBssSync(pAd);
1633 // Add BSSID to WCID search table
1634 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1636 NdisAcquireSpinLock(&pAd->MacTabLock);
1637 // add this BSSID entry into HASH table
1641 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1642 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1643 if (pAd->MacTab.Hash[HashIdx] == NULL)
1645 pAd->MacTab.Hash[HashIdx] = pEntry;
1649 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1650 while (pCurrEntry->pNext != NULL)
1651 pCurrEntry = pCurrEntry->pNext;
1652 pCurrEntry->pNext = pEntry;
1655 NdisReleaseSpinLock(&pAd->MacTabLock);
1658 // If WEP is enabled, add paiewise and shared key
1659 #ifdef WPA_SUPPLICANT_SUPPORT
1660 if (((pAd->StaCfg.WpaSupplicantUP)&&
1661 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1662 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1663 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1664 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1666 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1667 #endif // WPA_SUPPLICANT_SUPPORT //
1672 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1674 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1675 Key = pAd->SharedKey[BSS0][idx].Key;
1677 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1679 // Set key material and cipherAlg to Asic
1680 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1682 if (idx == pAd->StaCfg.DefaultKeyId)
1684 // Assign group key info
1685 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1687 // Assign pairwise key info
1688 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1694 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1695 // should wait until at least 2 active nodes in this BSSID.
1696 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1699 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1701 pAd->IndicateMediaState = NdisMediaStateConnected;
1702 pAd->ExtraInfo = GENERAL_LINK_UP;
1703 RTMP_IndicateMediaState(pAd);
1707 // Add BSSID in my MAC Table.
1708 NdisAcquireSpinLock(&pAd->MacTabLock);
1709 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1710 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1711 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1712 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1713 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1714 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1715 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1716 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1717 NdisReleaseSpinLock(&pAd->MacTabLock);
1719 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1720 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1722 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1723 #ifdef DOT11_N_SUPPORT
1724 MlmeUpdateHtTxRates(pAd, BSS0);
1725 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1726 #endif // DOT11_N_SUPPORT //
1729 // Report Adjacent AP report.
1732 CCXAdjacentAPReport(pAd);
1733 #endif // LEAP_SUPPORT //
1735 if (pAd->CommonCfg.bAggregationCapable)
1737 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1740 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1741 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1742 RTMPSetPiggyBack(pAd, TRUE);
1743 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1745 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1747 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1751 if (pAd->MlmeAux.APRalinkIe != 0x0)
1753 #ifdef DOT11_N_SUPPORT
1754 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1758 #endif // DOT11_N_SUPPORT //
1759 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1760 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1764 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1765 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1769 #ifdef DOT11_N_SUPPORT
1770 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));
1771 #endif // DOT11_N_SUPPORT //
1774 RTMPSetLED(pAd, LED_LINK_UP);
1776 pAd->Mlme.PeriodicRound = 0;
1777 pAd->Mlme.OneSecPeriodicRound = 0;
1778 pAd->bConfigChanged = FALSE; // Reset config flag
1779 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1781 // Set asic auto fall back
1784 UCHAR TableSize = 0;
1786 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1787 AsicUpdateAutoFallBackTable(pAd, pTable);
1790 NdisAcquireSpinLock(&pAd->MacTabLock);
1791 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1792 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1793 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1795 pEntry->bAutoTxRateSwitch = FALSE;
1796 #ifdef DOT11_N_SUPPORT
1797 if (pEntry->HTPhyMode.field.MCS == 32)
1798 pEntry->HTPhyMode.field.ShortGI = GI_800;
1800 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1801 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1802 #endif // DOT11_N_SUPPORT //
1803 // If the legacy mode is set, overwrite the transmit setting of this entry.
1804 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1805 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1808 pEntry->bAutoTxRateSwitch = TRUE;
1809 NdisReleaseSpinLock(&pAd->MacTabLock);
1811 // Let Link Status Page display first initial rate.
1812 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1813 // Select DAC according to HT or Legacy
1814 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1816 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1818 if (pAd->Antenna.field.TxPath == 2)
1822 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1826 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1828 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1831 #ifdef DOT11_N_SUPPORT
1832 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1835 else if (pEntry->MaxRAmpduFactor == 0)
1837 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1838 // Because our Init value is 1 at MACRegTable.
1839 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1841 #endif // DOT11_N_SUPPORT //
1843 // Patch for Marvel AP to gain high throughput
1844 // Need to set as following,
1845 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1846 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1847 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1848 // 4. kick per two packets when dequeue
1850 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1852 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1853 #ifdef DOT11_N_SUPPORT
1854 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1855 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1857 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1859 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1861 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1862 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1865 #endif // DOT11_N_SUPPORT //
1866 if (pAd->CommonCfg.bEnableTxBurst)
1868 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1871 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1872 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1874 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1875 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1879 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1881 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1883 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1884 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1887 #ifdef DOT11_N_SUPPORT
1888 // Re-check to turn on TX burst or not.
1889 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1891 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1892 if (pAd->CommonCfg.bEnableTxBurst)
1894 UINT32 MACValue = 0;
1895 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1896 // I didn't change PBF_MAX_PCNT setting.
1897 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1898 MACValue &= 0xFFFFFF00;
1899 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1900 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1905 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1907 #endif // DOT11_N_SUPPORT //
1909 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1910 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1911 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1912 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1913 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1914 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1916 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1918 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1919 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1922 NdisAcquireSpinLock(&pAd->MacTabLock);
1923 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1924 NdisReleaseSpinLock(&pAd->MacTabLock);
1927 // Patch Atheros AP TX will breakdown issue.
1928 // AP Model: DLink DWL-8200AP
1930 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1932 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1936 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1939 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1942 #ifdef DOT11_N_SUPPORT
1943 #ifdef DOT11N_DRAFT3
1944 if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
1946 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
1947 BuildEffectedChannelList(pAd);
1949 #endif // DOT11N_DRAFT3 //
1950 #endif // DOT11_N_SUPPORT //
1954 ==========================================================================
1956 Routine Description:
1957 Disconnect current BSSID
1960 pAd - Pointer to our adapter
1961 IsReqFromAP - Request from AP
1966 IRQL = DISPATCH_LEVEL
1969 We need more information to know it's this requst from AP.
1970 If yes! we need to do extra handling, for example, remove the WPA key.
1971 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1972 remove while auto reconnect.
1973 Disconnect request from AP, it means we will start afresh 4-way handshaking
1976 ==========================================================================
1979 IN PRTMP_ADAPTER pAd,
1980 IN BOOLEAN IsReqFromAP)
1982 UCHAR i, ByteValue = 0;
1984 // Do nothing if monitor mode is on
1985 if (MONITOR_ON(pAd))
1988 if (pAd->CommonCfg.bWirelessEvent)
1990 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1993 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1994 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1996 if (ADHOC_ON(pAd)) // Adhoc mode link down
1998 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
2000 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
2001 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2002 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2003 RTMP_IndicateMediaState(pAd);
2004 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2005 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2006 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
2008 else // Infra structure mode
2010 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
2012 #ifdef QOS_DLS_SUPPORT
2013 // DLS tear down frame must be sent before link down
2014 // send DLS-TEAR_DOWN message
2015 if (pAd->CommonCfg.bDLSCapable)
2017 // tear down local dls table entry
2018 for (i=0; i<MAX_NUM_OF_INIT_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 // tear down peer dls table entry
2028 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
2030 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2032 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2033 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2037 #endif // QOS_DLS_SUPPORT //
2039 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
2040 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2042 // Saved last SSID for linkup comparison
2043 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
2044 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
2045 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
2046 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
2048 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2049 RTMP_IndicateMediaState(pAd);
2050 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2051 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
2052 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
2057 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
2058 // Otherwise lost beacon or receive De-Authentication from AP,
2059 // then we should delete BSSID from BssTable.
2060 // If we don't delete from entry, roaming will fail.
2062 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2065 // restore back to -
2066 // 1. long slot (20 us) or short slot (9 us) time
2067 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
2068 // 3. short preamble
2069 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
2071 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
2074 // Record current AP's information.
2075 // for later used reporting Adjacent AP report.
2077 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
2078 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
2079 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
2080 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
2083 #ifdef EXT_BUILD_CHANNEL_LIST
2084 // Country IE of the AP will be evaluated and will be used.
2085 if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
2087 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
2088 pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
2089 BuildChannelListEx(pAd);
2091 #endif // EXT_BUILD_CHANNEL_LIST //
2095 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2097 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2098 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
2101 pAd->StaCfg.CCXQosECWMin = 4;
2102 pAd->StaCfg.CCXQosECWMax = 10;
2104 AsicSetSlotTime(pAd, TRUE); //FALSE);
2105 AsicSetEdcaParm(pAd, NULL);
2108 RTMPSetLED(pAd, LED_LINK_DOWN);
2109 pAd->LedIndicatorStregth = 0xF0;
2110 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
2112 AsicDisableSync(pAd);
2114 pAd->Mlme.PeriodicRound = 0;
2115 pAd->Mlme.OneSecPeriodicRound = 0;
2117 if (pAd->StaCfg.BssType == BSS_INFRA)
2119 // Remove StaCfg Information after link down
2120 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
2121 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
2122 pAd->CommonCfg.SsidLen = 0;
2124 #ifdef DOT11_N_SUPPORT
2125 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
2126 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
2127 pAd->MlmeAux.HtCapabilityLen = 0;
2128 pAd->MlmeAux.NewExtChannelOffset = 0xff;
2129 #endif // DOT11_N_SUPPORT //
2131 // Reset WPA-PSK state. Only reset when supplicant enabled
2132 if (pAd->StaCfg.WpaState != SS_NOTUSE)
2134 pAd->StaCfg.WpaState = SS_START;
2135 // Clear Replay counter
2136 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2138 #ifdef QOS_DLS_SUPPORT
2139 if (pAd->CommonCfg.bDLSCapable)
2140 NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
2141 #endif // QOS_DLS_SUPPORT //
2146 // if link down come from AP, we need to remove all WPA keys on WPA mode.
2147 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
2149 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
2151 // Remove all WPA keys
2152 RTMPWPARemoveAllKeys(pAd);
2155 // 802.1x port control
2156 #ifdef WPA_SUPPLICANT_SUPPORT
2157 // Prevent clear PortSecured here with static WEP
2158 // NetworkManger set security policy first then set SSID to connect AP.
2159 if (pAd->StaCfg.WpaSupplicantUP &&
2160 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
2161 (pAd->StaCfg.IEEE8021X == FALSE))
2163 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2166 #endif // WPA_SUPPLICANT_SUPPORT //
2168 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2169 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2172 NdisAcquireSpinLock(&pAd->MacTabLock);
2173 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2174 NdisReleaseSpinLock(&pAd->MacTabLock);
2176 pAd->StaCfg.MicErrCnt = 0;
2178 // Turn off Ckip control flag
2179 pAd->StaCfg.bCkipOn = FALSE;
2180 pAd->StaCfg.CCXEnable = FALSE;
2182 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2183 // Update extra information to link is up
2184 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2186 //pAd->StaCfg.AdhocBOnlyJoined = FALSE;
2187 //pAd->StaCfg.AdhocBGJoined = FALSE;
2188 //pAd->StaCfg.Adhoc20NJoined = FALSE;
2189 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2191 // Reset the Current AP's IP address
2192 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
2194 pAd->bUsbTxBulkAggre = FALSE;
2197 // Clean association information
2198 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
2199 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
2200 pAd->StaCfg.ReqVarIELen = 0;
2201 pAd->StaCfg.ResVarIELen = 0;
2204 // Reset RSSI value after link down
2206 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2207 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2208 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2209 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2210 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2211 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2214 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2215 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2217 #ifdef DOT11_N_SUPPORT
2219 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
2221 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
2223 pAd->CommonCfg.BBPCurrentBW = BW_20;
2224 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2225 ByteValue &= (~0x18);
2226 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2228 #endif // DOT11_N_SUPPORT //
2230 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2231 ByteValue &= (~0x18);
2232 if (pAd->Antenna.field.TxPath == 2)
2236 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2238 RTMPSetPiggyBack(pAd,FALSE);
2239 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2241 #ifdef DOT11_N_SUPPORT
2242 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2243 #endif // DOT11_N_SUPPORT //
2245 // Restore all settings in the following.
2246 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2247 AsicDisableRDG(pAd);
2248 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2249 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2251 #ifdef DOT11_N_SUPPORT
2252 #ifdef DOT11N_DRAFT3
2253 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
2254 pAd->CommonCfg.BSSCoexist2040.word = 0;
2256 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
2258 pAd->ChannelList[i].bEffectedChannel = FALSE;
2260 #endif // DOT11N_DRAFT3 //
2261 #endif // DOT11_N_SUPPORT //
2263 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2264 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2266 #ifdef WPA_SUPPLICANT_SUPPORT
2267 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2268 if (pAd->StaCfg.WpaSupplicantUP) {
2269 union iwreq_data wrqu;
2270 //send disassociate event to wpa_supplicant
2271 memset(&wrqu, 0, sizeof(wrqu));
2272 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2273 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2275 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2276 #endif // WPA_SUPPLICANT_SUPPORT //
2278 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2280 union iwreq_data wrqu;
2281 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2282 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2284 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2288 ==========================================================================
2291 IRQL = DISPATCH_LEVEL
2293 ==========================================================================
2295 VOID IterateOnBssTab(
2296 IN PRTMP_ADAPTER pAd)
2298 MLME_START_REQ_STRUCT StartReq;
2299 MLME_JOIN_REQ_STRUCT JoinReq;
2302 // Change the wepstatus to original wepstatus
2303 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2304 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2305 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2307 BssIdx = pAd->MlmeAux.BssIdx;
2308 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2310 // Check cipher suite, AP must have more secured cipher than station setting
2311 // Set the Pairwise and Group cipher to match the intended AP setting
2312 // We can only connect to AP with less secured cipher setting
2313 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2315 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2317 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2318 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2319 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2320 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2321 else // There is no PairCipher Aux, downgrade our capability to TKIP
2322 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2324 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2326 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2328 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2329 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2330 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2331 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2332 else // There is no PairCipher Aux, downgrade our capability to TKIP
2333 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2336 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2339 // Set Mix cipher flag
2340 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2341 if (pAd->StaCfg.bMixCipher == TRUE)
2343 // If mix cipher, re-build RSNIE
2344 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2347 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2348 JoinParmFill(pAd, &JoinReq, BssIdx);
2349 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2351 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2353 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2355 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2356 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2357 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2358 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2362 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2363 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2364 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2365 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2369 // for re-association only
2370 // IRQL = DISPATCH_LEVEL
2371 VOID IterateOnBssTab2(
2372 IN PRTMP_ADAPTER pAd)
2374 MLME_REASSOC_REQ_STRUCT ReassocReq;
2378 BssIdx = pAd->MlmeAux.RoamIdx;
2379 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2381 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2383 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2385 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2386 AsicLockChannel(pAd, pBss->Channel);
2388 // reassociate message has the same structure as associate message
2389 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2390 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2391 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2392 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2394 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2398 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2399 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2400 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2401 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2406 ==========================================================================
2409 IRQL = DISPATCH_LEVEL
2411 ==========================================================================
2414 IN PRTMP_ADAPTER pAd,
2415 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2418 JoinReq->BssIdx = BssIdx;
2422 ==========================================================================
2425 IRQL = DISPATCH_LEVEL
2427 ==========================================================================
2430 IN PRTMP_ADAPTER pAd,
2431 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2437 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2438 ScanReq->SsidLen = SsidLen;
2439 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2440 ScanReq->BssType = BssType;
2441 ScanReq->ScanType = ScanType;
2444 #ifdef QOS_DLS_SUPPORT
2446 ==========================================================================
2449 IRQL = DISPATCH_LEVEL
2451 ==========================================================================
2454 IN PRTMP_ADAPTER pAd,
2455 IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
2456 IN PRT_802_11_DLS pDls,
2459 pDlsReq->pDLS = pDls;
2460 pDlsReq->Reason = reason;
2462 #endif // QOS_DLS_SUPPORT //
2465 ==========================================================================
2468 IRQL = DISPATCH_LEVEL
2470 ==========================================================================
2473 IN PRTMP_ADAPTER pAd,
2474 IN OUT MLME_START_REQ_STRUCT *StartReq,
2478 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2479 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2480 StartReq->SsidLen = SsidLen;
2484 ==========================================================================
2487 IRQL = DISPATCH_LEVEL
2489 ==========================================================================
2492 IN PRTMP_ADAPTER pAd,
2493 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2497 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2499 AuthReq->Timeout = AUTH_TIMEOUT;
2503 ==========================================================================
2506 IRQL = DISPATCH_LEVEL
2508 ==========================================================================
2514 VOID MlmeCntlConfirm(
2515 IN PRTMP_ADAPTER pAd,
2519 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
2523 IN PRTMP_ADAPTER pAd)
2525 PTXINFO_STRUC pTxInfo;
2528 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2529 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2531 pAd->PsPollFrame.FC.PwrMgmt = 0;
2532 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2533 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2534 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2535 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2536 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2538 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
2539 pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
2540 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2541 pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2542 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
2543 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2544 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2545 // Append 4 extra zero bytes.
2546 pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
2549 // IRQL = DISPATCH_LEVEL
2550 VOID ComposeNullFrame(
2551 IN PRTMP_ADAPTER pAd)
2553 PTXINFO_STRUC pTxInfo;
2556 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2557 pAd->NullFrame.FC.Type = BTYPE_DATA;
2558 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2559 pAd->NullFrame.FC.ToDs = 1;
2560 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2561 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2562 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2563 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
2564 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
2565 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2566 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2567 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
2568 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2569 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
2570 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2576 ==========================================================================
2578 Pre-build a BEACON frame in the shared memory
2580 IRQL = PASSIVE_LEVEL
2581 IRQL = DISPATCH_LEVEL
2583 ==========================================================================
2585 ULONG MakeIbssBeacon(
2586 IN PRTMP_ADAPTER pAd)
2588 UCHAR DsLen = 1, IbssLen = 2;
2589 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2590 HEADER_802_11 BcnHdr;
2591 USHORT CapabilityInfo;
2592 LARGE_INTEGER FakeTimestamp;
2594 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2595 CHAR *pBeaconFrame = pAd->BeaconBuf;
2597 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2598 UCHAR SupRateLen = 0;
2599 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2600 UCHAR ExtRateLen = 0;
2601 UCHAR RSNIe = IE_WPA;
2603 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2605 SupRate[0] = 0x82; // 1 mbps
2606 SupRate[1] = 0x84; // 2 mbps
2607 SupRate[2] = 0x8b; // 5.5 mbps
2608 SupRate[3] = 0x96; // 11 mbps
2612 else if (pAd->CommonCfg.Channel > 14)
2614 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2615 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2616 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2617 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2618 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2619 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2620 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2621 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2626 // Also Update MlmeRate & RtsRate for G only & A only
2628 pAd->CommonCfg.MlmeRate = RATE_6;
2629 pAd->CommonCfg.RtsRate = RATE_6;
2630 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2631 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2632 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2633 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2637 SupRate[0] = 0x82; // 1 mbps
2638 SupRate[1] = 0x84; // 2 mbps
2639 SupRate[2] = 0x8b; // 5.5 mbps
2640 SupRate[3] = 0x96; // 11 mbps
2643 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2644 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2645 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2646 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2647 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2648 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2649 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2650 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2654 pAd->StaActive.SupRateLen = SupRateLen;
2655 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2656 pAd->StaActive.ExtRateLen = ExtRateLen;
2657 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2659 // compose IBSS beacon frame
2660 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2661 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2662 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2663 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2664 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2666 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2667 sizeof(HEADER_802_11), &BcnHdr,
2668 TIMESTAMP_LEN, &FakeTimestamp,
2669 2, &pAd->CommonCfg.BeaconPeriod,
2672 1, &pAd->CommonCfg.SsidLen,
2673 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2676 SupRateLen, SupRate,
2679 1, &pAd->CommonCfg.Channel,
2682 2, &pAd->StaActive.AtimWin,
2685 // add ERP_IE and EXT_RAE IE of in 802.11g
2690 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2694 ExtRateLen, ExtRate,
2699 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2700 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2703 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2705 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2707 1, &pAd->StaCfg.RSNIE_Len,
2708 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2713 #ifdef DOT11_N_SUPPORT
2714 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2717 UCHAR HtLen, HtLen1;
2719 #ifdef RT_BIG_ENDIAN
2720 HT_CAPABILITY_IE HtCapabilityTmp;
2721 ADD_HT_INFO_IE addHTInfoTmp;
2722 USHORT b2lTmp, b2lTmp2;
2725 // add HT Capability IE
2726 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2727 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2728 #ifndef RT_BIG_ENDIAN
2729 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2732 HtLen, &pAd->CommonCfg.HtCapability,
2735 HtLen1, &pAd->CommonCfg.AddHTInfo,
2738 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2739 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2740 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2742 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2743 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2744 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2746 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2749 HtLen, &HtCapabilityTmp,
2752 HtLen1, &addHTInfoTmp,
2757 #endif // DOT11_N_SUPPORT //
2759 //beacon use reserved WCID 0xff
2760 if (pAd->CommonCfg.Channel > 14)
2762 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2763 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2767 // Set to use 1Mbps for Adhoc beacon.
2768 HTTRANSMIT_SETTING Transmit;
2770 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2771 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2774 #ifdef RT_BIG_ENDIAN
2775 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2776 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2779 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2780 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));