Staging: rt2870: remove dead DOT11N_DRAFT3 code
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rt2870 / sta / connect.c
blob210c0a05a9a03c550486990c9dbf8d5220485d79
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:
126 CntlIdleProc(pAd, Elem);
127 break;
128 case CNTL_WAIT_DISASSOC:
129 CntlWaitDisassocProc(pAd, Elem);
130 break;
131 case CNTL_WAIT_JOIN:
132 CntlWaitJoinProc(pAd, Elem);
133 break;
135 // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
136 // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
137 // Therefore not protected by NDIS's "only one outstanding OID request"
138 // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
139 // Current approach is to block new SET request at RTMPSetInformation()
140 // when CntlMachine.CurrState is not CNTL_IDLE
141 case CNTL_WAIT_REASSOC:
142 CntlWaitReassocProc(pAd, Elem);
143 break;
145 case CNTL_WAIT_START:
146 CntlWaitStartProc(pAd, Elem);
147 break;
148 case CNTL_WAIT_AUTH:
149 CntlWaitAuthProc(pAd, Elem);
150 break;
151 case CNTL_WAIT_AUTH2:
152 CntlWaitAuthProc2(pAd, Elem);
153 break;
154 case CNTL_WAIT_ASSOC:
155 CntlWaitAssocProc(pAd, Elem);
156 break;
158 case CNTL_WAIT_OID_LIST_SCAN:
159 if(Elem->MsgType == MT2_SCAN_CONF)
161 // Resume TxRing after SCANING complete. We hope the out-of-service time
162 // won't be too long to let upper layer time-out the waiting frames
163 RTMPResumeMsduTransmission(pAd);
164 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
166 // Cisco scan request is finished, prepare beacon report
167 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
169 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
172 // Set LED status to previous status.
174 if (pAd->bLedOnScanning)
176 pAd->bLedOnScanning = FALSE;
177 RTMPSetLED(pAd, pAd->LedStatus);
180 break;
182 case CNTL_WAIT_OID_DISASSOC:
183 if (Elem->MsgType == MT2_DISASSOC_CONF)
185 LinkDown(pAd, FALSE);
186 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
188 break;
189 #ifdef RT2870
191 // This state is for that we want to connect to an AP but
192 // it didn't find on BSS List table. So we need to scan the air first,
193 // after that we can try to connect to the desired AP if available.
195 case CNTL_WAIT_SCAN_FOR_CONNECT:
196 if(Elem->MsgType == MT2_SCAN_CONF)
198 // Resume TxRing after SCANING complete. We hope the out-of-service time
199 // won't be too long to let upper layer time-out the waiting frames
200 RTMPResumeMsduTransmission(pAd);
201 #ifdef CCX_SUPPORT
202 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
204 // Cisco scan request is finished, prepare beacon report
205 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
207 #endif // CCX_SUPPORT //
208 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
211 // Check if we can connect to.
213 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
214 if (pAd->MlmeAux.SsidBssTab.BssNr > 0)
216 MlmeAutoReconnectLastSSID(pAd);
219 break;
220 #endif // RT2870 //
221 default:
222 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
223 break;
229 ==========================================================================
230 Description:
232 IRQL = DISPATCH_LEVEL
234 ==========================================================================
236 VOID CntlIdleProc(
237 IN PRTMP_ADAPTER pAd,
238 IN MLME_QUEUE_ELEM *Elem)
240 MLME_DISASSOC_REQ_STRUCT DisassocReq;
242 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
243 return;
245 switch(Elem->MsgType)
247 case OID_802_11_SSID:
248 CntlOidSsidProc(pAd, Elem);
249 break;
251 case OID_802_11_BSSID:
252 CntlOidRTBssidProc(pAd,Elem);
253 break;
255 case OID_802_11_BSSID_LIST_SCAN:
256 CntlOidScanProc(pAd,Elem);
257 break;
259 case OID_802_11_DISASSOCIATE:
260 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
261 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
262 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
263 #ifdef WPA_SUPPLICANT_SUPPORT
264 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
265 #endif // WPA_SUPPLICANT_SUPPORT //
267 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
268 // Since calling this indicate user don't want to connect to that SSID anymore.
269 pAd->MlmeAux.AutoReconnectSsidLen= 32;
270 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
272 break;
274 case MT2_MLME_ROAMING_REQ:
275 CntlMlmeRoamingProc(pAd, Elem);
276 break;
278 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
279 WpaMicFailureReportFrame(pAd, Elem);
280 break;
282 default:
283 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
284 break;
288 VOID CntlOidScanProc(
289 IN PRTMP_ADAPTER pAd,
290 IN MLME_QUEUE_ELEM *Elem)
292 MLME_SCAN_REQ_STRUCT ScanReq;
293 ULONG BssIdx = BSS_NOT_FOUND;
294 BSS_ENTRY CurrBss;
296 // record current BSS if network is connected.
297 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
298 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
300 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
301 if (BssIdx != BSS_NOT_FOUND)
303 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
307 // clean up previous SCAN result, add current BSS back to table if any
308 BssTableInit(&pAd->ScanTab);
309 if (BssIdx != BSS_NOT_FOUND)
311 // DDK Note: If the NIC is associated with a particular BSSID and SSID
312 // that are not contained in the list of BSSIDs generated by this scan, the
313 // BSSID description of the currently associated BSSID and SSID should be
314 // appended to the list of BSSIDs in the NIC's database.
315 // To ensure this, we append this BSS as the first entry in SCAN result
316 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
317 pAd->ScanTab.BssNr = 1;
320 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
321 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
322 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
323 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
327 ==========================================================================
328 Description:
329 Before calling this routine, user desired SSID should already been
330 recorded in CommonCfg.Ssid[]
331 IRQL = DISPATCH_LEVEL
333 ==========================================================================
335 VOID CntlOidSsidProc(
336 IN PRTMP_ADAPTER pAd,
337 IN MLME_QUEUE_ELEM * Elem)
339 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
340 MLME_DISASSOC_REQ_STRUCT DisassocReq;
341 ULONG Now;
343 // Step 1. record the desired user settings to MlmeAux
344 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
345 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
346 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
347 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
348 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
352 // Update Reconnect Ssid, that user desired to connect.
354 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
355 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
356 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
358 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
359 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
360 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
362 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
363 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
364 NdisGetSystemUpTime(&Now);
366 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
367 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
368 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
369 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
371 // Case 1. already connected with an AP who has the desired SSID
372 // with highest RSSI
374 // Add checking Mode "LEAP" for CCX 1.0
375 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
376 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
377 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
378 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
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 // record user desired settings
513 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
514 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
517 // Update Reconnect Ssid, that user desired to connect.
519 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
520 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
521 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
523 // find the desired BSS in the latest SCAN result table
524 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
525 if (BssIdx == BSS_NOT_FOUND)
527 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
528 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
529 return;
532 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
533 // Because we need this entry to become the JOIN target in later on SYNC state machine
534 pAd->MlmeAux.BssIdx = 0;
535 pAd->MlmeAux.SsidBssTab.BssNr = 1;
536 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
538 //pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
539 //NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
541 // Add SSID into MlmeAux for site surey joining hidden SSID
542 //pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
543 //NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
545 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
546 // we just follow normal procedure. The reason of user doing this may because he/she changed
547 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
548 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
549 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
550 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
551 // connection when setting the same BSSID.
552 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
553 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
555 // already connected to the same BSSID, go back to idle state directly
556 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
557 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
558 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
560 union iwreq_data wrqu;
562 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
563 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
564 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
567 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
569 else
571 if (INFRA_ON(pAd))
573 // disassoc from current AP first
574 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
575 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
576 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
577 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
579 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
581 else
583 if (ADHOC_ON(pAd))
585 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
586 LinkDown(pAd, FALSE);
587 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
588 pAd->IndicateMediaState = NdisMediaStateDisconnected;
589 RTMP_IndicateMediaState(pAd);
590 pAd->ExtraInfo = GENERAL_LINK_DOWN;
591 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
594 // Change the wepstatus to original wepstatus
595 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
596 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
597 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
599 // Check cipher suite, AP must have more secured cipher than station setting
600 // Set the Pairwise and Group cipher to match the intended AP setting
601 // We can only connect to AP with less secured cipher setting
602 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
604 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
606 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
607 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
608 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
609 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
610 else // There is no PairCipher Aux, downgrade our capability to TKIP
611 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
613 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
615 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
617 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
618 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
619 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
620 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
621 else // There is no PairCipher Aux, downgrade our capability to TKIP
622 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
624 // RSN capability
625 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
628 // Set Mix cipher flag
629 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
630 if (pAd->StaCfg.bMixCipher == TRUE)
632 // If mix cipher, re-build RSNIE
633 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
635 // No active association, join the BSS immediately
636 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
637 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
639 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
640 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
642 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
647 // Roaming is the only external request triggering CNTL state machine
648 // despite of other "SET OID" operation. All "SET OID" related oerations
649 // happen in sequence, because no other SET OID will be sent to this device
650 // until the the previous SET operation is complete (successful o failed).
651 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
652 // or been corrupted by other "SET OID"?
654 // IRQL = DISPATCH_LEVEL
655 VOID CntlMlmeRoamingProc(
656 IN PRTMP_ADAPTER pAd,
657 IN MLME_QUEUE_ELEM *Elem)
659 // TODO:
660 // AP in different channel may show lower RSSI than actual value??
661 // should we add a weighting factor to compensate it?
662 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
664 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
665 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
667 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
668 pAd->MlmeAux.BssIdx = 0;
669 IterateOnBssTab(pAd);
673 ==========================================================================
674 Description:
676 IRQL = DISPATCH_LEVEL
678 ==========================================================================
680 VOID CntlWaitDisassocProc(
681 IN PRTMP_ADAPTER pAd,
682 IN MLME_QUEUE_ELEM *Elem)
684 MLME_START_REQ_STRUCT StartReq;
686 if (Elem->MsgType == MT2_DISASSOC_CONF)
688 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
690 if (pAd->CommonCfg.bWirelessEvent)
692 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
695 LinkDown(pAd, FALSE);
697 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
698 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
700 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
701 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
702 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
703 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
705 // case 2. try each matched BSS
706 else
708 pAd->MlmeAux.BssIdx = 0;
710 IterateOnBssTab(pAd);
716 ==========================================================================
717 Description:
719 IRQL = DISPATCH_LEVEL
721 ==========================================================================
723 VOID CntlWaitJoinProc(
724 IN PRTMP_ADAPTER pAd,
725 IN MLME_QUEUE_ELEM *Elem)
727 USHORT Reason;
728 MLME_AUTH_REQ_STRUCT AuthReq;
730 if (Elem->MsgType == MT2_JOIN_CONF)
732 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
733 if (Reason == MLME_SUCCESS)
735 // 1. joined an IBSS, we are pretty much done here
736 if (pAd->MlmeAux.BssType == BSS_ADHOC)
739 // 5G bands rules of Japan:
740 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
742 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
743 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
746 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
747 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
748 return;
751 LinkUp(pAd, BSS_ADHOC);
752 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
753 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
754 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
755 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
757 pAd->IndicateMediaState = NdisMediaStateConnected;
758 pAd->ExtraInfo = GENERAL_LINK_UP;
760 // 2. joined a new INFRA network, start from authentication
761 else
764 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
765 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
766 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
768 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
770 else
772 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
775 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
776 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
778 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
781 else
783 // 3. failed, try next BSS
784 pAd->MlmeAux.BssIdx++;
785 IterateOnBssTab(pAd);
792 ==========================================================================
793 Description:
795 IRQL = DISPATCH_LEVEL
797 ==========================================================================
799 VOID CntlWaitStartProc(
800 IN PRTMP_ADAPTER pAd,
801 IN MLME_QUEUE_ELEM *Elem)
803 USHORT Result;
805 if (Elem->MsgType == MT2_START_CONF)
807 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
808 if (Result == MLME_SUCCESS)
811 // 5G bands rules of Japan:
812 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
814 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
815 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
818 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
819 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
820 return;
822 #ifdef DOT11_N_SUPPORT
823 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
825 N_ChannelCheck(pAd);
826 SetCommonHT(pAd);
827 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
828 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
829 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
830 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
831 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
832 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
834 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
835 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
837 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
839 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
840 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
842 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
845 else
846 #endif // DOT11_N_SUPPORT //
848 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
850 LinkUp(pAd, BSS_ADHOC);
851 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
852 // Before send beacon, driver need do radar detection
853 if ((pAd->CommonCfg.Channel > 14 )
854 && (pAd->CommonCfg.bIEEE80211H == 1)
855 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
857 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
858 pAd->CommonCfg.RadarDetect.RDCount = 0;
861 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
862 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
863 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
865 else
867 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
868 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
874 ==========================================================================
875 Description:
877 IRQL = DISPATCH_LEVEL
879 ==========================================================================
881 VOID CntlWaitAuthProc(
882 IN PRTMP_ADAPTER pAd,
883 IN MLME_QUEUE_ELEM *Elem)
885 USHORT Reason;
886 MLME_ASSOC_REQ_STRUCT AssocReq;
887 MLME_AUTH_REQ_STRUCT AuthReq;
889 if (Elem->MsgType == MT2_AUTH_CONF)
891 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
892 if (Reason == MLME_SUCCESS)
894 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
895 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
896 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
899 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
900 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
902 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
905 else
907 // This fail may because of the AP already keep us in its MAC table without
908 // ageing-out. The previous authentication attempt must have let it remove us.
909 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
910 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
913 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
914 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
916 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
917 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
919 else
921 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
924 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
925 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
927 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
933 ==========================================================================
934 Description:
936 IRQL = DISPATCH_LEVEL
938 ==========================================================================
940 VOID CntlWaitAuthProc2(
941 IN PRTMP_ADAPTER pAd,
942 IN MLME_QUEUE_ELEM *Elem)
944 USHORT Reason;
945 MLME_ASSOC_REQ_STRUCT AssocReq;
946 MLME_AUTH_REQ_STRUCT AuthReq;
948 if (Elem->MsgType == MT2_AUTH_CONF)
950 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
951 if (Reason == MLME_SUCCESS)
953 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
954 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
955 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
956 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
957 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
959 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
961 else
963 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
964 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
966 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
967 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
968 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
969 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
971 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
973 else
975 // not success, try next BSS
976 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
977 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
978 pAd->MlmeAux.BssIdx++;
979 IterateOnBssTab(pAd);
986 ==========================================================================
987 Description:
989 IRQL = DISPATCH_LEVEL
991 ==========================================================================
993 VOID CntlWaitAssocProc(
994 IN PRTMP_ADAPTER pAd,
995 IN MLME_QUEUE_ELEM *Elem)
997 USHORT Reason;
999 if (Elem->MsgType == MT2_ASSOC_CONF)
1001 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1002 if (Reason == MLME_SUCCESS)
1004 LinkUp(pAd, BSS_INFRA);
1005 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1006 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1008 if (pAd->CommonCfg.bWirelessEvent)
1010 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1013 else
1015 // not success, try next BSS
1016 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1017 pAd->MlmeAux.BssIdx++;
1018 IterateOnBssTab(pAd);
1024 ==========================================================================
1025 Description:
1027 IRQL = DISPATCH_LEVEL
1029 ==========================================================================
1031 VOID CntlWaitReassocProc(
1032 IN PRTMP_ADAPTER pAd,
1033 IN MLME_QUEUE_ELEM *Elem)
1035 USHORT Result;
1037 if (Elem->MsgType == MT2_REASSOC_CONF)
1039 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1040 if (Result == MLME_SUCCESS)
1043 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1045 LinkUp(pAd, BSS_INFRA);
1047 // send wireless event - for association
1048 if (pAd->CommonCfg.bWirelessEvent)
1049 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1051 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1052 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1054 else
1056 // reassoc failed, try to pick next BSS in the BSS Table
1057 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1058 pAd->MlmeAux.RoamIdx++;
1059 IterateOnBssTab2(pAd);
1065 VOID AdhocTurnOnQos(
1066 IN PRTMP_ADAPTER pAd)
1068 #define AC0_DEF_TXOP 0
1069 #define AC1_DEF_TXOP 0
1070 #define AC2_DEF_TXOP 94
1071 #define AC3_DEF_TXOP 47
1073 // Turn on QOs if use HT rate.
1074 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1076 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1077 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1078 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1079 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1080 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1082 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1083 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1084 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1085 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1087 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1088 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1089 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1090 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1092 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1093 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1094 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1095 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1097 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1101 ==========================================================================
1102 Description:
1104 IRQL = DISPATCH_LEVEL
1106 ==========================================================================
1108 VOID LinkUp(
1109 IN PRTMP_ADAPTER pAd,
1110 IN UCHAR BssType)
1112 ULONG Now;
1113 UINT32 Data;
1114 BOOLEAN Cancelled;
1115 UCHAR Value = 0, idx;
1116 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1118 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1121 // ASSOC - DisassocTimeoutAction
1122 // CNTL - Dis-associate successful
1123 // !!! LINK DOWN !!!
1124 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1126 // To prevent DisassocTimeoutAction to call Link down after we link up,
1127 // cancel the DisassocTimer no matter what it start or not.
1129 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1131 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1133 #ifdef DOT11_N_SUPPORT
1134 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1135 #endif // DOT11_N_SUPPORT //
1136 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1137 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1138 // to examine if cipher algorithm switching is required.
1139 //rt2860b. Don't know why need this
1140 SwitchBetweenWepAndCkip(pAd);
1143 if (BssType == BSS_ADHOC)
1145 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1146 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1148 #ifdef DOT11_N_SUPPORT
1149 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1150 AdhocTurnOnQos(pAd);
1151 #endif // DOT11_N_SUPPORT //
1153 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1155 else
1157 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1158 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1160 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1163 // 3*3
1164 // reset Tx beamforming bit
1165 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1166 Value &= (~0x01);
1167 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1168 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1170 #ifdef DOT11_N_SUPPORT
1171 // Change to AP channel
1172 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1174 // Must using 40MHz.
1175 pAd->CommonCfg.BBPCurrentBW = BW_40;
1176 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1177 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1179 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1180 Value &= (~0x18);
1181 Value |= 0x10;
1182 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1184 // RX : control channel at lower
1185 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1186 Value &= (~0x20);
1187 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1189 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1190 Data &= 0xfffffffe;
1191 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1193 if (pAd->MACVersion == 0x28600100)
1195 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1196 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1197 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1198 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1201 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1203 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1205 // Must using 40MHz.
1206 pAd->CommonCfg.BBPCurrentBW = BW_40;
1207 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1208 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1210 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1211 Value &= (~0x18);
1212 Value |= 0x10;
1213 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1215 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1216 Data |= 0x1;
1217 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1219 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1220 Value |= (0x20);
1221 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1223 if (pAd->MACVersion == 0x28600100)
1225 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1226 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1227 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1228 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1231 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1233 else
1234 #endif // DOT11_N_SUPPORT //
1236 pAd->CommonCfg.BBPCurrentBW = BW_20;
1237 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1238 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1239 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1241 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1242 Value &= (~0x18);
1243 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1245 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1246 Data &= 0xfffffffe;
1247 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1249 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1250 Value &= (~0x20);
1251 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1253 if (pAd->MACVersion == 0x28600100)
1255 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1256 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1257 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1258 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1261 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1264 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1266 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1268 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1270 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1271 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1273 #ifdef DOT11_N_SUPPORT
1274 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1275 #endif // DOT11_N_SUPPORT //
1277 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1279 AsicSetSlotTime(pAd, TRUE);
1280 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1282 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1283 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1285 #ifdef DOT11_N_SUPPORT
1286 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1288 // Update HT protectionfor based on AP's operating mode.
1289 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1291 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1293 else
1294 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1296 #endif // DOT11_N_SUPPORT //
1298 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1300 NdisGetSystemUpTime(&Now);
1301 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1303 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1304 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1306 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1309 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1311 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1314 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1316 if (BssType == BSS_ADHOC)
1318 MakeIbssBeacon(pAd);
1319 if ((pAd->CommonCfg.Channel > 14)
1320 && (pAd->CommonCfg.bIEEE80211H == 1)
1321 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1323 ; //Do nothing
1325 else
1327 AsicEnableIbssSync(pAd);
1330 // In ad hoc mode, use MAC table from index 1.
1331 // 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.
1332 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1333 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1335 // If WEP is enabled, add key material and cipherAlg into Asic
1336 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1338 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1340 PUCHAR Key;
1341 UCHAR CipherAlg;
1343 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1345 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1346 Key = pAd->SharedKey[BSS0][idx].Key;
1348 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1350 // Set key material and cipherAlg to Asic
1351 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1353 if (idx == pAd->StaCfg.DefaultKeyId)
1355 // Update WCID attribute table and IVEIV table for this group key table
1356 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1363 // If WPANone is enabled, add key material and cipherAlg into Asic
1364 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1365 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1367 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1369 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1370 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1371 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1373 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1375 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1376 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1379 // Decide its ChiperAlg
1380 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1381 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1382 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1383 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1384 else
1386 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1387 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1390 // Set key material and cipherAlg to Asic
1391 AsicAddSharedKeyEntry(pAd,
1392 BSS0,
1394 pAd->SharedKey[BSS0][0].CipherAlg,
1395 pAd->SharedKey[BSS0][0].Key,
1396 pAd->SharedKey[BSS0][0].TxMic,
1397 pAd->SharedKey[BSS0][0].RxMic);
1399 // Update WCID attribute table and IVEIV table for this group key table
1400 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1405 else // BSS_INFRA
1407 // Check the new SSID with last SSID
1408 while (Cancelled == TRUE)
1410 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1412 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1414 // Link to the old one no linkdown is required.
1415 break;
1418 // Send link down event before set to link up
1419 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1420 RTMP_IndicateMediaState(pAd);
1421 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1422 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1423 break;
1427 // On WPA mode, Remove All Keys if not connect to the last BSSID
1428 // Key will be set after 4-way handshake.
1430 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1432 ULONG IV;
1434 // Remove all WPA keys
1435 RTMPWPARemoveAllKeys(pAd);
1436 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1437 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1439 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1440 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1441 IV = 0;
1442 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1443 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1445 // NOTE:
1446 // the decision of using "short slot time" or not may change dynamically due to
1447 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1449 // NOTE:
1450 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1451 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1453 ComposePsPoll(pAd);
1454 ComposeNullFrame(pAd);
1456 AsicEnableBssSync(pAd);
1458 // Add BSSID to WCID search table
1459 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1461 NdisAcquireSpinLock(&pAd->MacTabLock);
1462 // add this BSSID entry into HASH table
1464 UCHAR HashIdx;
1466 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1467 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1468 if (pAd->MacTab.Hash[HashIdx] == NULL)
1470 pAd->MacTab.Hash[HashIdx] = pEntry;
1472 else
1474 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1475 while (pCurrEntry->pNext != NULL)
1476 pCurrEntry = pCurrEntry->pNext;
1477 pCurrEntry->pNext = pEntry;
1480 NdisReleaseSpinLock(&pAd->MacTabLock);
1483 // If WEP is enabled, add paiewise and shared key
1484 #ifdef WPA_SUPPLICANT_SUPPORT
1485 if (((pAd->StaCfg.WpaSupplicantUP)&&
1486 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1487 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1488 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1489 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1490 #else
1491 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1492 #endif // WPA_SUPPLICANT_SUPPORT //
1494 PUCHAR Key;
1495 UCHAR CipherAlg;
1497 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1499 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1500 Key = pAd->SharedKey[BSS0][idx].Key;
1502 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1504 // Set key material and cipherAlg to Asic
1505 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1507 if (idx == pAd->StaCfg.DefaultKeyId)
1509 // Assign group key info
1510 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1512 // Assign pairwise key info
1513 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1519 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1520 // should wait until at least 2 active nodes in this BSSID.
1521 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1523 // For GUI ++
1524 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1526 pAd->IndicateMediaState = NdisMediaStateConnected;
1527 pAd->ExtraInfo = GENERAL_LINK_UP;
1528 RTMP_IndicateMediaState(pAd);
1530 // --
1532 // Add BSSID in my MAC Table.
1533 NdisAcquireSpinLock(&pAd->MacTabLock);
1534 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1535 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1536 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1537 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1538 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1539 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1540 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1541 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1542 NdisReleaseSpinLock(&pAd->MacTabLock);
1544 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1545 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1547 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1548 #ifdef DOT11_N_SUPPORT
1549 MlmeUpdateHtTxRates(pAd, BSS0);
1550 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1551 #endif // DOT11_N_SUPPORT //
1553 if (pAd->CommonCfg.bAggregationCapable)
1555 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1558 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1559 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1560 RTMPSetPiggyBack(pAd, TRUE);
1561 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1563 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1565 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1569 if (pAd->MlmeAux.APRalinkIe != 0x0)
1571 #ifdef DOT11_N_SUPPORT
1572 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1574 AsicEnableRDG(pAd);
1576 #endif // DOT11_N_SUPPORT //
1577 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1578 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1580 else
1582 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1583 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1587 #ifdef DOT11_N_SUPPORT
1588 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));
1589 #endif // DOT11_N_SUPPORT //
1591 // Set LED
1592 RTMPSetLED(pAd, LED_LINK_UP);
1594 pAd->Mlme.PeriodicRound = 0;
1595 pAd->Mlme.OneSecPeriodicRound = 0;
1596 pAd->bConfigChanged = FALSE; // Reset config flag
1597 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1599 // Set asic auto fall back
1601 PUCHAR pTable;
1602 UCHAR TableSize = 0;
1604 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1605 AsicUpdateAutoFallBackTable(pAd, pTable);
1608 NdisAcquireSpinLock(&pAd->MacTabLock);
1609 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1610 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1611 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1613 pEntry->bAutoTxRateSwitch = FALSE;
1614 #ifdef DOT11_N_SUPPORT
1615 if (pEntry->HTPhyMode.field.MCS == 32)
1616 pEntry->HTPhyMode.field.ShortGI = GI_800;
1618 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1619 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1620 #endif // DOT11_N_SUPPORT //
1621 // If the legacy mode is set, overwrite the transmit setting of this entry.
1622 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1623 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1625 else
1626 pEntry->bAutoTxRateSwitch = TRUE;
1627 NdisReleaseSpinLock(&pAd->MacTabLock);
1629 // Let Link Status Page display first initial rate.
1630 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1631 // Select DAC according to HT or Legacy
1632 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1634 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1635 Value &= (~0x18);
1636 if (pAd->Antenna.field.TxPath == 2)
1638 Value |= 0x10;
1640 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1642 else
1644 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1645 Value &= (~0x18);
1646 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1649 #ifdef DOT11_N_SUPPORT
1650 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1653 else if (pEntry->MaxRAmpduFactor == 0)
1655 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1656 // Because our Init value is 1 at MACRegTable.
1657 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1659 #endif // DOT11_N_SUPPORT //
1661 // Patch for Marvel AP to gain high throughput
1662 // Need to set as following,
1663 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1664 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1665 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1666 // 4. kick per two packets when dequeue
1668 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1670 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1671 #ifdef DOT11_N_SUPPORT
1672 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1673 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1675 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1676 Data &= 0xFFFFFF00;
1677 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1679 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1680 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1682 else
1683 #endif // DOT11_N_SUPPORT //
1684 if (pAd->CommonCfg.bEnableTxBurst)
1686 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1687 Data &= 0xFFFFFF00;
1688 Data |= 0x60;
1689 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1690 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1692 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1693 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1695 else
1697 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1698 Data &= 0xFFFFFF00;
1699 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1701 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1702 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1705 #ifdef DOT11_N_SUPPORT
1706 // Re-check to turn on TX burst or not.
1707 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1709 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1710 if (pAd->CommonCfg.bEnableTxBurst)
1712 UINT32 MACValue = 0;
1713 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1714 // I didn't change PBF_MAX_PCNT setting.
1715 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1716 MACValue &= 0xFFFFFF00;
1717 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1718 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1721 else
1723 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1725 #endif // DOT11_N_SUPPORT //
1727 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1728 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1729 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1730 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1731 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1732 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1734 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1736 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1737 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1740 NdisAcquireSpinLock(&pAd->MacTabLock);
1741 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1742 NdisReleaseSpinLock(&pAd->MacTabLock);
1745 // Patch Atheros AP TX will breakdown issue.
1746 // AP Model: DLink DWL-8200AP
1748 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1750 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1752 else
1754 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1757 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1761 ==========================================================================
1763 Routine Description:
1764 Disconnect current BSSID
1766 Arguments:
1767 pAd - Pointer to our adapter
1768 IsReqFromAP - Request from AP
1770 Return Value:
1771 None
1773 IRQL = DISPATCH_LEVEL
1775 Note:
1776 We need more information to know it's this requst from AP.
1777 If yes! we need to do extra handling, for example, remove the WPA key.
1778 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1779 remove while auto reconnect.
1780 Disconnect request from AP, it means we will start afresh 4-way handshaking
1781 on WPA mode.
1783 ==========================================================================
1785 VOID LinkDown(
1786 IN PRTMP_ADAPTER pAd,
1787 IN BOOLEAN IsReqFromAP)
1789 UCHAR i, ByteValue = 0;
1791 // Do nothing if monitor mode is on
1792 if (MONITOR_ON(pAd))
1793 return;
1795 if (pAd->CommonCfg.bWirelessEvent)
1797 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1800 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1801 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1803 if (ADHOC_ON(pAd)) // Adhoc mode link down
1805 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1807 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1808 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1809 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1810 RTMP_IndicateMediaState(pAd);
1811 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1812 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1813 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1815 else // Infra structure mode
1817 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1819 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1820 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1822 // Saved last SSID for linkup comparison
1823 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1824 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
1825 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1826 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
1828 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1829 RTMP_IndicateMediaState(pAd);
1830 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1831 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1832 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1834 else
1837 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
1838 // Otherwise lost beacon or receive De-Authentication from AP,
1839 // then we should delete BSSID from BssTable.
1840 // If we don't delete from entry, roaming will fail.
1842 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1845 // restore back to -
1846 // 1. long slot (20 us) or short slot (9 us) time
1847 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1848 // 3. short preamble
1849 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1851 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
1854 // Record current AP's information.
1855 // for later used reporting Adjacent AP report.
1857 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
1858 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
1859 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
1860 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
1864 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
1866 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1867 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
1870 pAd->StaCfg.CCXQosECWMin = 4;
1871 pAd->StaCfg.CCXQosECWMax = 10;
1873 AsicSetSlotTime(pAd, TRUE); //FALSE);
1874 AsicSetEdcaParm(pAd, NULL);
1876 // Set LED
1877 RTMPSetLED(pAd, LED_LINK_DOWN);
1878 pAd->LedIndicatorStregth = 0xF0;
1879 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
1881 AsicDisableSync(pAd);
1883 pAd->Mlme.PeriodicRound = 0;
1884 pAd->Mlme.OneSecPeriodicRound = 0;
1886 if (pAd->StaCfg.BssType == BSS_INFRA)
1888 // Remove StaCfg Information after link down
1889 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1890 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1891 pAd->CommonCfg.SsidLen = 0;
1893 #ifdef DOT11_N_SUPPORT
1894 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
1895 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
1896 pAd->MlmeAux.HtCapabilityLen = 0;
1897 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1898 #endif // DOT11_N_SUPPORT //
1900 // Reset WPA-PSK state. Only reset when supplicant enabled
1901 if (pAd->StaCfg.WpaState != SS_NOTUSE)
1903 pAd->StaCfg.WpaState = SS_START;
1904 // Clear Replay counter
1905 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1910 // if link down come from AP, we need to remove all WPA keys on WPA mode.
1911 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
1913 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1915 // Remove all WPA keys
1916 RTMPWPARemoveAllKeys(pAd);
1919 // 802.1x port control
1920 #ifdef WPA_SUPPLICANT_SUPPORT
1921 // Prevent clear PortSecured here with static WEP
1922 // NetworkManger set security policy first then set SSID to connect AP.
1923 if (pAd->StaCfg.WpaSupplicantUP &&
1924 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1925 (pAd->StaCfg.IEEE8021X == FALSE))
1927 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1929 else
1930 #endif // WPA_SUPPLICANT_SUPPORT //
1932 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1933 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1936 NdisAcquireSpinLock(&pAd->MacTabLock);
1937 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
1938 NdisReleaseSpinLock(&pAd->MacTabLock);
1940 pAd->StaCfg.MicErrCnt = 0;
1942 // Turn off Ckip control flag
1943 pAd->StaCfg.bCkipOn = FALSE;
1944 pAd->StaCfg.CCXEnable = FALSE;
1946 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1947 // Update extra information to link is up
1948 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1950 //pAd->StaCfg.AdhocBOnlyJoined = FALSE;
1951 //pAd->StaCfg.AdhocBGJoined = FALSE;
1952 //pAd->StaCfg.Adhoc20NJoined = FALSE;
1953 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1955 // Reset the Current AP's IP address
1956 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
1957 #ifdef RT2870
1958 pAd->bUsbTxBulkAggre = FALSE;
1959 #endif // RT2870 //
1961 // Clean association information
1962 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
1963 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
1964 pAd->StaCfg.ReqVarIELen = 0;
1965 pAd->StaCfg.ResVarIELen = 0;
1968 // Reset RSSI value after link down
1970 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
1971 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
1972 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
1973 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
1974 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
1975 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
1977 // Restore MlmeRate
1978 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
1979 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
1981 #ifdef DOT11_N_SUPPORT
1983 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
1985 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1987 pAd->CommonCfg.BBPCurrentBW = BW_20;
1988 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
1989 ByteValue &= (~0x18);
1990 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
1992 #endif // DOT11_N_SUPPORT //
1993 // Reset DAC
1994 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
1995 ByteValue &= (~0x18);
1996 if (pAd->Antenna.field.TxPath == 2)
1998 ByteValue |= 0x10;
2000 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2002 RTMPSetPiggyBack(pAd,FALSE);
2003 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2005 #ifdef DOT11_N_SUPPORT
2006 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2007 #endif // DOT11_N_SUPPORT //
2009 // Restore all settings in the following.
2010 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2011 AsicDisableRDG(pAd);
2012 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2013 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2015 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2016 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2018 #ifdef WPA_SUPPLICANT_SUPPORT
2019 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2020 if (pAd->StaCfg.WpaSupplicantUP) {
2021 union iwreq_data wrqu;
2022 //send disassociate event to wpa_supplicant
2023 memset(&wrqu, 0, sizeof(wrqu));
2024 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2025 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2027 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2028 #endif // WPA_SUPPLICANT_SUPPORT //
2030 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2032 union iwreq_data wrqu;
2033 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2034 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2036 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2040 ==========================================================================
2041 Description:
2043 IRQL = DISPATCH_LEVEL
2045 ==========================================================================
2047 VOID IterateOnBssTab(
2048 IN PRTMP_ADAPTER pAd)
2050 MLME_START_REQ_STRUCT StartReq;
2051 MLME_JOIN_REQ_STRUCT JoinReq;
2052 ULONG BssIdx;
2054 // Change the wepstatus to original wepstatus
2055 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2056 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2057 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2059 BssIdx = pAd->MlmeAux.BssIdx;
2060 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2062 // Check cipher suite, AP must have more secured cipher than station setting
2063 // Set the Pairwise and Group cipher to match the intended AP setting
2064 // We can only connect to AP with less secured cipher setting
2065 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2067 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2069 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2070 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2071 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2072 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2073 else // There is no PairCipher Aux, downgrade our capability to TKIP
2074 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2076 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2078 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2080 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2081 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2082 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2083 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2084 else // There is no PairCipher Aux, downgrade our capability to TKIP
2085 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2087 // RSN capability
2088 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2091 // Set Mix cipher flag
2092 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2093 if (pAd->StaCfg.bMixCipher == TRUE)
2095 // If mix cipher, re-build RSNIE
2096 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2099 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2100 JoinParmFill(pAd, &JoinReq, BssIdx);
2101 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2102 &JoinReq);
2103 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2105 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2107 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2108 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2109 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2110 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2112 else // no more BSS
2114 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2115 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2116 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2117 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2121 // for re-association only
2122 // IRQL = DISPATCH_LEVEL
2123 VOID IterateOnBssTab2(
2124 IN PRTMP_ADAPTER pAd)
2126 MLME_REASSOC_REQ_STRUCT ReassocReq;
2127 ULONG BssIdx;
2128 BSS_ENTRY *pBss;
2130 BssIdx = pAd->MlmeAux.RoamIdx;
2131 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2133 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2135 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2137 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2138 AsicLockChannel(pAd, pBss->Channel);
2140 // reassociate message has the same structure as associate message
2141 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2142 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2143 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2144 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2146 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2148 else // no more BSS
2150 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2151 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2152 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2153 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2158 ==========================================================================
2159 Description:
2161 IRQL = DISPATCH_LEVEL
2163 ==========================================================================
2165 VOID JoinParmFill(
2166 IN PRTMP_ADAPTER pAd,
2167 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2168 IN ULONG BssIdx)
2170 JoinReq->BssIdx = BssIdx;
2174 ==========================================================================
2175 Description:
2177 IRQL = DISPATCH_LEVEL
2179 ==========================================================================
2181 VOID ScanParmFill(
2182 IN PRTMP_ADAPTER pAd,
2183 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2184 IN CHAR Ssid[],
2185 IN UCHAR SsidLen,
2186 IN UCHAR BssType,
2187 IN UCHAR ScanType)
2189 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2190 ScanReq->SsidLen = SsidLen;
2191 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2192 ScanReq->BssType = BssType;
2193 ScanReq->ScanType = ScanType;
2197 ==========================================================================
2198 Description:
2200 IRQL = DISPATCH_LEVEL
2202 ==========================================================================
2204 VOID StartParmFill(
2205 IN PRTMP_ADAPTER pAd,
2206 IN OUT MLME_START_REQ_STRUCT *StartReq,
2207 IN CHAR Ssid[],
2208 IN UCHAR SsidLen)
2210 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2211 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2212 StartReq->SsidLen = SsidLen;
2216 ==========================================================================
2217 Description:
2219 IRQL = DISPATCH_LEVEL
2221 ==========================================================================
2223 VOID AuthParmFill(
2224 IN PRTMP_ADAPTER pAd,
2225 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2226 IN PUCHAR pAddr,
2227 IN USHORT Alg)
2229 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2230 AuthReq->Alg = Alg;
2231 AuthReq->Timeout = AUTH_TIMEOUT;
2235 ==========================================================================
2236 Description:
2238 IRQL = DISPATCH_LEVEL
2240 ==========================================================================
2244 #ifdef RT2870
2246 VOID MlmeCntlConfirm(
2247 IN PRTMP_ADAPTER pAd,
2248 IN ULONG MsgType,
2249 IN USHORT Msg)
2251 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
2254 VOID ComposePsPoll(
2255 IN PRTMP_ADAPTER pAd)
2257 PTXINFO_STRUC pTxInfo;
2258 PTXWI_STRUC pTxWI;
2260 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2261 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2263 pAd->PsPollFrame.FC.PwrMgmt = 0;
2264 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2265 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2266 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2267 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2268 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2270 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
2271 pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
2272 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2273 pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2274 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
2275 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2276 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2277 // Append 4 extra zero bytes.
2278 pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
2281 // IRQL = DISPATCH_LEVEL
2282 VOID ComposeNullFrame(
2283 IN PRTMP_ADAPTER pAd)
2285 PTXINFO_STRUC pTxInfo;
2286 PTXWI_STRUC pTxWI;
2288 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2289 pAd->NullFrame.FC.Type = BTYPE_DATA;
2290 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2291 pAd->NullFrame.FC.ToDs = 1;
2292 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2293 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2294 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2295 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
2296 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
2297 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2298 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2299 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
2300 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2301 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
2302 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2304 #endif // RT2870 //
2308 ==========================================================================
2309 Description:
2310 Pre-build a BEACON frame in the shared memory
2312 IRQL = PASSIVE_LEVEL
2313 IRQL = DISPATCH_LEVEL
2315 ==========================================================================
2317 ULONG MakeIbssBeacon(
2318 IN PRTMP_ADAPTER pAd)
2320 UCHAR DsLen = 1, IbssLen = 2;
2321 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2322 HEADER_802_11 BcnHdr;
2323 USHORT CapabilityInfo;
2324 LARGE_INTEGER FakeTimestamp;
2325 ULONG FrameLen = 0;
2326 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2327 CHAR *pBeaconFrame = pAd->BeaconBuf;
2328 BOOLEAN Privacy;
2329 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2330 UCHAR SupRateLen = 0;
2331 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2332 UCHAR ExtRateLen = 0;
2333 UCHAR RSNIe = IE_WPA;
2335 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2337 SupRate[0] = 0x82; // 1 mbps
2338 SupRate[1] = 0x84; // 2 mbps
2339 SupRate[2] = 0x8b; // 5.5 mbps
2340 SupRate[3] = 0x96; // 11 mbps
2341 SupRateLen = 4;
2342 ExtRateLen = 0;
2344 else if (pAd->CommonCfg.Channel > 14)
2346 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2347 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2348 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2349 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2350 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2351 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2352 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2353 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2354 SupRateLen = 8;
2355 ExtRateLen = 0;
2358 // Also Update MlmeRate & RtsRate for G only & A only
2360 pAd->CommonCfg.MlmeRate = RATE_6;
2361 pAd->CommonCfg.RtsRate = RATE_6;
2362 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2363 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2364 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2365 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2367 else
2369 SupRate[0] = 0x82; // 1 mbps
2370 SupRate[1] = 0x84; // 2 mbps
2371 SupRate[2] = 0x8b; // 5.5 mbps
2372 SupRate[3] = 0x96; // 11 mbps
2373 SupRateLen = 4;
2375 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2376 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2377 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2378 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2379 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2380 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2381 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2382 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2383 ExtRateLen = 8;
2386 pAd->StaActive.SupRateLen = SupRateLen;
2387 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2388 pAd->StaActive.ExtRateLen = ExtRateLen;
2389 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2391 // compose IBSS beacon frame
2392 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2393 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2394 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2395 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2396 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2398 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2399 sizeof(HEADER_802_11), &BcnHdr,
2400 TIMESTAMP_LEN, &FakeTimestamp,
2401 2, &pAd->CommonCfg.BeaconPeriod,
2402 2, &CapabilityInfo,
2403 1, &SsidIe,
2404 1, &pAd->CommonCfg.SsidLen,
2405 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2406 1, &SupRateIe,
2407 1, &SupRateLen,
2408 SupRateLen, SupRate,
2409 1, &DsIe,
2410 1, &DsLen,
2411 1, &pAd->CommonCfg.Channel,
2412 1, &IbssIe,
2413 1, &IbssLen,
2414 2, &pAd->StaActive.AtimWin,
2415 END_OF_ARGS);
2417 // add ERP_IE and EXT_RAE IE of in 802.11g
2418 if (ExtRateLen)
2420 ULONG tmp;
2422 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2423 3, LocalErpIe,
2424 1, &ExtRateIe,
2425 1, &ExtRateLen,
2426 ExtRateLen, ExtRate,
2427 END_OF_ARGS);
2428 FrameLen += tmp;
2431 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2432 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2434 ULONG tmp;
2435 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2437 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2438 1, &RSNIe,
2439 1, &pAd->StaCfg.RSNIE_Len,
2440 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2441 END_OF_ARGS);
2442 FrameLen += tmp;
2445 #ifdef DOT11_N_SUPPORT
2446 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2448 ULONG TmpLen;
2449 UCHAR HtLen, HtLen1;
2451 #ifdef RT_BIG_ENDIAN
2452 HT_CAPABILITY_IE HtCapabilityTmp;
2453 ADD_HT_INFO_IE addHTInfoTmp;
2454 USHORT b2lTmp, b2lTmp2;
2455 #endif
2457 // add HT Capability IE
2458 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2459 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2460 #ifndef RT_BIG_ENDIAN
2461 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2462 1, &HtCapIe,
2463 1, &HtLen,
2464 HtLen, &pAd->CommonCfg.HtCapability,
2465 1, &AddHtInfoIe,
2466 1, &HtLen1,
2467 HtLen1, &pAd->CommonCfg.AddHTInfo,
2468 END_OF_ARGS);
2469 #else
2470 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2471 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2472 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2474 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2475 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2476 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2478 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2479 1, &HtCapIe,
2480 1, &HtLen,
2481 HtLen, &HtCapabilityTmp,
2482 1, &AddHtInfoIe,
2483 1, &HtLen1,
2484 HtLen1, &addHTInfoTmp,
2485 END_OF_ARGS);
2486 #endif
2487 FrameLen += TmpLen;
2489 #endif // DOT11_N_SUPPORT //
2491 //beacon use reserved WCID 0xff
2492 if (pAd->CommonCfg.Channel > 14)
2494 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2495 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2497 else
2499 // Set to use 1Mbps for Adhoc beacon.
2500 HTTRANSMIT_SETTING Transmit;
2501 Transmit.word = 0;
2502 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2503 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2506 #ifdef RT_BIG_ENDIAN
2507 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2508 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2509 #endif
2511 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2512 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));
2513 return FrameLen;