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 NdisZeroMemory((_pAd)->CommonCfg.Ssid, MAX_LEN_OF_SSID); \
68 (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \
69 NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
70 COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \
71 (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel; \
72 (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel; \
73 (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid; \
74 (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin; \
75 (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo; \
76 (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod; \
77 (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration; \
78 (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod; \
79 (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen; \
80 NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
81 (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen; \
82 NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
83 NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\
84 NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\
85 NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\
86 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid); \
87 (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid; \
88 (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
89 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
90 (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
94 ==========================================================================
99 ==========================================================================
102 IN PRTMP_ADAPTER pAd,
104 OUT STATE_MACHINE_FUNC Trans[])
106 // Control state machine differs from other state machines, the interface
107 // follows the standard interface
108 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
112 ==========================================================================
115 IRQL = DISPATCH_LEVEL
117 ==========================================================================
119 VOID MlmeCntlMachinePerformAction(
120 IN PRTMP_ADAPTER pAd,
122 IN MLME_QUEUE_ELEM *Elem)
124 switch(pAd->Mlme.CntlMachine.CurrState)
127 CntlIdleProc(pAd, Elem);
129 case CNTL_WAIT_DISASSOC:
130 CntlWaitDisassocProc(pAd, Elem);
133 CntlWaitJoinProc(pAd, Elem);
136 // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
137 // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
138 // Therefore not protected by NDIS's "only one outstanding OID request"
139 // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
140 // Current approach is to block new SET request at RTMPSetInformation()
141 // when CntlMachine.CurrState is not CNTL_IDLE
142 case CNTL_WAIT_REASSOC:
143 CntlWaitReassocProc(pAd, Elem);
146 case CNTL_WAIT_START:
147 CntlWaitStartProc(pAd, Elem);
150 CntlWaitAuthProc(pAd, Elem);
152 case CNTL_WAIT_AUTH2:
153 CntlWaitAuthProc2(pAd, Elem);
155 case CNTL_WAIT_ASSOC:
156 CntlWaitAssocProc(pAd, Elem);
159 case CNTL_WAIT_OID_LIST_SCAN:
160 if(Elem->MsgType == MT2_SCAN_CONF)
162 // Resume TxRing after SCANING complete. We hope the out-of-service time
163 // won't be too long to let upper layer time-out the waiting frames
164 RTMPResumeMsduTransmission(pAd);
166 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
169 // Set LED status to previous status.
171 if (pAd->bLedOnScanning)
173 pAd->bLedOnScanning = FALSE;
174 RTMPSetLED(pAd, pAd->LedStatus);
179 case CNTL_WAIT_OID_DISASSOC:
180 if (Elem->MsgType == MT2_DISASSOC_CONF)
182 LinkDown(pAd, FALSE);
183 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
188 // This state is for that we want to connect to an AP but
189 // it didn't find on BSS List table. So we need to scan the air first,
190 // after that we can try to connect to the desired AP if available.
192 case CNTL_WAIT_SCAN_FOR_CONNECT:
193 if(Elem->MsgType == MT2_SCAN_CONF)
195 // Resume TxRing after SCANING complete. We hope the out-of-service time
196 // won't be too long to let upper layer time-out the waiting frames
197 RTMPResumeMsduTransmission(pAd);
199 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
201 // Cisco scan request is finished, prepare beacon report
202 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
204 #endif // CCX_SUPPORT //
205 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
208 // Check if we can connect to.
210 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, (CHAR *) pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
211 if (pAd->MlmeAux.SsidBssTab.BssNr > 0)
213 MlmeAutoReconnectLastSSID(pAd);
217 #endif // RTMP_MAC_USB //
219 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
226 ==========================================================================
229 IRQL = DISPATCH_LEVEL
231 ==========================================================================
234 IN PRTMP_ADAPTER pAd,
235 IN MLME_QUEUE_ELEM *Elem)
237 MLME_DISASSOC_REQ_STRUCT DisassocReq;
239 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
242 switch(Elem->MsgType)
244 case OID_802_11_SSID:
245 CntlOidSsidProc(pAd, Elem);
248 case OID_802_11_BSSID:
249 CntlOidRTBssidProc(pAd,Elem);
252 case OID_802_11_BSSID_LIST_SCAN:
253 CntlOidScanProc(pAd,Elem);
256 case OID_802_11_DISASSOCIATE:
257 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
258 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
259 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
261 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
263 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
264 // Since calling this indicate user don't want to connect to that SSID anymore.
265 pAd->MlmeAux.AutoReconnectSsidLen= 32;
266 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
270 case MT2_MLME_ROAMING_REQ:
271 CntlMlmeRoamingProc(pAd, Elem);
274 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
275 WpaMicFailureReportFrame(pAd, Elem);
279 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
284 VOID CntlOidScanProc(
285 IN PRTMP_ADAPTER pAd,
286 IN MLME_QUEUE_ELEM *Elem)
288 MLME_SCAN_REQ_STRUCT ScanReq;
289 ULONG BssIdx = BSS_NOT_FOUND;
294 // record current BSS if network is connected.
295 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
296 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
298 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, (PUCHAR)pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
299 if (BssIdx != BSS_NOT_FOUND)
301 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
305 // clean up previous SCAN result, add current BSS back to table if any
306 BssTableInit(&pAd->ScanTab);
307 if (BssIdx != BSS_NOT_FOUND)
309 // DDK Note: If the NIC is associated with a particular BSSID and SSID
310 // that are not contained in the list of BSSIDs generated by this scan, the
311 // BSSID description of the currently associated BSSID and SSID should be
312 // appended to the list of BSSIDs in the NIC's database.
313 // To ensure this, we append this BSS as the first entry in SCAN result
314 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
315 pAd->ScanTab.BssNr = 1;
318 ScanParmFill(pAd, &ScanReq, (PSTRING) Elem->Msg, Elem->MsgLen, BSS_ANY, SCAN_ACTIVE);
319 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
320 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
321 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
325 ==========================================================================
327 Before calling this routine, user desired SSID should already been
328 recorded in CommonCfg.Ssid[]
329 IRQL = DISPATCH_LEVEL
331 ==========================================================================
333 VOID CntlOidSsidProc(
334 IN PRTMP_ADAPTER pAd,
335 IN MLME_QUEUE_ELEM * Elem)
337 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
338 MLME_DISASSOC_REQ_STRUCT DisassocReq;
342 // Step 1. record the desired user settings to MlmeAux
343 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
344 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
345 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
346 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
347 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
349 pAd->StaCfg.bAutoConnectByBssid = FALSE;
352 // Update Reconnect Ssid, that user desired to connect.
354 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
355 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
356 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
358 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
359 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
360 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, (PCHAR)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
362 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
363 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
364 NdisGetSystemUpTime(&Now);
366 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
367 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
368 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
369 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
371 // Case 1. already connected with an AP who has the desired SSID
374 // Add checking Mode "LEAP" for CCX 1.0
375 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
376 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
377 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
378 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
380 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
382 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
383 // connection process
384 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
385 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
386 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
387 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
388 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
390 else if (pAd->bConfigChanged == TRUE)
392 // case 1.2 Important Config has changed, we have to reconnect to the same AP
393 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
394 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
395 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
396 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
397 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
401 // case 1.3. already connected to the SSID with highest RSSI.
402 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
404 // (HCT 12.1) 1c_wlan_mediaevents required
405 // media connect events are indicated when associating with the same AP
410 // Since MediaState already is NdisMediaStateConnected
411 // We just indicate the connect event again to meet the WHQL required.
413 pAd->IndicateMediaState = NdisMediaStateConnected;
414 RTMP_IndicateMediaState(pAd);
415 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
418 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
419 RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, &pAd->MlmeAux.Bssid[0], NULL, 0);
422 else if (INFRA_ON(pAd))
426 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
427 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
428 // But media status is connected, so the SSID not report correctly.
430 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
433 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
435 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
437 // case 2. active INFRA association existent
438 // roaming is done within miniport driver, nothing to do with configuration
439 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
440 // disassociate with the current associated AP,
441 // then perform a new association with this new SSID, no matter the
442 // new/old SSID are the same or not.
443 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
444 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
445 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
446 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
447 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
453 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
454 LinkDown(pAd, FALSE);
455 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
456 pAd->IndicateMediaState = NdisMediaStateDisconnected;
457 RTMP_IndicateMediaState(pAd);
458 pAd->ExtraInfo = GENERAL_LINK_DOWN;
459 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
462 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
463 (pAd->StaCfg.bAutoReconnect == TRUE) &&
464 (pAd->MlmeAux.BssType == BSS_INFRA) &&
465 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
468 MLME_SCAN_REQ_STRUCT ScanReq;
470 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
471 ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
472 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
473 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
474 // Reset Missed scan number
475 pAd->StaCfg.LastScanTime = Now;
479 pAd->MlmeAux.BssIdx = 0;
480 IterateOnBssTab(pAd);
487 ==========================================================================
490 IRQL = DISPATCH_LEVEL
492 ==========================================================================
494 VOID CntlOidRTBssidProc(
495 IN PRTMP_ADAPTER pAd,
496 IN MLME_QUEUE_ELEM * Elem)
499 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
500 MLME_DISASSOC_REQ_STRUCT DisassocReq;
501 MLME_JOIN_REQ_STRUCT JoinReq;
503 // record user desired settings
504 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
505 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
507 // find the desired BSS in the latest SCAN result table
508 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
509 if (BssIdx == BSS_NOT_FOUND)
511 MLME_SCAN_REQ_STRUCT ScanReq;
513 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
514 //pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
516 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. start a new scan\n"));
517 ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
518 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
519 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
520 // Reset Missed scan number
521 NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
526 // Update Reconnect Ssid, that user desired to connect.
528 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
529 pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
530 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
532 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
533 // Because we need this entry to become the JOIN target in later on SYNC state machine
534 pAd->MlmeAux.BssIdx = 0;
535 pAd->MlmeAux.SsidBssTab.BssNr = 1;
536 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
538 // Add SSID into MlmeAux for site surey joining hidden SSID
539 pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
540 NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
545 // disassoc from current AP first
546 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
547 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
548 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
549 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
551 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
557 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
558 LinkDown(pAd, FALSE);
559 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
560 pAd->IndicateMediaState = NdisMediaStateDisconnected;
561 RTMP_IndicateMediaState(pAd);
562 pAd->ExtraInfo = GENERAL_LINK_DOWN;
563 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
566 // Change the wepstatus to original wepstatus
567 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
568 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
569 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
571 // Check cipher suite, AP must have more secured cipher than station setting
572 // Set the Pairwise and Group cipher to match the intended AP setting
573 // We can only connect to AP with less secured cipher setting
574 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
576 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
578 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
579 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
580 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
581 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
582 else // There is no PairCipher Aux, downgrade our capability to TKIP
583 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
585 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
587 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
589 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
590 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
591 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
592 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
593 else // There is no PairCipher Aux, downgrade our capability to TKIP
594 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
597 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
600 // Set Mix cipher flag
601 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
602 /*if (pAd->StaCfg.bMixCipher == TRUE)
604 // If mix cipher, re-build RSNIE
605 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
607 // No active association, join the BSS immediately
608 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
609 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
611 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
612 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
614 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
619 // Roaming is the only external request triggering CNTL state machine
620 // despite of other "SET OID" operation. All "SET OID" related oerations
621 // happen in sequence, because no other SET OID will be sent to this device
622 // until the the previous SET operation is complete (successful o failed).
623 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
624 // or been corrupted by other "SET OID"?
626 // IRQL = DISPATCH_LEVEL
627 VOID CntlMlmeRoamingProc(
628 IN PRTMP_ADAPTER pAd,
629 IN MLME_QUEUE_ELEM *Elem)
633 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
636 //Let BBP register at 20MHz to do (fast) roaming.
637 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
639 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
641 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
642 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
644 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
645 pAd->MlmeAux.BssIdx = 0;
646 IterateOnBssTab(pAd);
652 ==========================================================================
655 IRQL = DISPATCH_LEVEL
657 ==========================================================================
659 VOID CntlWaitDisassocProc(
660 IN PRTMP_ADAPTER pAd,
661 IN MLME_QUEUE_ELEM *Elem)
663 MLME_START_REQ_STRUCT StartReq;
665 if (Elem->MsgType == MT2_DISASSOC_CONF)
667 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
669 if (pAd->CommonCfg.bWirelessEvent)
671 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
674 LinkDown(pAd, FALSE);
676 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
677 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
679 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
680 StartParmFill(pAd, &StartReq, (PCHAR)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
681 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
682 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
684 // case 2. try each matched BSS
687 pAd->MlmeAux.BssIdx = 0;
689 IterateOnBssTab(pAd);
695 ==========================================================================
698 IRQL = DISPATCH_LEVEL
700 ==========================================================================
702 VOID CntlWaitJoinProc(
703 IN PRTMP_ADAPTER pAd,
704 IN MLME_QUEUE_ELEM *Elem)
707 MLME_AUTH_REQ_STRUCT AuthReq;
709 if (Elem->MsgType == MT2_JOIN_CONF)
711 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
712 if (Reason == MLME_SUCCESS)
714 // 1. joined an IBSS, we are pretty much done here
715 if (pAd->MlmeAux.BssType == BSS_ADHOC)
718 // 5G bands rules of Japan:
719 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
721 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
722 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
725 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
726 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
730 LinkUp(pAd, BSS_ADHOC);
731 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
732 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
733 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
734 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
736 pAd->IndicateMediaState = NdisMediaStateConnected;
737 pAd->ExtraInfo = GENERAL_LINK_UP;
739 // 2. joined a new INFRA network, start from authentication
743 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
744 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
745 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
747 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_KEY);
751 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_OPEN);
753 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
754 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
757 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
762 // 3. failed, try next BSS
763 pAd->MlmeAux.BssIdx++;
764 IterateOnBssTab(pAd);
771 ==========================================================================
774 IRQL = DISPATCH_LEVEL
776 ==========================================================================
778 VOID CntlWaitStartProc(
779 IN PRTMP_ADAPTER pAd,
780 IN MLME_QUEUE_ELEM *Elem)
784 if (Elem->MsgType == MT2_START_CONF)
786 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
787 if (Result == MLME_SUCCESS)
790 // 5G bands rules of Japan:
791 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
793 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
794 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
797 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
798 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
801 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
802 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
806 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
807 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
808 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
809 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
810 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
812 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
813 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
815 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
817 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
818 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
820 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
825 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
827 LinkUp(pAd, BSS_ADHOC);
828 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
829 // Before send beacon, driver need do radar detection
830 if ((pAd->CommonCfg.Channel > 14 )
831 && (pAd->CommonCfg.bIEEE80211H == 1)
832 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
834 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
835 pAd->CommonCfg.RadarDetect.RDCount = 0;
838 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
839 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
840 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
844 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
845 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
851 ==========================================================================
854 IRQL = DISPATCH_LEVEL
856 ==========================================================================
858 VOID CntlWaitAuthProc(
859 IN PRTMP_ADAPTER pAd,
860 IN MLME_QUEUE_ELEM *Elem)
863 MLME_ASSOC_REQ_STRUCT AssocReq;
864 MLME_AUTH_REQ_STRUCT AuthReq;
866 if (Elem->MsgType == MT2_AUTH_CONF)
868 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
869 if (Reason == MLME_SUCCESS)
871 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
872 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
873 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
876 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
877 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
879 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
884 // This fail may because of the AP already keep us in its MAC table without
885 // ageing-out. The previous authentication attempt must have let it remove us.
886 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
887 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
890 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
891 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
893 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
894 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_KEY);
898 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_OPEN);
900 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
901 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
904 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
910 ==========================================================================
913 IRQL = DISPATCH_LEVEL
915 ==========================================================================
917 VOID CntlWaitAuthProc2(
918 IN PRTMP_ADAPTER pAd,
919 IN MLME_QUEUE_ELEM *Elem)
922 MLME_ASSOC_REQ_STRUCT AssocReq;
923 MLME_AUTH_REQ_STRUCT AuthReq;
925 if (Elem->MsgType == MT2_AUTH_CONF)
927 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
928 if (Reason == MLME_SUCCESS)
930 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
931 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
932 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
934 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
935 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
937 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
942 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
943 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
945 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
946 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
947 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
948 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
950 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
954 // not success, try next BSS
955 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
956 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
957 pAd->MlmeAux.BssIdx++;
958 IterateOnBssTab(pAd);
965 ==========================================================================
968 IRQL = DISPATCH_LEVEL
970 ==========================================================================
972 VOID CntlWaitAssocProc(
973 IN PRTMP_ADAPTER pAd,
974 IN MLME_QUEUE_ELEM *Elem)
978 if (Elem->MsgType == MT2_ASSOC_CONF)
980 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
981 if (Reason == MLME_SUCCESS)
983 if (pAd->CommonCfg.bWirelessEvent)
985 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
988 LinkUp(pAd, BSS_INFRA);
989 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
990 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
994 // not success, try next BSS
995 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
996 pAd->MlmeAux.BssIdx++;
997 IterateOnBssTab(pAd);
1003 ==========================================================================
1006 IRQL = DISPATCH_LEVEL
1008 ==========================================================================
1010 VOID CntlWaitReassocProc(
1011 IN PRTMP_ADAPTER pAd,
1012 IN MLME_QUEUE_ELEM *Elem)
1016 if (Elem->MsgType == MT2_REASSOC_CONF)
1018 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1019 if (Result == MLME_SUCCESS)
1021 // send wireless event - for association
1022 if (pAd->CommonCfg.bWirelessEvent)
1023 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1027 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1029 LinkUp(pAd, BSS_INFRA);
1031 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1032 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1036 // reassoc failed, try to pick next BSS in the BSS Table
1037 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1039 pAd->MlmeAux.RoamIdx++;
1040 IterateOnBssTab2(pAd);
1047 VOID AdhocTurnOnQos(
1048 IN PRTMP_ADAPTER pAd)
1050 #define AC0_DEF_TXOP 0
1051 #define AC1_DEF_TXOP 0
1052 #define AC2_DEF_TXOP 94
1053 #define AC3_DEF_TXOP 47
1055 // Turn on QOs if use HT rate.
1056 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1058 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1059 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1060 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1061 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1062 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1064 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1065 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1066 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1067 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1069 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1070 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1071 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1072 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1074 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1075 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1076 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1077 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1079 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1083 ==========================================================================
1086 IRQL = DISPATCH_LEVEL
1088 ==========================================================================
1091 IN PRTMP_ADAPTER pAd,
1097 UCHAR Value = 0, idx = 0, HashIdx = 0;
1098 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry = NULL;
1100 // Init ChannelQuality to prevent DEAD_CQI at initial LinkUp
1101 pAd->Mlme.ChannelQuality = 50;
1103 pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid);
1106 MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
1111 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1114 // ASSOC - DisassocTimeoutAction
1115 // CNTL - Dis-associate successful
1116 // !!! LINK DOWN !!!
1117 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1119 // To prevent DisassocTimeoutAction to call Link down after we link up,
1120 // cancel the DisassocTimer no matter what it start or not.
1122 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1124 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1126 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1129 // Before power save before link up function, We will force use 1R.
1130 // So after link up, check Rx antenna # again.
1131 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1132 if(pAd->Antenna.field.RxPath == 3)
1136 else if(pAd->Antenna.field.RxPath == 2)
1140 else if(pAd->Antenna.field.RxPath == 1)
1144 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1145 pAd->StaCfg.BBPR3 = Value;
1146 #endif // RTMP_MAC_PCI //
1148 if (BssType == BSS_ADHOC)
1150 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1151 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1154 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1155 AdhocTurnOnQos(pAd);
1157 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1161 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1162 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1164 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1168 // reset Tx beamforming bit
1169 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1171 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1172 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1174 // Change to AP channel
1175 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1177 // Must using 40MHz.
1178 pAd->CommonCfg.BBPCurrentBW = BW_40;
1179 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1180 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1182 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1185 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1187 // RX : control channel at lower
1188 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1190 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1192 pAd->StaCfg.BBPR3 = Value;
1193 #endif // RTMP_MAC_PCI //
1195 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1197 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1199 if (pAd->MACVersion == 0x28600100)
1201 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1202 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1203 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1204 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1207 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1209 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1211 // Must using 40MHz.
1212 pAd->CommonCfg.BBPCurrentBW = BW_40;
1213 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1214 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1216 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1219 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1221 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1223 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1225 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1227 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1229 pAd->StaCfg.BBPR3 = Value;
1230 #endif // RTMP_MAC_PCI //
1232 if (pAd->MACVersion == 0x28600100)
1234 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1235 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1236 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1237 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1240 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1244 pAd->CommonCfg.BBPCurrentBW = BW_20;
1245 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1246 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1247 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1249 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1251 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1253 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1255 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1257 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1259 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1261 pAd->StaCfg.BBPR3 = Value;
1262 #endif // RTMP_MAC_PCI //
1264 if (pAd->MACVersion == 0x28600100)
1266 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1267 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1268 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1269 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1272 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1275 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1278 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1280 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1282 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1283 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1285 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1287 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1289 AsicSetSlotTime(pAd, TRUE);
1290 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1292 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1293 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1295 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1297 // Update HT protectionfor based on AP's operating mode.
1298 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1300 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1303 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1306 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1308 NdisGetSystemUpTime(&Now);
1309 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1311 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1312 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1314 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1317 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1319 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1322 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1324 if (BssType == BSS_ADHOC)
1326 MakeIbssBeacon(pAd);
1327 if ((pAd->CommonCfg.Channel > 14)
1328 && (pAd->CommonCfg.bIEEE80211H == 1)
1329 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1335 AsicEnableIbssSync(pAd);
1338 // In ad hoc mode, use MAC table from index 1.
1339 // 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.
1340 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1341 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1343 // If WEP is enabled, add key material and cipherAlg into Asic
1344 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1346 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1351 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1353 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1354 Key = pAd->SharedKey[BSS0][idx].Key;
1356 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1358 // Set key material and cipherAlg to Asic
1359 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1361 if (idx == pAd->StaCfg.DefaultKeyId)
1363 // Update WCID attribute table and IVEIV table for this group key table
1364 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1371 // If WPANone is enabled, add key material and cipherAlg into Asic
1372 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1373 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1375 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1377 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1378 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1379 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1381 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1383 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1384 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1387 // Decide its ChiperAlg
1388 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1389 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1390 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1391 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1394 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1395 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1398 // Set key material and cipherAlg to Asic
1399 AsicAddSharedKeyEntry(pAd,
1402 pAd->SharedKey[BSS0][0].CipherAlg,
1403 pAd->SharedKey[BSS0][0].Key,
1404 pAd->SharedKey[BSS0][0].TxMic,
1405 pAd->SharedKey[BSS0][0].RxMic);
1407 // Update WCID attribute table and IVEIV table for this group key table
1408 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1415 // Check the new SSID with last SSID
1416 while (Cancelled == TRUE)
1418 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1420 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1422 // Link to the old one no linkdown is required.
1426 // Send link down event before set to link up
1427 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1428 RTMP_IndicateMediaState(pAd);
1429 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1430 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1435 // On WPA mode, Remove All Keys if not connect to the last BSSID
1436 // Key will be set after 4-way handshake.
1438 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
1442 // Remove all WPA keys
1443 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1444 RTMPWPARemoveAllKeys(pAd);
1445 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1446 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1448 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1449 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1451 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1452 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1456 // the decision of using "short slot time" or not may change dynamically due to
1457 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1460 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1461 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1464 ComposeNullFrame(pAd);
1466 AsicEnableBssSync(pAd);
1468 // Add BSSID to WCID search table
1469 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1471 // If WEP is enabled, add paiewise and shared key
1472 if (((pAd->StaCfg.WpaSupplicantUP)&&
1473 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1474 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1475 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1476 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1481 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1483 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1484 Key = pAd->SharedKey[BSS0][idx].Key;
1486 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1488 // Set key material and cipherAlg to Asic
1489 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1491 if (idx == pAd->StaCfg.DefaultKeyId)
1493 // Assign group key info
1494 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1496 pEntry->Aid = BSSID_WCID;
1497 // Assign pairwise key info
1498 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1504 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1505 // should wait until at least 2 active nodes in this BSSID.
1506 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1509 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1511 pAd->IndicateMediaState = NdisMediaStateConnected;
1512 pAd->ExtraInfo = GENERAL_LINK_UP;
1513 RTMP_IndicateMediaState(pAd);
1515 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1516 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1518 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
1519 RTMPSetTimer(&pAd->Mlme.LinkDownTimer, LINK_DOWN_TIMEOUT);
1523 // Add BSSID in my MAC Table.
1524 NdisAcquireSpinLock(&pAd->MacTabLock);
1525 // add this MAC entry into HASH table
1528 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1529 if (pAd->MacTab.Hash[HashIdx] == NULL)
1531 pAd->MacTab.Hash[HashIdx] = pEntry;
1535 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1536 while (pCurrEntry->pNext != NULL)
1538 pCurrEntry = pCurrEntry->pNext;
1540 pCurrEntry->pNext = pEntry;
1543 RTMPMoveMemory(pEntry->Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1544 pEntry->Aid = BSSID_WCID;
1546 pEntry->ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1547 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1548 pEntry->Sst = SST_ASSOC;
1549 pEntry->AuthState = SST_ASSOC;
1550 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1551 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1552 if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
1554 pEntry->WpaState = AS_NOTUSE;
1555 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1559 pEntry->WpaState = AS_PTKSTART;
1560 pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1562 NdisReleaseSpinLock(&pAd->MacTabLock);
1564 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1565 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1567 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1568 MlmeUpdateHtTxRates(pAd, BSS0);
1569 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1571 if (pAd->CommonCfg.bAggregationCapable)
1573 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1575 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1576 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1577 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
1578 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
1579 RTMPSetPiggyBack(pAd, TRUE);
1580 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1582 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1584 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1585 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
1586 DBGPRINT(RT_DEBUG_TRACE, ("Ralink Aggregation\n"));
1590 if (pAd->MlmeAux.APRalinkIe != 0x0)
1592 if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE))
1596 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1597 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET);
1601 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1602 CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET);
1606 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));
1609 RTMPSetLED(pAd, LED_LINK_UP);
1611 pAd->Mlme.PeriodicRound = 0;
1612 pAd->Mlme.OneSecPeriodicRound = 0;
1613 pAd->bConfigChanged = FALSE; // Reset config flag
1614 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1616 // Set asic auto fall back
1619 UCHAR TableSize = 0;
1621 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1622 AsicUpdateAutoFallBackTable(pAd, pTable);
1625 NdisAcquireSpinLock(&pAd->MacTabLock);
1626 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1627 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1628 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1630 pEntry->bAutoTxRateSwitch = FALSE;
1632 if (pEntry->HTPhyMode.field.MCS == 32)
1633 pEntry->HTPhyMode.field.ShortGI = GI_800;
1635 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1636 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1638 // If the legacy mode is set, overwrite the transmit setting of this entry.
1639 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1640 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1643 pEntry->bAutoTxRateSwitch = TRUE;
1644 NdisReleaseSpinLock(&pAd->MacTabLock);
1646 // Let Link Status Page display first initial rate.
1647 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1648 // Select DAC according to HT or Legacy
1649 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1651 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1653 if (pAd->Antenna.field.TxPath == 2)
1657 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1661 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1663 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1666 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1669 else if (pEntry->MaxRAmpduFactor == 0)
1671 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1672 // Because our Init value is 1 at MACRegTable.
1673 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1676 // Patch for Marvel AP to gain high throughput
1677 // Need to set as following,
1678 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1679 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1680 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1681 // 4. kick per two packets when dequeue
1683 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1685 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1686 if (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) &&
1687 (pAd->StaCfg.bForceTxBurst == FALSE) &&
1688 (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
1689 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))))
1691 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1693 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1695 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1696 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1699 if (pAd->CommonCfg.bEnableTxBurst)
1701 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1704 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1705 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1707 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1708 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1712 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1714 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1716 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1717 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1720 // Re-check to turn on TX burst or not.
1721 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1723 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1724 if (pAd->CommonCfg.bEnableTxBurst)
1726 UINT32 MACValue = 0;
1727 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1728 // I didn't change PBF_MAX_PCNT setting.
1729 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1730 MACValue &= 0xFFFFFF00;
1731 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1732 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1737 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1740 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1741 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1742 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1743 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1744 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1745 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1747 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1749 if (pAd->StaCfg.WpaSupplicantUP &&
1750 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1751 (pAd->StaCfg.IEEE8021X == TRUE))
1755 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1756 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1760 NdisAcquireSpinLock(&pAd->MacTabLock);
1761 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1762 NdisReleaseSpinLock(&pAd->MacTabLock);
1765 // Patch Atheros AP TX will breakdown issue.
1766 // AP Model: DLink DWL-8200AP
1768 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1770 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1774 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1777 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1779 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1783 ==========================================================================
1785 Routine Description:
1786 Disconnect current BSSID
1789 pAd - Pointer to our adapter
1790 IsReqFromAP - Request from AP
1795 IRQL = DISPATCH_LEVEL
1798 We need more information to know it's this requst from AP.
1799 If yes! we need to do extra handling, for example, remove the WPA key.
1800 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1801 remove while auto reconnect.
1802 Disconnect request from AP, it means we will start afresh 4-way handshaking
1805 ==========================================================================
1808 IN PRTMP_ADAPTER pAd,
1809 IN BOOLEAN IsReqFromAP)
1811 UCHAR i, ByteValue = 0;
1813 // Do nothing if monitor mode is on
1814 if (MONITOR_ON(pAd))
1817 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1818 //Comment the codes, beasue the line 2291 call the same function.
1819 //RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1820 // Not allow go to sleep within linkdown function.
1821 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1823 if (pAd->CommonCfg.bWirelessEvent)
1825 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1828 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1829 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1832 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
1835 pAd->Mlme.bPsPollTimerRunning = FALSE;
1836 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1839 pAd->bPCIclkOff = FALSE;
1840 #endif // RTMP_MAC_PCI //
1842 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
1843 || RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)
1844 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
1846 AUTO_WAKEUP_STRUC AutoWakeupCfg;
1847 AsicForceWakeup(pAd, TRUE);
1848 AutoWakeupCfg.word = 0;
1849 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1850 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1854 pAd->bPCIclkOff = FALSE;
1855 #endif // RTMP_MAC_PCI //
1857 if (ADHOC_ON(pAd)) // Adhoc mode link down
1859 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1861 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1862 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1863 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1864 RTMP_IndicateMediaState(pAd);
1865 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1866 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1867 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1869 else // Infra structure mode
1871 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1873 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1874 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1876 // Saved last SSID for linkup comparison
1877 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1878 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
1879 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1880 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
1882 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1883 RTMP_IndicateMediaState(pAd);
1884 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1885 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1886 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1891 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
1892 // Otherwise lost beacon or receive De-Authentication from AP,
1893 // then we should delete BSSID from BssTable.
1894 // If we don't delete from entry, roaming will fail.
1896 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1899 // restore back to -
1900 // 1. long slot (20 us) or short slot (9 us) time
1901 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1902 // 3. short preamble
1903 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1909 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
1911 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1912 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
1915 AsicSetSlotTime(pAd, TRUE); //FALSE);
1916 AsicSetEdcaParm(pAd, NULL);
1919 RTMPSetLED(pAd, LED_LINK_DOWN);
1920 pAd->LedIndicatorStrength = 0xF0;
1921 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
1923 AsicDisableSync(pAd);
1925 pAd->Mlme.PeriodicRound = 0;
1926 pAd->Mlme.OneSecPeriodicRound = 0;
1928 if (pAd->StaCfg.BssType == BSS_INFRA)
1930 // Remove StaCfg Information after link down
1931 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1932 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1933 pAd->CommonCfg.SsidLen = 0;
1936 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
1937 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
1938 pAd->MlmeAux.HtCapabilityLen = 0;
1939 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1941 // Reset WPA-PSK state. Only reset when supplicant enabled
1942 if (pAd->StaCfg.WpaState != SS_NOTUSE)
1944 pAd->StaCfg.WpaState = SS_START;
1945 // Clear Replay counter
1946 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1951 // if link down come from AP, we need to remove all WPA keys on WPA mode.
1952 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
1954 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1956 // Remove all WPA keys
1957 RTMPWPARemoveAllKeys(pAd);
1960 // 802.1x port control
1962 // Prevent clear PortSecured here with static WEP
1963 // NetworkManger set security policy first then set SSID to connect AP.
1964 if (pAd->StaCfg.WpaSupplicantUP &&
1965 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1966 (pAd->StaCfg.IEEE8021X == FALSE))
1968 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1972 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1973 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1976 NdisAcquireSpinLock(&pAd->MacTabLock);
1977 NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
1978 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
1979 NdisReleaseSpinLock(&pAd->MacTabLock);
1981 pAd->StaCfg.MicErrCnt = 0;
1983 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1984 // Update extra information to link is up
1985 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1987 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1990 pAd->bUsbTxBulkAggre = FALSE;
1991 #endif // RTMP_MAC_USB //
1993 // Clean association information
1994 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
1995 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
1996 pAd->StaCfg.ReqVarIELen = 0;
1997 pAd->StaCfg.ResVarIELen = 0;
2000 // Reset RSSI value after link down
2002 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2003 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2004 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2005 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2006 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2007 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2010 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2011 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2014 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
2016 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
2018 pAd->CommonCfg.BBPCurrentBW = BW_20;
2019 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2020 ByteValue &= (~0x18);
2021 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2025 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2026 ByteValue &= (~0x18);
2027 if (pAd->Antenna.field.TxPath == 2)
2031 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2033 RTMPSetPiggyBack(pAd,FALSE);
2034 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2036 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2038 // Restore all settings in the following.
2039 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2040 AsicDisableRDG(pAd);
2041 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2042 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2044 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2045 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2047 // Allow go to sleep after linkdown steps.
2048 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
2050 RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
2053 if ((IS_RT30xx(pAd) || IS_RT3090(pAd)||IS_RT3390(pAd))
2054 &&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1))
2056 RTMP_ASIC_MMPS_DISABLE(pAd);
2062 ==========================================================================
2065 IRQL = DISPATCH_LEVEL
2067 ==========================================================================
2069 VOID IterateOnBssTab(
2070 IN PRTMP_ADAPTER pAd)
2072 MLME_START_REQ_STRUCT StartReq;
2073 MLME_JOIN_REQ_STRUCT JoinReq;
2076 // Change the wepstatus to original wepstatus
2077 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2078 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2079 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2081 BssIdx = pAd->MlmeAux.BssIdx;
2082 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2084 // Check cipher suite, AP must have more secured cipher than station setting
2085 // Set the Pairwise and Group cipher to match the intended AP setting
2086 // We can only connect to AP with less secured cipher setting
2087 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2089 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2091 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2092 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2093 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2094 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2095 else // There is no PairCipher Aux, downgrade our capability to TKIP
2096 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2098 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2100 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2102 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2103 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2104 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2105 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2106 else // There is no PairCipher Aux, downgrade our capability to TKIP
2107 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2110 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2113 // Set Mix cipher flag
2114 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2115 /*if (pAd->StaCfg.bMixCipher == TRUE)
2117 // If mix cipher, re-build RSNIE
2118 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2121 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2122 JoinParmFill(pAd, &JoinReq, BssIdx);
2123 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2125 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2127 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2129 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2130 StartParmFill(pAd, &StartReq, (PCHAR)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2131 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2132 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2138 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2139 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2140 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
2143 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2147 // for re-association only
2148 // IRQL = DISPATCH_LEVEL
2149 VOID IterateOnBssTab2(
2150 IN PRTMP_ADAPTER pAd)
2152 MLME_REASSOC_REQ_STRUCT ReassocReq;
2156 BssIdx = pAd->MlmeAux.RoamIdx;
2157 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2159 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2161 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2163 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2164 AsicLockChannel(pAd, pBss->Channel);
2166 // reassociate message has the same structure as associate message
2167 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2168 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2169 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2170 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2172 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2178 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2179 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2180 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
2183 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2188 ==========================================================================
2191 IRQL = DISPATCH_LEVEL
2193 ==========================================================================
2196 IN PRTMP_ADAPTER pAd,
2197 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2200 JoinReq->BssIdx = BssIdx;
2204 ==========================================================================
2207 IRQL = DISPATCH_LEVEL
2209 ==========================================================================
2212 IN PRTMP_ADAPTER pAd,
2213 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2219 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2220 ScanReq->SsidLen = SsidLen;
2221 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2222 ScanReq->BssType = BssType;
2223 ScanReq->ScanType = ScanType;
2227 ==========================================================================
2230 IRQL = DISPATCH_LEVEL
2232 ==========================================================================
2235 IN PRTMP_ADAPTER pAd,
2236 IN OUT MLME_START_REQ_STRUCT *StartReq,
2240 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2241 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2242 StartReq->SsidLen = SsidLen;
2246 ==========================================================================
2249 IRQL = DISPATCH_LEVEL
2251 ==========================================================================
2254 IN PRTMP_ADAPTER pAd,
2255 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2259 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2261 AuthReq->Timeout = AUTH_TIMEOUT;
2265 ==========================================================================
2268 IRQL = DISPATCH_LEVEL
2270 ==========================================================================
2274 IN PRTMP_ADAPTER pAd)
2276 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2277 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2278 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2279 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2280 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2281 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2284 // IRQL = DISPATCH_LEVEL
2285 VOID ComposeNullFrame(
2286 IN PRTMP_ADAPTER pAd)
2288 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2289 pAd->NullFrame.FC.Type = BTYPE_DATA;
2290 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2291 pAd->NullFrame.FC.ToDs = 1;
2292 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2293 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2294 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2296 #endif // RTMP_MAC_PCI //
2298 VOID MlmeCntlConfirm(
2299 IN PRTMP_ADAPTER pAd,
2303 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
2307 IN PRTMP_ADAPTER pAd)
2309 PTXINFO_STRUC pTxInfo;
2312 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2313 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2315 pAd->PsPollFrame.FC.PwrMgmt = 0;
2316 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2317 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2318 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2319 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2320 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2322 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
2323 pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
2324 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2325 pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2326 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
2327 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2328 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2329 // Append 4 extra zero bytes.
2330 pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
2333 // IRQL = DISPATCH_LEVEL
2334 VOID ComposeNullFrame(
2335 IN PRTMP_ADAPTER pAd)
2337 PTXINFO_STRUC pTxInfo;
2340 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2341 pAd->NullFrame.FC.Type = BTYPE_DATA;
2342 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2343 pAd->NullFrame.FC.ToDs = 1;
2344 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2345 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2346 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2347 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
2348 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
2349 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2350 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2351 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
2352 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2353 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
2354 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2356 #endif // RTMP_MAC_USB //
2359 ==========================================================================
2361 Pre-build a BEACON frame in the shared memory
2363 IRQL = PASSIVE_LEVEL
2364 IRQL = DISPATCH_LEVEL
2366 ==========================================================================
2368 ULONG MakeIbssBeacon(
2369 IN PRTMP_ADAPTER pAd)
2371 UCHAR DsLen = 1, IbssLen = 2;
2372 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2373 HEADER_802_11 BcnHdr;
2374 USHORT CapabilityInfo;
2375 LARGE_INTEGER FakeTimestamp;
2377 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2378 UCHAR *pBeaconFrame = pAd->BeaconBuf;
2380 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2381 UCHAR SupRateLen = 0;
2382 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2383 UCHAR ExtRateLen = 0;
2384 UCHAR RSNIe = IE_WPA;
2386 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2388 SupRate[0] = 0x82; // 1 mbps
2389 SupRate[1] = 0x84; // 2 mbps
2390 SupRate[2] = 0x8b; // 5.5 mbps
2391 SupRate[3] = 0x96; // 11 mbps
2395 else if (pAd->CommonCfg.Channel > 14)
2397 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2398 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2399 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2400 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2401 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2402 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2403 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2404 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2409 // Also Update MlmeRate & RtsRate for G only & A only
2411 pAd->CommonCfg.MlmeRate = RATE_6;
2412 pAd->CommonCfg.RtsRate = RATE_6;
2413 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2414 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2415 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2416 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2420 SupRate[0] = 0x82; // 1 mbps
2421 SupRate[1] = 0x84; // 2 mbps
2422 SupRate[2] = 0x8b; // 5.5 mbps
2423 SupRate[3] = 0x96; // 11 mbps
2426 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2427 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2428 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2429 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2430 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2431 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2432 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2433 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2437 pAd->StaActive.SupRateLen = SupRateLen;
2438 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2439 pAd->StaActive.ExtRateLen = ExtRateLen;
2440 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2442 // compose IBSS beacon frame
2443 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2444 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2445 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2446 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2447 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2449 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2450 sizeof(HEADER_802_11), &BcnHdr,
2451 TIMESTAMP_LEN, &FakeTimestamp,
2452 2, &pAd->CommonCfg.BeaconPeriod,
2455 1, &pAd->CommonCfg.SsidLen,
2456 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2459 SupRateLen, SupRate,
2462 1, &pAd->CommonCfg.Channel,
2465 2, &pAd->StaActive.AtimWin,
2468 // add ERP_IE and EXT_RAE IE of in 802.11g
2473 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2477 ExtRateLen, ExtRate,
2482 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2483 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2486 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2488 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2490 1, &pAd->StaCfg.RSNIE_Len,
2491 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2496 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2499 UCHAR HtLen, HtLen1;
2501 // add HT Capability IE
2502 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2503 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2505 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2508 HtLen, &pAd->CommonCfg.HtCapability,
2511 HtLen1, &pAd->CommonCfg.AddHTInfo,
2517 //beacon use reserved WCID 0xff
2518 if (pAd->CommonCfg.Channel > 14)
2520 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2521 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2525 // Set to use 1Mbps for Adhoc beacon.
2526 HTTRANSMIT_SETTING Transmit;
2528 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2529 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2532 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2533 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));