repo init
[linux-rt-nao.git] / drivers / staging / rt2860 / sta / connect.c
blob36f28f8b4aa4605ab2d517be1a933c19c7e124ad
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
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. *
14 * *
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. *
19 * *
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. *
24 * *
25 *************************************************************************
27 Module Name:
28 connect.c
30 Abstract:
32 Revision History:
33 Who When What
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) \
66 { \
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 ==========================================================================
94 Description:
96 IRQL = PASSIVE_LEVEL
98 ==========================================================================
100 VOID MlmeCntlInit(
101 IN PRTMP_ADAPTER pAd,
102 IN STATE_MACHINE *S,
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 ==========================================================================
112 Description:
114 IRQL = DISPATCH_LEVEL
116 ==========================================================================
118 VOID MlmeCntlMachinePerformAction(
119 IN PRTMP_ADAPTER pAd,
120 IN STATE_MACHINE *S,
121 IN MLME_QUEUE_ELEM *Elem)
123 switch(pAd->Mlme.CntlMachine.CurrState)
125 case CNTL_IDLE:
127 CntlIdleProc(pAd, Elem);
129 break;
130 case CNTL_WAIT_DISASSOC:
131 CntlWaitDisassocProc(pAd, Elem);
132 break;
133 case CNTL_WAIT_JOIN:
134 CntlWaitJoinProc(pAd, Elem);
135 break;
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);
145 break;
147 case CNTL_WAIT_START:
148 CntlWaitStartProc(pAd, Elem);
149 break;
150 case CNTL_WAIT_AUTH:
151 CntlWaitAuthProc(pAd, Elem);
152 break;
153 case CNTL_WAIT_AUTH2:
154 CntlWaitAuthProc2(pAd, Elem);
155 break;
156 case CNTL_WAIT_ASSOC:
157 CntlWaitAssocProc(pAd, Elem);
158 break;
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);
181 #ifdef DOT11N_DRAFT3
182 // AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone.
183 if (pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1)
185 Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
187 #endif // DOT11N_DRAFT3 //
189 break;
191 case CNTL_WAIT_OID_DISASSOC:
192 if (Elem->MsgType == MT2_DISASSOC_CONF)
194 LinkDown(pAd, FALSE);
195 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
197 break;
198 default:
199 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
200 break;
206 ==========================================================================
207 Description:
209 IRQL = DISPATCH_LEVEL
211 ==========================================================================
213 VOID CntlIdleProc(
214 IN PRTMP_ADAPTER pAd,
215 IN MLME_QUEUE_ELEM *Elem)
217 MLME_DISASSOC_REQ_STRUCT DisassocReq;
219 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
220 return;
222 switch(Elem->MsgType)
224 case OID_802_11_SSID:
225 CntlOidSsidProc(pAd, Elem);
226 break;
228 case OID_802_11_BSSID:
229 CntlOidRTBssidProc(pAd,Elem);
230 break;
232 case OID_802_11_BSSID_LIST_SCAN:
233 CntlOidScanProc(pAd,Elem);
234 break;
236 case OID_802_11_DISASSOCIATE:
237 #ifdef RALINK_ATE
238 if(ATE_ON(pAd))
240 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
241 break;
243 #endif // RALINK_ATE //
244 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
245 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
246 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
247 #ifdef WPA_SUPPLICANT_SUPPORT
248 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
249 #endif // WPA_SUPPLICANT_SUPPORT //
251 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
252 // Since calling this indicate user don't want to connect to that SSID anymore.
253 pAd->MlmeAux.AutoReconnectSsidLen= 32;
254 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
256 break;
258 case MT2_MLME_ROAMING_REQ:
259 CntlMlmeRoamingProc(pAd, Elem);
260 break;
262 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
263 WpaMicFailureReportFrame(pAd, Elem);
264 break;
266 #ifdef QOS_DLS_SUPPORT
267 case RT_OID_802_11_SET_DLS_PARAM:
268 CntlOidDLSSetupProc(pAd, Elem);
269 break;
270 #endif // QOS_DLS_SUPPORT //
272 default:
273 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
274 break;
278 VOID CntlOidScanProc(
279 IN PRTMP_ADAPTER pAd,
280 IN MLME_QUEUE_ELEM *Elem)
282 MLME_SCAN_REQ_STRUCT ScanReq;
283 ULONG BssIdx = BSS_NOT_FOUND;
284 BSS_ENTRY CurrBss;
286 #ifdef RALINK_ATE
287 /* Disable scanning when ATE is running. */
288 if (ATE_ON(pAd))
289 return;
290 #endif // RALINK_ATE //
293 // record current BSS if network is connected.
294 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
295 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
297 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
298 if (BssIdx != BSS_NOT_FOUND)
300 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
304 // clean up previous SCAN result, add current BSS back to table if any
305 BssTableInit(&pAd->ScanTab);
306 if (BssIdx != BSS_NOT_FOUND)
308 // DDK Note: If the NIC is associated with a particular BSSID and SSID
309 // that are not contained in the list of BSSIDs generated by this scan, the
310 // BSSID description of the currently associated BSSID and SSID should be
311 // appended to the list of BSSIDs in the NIC's database.
312 // To ensure this, we append this BSS as the first entry in SCAN result
313 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
314 pAd->ScanTab.BssNr = 1;
317 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
318 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
319 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
320 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
324 ==========================================================================
325 Description:
326 Before calling this routine, user desired SSID should already been
327 recorded in CommonCfg.Ssid[]
328 IRQL = DISPATCH_LEVEL
330 ==========================================================================
332 VOID CntlOidSsidProc(
333 IN PRTMP_ADAPTER pAd,
334 IN MLME_QUEUE_ELEM * Elem)
336 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
337 MLME_DISASSOC_REQ_STRUCT DisassocReq;
338 ULONG Now;
340 // Step 1. record the desired user settings to MlmeAux
341 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
342 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
343 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
344 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
345 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
349 // Update Reconnect Ssid, that user desired to connect.
351 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
352 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
353 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
355 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
356 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
357 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
359 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
360 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
361 NdisGetSystemUpTime(&Now);
363 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
364 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
365 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
366 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
368 // Case 1. already connected with an AP who has the desired SSID
369 // with highest RSSI
371 // Add checking Mode "LEAP" for CCX 1.0
372 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
373 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
374 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
375 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
376 #ifdef LEAP_SUPPORT
377 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
378 #endif // LEAP_SUPPORT //
379 ) &&
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;
399 else
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
407 if (INFRA_ON(pAd))
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 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
421 union iwreq_data wrqu;
423 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
424 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
425 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
428 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
431 else if (INFRA_ON(pAd))
434 // For RT61
435 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
436 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
437 // But media status is connected, so the SSID not report correctly.
439 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
442 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
444 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
446 // case 2. active INFRA association existent
447 // roaming is done within miniport driver, nothing to do with configuration
448 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
449 // disassociate with the current associated AP,
450 // then perform a new association with this new SSID, no matter the
451 // new/old SSID are the same or not.
452 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
453 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
454 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
455 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
456 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
458 else
460 if (ADHOC_ON(pAd))
462 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
463 LinkDown(pAd, FALSE);
464 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
465 pAd->IndicateMediaState = NdisMediaStateDisconnected;
466 RTMP_IndicateMediaState(pAd);
467 pAd->ExtraInfo = GENERAL_LINK_DOWN;
468 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
471 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
472 (pAd->StaCfg.bAutoReconnect == TRUE) &&
473 (pAd->MlmeAux.BssType == BSS_INFRA) &&
474 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
477 MLME_SCAN_REQ_STRUCT ScanReq;
479 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
480 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
481 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
482 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
483 // Reset Missed scan number
484 pAd->StaCfg.LastScanTime = Now;
486 else
488 pAd->MlmeAux.BssIdx = 0;
489 IterateOnBssTab(pAd);
496 ==========================================================================
497 Description:
499 IRQL = DISPATCH_LEVEL
501 ==========================================================================
503 VOID CntlOidRTBssidProc(
504 IN PRTMP_ADAPTER pAd,
505 IN MLME_QUEUE_ELEM * Elem)
507 ULONG BssIdx;
508 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
509 MLME_DISASSOC_REQ_STRUCT DisassocReq;
510 MLME_JOIN_REQ_STRUCT JoinReq;
512 #ifdef RALINK_ATE
513 /* No need to perform this routine when ATE is running. */
514 if (ATE_ON(pAd))
515 return;
516 #endif // RALINK_ATE //
518 // record user desired settings
519 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
520 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
523 // Update Reconnect Ssid, that user desired to connect.
525 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
526 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
527 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
529 // find the desired BSS in the latest SCAN result table
530 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
531 if (BssIdx == BSS_NOT_FOUND)
533 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
534 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
535 return;
538 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
539 // Because we need this entry to become the JOIN target in later on SYNC state machine
540 pAd->MlmeAux.BssIdx = 0;
541 pAd->MlmeAux.SsidBssTab.BssNr = 1;
542 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
544 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
545 // we just follow normal procedure. The reason of user doing this may because he/she changed
546 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
547 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
548 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
549 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
550 // connection when setting the same BSSID.
551 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
552 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
554 // already connected to the same BSSID, go back to idle state directly
555 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
556 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
557 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
559 union iwreq_data wrqu;
561 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
562 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
563 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
566 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
568 else
570 if (INFRA_ON(pAd))
572 // disassoc from current AP first
573 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
574 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
575 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
576 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
578 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
580 else
582 if (ADHOC_ON(pAd))
584 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
585 LinkDown(pAd, FALSE);
586 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
587 pAd->IndicateMediaState = NdisMediaStateDisconnected;
588 RTMP_IndicateMediaState(pAd);
589 pAd->ExtraInfo = GENERAL_LINK_DOWN;
590 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
593 // Change the wepstatus to original wepstatus
594 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
595 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
596 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
598 // Check cipher suite, AP must have more secured cipher than station setting
599 // Set the Pairwise and Group cipher to match the intended AP setting
600 // We can only connect to AP with less secured cipher setting
601 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
603 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
605 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
606 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
607 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
608 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
609 else // There is no PairCipher Aux, downgrade our capability to TKIP
610 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
612 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
614 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
616 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
617 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
618 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
619 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
620 else // There is no PairCipher Aux, downgrade our capability to TKIP
621 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
623 // RSN capability
624 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
627 // Set Mix cipher flag
628 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
629 if (pAd->StaCfg.bMixCipher == TRUE)
631 // If mix cipher, re-build RSNIE
632 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
634 // No active association, join the BSS immediately
635 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
636 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
638 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
639 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
641 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
646 // Roaming is the only external request triggering CNTL state machine
647 // despite of other "SET OID" operation. All "SET OID" related oerations
648 // happen in sequence, because no other SET OID will be sent to this device
649 // until the the previous SET operation is complete (successful o failed).
650 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
651 // or been corrupted by other "SET OID"?
653 // IRQL = DISPATCH_LEVEL
654 VOID CntlMlmeRoamingProc(
655 IN PRTMP_ADAPTER pAd,
656 IN MLME_QUEUE_ELEM *Elem)
658 // TODO:
659 // AP in different channel may show lower RSSI than actual value??
660 // should we add a weighting factor to compensate it?
661 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
663 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
664 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
666 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
667 pAd->MlmeAux.BssIdx = 0;
668 IterateOnBssTab(pAd);
671 #ifdef QOS_DLS_SUPPORT
673 ==========================================================================
674 Description:
676 IRQL = DISPATCH_LEVEL
678 ==========================================================================
680 VOID CntlOidDLSSetupProc(
681 IN PRTMP_ADAPTER pAd,
682 IN MLME_QUEUE_ELEM *Elem)
684 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)Elem->Msg;
685 MLME_DLS_REQ_STRUCT MlmeDlsReq;
686 INT i;
687 USHORT reason = REASON_UNSPECIFY;
689 DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n",
690 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5],
691 pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer));
693 if (!pAd->CommonCfg.bDLSCapable)
694 return;
696 // DLS will not be supported when Adhoc mode
697 if (INFRA_ON(pAd))
699 for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++)
701 if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
702 (pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
704 // 1. Same setting, just drop it
705 DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n"));
706 break;
708 else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
709 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
711 // 2. Disable DLS link case, just tear down DLS link
712 reason = REASON_QOS_UNWANTED_MECHANISM;
713 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
714 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
715 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
716 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
717 DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n"));
718 break;
720 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid)
722 // 3. Enable case, start DLS setup procedure
723 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
725 //Update countdown timer
726 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
727 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
728 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
729 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n"));
730 break;
732 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
733 (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
735 // 4. update mac case, tear down old DLS and setup new DLS
736 reason = REASON_QOS_UNWANTED_MECHANISM;
737 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
738 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
739 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
740 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
741 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
742 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
743 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
744 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS tear down and restart case\n"));
745 break;
747 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
748 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr) && (pAd->StaCfg.DLSEntry[i].TimeOut != pDLS->TimeOut))
750 // 5. update timeout case, start DLS setup procedure (no tear down)
751 pAd->StaCfg.DLSEntry[i].TimeOut = pDLS->TimeOut;
752 //Update countdown timer
753 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
754 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
755 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
756 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS update timeout case\n"));
757 break;
759 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
760 (pAd->StaCfg.DLSEntry[i].Status != DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
762 // 6. re-setup case, start DLS setup procedure (no tear down)
763 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
764 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
765 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS retry setup procedure\n"));
766 break;
768 else
770 DBGPRINT(RT_DEBUG_WARN,("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n",
771 i, pAd->StaCfg.DLSEntry[i].Valid, pAd->StaCfg.DLSEntry[i].Status, pAd->StaCfg.DLSEntry[i].TimeOut));
776 #endif // QOS_DLS_SUPPORT //
779 ==========================================================================
780 Description:
782 IRQL = DISPATCH_LEVEL
784 ==========================================================================
786 VOID CntlWaitDisassocProc(
787 IN PRTMP_ADAPTER pAd,
788 IN MLME_QUEUE_ELEM *Elem)
790 MLME_START_REQ_STRUCT StartReq;
792 if (Elem->MsgType == MT2_DISASSOC_CONF)
794 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
796 if (pAd->CommonCfg.bWirelessEvent)
798 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
801 LinkDown(pAd, FALSE);
803 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
804 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
806 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
807 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
808 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
809 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
811 // case 2. try each matched BSS
812 else
814 pAd->MlmeAux.BssIdx = 0;
816 IterateOnBssTab(pAd);
822 ==========================================================================
823 Description:
825 IRQL = DISPATCH_LEVEL
827 ==========================================================================
829 VOID CntlWaitJoinProc(
830 IN PRTMP_ADAPTER pAd,
831 IN MLME_QUEUE_ELEM *Elem)
833 USHORT Reason;
834 MLME_AUTH_REQ_STRUCT AuthReq;
836 if (Elem->MsgType == MT2_JOIN_CONF)
838 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
839 if (Reason == MLME_SUCCESS)
841 // 1. joined an IBSS, we are pretty much done here
842 if (pAd->MlmeAux.BssType == BSS_ADHOC)
845 // 5G bands rules of Japan:
846 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
848 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
849 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
852 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
853 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
854 return;
857 LinkUp(pAd, BSS_ADHOC);
858 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
859 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
860 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
861 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
863 pAd->IndicateMediaState = NdisMediaStateConnected;
864 pAd->ExtraInfo = GENERAL_LINK_UP;
866 // 2. joined a new INFRA network, start from authentication
867 else
869 #ifdef LEAP_SUPPORT
870 // Add AuthMode "LEAP" for CCX 1.X
871 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
873 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
875 else
876 #endif // LEAP_SUPPORT //
878 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
879 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
880 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
882 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
884 else
886 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
889 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
890 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
892 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
895 else
897 // 3. failed, try next BSS
898 pAd->MlmeAux.BssIdx++;
899 IterateOnBssTab(pAd);
906 ==========================================================================
907 Description:
909 IRQL = DISPATCH_LEVEL
911 ==========================================================================
913 VOID CntlWaitStartProc(
914 IN PRTMP_ADAPTER pAd,
915 IN MLME_QUEUE_ELEM *Elem)
917 USHORT Result;
919 if (Elem->MsgType == MT2_START_CONF)
921 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
922 if (Result == MLME_SUCCESS)
925 // 5G bands rules of Japan:
926 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
928 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
929 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
932 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
933 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
934 return;
936 #ifdef DOT11_N_SUPPORT
937 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
939 N_ChannelCheck(pAd);
940 SetCommonHT(pAd);
941 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
942 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
943 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
944 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
945 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
946 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
948 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
949 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
951 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
953 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
954 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
956 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
959 else
960 #endif // DOT11_N_SUPPORT //
962 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
964 LinkUp(pAd, BSS_ADHOC);
965 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
966 // Before send beacon, driver need do radar detection
967 if ((pAd->CommonCfg.Channel > 14 )
968 && (pAd->CommonCfg.bIEEE80211H == 1)
969 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
971 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
972 pAd->CommonCfg.RadarDetect.RDCount = 0;
973 #ifdef DFS_SUPPORT
974 BbpRadarDetectionStart(pAd);
975 #endif // DFS_SUPPORT //
978 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
979 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
980 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
982 else
984 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
985 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
991 ==========================================================================
992 Description:
994 IRQL = DISPATCH_LEVEL
996 ==========================================================================
998 VOID CntlWaitAuthProc(
999 IN PRTMP_ADAPTER pAd,
1000 IN MLME_QUEUE_ELEM *Elem)
1002 USHORT Reason;
1003 MLME_ASSOC_REQ_STRUCT AssocReq;
1004 MLME_AUTH_REQ_STRUCT AuthReq;
1006 if (Elem->MsgType == MT2_AUTH_CONF)
1008 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1009 if (Reason == MLME_SUCCESS)
1011 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1012 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1013 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1015 #ifdef LEAP_SUPPORT
1017 // Cisco Leap CCKM supported Re-association.
1019 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
1021 //if CCKM is turn on , that's mean Fast Reauthentication
1022 //Use CCKM Reassociation instead of normal association for Fast Roaming.
1023 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
1024 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1026 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
1028 else
1029 #endif // LEAP_SUPPORT //
1031 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1032 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1034 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1037 else
1039 // This fail may because of the AP already keep us in its MAC table without
1040 // ageing-out. The previous authentication attempt must have let it remove us.
1041 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
1042 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
1043 #ifdef LEAP_SUPPORT
1044 //Add AuthMode "LEAP" for CCX 1.X
1045 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1047 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
1049 else
1050 #endif // LEAP_SUPPORT //
1052 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
1053 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
1055 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
1056 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
1058 else
1060 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1063 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1064 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1066 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1072 ==========================================================================
1073 Description:
1075 IRQL = DISPATCH_LEVEL
1077 ==========================================================================
1079 VOID CntlWaitAuthProc2(
1080 IN PRTMP_ADAPTER pAd,
1081 IN MLME_QUEUE_ELEM *Elem)
1083 USHORT Reason;
1084 MLME_ASSOC_REQ_STRUCT AssocReq;
1085 MLME_AUTH_REQ_STRUCT AuthReq;
1087 if (Elem->MsgType == MT2_AUTH_CONF)
1089 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1090 if (Reason == MLME_SUCCESS)
1092 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1093 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1094 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1095 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1096 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1098 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1100 else
1102 #ifdef LEAP_SUPPORT
1103 // Process LEAP first, since it use different control variable
1104 // We don't want to affect other poven operation
1105 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1107 // LEAP Auth not success, try next BSS
1108 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
1109 DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
1110 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1111 pAd->MlmeAux.BssIdx++;
1112 IterateOnBssTab(pAd);
1114 else
1115 #endif // LEAP_SUPPORT //
1116 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
1117 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
1119 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
1120 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1121 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1122 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1124 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1126 else
1128 // not success, try next BSS
1129 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
1130 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
1131 pAd->MlmeAux.BssIdx++;
1132 IterateOnBssTab(pAd);
1139 ==========================================================================
1140 Description:
1142 IRQL = DISPATCH_LEVEL
1144 ==========================================================================
1146 VOID CntlWaitAssocProc(
1147 IN PRTMP_ADAPTER pAd,
1148 IN MLME_QUEUE_ELEM *Elem)
1150 USHORT Reason;
1152 if (Elem->MsgType == MT2_ASSOC_CONF)
1154 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1155 if (Reason == MLME_SUCCESS)
1157 LinkUp(pAd, BSS_INFRA);
1158 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1159 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1161 if (pAd->CommonCfg.bWirelessEvent)
1163 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1166 else
1168 // not success, try next BSS
1169 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1170 pAd->MlmeAux.BssIdx++;
1171 IterateOnBssTab(pAd);
1177 ==========================================================================
1178 Description:
1180 IRQL = DISPATCH_LEVEL
1182 ==========================================================================
1184 VOID CntlWaitReassocProc(
1185 IN PRTMP_ADAPTER pAd,
1186 IN MLME_QUEUE_ELEM *Elem)
1188 USHORT Result;
1190 if (Elem->MsgType == MT2_REASSOC_CONF)
1192 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1193 if (Result == MLME_SUCCESS)
1196 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1198 LinkUp(pAd, BSS_INFRA);
1200 // send wireless event - for association
1201 if (pAd->CommonCfg.bWirelessEvent)
1202 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1205 #ifdef LEAP_SUPPORT
1206 if (LEAP_CCKM_ON(pAd))
1208 STA_PORT_SECURED(pAd);
1209 pAd->StaCfg.WpaState = SS_FINISH;
1211 #endif // LEAP_SUPPORT //
1212 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1213 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1215 else
1217 // reassoc failed, try to pick next BSS in the BSS Table
1218 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1219 pAd->MlmeAux.RoamIdx++;
1220 IterateOnBssTab2(pAd);
1226 ==========================================================================
1227 Description:
1229 IRQL = DISPATCH_LEVEL
1231 ==========================================================================
1233 VOID LinkUp(
1234 IN PRTMP_ADAPTER pAd,
1235 IN UCHAR BssType)
1237 ULONG Now;
1238 UINT32 Data;
1239 BOOLEAN Cancelled;
1240 UCHAR Value = 0, idx;
1241 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1243 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1246 // ASSOC - DisassocTimeoutAction
1247 // CNTL - Dis-associate successful
1248 // !!! LINK DOWN !!!
1249 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1251 // To prevent DisassocTimeoutAction to call Link down after we link up,
1252 // cancel the DisassocTimer no matter what it start or not.
1254 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1256 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1258 #ifdef DOT11_N_SUPPORT
1259 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1260 #endif // DOT11_N_SUPPORT //
1261 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1262 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1263 // to examine if cipher algorithm switching is required.
1264 //rt2860b. Don't know why need this
1265 SwitchBetweenWepAndCkip(pAd);
1267 #ifdef RT2860
1268 // Before power save before link up function, We will force use 1R.
1269 // So after link up, check Rx antenna # again.
1270 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1271 if(pAd->Antenna.field.RxPath == 3)
1273 Value |= (0x10);
1275 else if(pAd->Antenna.field.RxPath == 2)
1277 Value |= (0x8);
1279 else if(pAd->Antenna.field.RxPath == 1)
1281 Value |= (0x0);
1283 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1284 pAd->StaCfg.BBPR3 = Value;
1285 #endif // RT2860 //
1287 if (BssType == BSS_ADHOC)
1289 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1290 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1292 #ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1293 // No carrier detection when adhoc
1294 // CarrierDetectionStop(pAd);
1295 pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
1296 #endif // CARRIER_DETECTION_SUPPORT //
1298 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1300 else
1302 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1303 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1305 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1308 // 3*3
1309 // reset Tx beamforming bit
1310 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1311 Value &= (~0x01);
1312 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1313 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1315 #ifdef DOT11_N_SUPPORT
1316 // Change to AP channel
1317 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1319 // Must using 40MHz.
1320 pAd->CommonCfg.BBPCurrentBW = BW_40;
1321 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1322 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1324 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1325 Value &= (~0x18);
1326 Value |= 0x10;
1327 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1329 // RX : control channel at lower
1330 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1331 Value &= (~0x20);
1332 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1333 #ifdef RT2860
1334 pAd->StaCfg.BBPR3 = Value;
1335 #endif // RT2860 //
1337 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1338 Data &= 0xfffffffe;
1339 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1341 if (pAd->MACVersion == 0x28600100)
1343 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1344 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1345 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1346 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1349 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1351 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1353 // Must using 40MHz.
1354 pAd->CommonCfg.BBPCurrentBW = BW_40;
1355 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1356 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1358 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1359 Value &= (~0x18);
1360 Value |= 0x10;
1361 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1363 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1364 Data |= 0x1;
1365 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1367 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1368 Value |= (0x20);
1369 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1370 #ifdef RT2860
1371 pAd->StaCfg.BBPR3 = Value;
1372 #endif // RT2860 //
1374 if (pAd->MACVersion == 0x28600100)
1376 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1377 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1378 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1379 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1382 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1384 else
1385 #endif // DOT11_N_SUPPORT //
1387 pAd->CommonCfg.BBPCurrentBW = BW_20;
1388 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1389 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1390 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1392 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1393 Value &= (~0x18);
1394 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1396 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1397 Data &= 0xfffffffe;
1398 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1400 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1401 Value &= (~0x20);
1402 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1403 #ifdef RT2860
1404 pAd->StaCfg.BBPR3 = Value;
1405 #endif // RT2860 //
1407 if (pAd->MACVersion == 0x28600100)
1409 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1410 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1411 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1412 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1415 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1418 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1420 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1422 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1424 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1425 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1427 #ifdef DOT11_N_SUPPORT
1428 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1429 #endif // DOT11_N_SUPPORT //
1431 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1433 AsicSetSlotTime(pAd, TRUE);
1434 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1436 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1437 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1439 #ifdef DOT11_N_SUPPORT
1440 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1442 // Update HT protectionfor based on AP's operating mode.
1443 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1445 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1447 else
1448 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1450 #endif // DOT11_N_SUPPORT //
1452 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1454 NdisGetSystemUpTime(&Now);
1455 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1457 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1458 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1460 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1463 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1465 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1467 #ifdef DFS_SUPPORT
1468 RadarDetectionStop(pAd);
1469 #endif // DFS_SUPPORT //
1471 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1473 if (BssType == BSS_ADHOC)
1475 MakeIbssBeacon(pAd);
1476 if ((pAd->CommonCfg.Channel > 14)
1477 && (pAd->CommonCfg.bIEEE80211H == 1)
1478 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1480 ; //Do nothing
1482 else
1484 AsicEnableIbssSync(pAd);
1487 // In ad hoc mode, use MAC table from index 1.
1488 // 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.
1489 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1490 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1492 // If WEP is enabled, add key material and cipherAlg into Asic
1493 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1495 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1497 PUCHAR Key;
1498 UCHAR CipherAlg;
1500 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1502 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1503 Key = pAd->SharedKey[BSS0][idx].Key;
1505 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1507 // Set key material and cipherAlg to Asic
1508 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1510 if (idx == pAd->StaCfg.DefaultKeyId)
1512 // Update WCID attribute table and IVEIV table for this group key table
1513 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1520 // If WPANone is enabled, add key material and cipherAlg into Asic
1521 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1522 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1524 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1526 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1527 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1528 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1530 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1532 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1533 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1536 // Decide its ChiperAlg
1537 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1538 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1539 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1540 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1541 else
1543 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1544 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1547 // Set key material and cipherAlg to Asic
1548 AsicAddSharedKeyEntry(pAd,
1549 BSS0,
1551 pAd->SharedKey[BSS0][0].CipherAlg,
1552 pAd->SharedKey[BSS0][0].Key,
1553 pAd->SharedKey[BSS0][0].TxMic,
1554 pAd->SharedKey[BSS0][0].RxMic);
1556 // Update WCID attribute table and IVEIV table for this group key table
1557 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1562 else // BSS_INFRA
1564 // Check the new SSID with last SSID
1565 while (Cancelled == TRUE)
1567 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1569 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1571 // Link to the old one no linkdown is required.
1572 break;
1575 // Send link down event before set to link up
1576 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1577 RTMP_IndicateMediaState(pAd);
1578 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1579 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1580 break;
1584 // On WPA mode, Remove All Keys if not connect to the last BSSID
1585 // Key will be set after 4-way handshake.
1587 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1589 ULONG IV;
1591 // Remove all WPA keys
1592 RTMPWPARemoveAllKeys(pAd);
1593 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1594 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1596 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1597 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1598 IV = 0;
1599 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1600 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1602 // NOTE:
1603 // the decision of using "short slot time" or not may change dynamically due to
1604 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1606 // NOTE:
1607 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1608 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1610 ComposePsPoll(pAd);
1611 ComposeNullFrame(pAd);
1613 AsicEnableBssSync(pAd);
1615 // Add BSSID to WCID search table
1616 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1618 NdisAcquireSpinLock(&pAd->MacTabLock);
1619 // add this BSSID entry into HASH table
1621 UCHAR HashIdx;
1623 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1624 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1625 if (pAd->MacTab.Hash[HashIdx] == NULL)
1627 pAd->MacTab.Hash[HashIdx] = pEntry;
1629 else
1631 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1632 while (pCurrEntry->pNext != NULL)
1633 pCurrEntry = pCurrEntry->pNext;
1634 pCurrEntry->pNext = pEntry;
1637 NdisReleaseSpinLock(&pAd->MacTabLock);
1640 // If WEP is enabled, add paiewise and shared key
1641 #ifdef WPA_SUPPLICANT_SUPPORT
1642 if (((pAd->StaCfg.WpaSupplicantUP)&&
1643 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1644 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1645 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1646 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1647 #else
1648 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1649 #endif // WPA_SUPPLICANT_SUPPORT //
1651 PUCHAR Key;
1652 UCHAR CipherAlg;
1654 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1656 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1657 Key = pAd->SharedKey[BSS0][idx].Key;
1659 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1661 // Set key material and cipherAlg to Asic
1662 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1664 if (idx == pAd->StaCfg.DefaultKeyId)
1666 // Assign group key info
1667 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1669 // Assign pairwise key info
1670 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1676 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1677 // should wait until at least 2 active nodes in this BSSID.
1678 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1680 // For GUI ++
1681 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1683 pAd->IndicateMediaState = NdisMediaStateConnected;
1684 pAd->ExtraInfo = GENERAL_LINK_UP;
1686 // --
1687 RTMP_IndicateMediaState(pAd);
1689 // Add BSSID in my MAC Table.
1690 NdisAcquireSpinLock(&pAd->MacTabLock);
1691 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1692 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1693 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1694 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1695 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1696 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1697 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1698 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1699 NdisReleaseSpinLock(&pAd->MacTabLock);
1701 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1702 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1704 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1705 #ifdef DOT11_N_SUPPORT
1706 MlmeUpdateHtTxRates(pAd, BSS0);
1707 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1708 #endif // DOT11_N_SUPPORT //
1711 // Report Adjacent AP report.
1713 #ifdef LEAP_SUPPORT
1714 CCXAdjacentAPReport(pAd);
1715 #endif // LEAP_SUPPORT //
1717 if (pAd->CommonCfg.bAggregationCapable)
1719 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1722 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1723 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1724 RTMPSetPiggyBack(pAd, TRUE);
1725 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1727 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1729 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1733 if (pAd->MlmeAux.APRalinkIe != 0x0)
1735 #ifdef DOT11_N_SUPPORT
1736 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1738 AsicEnableRDG(pAd);
1740 #endif // DOT11_N_SUPPORT //
1741 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1742 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1744 else
1746 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1747 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1751 #ifdef DOT11_N_SUPPORT
1752 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));
1753 #endif // DOT11_N_SUPPORT //
1755 // Set LED
1756 RTMPSetLED(pAd, LED_LINK_UP);
1758 pAd->Mlme.PeriodicRound = 0;
1759 pAd->Mlme.OneSecPeriodicRound = 0;
1760 pAd->bConfigChanged = FALSE; // Reset config flag
1761 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1763 // Set asic auto fall back
1765 PUCHAR pTable;
1766 UCHAR TableSize = 0;
1768 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1769 AsicUpdateAutoFallBackTable(pAd, pTable);
1772 NdisAcquireSpinLock(&pAd->MacTabLock);
1773 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1774 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1775 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1777 pEntry->bAutoTxRateSwitch = FALSE;
1778 #ifdef DOT11_N_SUPPORT
1779 if (pEntry->HTPhyMode.field.MCS == 32)
1780 pEntry->HTPhyMode.field.ShortGI = GI_800;
1782 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1783 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1784 #endif // DOT11_N_SUPPORT //
1785 // If the legacy mode is set, overwrite the transmit setting of this entry.
1786 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1787 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1789 else
1790 pEntry->bAutoTxRateSwitch = TRUE;
1791 NdisReleaseSpinLock(&pAd->MacTabLock);
1793 // Let Link Status Page display first initial rate.
1794 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1795 // Select DAC according to HT or Legacy
1796 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1798 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1799 Value &= (~0x18);
1800 if (pAd->Antenna.field.TxPath == 2)
1802 Value |= 0x10;
1804 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1806 else
1808 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1809 Value &= (~0x18);
1810 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1813 #ifdef DOT11_N_SUPPORT
1814 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1817 else if (pEntry->MaxRAmpduFactor == 0)
1819 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1820 // Because our Init value is 1 at MACRegTable.
1821 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1823 #endif // DOT11_N_SUPPORT //
1825 // Patch for Marvel AP to gain high throughput
1826 // Need to set as following,
1827 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1828 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1829 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1830 // 4. kick per two packets when dequeue
1832 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1834 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1835 #ifdef DOT11_N_SUPPORT
1836 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1837 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1839 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1840 Data &= 0xFFFFFF00;
1841 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1843 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1844 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1846 else
1847 #endif // DOT11_N_SUPPORT //
1848 if (pAd->CommonCfg.bEnableTxBurst)
1850 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1851 Data &= 0xFFFFFF00;
1852 Data |= 0x60;
1853 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1854 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1856 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1857 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1859 else
1861 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1862 Data &= 0xFFFFFF00;
1863 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1865 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1866 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1869 #ifdef DOT11_N_SUPPORT
1870 // Re-check to turn on TX burst or not.
1871 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1873 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1874 if (pAd->CommonCfg.bEnableTxBurst)
1876 UINT32 MACValue = 0;
1877 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1878 // I didn't change PBF_MAX_PCNT setting.
1879 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1880 MACValue &= 0xFFFFFF00;
1881 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1882 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1885 else
1887 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1889 #endif // DOT11_N_SUPPORT //
1891 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1892 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1893 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1894 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1895 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1896 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1898 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1900 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1901 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1904 NdisAcquireSpinLock(&pAd->MacTabLock);
1905 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1906 NdisReleaseSpinLock(&pAd->MacTabLock);
1909 // Patch Atheros AP TX will breakdown issue.
1910 // AP Model: DLink DWL-8200AP
1912 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1914 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1916 else
1918 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1921 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1923 #ifdef DOT11_N_SUPPORT
1924 #ifdef DOT11N_DRAFT3
1925 if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
1927 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
1928 BuildEffectedChannelList(pAd);
1930 #endif // DOT11N_DRAFT3 //
1931 #endif // DOT11_N_SUPPORT //
1935 ==========================================================================
1937 Routine Description:
1938 Disconnect current BSSID
1940 Arguments:
1941 pAd - Pointer to our adapter
1942 IsReqFromAP - Request from AP
1944 Return Value:
1945 None
1947 IRQL = DISPATCH_LEVEL
1949 Note:
1950 We need more information to know it's this requst from AP.
1951 If yes! we need to do extra handling, for example, remove the WPA key.
1952 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1953 remove while auto reconnect.
1954 Disconnect request from AP, it means we will start afresh 4-way handshaking
1955 on WPA mode.
1957 ==========================================================================
1959 VOID LinkDown(
1960 IN PRTMP_ADAPTER pAd,
1961 IN BOOLEAN IsReqFromAP)
1963 UCHAR i, ByteValue = 0;
1965 // Do nothing if monitor mode is on
1966 if (MONITOR_ON(pAd))
1967 return;
1969 #ifdef RALINK_ATE
1970 // Nothing to do in ATE mode.
1971 if (ATE_ON(pAd))
1972 return;
1973 #endif // RALINK_ATE //
1975 if (pAd->CommonCfg.bWirelessEvent)
1977 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1980 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1981 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1983 #ifdef RT2860
1984 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1986 BOOLEAN Cancelled;
1987 pAd->Mlme.bPsPollTimerRunning = FALSE;
1988 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1991 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1993 AUTO_WAKEUP_STRUC AutoWakeupCfg;
1994 AsicForceWakeup(pAd, TRUE);
1995 AutoWakeupCfg.word = 0;
1996 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1997 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
2000 pAd->bPCIclkOff = FALSE;
2001 #endif // RT2860 //
2002 if (ADHOC_ON(pAd)) // Adhoc mode link down
2004 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
2006 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
2007 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2008 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2009 RTMP_IndicateMediaState(pAd);
2010 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2011 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2012 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
2014 else // Infra structure mode
2016 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
2018 #ifdef QOS_DLS_SUPPORT
2019 // DLS tear down frame must be sent before link down
2020 // send DLS-TEAR_DOWN message
2021 if (pAd->CommonCfg.bDLSCapable)
2023 // tear down local dls table entry
2024 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
2026 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2028 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2029 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2033 // tear down peer dls table entry
2034 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
2036 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2038 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2039 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2043 #endif // QOS_DLS_SUPPORT //
2045 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
2046 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2048 // Saved last SSID for linkup comparison
2049 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
2050 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
2051 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
2052 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
2054 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2055 RTMP_IndicateMediaState(pAd);
2056 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2057 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
2058 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
2060 else
2063 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
2064 // Otherwise lost beacon or receive De-Authentication from AP,
2065 // then we should delete BSSID from BssTable.
2066 // If we don't delete from entry, roaming will fail.
2068 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2071 // restore back to -
2072 // 1. long slot (20 us) or short slot (9 us) time
2073 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
2074 // 3. short preamble
2075 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
2077 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
2080 // Record current AP's information.
2081 // for later used reporting Adjacent AP report.
2083 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
2084 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
2085 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
2086 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
2089 #ifdef EXT_BUILD_CHANNEL_LIST
2090 // Country IE of the AP will be evaluated and will be used.
2091 if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
2093 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
2094 pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
2095 BuildChannelListEx(pAd);
2097 #endif // EXT_BUILD_CHANNEL_LIST //
2101 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2103 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2104 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
2107 pAd->StaCfg.CCXQosECWMin = 4;
2108 pAd->StaCfg.CCXQosECWMax = 10;
2110 AsicSetSlotTime(pAd, TRUE); //FALSE);
2111 AsicSetEdcaParm(pAd, NULL);
2113 // Set LED
2114 RTMPSetLED(pAd, LED_LINK_DOWN);
2115 pAd->LedIndicatorStregth = 0xF0;
2116 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
2118 AsicDisableSync(pAd);
2120 pAd->Mlme.PeriodicRound = 0;
2121 pAd->Mlme.OneSecPeriodicRound = 0;
2123 if (pAd->StaCfg.BssType == BSS_INFRA)
2125 // Remove StaCfg Information after link down
2126 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
2127 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
2128 pAd->CommonCfg.SsidLen = 0;
2130 #ifdef DOT11_N_SUPPORT
2131 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
2132 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
2133 pAd->MlmeAux.HtCapabilityLen = 0;
2134 pAd->MlmeAux.NewExtChannelOffset = 0xff;
2135 #endif // DOT11_N_SUPPORT //
2137 // Reset WPA-PSK state. Only reset when supplicant enabled
2138 if (pAd->StaCfg.WpaState != SS_NOTUSE)
2140 pAd->StaCfg.WpaState = SS_START;
2141 // Clear Replay counter
2142 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2144 #ifdef QOS_DLS_SUPPORT
2145 if (pAd->CommonCfg.bDLSCapable)
2146 NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
2147 #endif // QOS_DLS_SUPPORT //
2152 // if link down come from AP, we need to remove all WPA keys on WPA mode.
2153 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
2155 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
2157 // Remove all WPA keys
2158 RTMPWPARemoveAllKeys(pAd);
2161 // 802.1x port control
2162 #ifdef WPA_SUPPLICANT_SUPPORT
2163 // Prevent clear PortSecured here with static WEP
2164 // NetworkManger set security policy first then set SSID to connect AP.
2165 if (pAd->StaCfg.WpaSupplicantUP &&
2166 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
2167 (pAd->StaCfg.IEEE8021X == FALSE))
2169 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2171 else
2172 #endif // WPA_SUPPLICANT_SUPPORT //
2174 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2175 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2178 NdisAcquireSpinLock(&pAd->MacTabLock);
2179 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2180 NdisReleaseSpinLock(&pAd->MacTabLock);
2182 pAd->StaCfg.MicErrCnt = 0;
2184 // Turn off Ckip control flag
2185 pAd->StaCfg.bCkipOn = FALSE;
2186 pAd->StaCfg.CCXEnable = FALSE;
2188 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2189 // Update extra information to link is up
2190 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2192 pAd->StaCfg.AdhocBOnlyJoined = FALSE;
2193 pAd->StaCfg.AdhocBGJoined = FALSE;
2194 pAd->StaCfg.Adhoc20NJoined = FALSE;
2195 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2197 // Reset the Current AP's IP address
2198 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
2200 // Clean association information
2201 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
2202 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
2203 pAd->StaCfg.ReqVarIELen = 0;
2204 pAd->StaCfg.ResVarIELen = 0;
2207 // Reset RSSI value after link down
2209 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2210 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2211 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2212 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2213 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2214 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2216 // Restore MlmeRate
2217 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2218 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2220 #ifdef DOT11_N_SUPPORT
2222 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
2224 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
2226 pAd->CommonCfg.BBPCurrentBW = BW_20;
2227 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2228 ByteValue &= (~0x18);
2229 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2231 #endif // DOT11_N_SUPPORT //
2232 // Reset DAC
2233 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2234 ByteValue &= (~0x18);
2235 if (pAd->Antenna.field.TxPath == 2)
2237 ByteValue |= 0x10;
2239 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2241 RTMPSetPiggyBack(pAd,FALSE);
2242 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2244 #ifdef DOT11_N_SUPPORT
2245 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2246 #endif // DOT11_N_SUPPORT //
2248 // Restore all settings in the following.
2249 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2250 AsicDisableRDG(pAd);
2251 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2252 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2254 #ifdef DOT11_N_SUPPORT
2255 #ifdef DOT11N_DRAFT3
2256 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
2257 pAd->CommonCfg.BSSCoexist2040.word = 0;
2258 TriEventInit(pAd);
2259 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
2261 pAd->ChannelList[i].bEffectedChannel = FALSE;
2263 #endif // DOT11N_DRAFT3 //
2264 #endif // DOT11_N_SUPPORT //
2266 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2267 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2269 #ifdef WPA_SUPPLICANT_SUPPORT
2270 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2271 if (pAd->StaCfg.WpaSupplicantUP) {
2272 union iwreq_data wrqu;
2273 //send disassociate event to wpa_supplicant
2274 memset(&wrqu, 0, sizeof(wrqu));
2275 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2276 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2278 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2279 #endif // WPA_SUPPLICANT_SUPPORT //
2281 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2283 union iwreq_data wrqu;
2284 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2285 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2287 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2291 ==========================================================================
2292 Description:
2294 IRQL = DISPATCH_LEVEL
2296 ==========================================================================
2298 VOID IterateOnBssTab(
2299 IN PRTMP_ADAPTER pAd)
2301 MLME_START_REQ_STRUCT StartReq;
2302 MLME_JOIN_REQ_STRUCT JoinReq;
2303 ULONG BssIdx;
2305 // Change the wepstatus to original wepstatus
2306 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2307 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2308 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2310 BssIdx = pAd->MlmeAux.BssIdx;
2311 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2313 // Check cipher suite, AP must have more secured cipher than station setting
2314 // Set the Pairwise and Group cipher to match the intended AP setting
2315 // We can only connect to AP with less secured cipher setting
2316 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2318 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2320 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2321 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2322 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2323 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2324 else // There is no PairCipher Aux, downgrade our capability to TKIP
2325 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2327 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2329 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2331 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2332 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2333 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2334 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2335 else // There is no PairCipher Aux, downgrade our capability to TKIP
2336 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2338 // RSN capability
2339 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2342 // Set Mix cipher flag
2343 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2344 if (pAd->StaCfg.bMixCipher == TRUE)
2346 // If mix cipher, re-build RSNIE
2347 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2350 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2351 JoinParmFill(pAd, &JoinReq, BssIdx);
2352 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2353 &JoinReq);
2354 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2356 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2358 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2359 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2360 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2361 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2363 else // no more BSS
2365 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2366 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2367 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2368 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2372 // for re-association only
2373 // IRQL = DISPATCH_LEVEL
2374 VOID IterateOnBssTab2(
2375 IN PRTMP_ADAPTER pAd)
2377 MLME_REASSOC_REQ_STRUCT ReassocReq;
2378 ULONG BssIdx;
2379 BSS_ENTRY *pBss;
2381 BssIdx = pAd->MlmeAux.RoamIdx;
2382 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2384 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2386 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2388 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2389 AsicLockChannel(pAd, pBss->Channel);
2391 // reassociate message has the same structure as associate message
2392 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2393 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2394 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2395 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2397 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2399 else // no more BSS
2401 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2402 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2403 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2404 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2409 ==========================================================================
2410 Description:
2412 IRQL = DISPATCH_LEVEL
2414 ==========================================================================
2416 VOID JoinParmFill(
2417 IN PRTMP_ADAPTER pAd,
2418 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2419 IN ULONG BssIdx)
2421 JoinReq->BssIdx = BssIdx;
2425 ==========================================================================
2426 Description:
2428 IRQL = DISPATCH_LEVEL
2430 ==========================================================================
2432 VOID ScanParmFill(
2433 IN PRTMP_ADAPTER pAd,
2434 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2435 IN CHAR Ssid[],
2436 IN UCHAR SsidLen,
2437 IN UCHAR BssType,
2438 IN UCHAR ScanType)
2440 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2441 ScanReq->SsidLen = SsidLen;
2442 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2443 ScanReq->BssType = BssType;
2444 ScanReq->ScanType = ScanType;
2447 #ifdef QOS_DLS_SUPPORT
2449 ==========================================================================
2450 Description:
2452 IRQL = DISPATCH_LEVEL
2454 ==========================================================================
2456 VOID DlsParmFill(
2457 IN PRTMP_ADAPTER pAd,
2458 IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
2459 IN PRT_802_11_DLS pDls,
2460 IN USHORT reason)
2462 pDlsReq->pDLS = pDls;
2463 pDlsReq->Reason = reason;
2465 #endif // QOS_DLS_SUPPORT //
2468 ==========================================================================
2469 Description:
2471 IRQL = DISPATCH_LEVEL
2473 ==========================================================================
2475 VOID StartParmFill(
2476 IN PRTMP_ADAPTER pAd,
2477 IN OUT MLME_START_REQ_STRUCT *StartReq,
2478 IN CHAR Ssid[],
2479 IN UCHAR SsidLen)
2481 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2482 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2483 StartReq->SsidLen = SsidLen;
2487 ==========================================================================
2488 Description:
2490 IRQL = DISPATCH_LEVEL
2492 ==========================================================================
2494 VOID AuthParmFill(
2495 IN PRTMP_ADAPTER pAd,
2496 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2497 IN PUCHAR pAddr,
2498 IN USHORT Alg)
2500 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2501 AuthReq->Alg = Alg;
2502 AuthReq->Timeout = AUTH_TIMEOUT;
2506 ==========================================================================
2507 Description:
2509 IRQL = DISPATCH_LEVEL
2511 ==========================================================================
2513 #ifdef RT2860
2514 VOID ComposePsPoll(
2515 IN PRTMP_ADAPTER pAd)
2517 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2518 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2519 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2520 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2521 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2522 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2525 // IRQL = DISPATCH_LEVEL
2526 VOID ComposeNullFrame(
2527 IN PRTMP_ADAPTER pAd)
2529 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2530 pAd->NullFrame.FC.Type = BTYPE_DATA;
2531 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2532 pAd->NullFrame.FC.ToDs = 1;
2533 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2534 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2535 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2537 #endif // RT2860 //
2543 ==========================================================================
2544 Description:
2545 Pre-build a BEACON frame in the shared memory
2547 IRQL = PASSIVE_LEVEL
2548 IRQL = DISPATCH_LEVEL
2550 ==========================================================================
2552 ULONG MakeIbssBeacon(
2553 IN PRTMP_ADAPTER pAd)
2555 UCHAR DsLen = 1, IbssLen = 2;
2556 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2557 HEADER_802_11 BcnHdr;
2558 USHORT CapabilityInfo;
2559 LARGE_INTEGER FakeTimestamp;
2560 ULONG FrameLen = 0;
2561 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2562 CHAR *pBeaconFrame = pAd->BeaconBuf;
2563 BOOLEAN Privacy;
2564 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2565 UCHAR SupRateLen = 0;
2566 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2567 UCHAR ExtRateLen = 0;
2568 UCHAR RSNIe = IE_WPA;
2570 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2572 SupRate[0] = 0x82; // 1 mbps
2573 SupRate[1] = 0x84; // 2 mbps
2574 SupRate[2] = 0x8b; // 5.5 mbps
2575 SupRate[3] = 0x96; // 11 mbps
2576 SupRateLen = 4;
2577 ExtRateLen = 0;
2579 else if (pAd->CommonCfg.Channel > 14)
2581 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2582 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2583 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2584 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2585 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2586 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2587 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2588 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2589 SupRateLen = 8;
2590 ExtRateLen = 0;
2593 // Also Update MlmeRate & RtsRate for G only & A only
2595 pAd->CommonCfg.MlmeRate = RATE_6;
2596 pAd->CommonCfg.RtsRate = RATE_6;
2597 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2598 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2599 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2600 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2602 else
2604 SupRate[0] = 0x82; // 1 mbps
2605 SupRate[1] = 0x84; // 2 mbps
2606 SupRate[2] = 0x8b; // 5.5 mbps
2607 SupRate[3] = 0x96; // 11 mbps
2608 SupRateLen = 4;
2610 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2611 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2612 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2613 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2614 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2615 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2616 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2617 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2618 ExtRateLen = 8;
2621 pAd->StaActive.SupRateLen = SupRateLen;
2622 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2623 pAd->StaActive.ExtRateLen = ExtRateLen;
2624 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2626 // compose IBSS beacon frame
2627 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2628 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2629 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2630 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2631 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2633 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2634 sizeof(HEADER_802_11), &BcnHdr,
2635 TIMESTAMP_LEN, &FakeTimestamp,
2636 2, &pAd->CommonCfg.BeaconPeriod,
2637 2, &CapabilityInfo,
2638 1, &SsidIe,
2639 1, &pAd->CommonCfg.SsidLen,
2640 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2641 1, &SupRateIe,
2642 1, &SupRateLen,
2643 SupRateLen, SupRate,
2644 1, &DsIe,
2645 1, &DsLen,
2646 1, &pAd->CommonCfg.Channel,
2647 1, &IbssIe,
2648 1, &IbssLen,
2649 2, &pAd->StaActive.AtimWin,
2650 END_OF_ARGS);
2652 // add ERP_IE and EXT_RAE IE of in 802.11g
2653 if (ExtRateLen)
2655 ULONG tmp;
2657 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2658 3, LocalErpIe,
2659 1, &ExtRateIe,
2660 1, &ExtRateLen,
2661 ExtRateLen, ExtRate,
2662 END_OF_ARGS);
2663 FrameLen += tmp;
2666 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2667 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2669 ULONG tmp;
2670 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2672 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2673 1, &RSNIe,
2674 1, &pAd->StaCfg.RSNIE_Len,
2675 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2676 END_OF_ARGS);
2677 FrameLen += tmp;
2680 #ifdef DOT11_N_SUPPORT
2681 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2683 ULONG TmpLen;
2684 UCHAR HtLen, HtLen1;
2686 #ifdef RT_BIG_ENDIAN
2687 HT_CAPABILITY_IE HtCapabilityTmp;
2688 ADD_HT_INFO_IE addHTInfoTmp;
2689 USHORT b2lTmp, b2lTmp2;
2690 #endif
2692 // add HT Capability IE
2693 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2694 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2695 #ifndef RT_BIG_ENDIAN
2696 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2697 1, &HtCapIe,
2698 1, &HtLen,
2699 HtLen, &pAd->CommonCfg.HtCapability,
2700 1, &AddHtInfoIe,
2701 1, &HtLen1,
2702 HtLen1, &pAd->CommonCfg.AddHTInfo,
2703 END_OF_ARGS);
2704 #else
2705 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2706 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2707 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2709 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2710 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2711 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2713 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2714 1, &HtCapIe,
2715 1, &HtLen,
2716 HtLen, &HtCapabilityTmp,
2717 1, &AddHtInfoIe,
2718 1, &HtLen1,
2719 HtLen1, &addHTInfoTmp,
2720 END_OF_ARGS);
2721 #endif
2722 FrameLen += TmpLen;
2724 #endif // DOT11_N_SUPPORT //
2726 //beacon use reserved WCID 0xff
2727 if (pAd->CommonCfg.Channel > 14)
2729 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2730 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2732 else
2734 // Set to use 1Mbps for Adhoc beacon.
2735 HTTRANSMIT_SETTING Transmit;
2736 Transmit.word = 0;
2737 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2738 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2741 #ifdef RT_BIG_ENDIAN
2742 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2743 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2744 #endif
2746 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2747 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));
2748 return FrameLen;