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);
184 case CNTL_WAIT_OID_DISASSOC:
185 if (Elem->MsgType == MT2_DISASSOC_CONF)
187 LinkDown(pAd, FALSE);
188 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
192 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
199 ==========================================================================
202 IRQL = DISPATCH_LEVEL
204 ==========================================================================
207 IN PRTMP_ADAPTER pAd,
208 IN MLME_QUEUE_ELEM *Elem)
210 MLME_DISASSOC_REQ_STRUCT DisassocReq;
212 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
215 switch(Elem->MsgType)
217 case OID_802_11_SSID:
218 CntlOidSsidProc(pAd, Elem);
221 case OID_802_11_BSSID:
222 CntlOidRTBssidProc(pAd,Elem);
225 case OID_802_11_BSSID_LIST_SCAN:
226 CntlOidScanProc(pAd,Elem);
229 case OID_802_11_DISASSOCIATE:
230 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
231 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
232 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
234 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
236 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
237 // Since calling this indicate user don't want to connect to that SSID anymore.
238 pAd->MlmeAux.AutoReconnectSsidLen= 32;
239 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
243 case MT2_MLME_ROAMING_REQ:
244 CntlMlmeRoamingProc(pAd, Elem);
247 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
248 WpaMicFailureReportFrame(pAd, Elem);
252 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
257 VOID CntlOidScanProc(
258 IN PRTMP_ADAPTER pAd,
259 IN MLME_QUEUE_ELEM *Elem)
261 MLME_SCAN_REQ_STRUCT ScanReq;
262 ULONG BssIdx = BSS_NOT_FOUND;
265 // record current BSS if network is connected.
266 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
267 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
269 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
270 if (BssIdx != BSS_NOT_FOUND)
272 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
276 // clean up previous SCAN result, add current BSS back to table if any
277 BssTableInit(&pAd->ScanTab);
278 if (BssIdx != BSS_NOT_FOUND)
280 // DDK Note: If the NIC is associated with a particular BSSID and SSID
281 // that are not contained in the list of BSSIDs generated by this scan, the
282 // BSSID description of the currently associated BSSID and SSID should be
283 // appended to the list of BSSIDs in the NIC's database.
284 // To ensure this, we append this BSS as the first entry in SCAN result
285 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
286 pAd->ScanTab.BssNr = 1;
289 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
290 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
291 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
292 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
296 ==========================================================================
298 Before calling this routine, user desired SSID should already been
299 recorded in CommonCfg.Ssid[]
300 IRQL = DISPATCH_LEVEL
302 ==========================================================================
304 VOID CntlOidSsidProc(
305 IN PRTMP_ADAPTER pAd,
306 IN MLME_QUEUE_ELEM * Elem)
308 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
309 MLME_DISASSOC_REQ_STRUCT DisassocReq;
312 // BBP and RF are not accessible in PS mode, we has to wake them up first
313 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
314 AsicForceWakeup(pAd, RTMP_HALT);
316 // Step 1. record the desired user settings to MlmeAux
317 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
318 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
319 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
320 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
321 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
325 // Update Reconnect Ssid, that user desired to connect.
327 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
328 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
329 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
331 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
332 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
333 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
335 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
336 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
337 NdisGetSystemUpTime(&Now);
339 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
340 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
341 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
342 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
344 // Case 1. already connected with an AP who has the desired SSID
347 // Add checking Mode "LEAP" for CCX 1.0
348 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
349 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
350 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
351 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
353 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
355 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
356 // connection process
357 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
358 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
359 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
360 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
361 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
363 else if (pAd->bConfigChanged == TRUE)
365 // case 1.2 Important Config has changed, we have to reconnect to the same AP
366 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
367 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
368 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
369 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
370 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
374 // case 1.3. already connected to the SSID with highest RSSI.
375 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
377 // (HCT 12.1) 1c_wlan_mediaevents required
378 // media connect events are indicated when associating with the same AP
383 // Since MediaState already is NdisMediaStateConnected
384 // We just indicate the connect event again to meet the WHQL required.
386 pAd->IndicateMediaState = NdisMediaStateConnected;
387 RTMP_IndicateMediaState(pAd);
388 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
391 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
394 union iwreq_data wrqu;
396 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
397 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
398 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
403 else if (INFRA_ON(pAd))
407 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
408 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
409 // But media status is connected, so the SSID not report correctly.
411 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
414 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
416 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
418 // case 2. active INFRA association existent
419 // roaming is done within miniport driver, nothing to do with configuration
420 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
421 // disassociate with the current associated AP,
422 // then perform a new association with this new SSID, no matter the
423 // new/old SSID are the same or not.
424 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
425 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
426 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
427 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
428 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
434 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
435 LinkDown(pAd, FALSE);
436 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
437 pAd->IndicateMediaState = NdisMediaStateDisconnected;
438 RTMP_IndicateMediaState(pAd);
439 pAd->ExtraInfo = GENERAL_LINK_DOWN;
440 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
443 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
444 (pAd->StaCfg.bAutoReconnect == TRUE) &&
445 (pAd->MlmeAux.BssType == BSS_INFRA) &&
446 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
449 MLME_SCAN_REQ_STRUCT ScanReq;
451 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
452 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
453 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
454 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
455 // Reset Missed scan number
456 pAd->StaCfg.LastScanTime = Now;
460 pAd->MlmeAux.BssIdx = 0;
461 IterateOnBssTab(pAd);
468 ==========================================================================
471 IRQL = DISPATCH_LEVEL
473 ==========================================================================
475 VOID CntlOidRTBssidProc(
476 IN PRTMP_ADAPTER pAd,
477 IN MLME_QUEUE_ELEM * Elem)
480 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
481 MLME_DISASSOC_REQ_STRUCT DisassocReq;
482 MLME_JOIN_REQ_STRUCT JoinReq;
484 // record user desired settings
485 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
486 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
489 // Update Reconnect Ssid, that user desired to connect.
491 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
492 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
493 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
495 // find the desired BSS in the latest SCAN result table
496 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
497 if (BssIdx == BSS_NOT_FOUND)
499 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
500 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
504 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
505 // Because we need this entry to become the JOIN target in later on SYNC state machine
506 pAd->MlmeAux.BssIdx = 0;
507 pAd->MlmeAux.SsidBssTab.BssNr = 1;
508 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
510 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
511 // we just follow normal procedure. The reason of user doing this may because he/she changed
512 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
513 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
514 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
515 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
516 // connection when setting the same BSSID.
517 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
518 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
520 // already connected to the same BSSID, go back to idle state directly
521 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
522 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
525 union iwreq_data wrqu;
527 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
528 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
529 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
537 // disassoc from current AP first
538 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
539 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
540 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
541 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
543 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
549 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
550 LinkDown(pAd, FALSE);
551 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
552 pAd->IndicateMediaState = NdisMediaStateDisconnected;
553 RTMP_IndicateMediaState(pAd);
554 pAd->ExtraInfo = GENERAL_LINK_DOWN;
555 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
558 // Change the wepstatus to original wepstatus
559 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
560 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
561 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
563 // Check cipher suite, AP must have more secured cipher than station setting
564 // Set the Pairwise and Group cipher to match the intended AP setting
565 // We can only connect to AP with less secured cipher setting
566 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
568 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
570 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
571 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
572 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
573 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
574 else // There is no PairCipher Aux, downgrade our capability to TKIP
575 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
577 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
579 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
581 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
582 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
583 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
584 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
585 else // There is no PairCipher Aux, downgrade our capability to TKIP
586 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
589 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
592 // Set Mix cipher flag
593 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
594 if (pAd->StaCfg.bMixCipher == TRUE)
596 // If mix cipher, re-build RSNIE
597 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
599 // No active association, join the BSS immediately
600 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
601 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
603 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
604 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
606 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
611 // Roaming is the only external request triggering CNTL state machine
612 // despite of other "SET OID" operation. All "SET OID" related oerations
613 // happen in sequence, because no other SET OID will be sent to this device
614 // until the the previous SET operation is complete (successful o failed).
615 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
616 // or been corrupted by other "SET OID"?
618 // IRQL = DISPATCH_LEVEL
619 VOID CntlMlmeRoamingProc(
620 IN PRTMP_ADAPTER pAd,
621 IN MLME_QUEUE_ELEM *Elem)
624 // AP in different channel may show lower RSSI than actual value??
625 // should we add a weighting factor to compensate it?
626 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
628 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
629 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
631 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
632 pAd->MlmeAux.BssIdx = 0;
633 IterateOnBssTab(pAd);
637 ==========================================================================
640 IRQL = DISPATCH_LEVEL
642 ==========================================================================
644 VOID CntlWaitDisassocProc(
645 IN PRTMP_ADAPTER pAd,
646 IN MLME_QUEUE_ELEM *Elem)
648 MLME_START_REQ_STRUCT StartReq;
650 if (Elem->MsgType == MT2_DISASSOC_CONF)
652 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
654 if (pAd->CommonCfg.bWirelessEvent)
656 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
659 LinkDown(pAd, FALSE);
661 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
662 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
664 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
665 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
666 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
667 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
669 // case 2. try each matched BSS
672 pAd->MlmeAux.BssIdx = 0;
674 IterateOnBssTab(pAd);
680 ==========================================================================
683 IRQL = DISPATCH_LEVEL
685 ==========================================================================
687 VOID CntlWaitJoinProc(
688 IN PRTMP_ADAPTER pAd,
689 IN MLME_QUEUE_ELEM *Elem)
692 MLME_AUTH_REQ_STRUCT AuthReq;
694 if (Elem->MsgType == MT2_JOIN_CONF)
696 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
697 if (Reason == MLME_SUCCESS)
699 // 1. joined an IBSS, we are pretty much done here
700 if (pAd->MlmeAux.BssType == BSS_ADHOC)
703 // 5G bands rules of Japan:
704 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
706 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
707 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
710 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
711 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
715 LinkUp(pAd, BSS_ADHOC);
716 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
717 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
718 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
719 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
721 pAd->IndicateMediaState = NdisMediaStateConnected;
722 pAd->ExtraInfo = GENERAL_LINK_UP;
724 // 2. joined a new INFRA network, start from authentication
728 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
729 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
730 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
732 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
736 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
739 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
740 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
742 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
747 // 3. failed, try next BSS
748 pAd->MlmeAux.BssIdx++;
749 IterateOnBssTab(pAd);
756 ==========================================================================
759 IRQL = DISPATCH_LEVEL
761 ==========================================================================
763 VOID CntlWaitStartProc(
764 IN PRTMP_ADAPTER pAd,
765 IN MLME_QUEUE_ELEM *Elem)
769 if (Elem->MsgType == MT2_START_CONF)
771 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
772 if (Result == MLME_SUCCESS)
775 // 5G bands rules of Japan:
776 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
778 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
779 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
782 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
783 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
787 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
791 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
792 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
793 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
794 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
795 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
796 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
798 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
799 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
801 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
803 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
804 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
806 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
811 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
813 LinkUp(pAd, BSS_ADHOC);
814 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
815 // Before send beacon, driver need do radar detection
816 if ((pAd->CommonCfg.Channel > 14 )
817 && (pAd->CommonCfg.bIEEE80211H == 1)
818 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
820 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
821 pAd->CommonCfg.RadarDetect.RDCount = 0;
824 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
825 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
826 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
830 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
831 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
837 ==========================================================================
840 IRQL = DISPATCH_LEVEL
842 ==========================================================================
844 VOID CntlWaitAuthProc(
845 IN PRTMP_ADAPTER pAd,
846 IN MLME_QUEUE_ELEM *Elem)
849 MLME_ASSOC_REQ_STRUCT AssocReq;
850 MLME_AUTH_REQ_STRUCT AuthReq;
852 if (Elem->MsgType == MT2_AUTH_CONF)
854 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
855 if (Reason == MLME_SUCCESS)
857 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
858 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
859 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
862 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
863 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
865 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
870 // This fail may because of the AP already keep us in its MAC table without
871 // ageing-out. The previous authentication attempt must have let it remove us.
872 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
873 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
876 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
877 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
879 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
880 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
884 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
887 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
888 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
890 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
896 ==========================================================================
899 IRQL = DISPATCH_LEVEL
901 ==========================================================================
903 VOID CntlWaitAuthProc2(
904 IN PRTMP_ADAPTER pAd,
905 IN MLME_QUEUE_ELEM *Elem)
908 MLME_ASSOC_REQ_STRUCT AssocReq;
909 MLME_AUTH_REQ_STRUCT AuthReq;
911 if (Elem->MsgType == MT2_AUTH_CONF)
913 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
914 if (Reason == MLME_SUCCESS)
916 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
917 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
918 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
919 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
920 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
922 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
926 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
927 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
929 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
930 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
931 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
932 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
934 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
938 // not success, try next BSS
939 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
940 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
941 pAd->MlmeAux.BssIdx++;
942 IterateOnBssTab(pAd);
949 ==========================================================================
952 IRQL = DISPATCH_LEVEL
954 ==========================================================================
956 VOID CntlWaitAssocProc(
957 IN PRTMP_ADAPTER pAd,
958 IN MLME_QUEUE_ELEM *Elem)
962 if (Elem->MsgType == MT2_ASSOC_CONF)
964 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
965 if (Reason == MLME_SUCCESS)
967 LinkUp(pAd, BSS_INFRA);
968 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
969 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
971 if (pAd->CommonCfg.bWirelessEvent)
973 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
978 // not success, try next BSS
979 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
980 pAd->MlmeAux.BssIdx++;
981 IterateOnBssTab(pAd);
987 ==========================================================================
990 IRQL = DISPATCH_LEVEL
992 ==========================================================================
994 VOID CntlWaitReassocProc(
995 IN PRTMP_ADAPTER pAd,
996 IN MLME_QUEUE_ELEM *Elem)
1000 if (Elem->MsgType == MT2_REASSOC_CONF)
1002 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1003 if (Result == MLME_SUCCESS)
1006 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1008 LinkUp(pAd, BSS_INFRA);
1010 // send wireless event - for association
1011 if (pAd->CommonCfg.bWirelessEvent)
1012 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1014 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1015 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1019 // reassoc failed, try to pick next BSS in the BSS Table
1020 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1021 pAd->MlmeAux.RoamIdx++;
1022 IterateOnBssTab2(pAd);
1028 ==========================================================================
1031 IRQL = DISPATCH_LEVEL
1033 ==========================================================================
1036 IN PRTMP_ADAPTER pAd,
1042 UCHAR Value = 0, idx;
1043 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1045 if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
1047 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
1048 RTMPusecDelay(6000);
1049 pAd->bPCIclkOff = FALSE;
1052 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1055 // ASSOC - DisassocTimeoutAction
1056 // CNTL - Dis-associate successful
1057 // !!! LINK DOWN !!!
1058 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1060 // To prevent DisassocTimeoutAction to call Link down after we link up,
1061 // cancel the DisassocTimer no matter what it start or not.
1063 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1065 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1067 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1069 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1070 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1071 // to examine if cipher algorithm switching is required.
1072 //rt2860b. Don't know why need this
1073 SwitchBetweenWepAndCkip(pAd);
1075 // Before power save before link up function, We will force use 1R.
1076 // So after link up, check Rx antenna # again.
1077 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1078 if(pAd->Antenna.field.RxPath == 3)
1082 else if(pAd->Antenna.field.RxPath == 2)
1086 else if(pAd->Antenna.field.RxPath == 1)
1090 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1091 pAd->StaCfg.BBPR3 = Value;
1093 if (BssType == BSS_ADHOC)
1095 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1096 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1098 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1102 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1103 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1105 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1109 // reset Tx beamforming bit
1110 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1112 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1113 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1115 // Change to AP channel
1116 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1118 // Must using 40MHz.
1119 pAd->CommonCfg.BBPCurrentBW = BW_40;
1120 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1121 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1123 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1126 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1128 // RX : control channel at lower
1129 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1131 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1132 pAd->StaCfg.BBPR3 = Value;
1134 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1136 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1138 if (pAd->MACVersion == 0x28600100)
1140 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1141 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1142 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1143 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1146 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1148 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1150 // Must using 40MHz.
1151 pAd->CommonCfg.BBPCurrentBW = BW_40;
1152 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1153 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1155 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1158 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1160 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1162 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1164 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1166 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1167 pAd->StaCfg.BBPR3 = Value;
1169 if (pAd->MACVersion == 0x28600100)
1171 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1172 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1173 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1174 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1177 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1181 pAd->CommonCfg.BBPCurrentBW = BW_20;
1182 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1183 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1184 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1186 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1188 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1190 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1192 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1194 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1196 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1197 pAd->StaCfg.BBPR3 = Value;
1199 if (pAd->MACVersion == 0x28600100)
1201 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1202 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1203 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1204 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1207 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1210 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1212 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1214 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1216 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1217 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1219 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1221 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1223 AsicSetSlotTime(pAd, TRUE);
1224 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1226 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1227 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1229 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1231 // Update HT protectionfor based on AP's operating mode.
1232 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1234 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1237 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1240 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1242 NdisGetSystemUpTime(&Now);
1243 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1245 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1246 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1248 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1251 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1253 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1256 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1258 if (BssType == BSS_ADHOC)
1260 MakeIbssBeacon(pAd);
1261 if ((pAd->CommonCfg.Channel > 14)
1262 && (pAd->CommonCfg.bIEEE80211H == 1)
1263 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1269 AsicEnableIbssSync(pAd);
1272 // In ad hoc mode, use MAC table from index 1.
1273 // 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.
1274 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1275 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1277 // If WEP is enabled, add key material and cipherAlg into Asic
1278 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1280 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1285 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1287 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1288 Key = pAd->SharedKey[BSS0][idx].Key;
1290 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1292 // Set key material and cipherAlg to Asic
1293 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1295 if (idx == pAd->StaCfg.DefaultKeyId)
1297 // Update WCID attribute table and IVEIV table for this group key table
1298 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1305 // If WPANone is enabled, add key material and cipherAlg into Asic
1306 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1307 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1309 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1311 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1312 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1313 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1315 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1317 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1318 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1321 // Decide its ChiperAlg
1322 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1323 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1324 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1325 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1328 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1329 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1332 // Set key material and cipherAlg to Asic
1333 AsicAddSharedKeyEntry(pAd,
1336 pAd->SharedKey[BSS0][0].CipherAlg,
1337 pAd->SharedKey[BSS0][0].Key,
1338 pAd->SharedKey[BSS0][0].TxMic,
1339 pAd->SharedKey[BSS0][0].RxMic);
1341 // Update WCID attribute table and IVEIV table for this group key table
1342 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1349 // Check the new SSID with last SSID
1350 while (Cancelled == TRUE)
1352 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1354 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1356 // Link to the old one no linkdown is required.
1360 // Send link down event before set to link up
1361 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1362 RTMP_IndicateMediaState(pAd);
1363 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1364 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1369 // On WPA mode, Remove All Keys if not connect to the last BSSID
1370 // Key will be set after 4-way handshake.
1372 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1376 // Remove all WPA keys
1377 RTMPWPARemoveAllKeys(pAd);
1378 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1379 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1381 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1382 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1384 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1385 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1387 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1390 // the decision of using "short slot time" or not may change dynamically due to
1391 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1394 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1395 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1398 ComposeNullFrame(pAd);
1400 AsicEnableBssSync(pAd);
1402 // Add BSSID to WCID search table
1403 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1405 NdisAcquireSpinLock(&pAd->MacTabLock);
1406 // add this BSSID entry into HASH table
1410 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1411 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1412 if (pAd->MacTab.Hash[HashIdx] == NULL)
1414 pAd->MacTab.Hash[HashIdx] = pEntry;
1418 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1419 while (pCurrEntry->pNext != NULL)
1420 pCurrEntry = pCurrEntry->pNext;
1421 pCurrEntry->pNext = pEntry;
1424 NdisReleaseSpinLock(&pAd->MacTabLock);
1427 // If WEP is enabled, add paiewise and shared key
1428 if (((pAd->StaCfg.WpaSupplicantUP)&&
1429 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1430 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1431 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1432 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1437 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1439 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1440 Key = pAd->SharedKey[BSS0][idx].Key;
1442 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1444 // Set key material and cipherAlg to Asic
1445 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1447 if (idx == pAd->StaCfg.DefaultKeyId)
1449 // Assign group key info
1450 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1452 // Assign pairwise key info
1453 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1459 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1460 // should wait until at least 2 active nodes in this BSSID.
1461 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1464 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1466 pAd->IndicateMediaState = NdisMediaStateConnected;
1467 pAd->ExtraInfo = GENERAL_LINK_UP;
1470 RTMP_IndicateMediaState(pAd);
1472 // Add BSSID in my MAC Table.
1473 NdisAcquireSpinLock(&pAd->MacTabLock);
1474 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1475 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1476 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1477 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1478 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1479 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1480 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1481 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1482 NdisReleaseSpinLock(&pAd->MacTabLock);
1484 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1485 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1487 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1488 MlmeUpdateHtTxRates(pAd, BSS0);
1489 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1491 if (pAd->CommonCfg.bAggregationCapable)
1493 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1496 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1497 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1498 RTMPSetPiggyBack(pAd, TRUE);
1499 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1501 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1503 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1507 if (pAd->MlmeAux.APRalinkIe != 0x0)
1509 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1514 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1515 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1519 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1520 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1524 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));
1527 RTMPSetLED(pAd, LED_LINK_UP);
1529 pAd->Mlme.PeriodicRound = 0;
1530 pAd->Mlme.OneSecPeriodicRound = 0;
1531 pAd->bConfigChanged = FALSE; // Reset config flag
1532 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1534 // Set asic auto fall back
1537 UCHAR TableSize = 0;
1539 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1540 AsicUpdateAutoFallBackTable(pAd, pTable);
1543 NdisAcquireSpinLock(&pAd->MacTabLock);
1544 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1545 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1546 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1548 pEntry->bAutoTxRateSwitch = FALSE;
1550 if (pEntry->HTPhyMode.field.MCS == 32)
1551 pEntry->HTPhyMode.field.ShortGI = GI_800;
1553 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1554 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1556 // If the legacy mode is set, overwrite the transmit setting of this entry.
1557 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1558 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1561 pEntry->bAutoTxRateSwitch = TRUE;
1562 NdisReleaseSpinLock(&pAd->MacTabLock);
1564 // Let Link Status Page display first initial rate.
1565 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1566 // Select DAC according to HT or Legacy
1567 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1569 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1571 if (pAd->Antenna.field.TxPath == 2)
1575 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1579 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1581 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1584 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1587 else if (pEntry->MaxRAmpduFactor == 0)
1589 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1590 // Because our Init value is 1 at MACRegTable.
1591 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1594 // Patch for Marvel AP to gain high throughput
1595 // Need to set as following,
1596 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1597 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1598 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1599 // 4. kick per two packets when dequeue
1601 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1603 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1604 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1605 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1607 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1609 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1611 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1612 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1615 if (pAd->CommonCfg.bEnableTxBurst)
1617 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1620 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1621 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1623 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1624 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1628 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1630 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1632 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1633 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1636 // Re-check to turn on TX burst or not.
1637 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1639 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1640 if (pAd->CommonCfg.bEnableTxBurst)
1642 UINT32 MACValue = 0;
1643 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1644 // I didn't change PBF_MAX_PCNT setting.
1645 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1646 MACValue &= 0xFFFFFF00;
1647 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1648 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1653 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1656 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1657 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1658 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1659 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1660 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1661 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1663 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1665 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1666 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1669 NdisAcquireSpinLock(&pAd->MacTabLock);
1670 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1671 NdisReleaseSpinLock(&pAd->MacTabLock);
1674 // Patch Atheros AP TX will breakdown issue.
1675 // AP Model: DLink DWL-8200AP
1677 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1679 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1683 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1686 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1687 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1691 ==========================================================================
1693 Routine Description:
1694 Disconnect current BSSID
1697 pAd - Pointer to our adapter
1698 IsReqFromAP - Request from AP
1703 IRQL = DISPATCH_LEVEL
1706 We need more information to know it's this requst from AP.
1707 If yes! we need to do extra handling, for example, remove the WPA key.
1708 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1709 remove while auto reconnect.
1710 Disconnect request from AP, it means we will start afresh 4-way handshaking
1713 ==========================================================================
1716 IN PRTMP_ADAPTER pAd,
1717 IN BOOLEAN IsReqFromAP)
1719 UCHAR i, ByteValue = 0;
1722 // Do nothing if monitor mode is on
1723 if (MONITOR_ON(pAd))
1726 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1727 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1729 // Not allow go to sleep within linkdown function.
1730 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1732 if (pAd->CommonCfg.bWirelessEvent)
1734 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1737 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1738 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1740 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1743 pAd->Mlme.bPsPollTimerRunning = FALSE;
1744 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1747 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
1748 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
1749 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
1751 AsicForceWakeup(pAd, RTMP_HALT);
1752 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1755 pAd->bPCIclkOff = FALSE;
1756 if (ADHOC_ON(pAd)) // Adhoc mode link down
1758 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1760 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1761 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1762 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1763 RTMP_IndicateMediaState(pAd);
1764 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1765 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1766 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1768 else // Infra structure mode
1770 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1772 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1773 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1775 // Saved last SSID for linkup comparison
1776 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1777 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
1778 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1779 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
1781 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1782 RTMP_IndicateMediaState(pAd);
1783 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1784 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1785 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1790 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
1791 // Otherwise lost beacon or receive De-Authentication from AP,
1792 // then we should delete BSSID from BssTable.
1793 // If we don't delete from entry, roaming will fail.
1795 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1798 // restore back to -
1799 // 1. long slot (20 us) or short slot (9 us) time
1800 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1801 // 3. short preamble
1802 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1804 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
1807 // Record current AP's information.
1808 // for later used reporting Adjacent AP report.
1810 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
1811 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
1812 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
1813 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
1817 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
1819 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1820 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
1823 pAd->StaCfg.CCXQosECWMin = 4;
1824 pAd->StaCfg.CCXQosECWMax = 10;
1826 AsicSetSlotTime(pAd, TRUE); //FALSE);
1827 AsicSetEdcaParm(pAd, NULL);
1830 RTMPSetLED(pAd, LED_LINK_DOWN);
1831 pAd->LedIndicatorStregth = 0xF0;
1832 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
1834 AsicDisableSync(pAd);
1836 pAd->Mlme.PeriodicRound = 0;
1837 pAd->Mlme.OneSecPeriodicRound = 0;
1839 if (pAd->StaCfg.BssType == BSS_INFRA)
1841 // Remove StaCfg Information after link down
1842 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1843 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1844 pAd->CommonCfg.SsidLen = 0;
1847 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
1848 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
1849 pAd->MlmeAux.HtCapabilityLen = 0;
1850 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1852 // Reset WPA-PSK state. Only reset when supplicant enabled
1853 if (pAd->StaCfg.WpaState != SS_NOTUSE)
1855 pAd->StaCfg.WpaState = SS_START;
1856 // Clear Replay counter
1857 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1862 // if link down come from AP, we need to remove all WPA keys on WPA mode.
1863 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
1865 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1867 // Remove all WPA keys
1868 RTMPWPARemoveAllKeys(pAd);
1871 // 802.1x port control
1873 // Prevent clear PortSecured here with static WEP
1874 // NetworkManger set security policy first then set SSID to connect AP.
1875 if (pAd->StaCfg.WpaSupplicantUP &&
1876 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1877 (pAd->StaCfg.IEEE8021X == FALSE))
1879 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1883 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1884 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1887 NdisAcquireSpinLock(&pAd->MacTabLock);
1888 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
1889 NdisReleaseSpinLock(&pAd->MacTabLock);
1891 pAd->StaCfg.MicErrCnt = 0;
1893 // Turn off Ckip control flag
1894 pAd->StaCfg.bCkipOn = FALSE;
1895 pAd->StaCfg.CCXEnable = FALSE;
1897 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1898 // Update extra information to link is up
1899 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1901 pAd->StaCfg.AdhocBOnlyJoined = FALSE;
1902 pAd->StaCfg.AdhocBGJoined = FALSE;
1903 pAd->StaCfg.Adhoc20NJoined = FALSE;
1904 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1906 // Reset the Current AP's IP address
1907 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
1909 // Clean association information
1910 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
1911 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
1912 pAd->StaCfg.ReqVarIELen = 0;
1913 pAd->StaCfg.ResVarIELen = 0;
1916 // Reset RSSI value after link down
1918 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
1919 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
1920 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
1921 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
1922 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
1923 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
1926 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
1927 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
1930 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
1932 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1934 pAd->CommonCfg.BBPCurrentBW = BW_20;
1935 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
1936 ByteValue &= (~0x18);
1937 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
1941 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
1942 ByteValue &= (~0x18);
1943 if (pAd->Antenna.field.TxPath == 2)
1947 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
1949 RTMPSetPiggyBack(pAd,FALSE);
1950 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1952 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
1954 // Restore all settings in the following.
1955 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
1956 AsicDisableRDG(pAd);
1957 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
1958 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1960 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
1961 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1963 // Allow go to sleep after linkdown steps.
1964 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1967 union iwreq_data wrqu;
1968 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1969 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1974 ==========================================================================
1977 IRQL = DISPATCH_LEVEL
1979 ==========================================================================
1981 VOID IterateOnBssTab(
1982 IN PRTMP_ADAPTER pAd)
1984 MLME_START_REQ_STRUCT StartReq;
1985 MLME_JOIN_REQ_STRUCT JoinReq;
1988 // Change the wepstatus to original wepstatus
1989 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
1990 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
1991 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
1993 BssIdx = pAd->MlmeAux.BssIdx;
1994 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
1996 // Check cipher suite, AP must have more secured cipher than station setting
1997 // Set the Pairwise and Group cipher to match the intended AP setting
1998 // We can only connect to AP with less secured cipher setting
1999 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2001 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2003 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2004 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2005 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2006 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2007 else // There is no PairCipher Aux, downgrade our capability to TKIP
2008 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2010 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2012 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2014 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2015 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2016 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2017 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2018 else // There is no PairCipher Aux, downgrade our capability to TKIP
2019 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2022 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2025 // Set Mix cipher flag
2026 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2027 if (pAd->StaCfg.bMixCipher == TRUE)
2029 // If mix cipher, re-build RSNIE
2030 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2033 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2034 JoinParmFill(pAd, &JoinReq, BssIdx);
2035 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2037 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2039 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2041 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2042 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2043 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2044 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2048 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2049 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2050 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2051 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2055 // for re-association only
2056 // IRQL = DISPATCH_LEVEL
2057 VOID IterateOnBssTab2(
2058 IN PRTMP_ADAPTER pAd)
2060 MLME_REASSOC_REQ_STRUCT ReassocReq;
2064 BssIdx = pAd->MlmeAux.RoamIdx;
2065 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2067 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2069 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2071 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2072 AsicLockChannel(pAd, pBss->Channel);
2074 // reassociate message has the same structure as associate message
2075 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2076 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2077 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2078 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2080 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2084 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2085 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2086 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2087 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2092 ==========================================================================
2095 IRQL = DISPATCH_LEVEL
2097 ==========================================================================
2100 IN PRTMP_ADAPTER pAd,
2101 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2104 JoinReq->BssIdx = BssIdx;
2108 ==========================================================================
2111 IRQL = DISPATCH_LEVEL
2113 ==========================================================================
2116 IN PRTMP_ADAPTER pAd,
2117 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2123 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2124 ScanReq->SsidLen = SsidLen;
2125 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2126 ScanReq->BssType = BssType;
2127 ScanReq->ScanType = ScanType;
2131 ==========================================================================
2134 IRQL = DISPATCH_LEVEL
2136 ==========================================================================
2139 IN PRTMP_ADAPTER pAd,
2140 IN OUT MLME_START_REQ_STRUCT *StartReq,
2144 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2145 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2146 StartReq->SsidLen = SsidLen;
2150 ==========================================================================
2153 IRQL = DISPATCH_LEVEL
2155 ==========================================================================
2158 IN PRTMP_ADAPTER pAd,
2159 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2163 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2165 AuthReq->Timeout = AUTH_TIMEOUT;
2169 ==========================================================================
2172 IRQL = DISPATCH_LEVEL
2174 ==========================================================================
2177 IN PRTMP_ADAPTER pAd)
2179 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2180 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2181 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2182 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2183 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2184 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2187 // IRQL = DISPATCH_LEVEL
2188 VOID ComposeNullFrame(
2189 IN PRTMP_ADAPTER pAd)
2191 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2192 pAd->NullFrame.FC.Type = BTYPE_DATA;
2193 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2194 pAd->NullFrame.FC.ToDs = 1;
2195 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2196 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2197 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2204 ==========================================================================
2206 Pre-build a BEACON frame in the shared memory
2208 IRQL = PASSIVE_LEVEL
2209 IRQL = DISPATCH_LEVEL
2211 ==========================================================================
2213 ULONG MakeIbssBeacon(
2214 IN PRTMP_ADAPTER pAd)
2216 UCHAR DsLen = 1, IbssLen = 2;
2217 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2218 HEADER_802_11 BcnHdr;
2219 USHORT CapabilityInfo;
2220 LARGE_INTEGER FakeTimestamp;
2222 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2223 CHAR *pBeaconFrame = pAd->BeaconBuf;
2225 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2226 UCHAR SupRateLen = 0;
2227 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2228 UCHAR ExtRateLen = 0;
2229 UCHAR RSNIe = IE_WPA;
2231 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2233 SupRate[0] = 0x82; // 1 mbps
2234 SupRate[1] = 0x84; // 2 mbps
2235 SupRate[2] = 0x8b; // 5.5 mbps
2236 SupRate[3] = 0x96; // 11 mbps
2240 else if (pAd->CommonCfg.Channel > 14)
2242 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2243 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2244 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2245 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2246 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2247 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2248 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2249 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2254 // Also Update MlmeRate & RtsRate for G only & A only
2256 pAd->CommonCfg.MlmeRate = RATE_6;
2257 pAd->CommonCfg.RtsRate = RATE_6;
2258 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2259 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2260 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2261 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2265 SupRate[0] = 0x82; // 1 mbps
2266 SupRate[1] = 0x84; // 2 mbps
2267 SupRate[2] = 0x8b; // 5.5 mbps
2268 SupRate[3] = 0x96; // 11 mbps
2271 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2272 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2273 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2274 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2275 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2276 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2277 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2278 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2282 pAd->StaActive.SupRateLen = SupRateLen;
2283 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2284 pAd->StaActive.ExtRateLen = ExtRateLen;
2285 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2287 // compose IBSS beacon frame
2288 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2289 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2290 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2291 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2292 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2294 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2295 sizeof(HEADER_802_11), &BcnHdr,
2296 TIMESTAMP_LEN, &FakeTimestamp,
2297 2, &pAd->CommonCfg.BeaconPeriod,
2300 1, &pAd->CommonCfg.SsidLen,
2301 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2304 SupRateLen, SupRate,
2307 1, &pAd->CommonCfg.Channel,
2310 2, &pAd->StaActive.AtimWin,
2313 // add ERP_IE and EXT_RAE IE of in 802.11g
2318 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2322 ExtRateLen, ExtRate,
2327 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2328 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2331 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2333 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2335 1, &pAd->StaCfg.RSNIE_Len,
2336 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2341 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2344 UCHAR HtLen, HtLen1;
2346 // add HT Capability IE
2347 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2348 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2350 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2353 HtLen, &pAd->CommonCfg.HtCapability,
2356 HtLen1, &pAd->CommonCfg.AddHTInfo,
2362 //beacon use reserved WCID 0xff
2363 if (pAd->CommonCfg.Channel > 14)
2365 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2366 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2370 // Set to use 1Mbps for Adhoc beacon.
2371 HTTRANSMIT_SETTING Transmit;
2373 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2374 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2377 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2378 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));