2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 John 2004-08-08 Major modification from RT2560
36 Justin P. Mattock 11/07/2010 Fix typos
38 #include "../rt_config.h"
40 u8 CipherSuiteWpaNoneTkip[] = {
41 0x00, 0x50, 0xf2, 0x01, /* oui */
42 0x01, 0x00, /* Version */
43 0x00, 0x50, 0xf2, 0x02, /* Multicast */
44 0x01, 0x00, /* Number of unicast */
45 0x00, 0x50, 0xf2, 0x02, /* unicast */
46 0x01, 0x00, /* number of authentication method */
47 0x00, 0x50, 0xf2, 0x00 /* authentication */
50 u8 CipherSuiteWpaNoneTkipLen =
51 (sizeof(CipherSuiteWpaNoneTkip) / sizeof(u8));
53 u8 CipherSuiteWpaNoneAes[] = {
54 0x00, 0x50, 0xf2, 0x01, /* oui */
55 0x01, 0x00, /* Version */
56 0x00, 0x50, 0xf2, 0x04, /* Multicast */
57 0x01, 0x00, /* Number of unicast */
58 0x00, 0x50, 0xf2, 0x04, /* unicast */
59 0x01, 0x00, /* number of authentication method */
60 0x00, 0x50, 0xf2, 0x00 /* authentication */
63 u8 CipherSuiteWpaNoneAesLen =
64 (sizeof(CipherSuiteWpaNoneAes) / sizeof(u8));
66 /* The following MACRO is called after 1. starting an new IBSS, 2. successfully JOIN an IBSS, */
67 /* or 3. successfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */
68 /* All settings successfuly negotiated firing MLME state machines become final settings */
69 /* and are copied to pAd->StaActive */
70 #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
72 NdisZeroMemory((_pAd)->CommonCfg.Ssid, MAX_LEN_OF_SSID); \
73 (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \
74 NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
75 COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \
76 (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel; \
77 (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel; \
78 (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid; \
79 (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin; \
80 (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo; \
81 (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod; \
82 (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration; \
83 (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod; \
84 (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen; \
85 NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
86 (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen; \
87 NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
88 NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(struct rt_edca_parm));\
89 NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(struct rt_qos_capability_parm));\
90 NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(struct rt_qbss_load_parm));\
91 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid); \
92 (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid; \
93 (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
94 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
95 (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
99 ==========================================================================
104 ==========================================================================
106 void MlmeCntlInit(struct rt_rtmp_adapter *pAd,
107 struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
109 /* Control state machine differs from other state machines, the interface */
110 /* follows the standard interface */
111 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
115 ==========================================================================
118 IRQL = DISPATCH_LEVEL
120 ==========================================================================
122 void MlmeCntlMachinePerformAction(struct rt_rtmp_adapter *pAd,
123 struct rt_state_machine *S,
124 struct rt_mlme_queue_elem *Elem)
126 switch (pAd->Mlme.CntlMachine.CurrState) {
128 CntlIdleProc(pAd, Elem);
130 case CNTL_WAIT_DISASSOC:
131 CntlWaitDisassocProc(pAd, Elem);
134 CntlWaitJoinProc(pAd, Elem);
137 /* CNTL_WAIT_REASSOC is the only state in CNTL machine that does */
138 /* not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)". */
139 /* Therefore not protected by NDIS's "only one outstanding OID request" */
140 /* rule. Which means NDIS may SET OID in the middle of ROAMing attempts. */
141 /* Current approach is to block new SET request at RTMPSetInformation() */
142 /* when CntlMachine.CurrState is not CNTL_IDLE */
143 case CNTL_WAIT_REASSOC:
144 CntlWaitReassocProc(pAd, Elem);
147 case CNTL_WAIT_START:
148 CntlWaitStartProc(pAd, Elem);
151 CntlWaitAuthProc(pAd, Elem);
153 case CNTL_WAIT_AUTH2:
154 CntlWaitAuthProc2(pAd, Elem);
156 case CNTL_WAIT_ASSOC:
157 CntlWaitAssocProc(pAd, Elem);
160 case CNTL_WAIT_OID_LIST_SCAN:
161 if (Elem->MsgType == MT2_SCAN_CONF) {
162 /* Resume TxRing after SCANING complete. We hope the out-of-service time */
163 /* won't be too long to let upper layer time-out the waiting frames */
164 RTMPResumeMsduTransmission(pAd);
166 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
169 /* Set LED status to previous status. */
171 if (pAd->bLedOnScanning) {
172 pAd->bLedOnScanning = FALSE;
173 RTMPSetLED(pAd, pAd->LedStatus);
178 case CNTL_WAIT_OID_DISASSOC:
179 if (Elem->MsgType == MT2_DISASSOC_CONF) {
180 LinkDown(pAd, FALSE);
181 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
186 /* This state is for that we want to connect to an AP but */
187 /* it didn't find on BSS List table. So we need to scan the air first, */
188 /* after that we can try to connect to the desired AP if available. */
190 case CNTL_WAIT_SCAN_FOR_CONNECT:
191 if (Elem->MsgType == MT2_SCAN_CONF) {
192 /* Resume TxRing after SCANING complete. We hope the out-of-service time */
193 /* won't be too long to let upper layer time-out the waiting frames */
194 RTMPResumeMsduTransmission(pAd);
196 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) {
197 /* Cisco scan request is finished, prepare beacon report */
198 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE,
199 MT2_AIRONET_SCAN_DONE, 0, NULL);
201 #endif /* CCX_SUPPORT // */
202 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
205 /* Check if we can connect to. */
207 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab,
208 (char *) pAd->MlmeAux.
210 pAd->MlmeAux.AutoReconnectSsidLen);
211 if (pAd->MlmeAux.SsidBssTab.BssNr > 0) {
212 MlmeAutoReconnectLastSSID(pAd);
216 #endif /* RTMP_MAC_USB // */
218 DBGPRINT_ERR(("ERROR! CNTL - Illegal message type(=%ld)",
225 ==========================================================================
228 IRQL = DISPATCH_LEVEL
230 ==========================================================================
232 void CntlIdleProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
234 struct rt_mlme_disassoc_req DisassocReq;
236 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
239 switch (Elem->MsgType) {
240 case OID_802_11_SSID:
241 CntlOidSsidProc(pAd, Elem);
244 case OID_802_11_BSSID:
245 CntlOidRTBssidProc(pAd, Elem);
248 case OID_802_11_BSSID_LIST_SCAN:
249 CntlOidScanProc(pAd, Elem);
252 case OID_802_11_DISASSOCIATE:
253 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid,
254 REASON_DISASSOC_STA_LEAVING);
255 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
256 sizeof(struct rt_mlme_disassoc_req), &DisassocReq);
257 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
259 if (pAd->StaCfg.WpaSupplicantUP !=
260 WPA_SUPPLICANT_ENABLE_WITH_WEB_UI) {
261 /* Set the AutoReconnectSsid to prevent it reconnect to old SSID */
262 /* Since calling this indicate user don't want to connect to that SSID anymore. */
263 pAd->MlmeAux.AutoReconnectSsidLen = 32;
264 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid,
265 pAd->MlmeAux.AutoReconnectSsidLen);
269 case MT2_MLME_ROAMING_REQ:
270 CntlMlmeRoamingProc(pAd, Elem);
273 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
274 WpaMicFailureReportFrame(pAd, Elem);
278 DBGPRINT(RT_DEBUG_TRACE,
279 ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",
285 void CntlOidScanProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
287 struct rt_mlme_scan_req ScanReq;
288 unsigned long BssIdx = BSS_NOT_FOUND;
289 struct rt_bss_entry CurrBss;
291 /* record current BSS if network is connected. */
292 /* 2003-2-13 do not include current IBSS if this is the only STA in this IBSS. */
293 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
295 BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid,
296 (u8 *)pAd->CommonCfg.Ssid,
297 pAd->CommonCfg.SsidLen,
298 pAd->CommonCfg.Channel);
299 if (BssIdx != BSS_NOT_FOUND) {
300 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx],
301 sizeof(struct rt_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) {
307 /* DDK Note: If the NIC is associated with a particular BSSID and SSID */
308 /* that are not contained in the list of BSSIDs generated by this scan, the */
309 /* BSSID description of the currently associated BSSID and SSID should be */
310 /* appended to the list of BSSIDs in the NIC's database. */
311 /* To ensure this, we append this BSS as the first entry in SCAN result */
312 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss,
313 sizeof(struct rt_bss_entry));
314 pAd->ScanTab.BssNr = 1;
317 ScanParmFill(pAd, &ScanReq, (char *)Elem->Msg, Elem->MsgLen, BSS_ANY,
319 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
320 sizeof(struct rt_mlme_scan_req), &ScanReq);
321 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
325 ==========================================================================
327 Before calling this routine, user desired SSID should already been
328 recorded in CommonCfg.Ssid[]
329 IRQL = DISPATCH_LEVEL
331 ==========================================================================
333 void CntlOidSsidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
335 struct rt_ndis_802_11_ssid * pOidSsid = (struct rt_ndis_802_11_ssid *) Elem->Msg;
336 struct rt_mlme_disassoc_req DisassocReq;
339 /* Step 1. record the desired user settings to MlmeAux */
340 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
341 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
342 pAd->MlmeAux.SsidLen = (u8)pOidSsid->SsidLength;
343 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
344 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
346 pAd->StaCfg.bAutoConnectByBssid = FALSE;
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,
353 pAd->MlmeAux.SsidLen);
354 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
356 /* step 2. find all matching BSS in the lastest SCAN result (inBssTab) */
357 /* & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order */
358 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab,
359 (char *)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
361 DBGPRINT(RT_DEBUG_TRACE,
362 ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
363 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr,
364 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
365 NdisGetSystemUpTime(&Now);
367 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
368 (pAd->CommonCfg.SsidLen ==
369 pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen)
370 && NdisEqualMemory(pAd->CommonCfg.Ssid,
371 pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid,
372 pAd->CommonCfg.SsidLen)
373 && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid,
374 pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid)) {
375 /* Case 1. already connected with an AP who has the desired SSID */
376 /* with highest RSSI */
378 /* Add checking Mode "LEAP" for CCX 1.0 */
379 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
380 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
381 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
382 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
384 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) {
385 /* case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo */
386 /* connection process */
387 DBGPRINT(RT_DEBUG_TRACE,
388 ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
389 DisassocParmFill(pAd, &DisassocReq,
390 pAd->CommonCfg.Bssid,
391 REASON_DISASSOC_STA_LEAVING);
392 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
393 MT2_MLME_DISASSOC_REQ,
394 sizeof(struct rt_mlme_disassoc_req),
396 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
397 } else if (pAd->bConfigChanged == TRUE) {
398 /* case 1.2 Important Config has changed, we have to reconnect to the same AP */
399 DBGPRINT(RT_DEBUG_TRACE,
400 ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
401 DisassocParmFill(pAd, &DisassocReq,
402 pAd->CommonCfg.Bssid,
403 REASON_DISASSOC_STA_LEAVING);
404 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
405 MT2_MLME_DISASSOC_REQ,
406 sizeof(struct rt_mlme_disassoc_req),
408 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
410 /* case 1.3. already connected to the SSID with highest RSSI. */
411 DBGPRINT(RT_DEBUG_TRACE,
412 ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
414 /* (HCT 12.1) 1c_wlan_mediaevents required */
415 /* media connect events are indicated when associating with the same AP */
419 /* Since MediaState already is NdisMediaStateConnected */
420 /* We just indicate the connect event again to meet the WHQL required. */
422 pAd->IndicateMediaState =
423 NdisMediaStateConnected;
424 RTMP_IndicateMediaState(pAd);
425 pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information to link is up */
428 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
429 RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1,
430 &pAd->MlmeAux.Bssid[0], NULL,
433 } else if (INFRA_ON(pAd)) {
436 /* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */
437 /* RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect */
438 /* But media status is connected, so the SSID not report correctly. */
441 (pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen,
442 pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)) {
444 /* Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event. */
446 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
448 /* case 2. active INFRA association existent */
449 /* roaming is done within miniport driver, nothing to do with configuration */
450 /* utility. so upon a new SET(OID_802_11_SSID) is received, we just */
451 /* disassociate with the current associated AP, */
452 /* then perform a new association with this new SSID, no matter the */
453 /* new/old SSID are the same or not. */
454 DBGPRINT(RT_DEBUG_TRACE,
455 ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
456 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid,
457 REASON_DISASSOC_STA_LEAVING);
458 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
459 sizeof(struct rt_mlme_disassoc_req), &DisassocReq);
460 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
463 DBGPRINT(RT_DEBUG_TRACE,
464 ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
465 LinkDown(pAd, FALSE);
466 OPSTATUS_CLEAR_FLAG(pAd,
467 fOP_STATUS_MEDIA_STATE_CONNECTED);
468 pAd->IndicateMediaState = NdisMediaStateDisconnected;
469 RTMP_IndicateMediaState(pAd);
470 pAd->ExtraInfo = GENERAL_LINK_DOWN;
471 DBGPRINT(RT_DEBUG_TRACE,
472 ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
475 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
476 (pAd->StaCfg.bAutoReconnect == TRUE) &&
477 (pAd->MlmeAux.BssType == BSS_INFRA) &&
478 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)
481 struct rt_mlme_scan_req ScanReq;
483 DBGPRINT(RT_DEBUG_TRACE,
484 ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
485 ScanParmFill(pAd, &ScanReq, (char *)pAd->MlmeAux.Ssid,
486 pAd->MlmeAux.SsidLen, BSS_ANY,
488 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
489 sizeof(struct rt_mlme_scan_req), &ScanReq);
490 pAd->Mlme.CntlMachine.CurrState =
491 CNTL_WAIT_OID_LIST_SCAN;
492 /* Reset Missed scan number */
493 pAd->StaCfg.LastScanTime = Now;
495 pAd->MlmeAux.BssIdx = 0;
496 IterateOnBssTab(pAd);
502 ==========================================================================
505 IRQL = DISPATCH_LEVEL
507 ==========================================================================
509 void CntlOidRTBssidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
511 unsigned long BssIdx;
512 u8 *pOidBssid = (u8 *)Elem->Msg;
513 struct rt_mlme_disassoc_req DisassocReq;
514 struct rt_mlme_join_req JoinReq;
516 /* record user desired settings */
517 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
518 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
520 /* find the desired BSS in the latest SCAN result table */
521 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
522 if (BssIdx == BSS_NOT_FOUND) {
523 struct rt_mlme_scan_req ScanReq;
525 DBGPRINT(RT_DEBUG_TRACE,
526 ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
527 /*pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; */
529 DBGPRINT(RT_DEBUG_TRACE,
530 ("CNTL - BSSID not found. start a new scan\n"));
531 ScanParmFill(pAd, &ScanReq, (char *)pAd->MlmeAux.Ssid,
532 pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
533 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
534 sizeof(struct rt_mlme_scan_req), &ScanReq);
535 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
536 /* Reset Missed scan number */
537 NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
541 /* Update Reconnect Ssid, that user desired to connect. */
543 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
544 pAd->MlmeAux.AutoReconnectSsidLen =
545 pAd->ScanTab.BssEntry[BssIdx].SsidLen;
546 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid,
547 pAd->ScanTab.BssEntry[BssIdx].Ssid,
548 pAd->ScanTab.BssEntry[BssIdx].SsidLen);
550 /* copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why? */
551 /* Because we need this entry to become the JOIN target in later on SYNC state machine */
552 pAd->MlmeAux.BssIdx = 0;
553 pAd->MlmeAux.SsidBssTab.BssNr = 1;
554 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0],
555 &pAd->ScanTab.BssEntry[BssIdx], sizeof(struct rt_bss_entry));
557 /* Add SSID into MlmeAux for site survey joining hidden SSID */
558 pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
559 NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid,
560 pAd->MlmeAux.SsidLen);
564 /* disassoc from current AP first */
565 DBGPRINT(RT_DEBUG_TRACE,
566 ("CNTL - disassociate with current AP ...\n"));
567 DisassocParmFill(pAd, &DisassocReq,
568 pAd->CommonCfg.Bssid,
569 REASON_DISASSOC_STA_LEAVING);
570 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
571 MT2_MLME_DISASSOC_REQ,
572 sizeof(struct rt_mlme_disassoc_req),
575 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
578 DBGPRINT(RT_DEBUG_TRACE,
579 ("CNTL - drop current ADHOC\n"));
580 LinkDown(pAd, FALSE);
581 OPSTATUS_CLEAR_FLAG(pAd,
582 fOP_STATUS_MEDIA_STATE_CONNECTED);
583 pAd->IndicateMediaState =
584 NdisMediaStateDisconnected;
585 RTMP_IndicateMediaState(pAd);
586 pAd->ExtraInfo = GENERAL_LINK_DOWN;
587 DBGPRINT(RT_DEBUG_TRACE,
588 ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
590 /* Change the wepstatus to original wepstatus */
591 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
592 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
593 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
595 /* Check cipher suite, AP must have more secured cipher than station setting */
596 /* Set the Pairwise and Group cipher to match the intended AP setting */
597 /* We can only connect to AP with less secured cipher setting */
598 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
599 || (pAd->StaCfg.AuthMode ==
600 Ndis802_11AuthModeWPAPSK)) {
601 pAd->StaCfg.GroupCipher =
602 pAd->ScanTab.BssEntry[BssIdx].WPA.
605 if (pAd->StaCfg.WepStatus ==
606 pAd->ScanTab.BssEntry[BssIdx].WPA.
608 pAd->StaCfg.PairCipher =
609 pAd->ScanTab.BssEntry[BssIdx].WPA.
611 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.
612 PairCipherAux != Ndis802_11WEPDisabled)
613 pAd->StaCfg.PairCipher =
614 pAd->ScanTab.BssEntry[BssIdx].WPA.
616 else /* There is no PairCipher Aux, downgrade our capability to TKIP */
617 pAd->StaCfg.PairCipher =
618 Ndis802_11Encryption2Enabled;
620 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
621 || (pAd->StaCfg.AuthMode ==
622 Ndis802_11AuthModeWPA2PSK)) {
623 pAd->StaCfg.GroupCipher =
624 pAd->ScanTab.BssEntry[BssIdx].WPA2.
627 if (pAd->StaCfg.WepStatus ==
628 pAd->ScanTab.BssEntry[BssIdx].WPA2.
630 pAd->StaCfg.PairCipher =
631 pAd->ScanTab.BssEntry[BssIdx].WPA2.
633 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.
634 PairCipherAux != Ndis802_11WEPDisabled)
635 pAd->StaCfg.PairCipher =
636 pAd->ScanTab.BssEntry[BssIdx].WPA2.
638 else /* There is no PairCipher Aux, downgrade our capability to TKIP */
639 pAd->StaCfg.PairCipher =
640 Ndis802_11Encryption2Enabled;
643 pAd->StaCfg.RsnCapability =
644 pAd->ScanTab.BssEntry[BssIdx].WPA2.
647 /* Set Mix cipher flag */
648 pAd->StaCfg.bMixCipher =
649 (pAd->StaCfg.PairCipher ==
650 pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
651 /*if (pAd->StaCfg.bMixCipher == TRUE)
653 // If mix cipher, re-build RSNIE
654 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
656 /* No active association, join the BSS immediately */
657 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %pM ...\n",
660 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
661 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ,
662 sizeof(struct rt_mlme_join_req), &JoinReq);
664 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
669 /* Roaming is the only external request triggering CNTL state machine */
670 /* despite of other "SET OID" operation. All "SET OID" related operations */
671 /* happen in sequence, because no other SET OID will be sent to this device */
672 /* until the the previous SET operation is complete (successful o failed). */
673 /* So, how do we quarantee this ROAMING request won't corrupt other "SET OID"? */
674 /* or been corrupted by other "SET OID"? */
676 /* IRQL = DISPATCH_LEVEL */
677 void CntlMlmeRoamingProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
681 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Roaming in MlmeAux.RoamTab...\n"));
684 /*Let BBP register at 20MHz to do (fast) roaming. */
685 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
687 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
689 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab,
690 sizeof(pAd->MlmeAux.RoamTab));
691 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
693 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
694 pAd->MlmeAux.BssIdx = 0;
695 IterateOnBssTab(pAd);
700 ==========================================================================
703 IRQL = DISPATCH_LEVEL
705 ==========================================================================
707 void CntlWaitDisassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
709 struct rt_mlme_start_req StartReq;
711 if (Elem->MsgType == MT2_DISASSOC_CONF) {
712 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
714 if (pAd->CommonCfg.bWirelessEvent) {
715 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG,
716 pAd->MacTab.Content[BSSID_WCID].
720 LinkDown(pAd, FALSE);
722 /* case 1. no matching BSS, and user wants ADHOC, so we just start a new one */
723 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0)
724 && (pAd->StaCfg.BssType == BSS_ADHOC)) {
725 DBGPRINT(RT_DEBUG_TRACE,
726 ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",
728 StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid,
729 pAd->MlmeAux.SsidLen);
730 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
731 sizeof(struct rt_mlme_start_req), &StartReq);
732 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
734 /* case 2. try each matched BSS */
736 pAd->MlmeAux.BssIdx = 0;
738 IterateOnBssTab(pAd);
744 ==========================================================================
747 IRQL = DISPATCH_LEVEL
749 ==========================================================================
751 void CntlWaitJoinProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
754 struct rt_mlme_auth_req AuthReq;
756 if (Elem->MsgType == MT2_JOIN_CONF) {
757 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
758 if (Reason == MLME_SUCCESS) {
759 /* 1. joined an IBSS, we are pretty much done here */
760 if (pAd->MlmeAux.BssType == BSS_ADHOC) {
762 /* 5G bands rules of Japan: */
763 /* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */
765 if ((pAd->CommonCfg.bIEEE80211H == 1) &&
766 RadarChannelCheck(pAd,
767 pAd->CommonCfg.Channel)
769 pAd->Mlme.CntlMachine.CurrState =
771 DBGPRINT(RT_DEBUG_TRACE,
772 ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n",
773 pAd->CommonCfg.Channel));
777 LinkUp(pAd, BSS_ADHOC);
778 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
779 DBGPRINT(RT_DEBUG_TRACE,
780 ("CNTL - join the IBSS = %pM ...\n",
781 pAd->CommonCfg.Bssid));
783 pAd->IndicateMediaState =
784 NdisMediaStateConnected;
785 pAd->ExtraInfo = GENERAL_LINK_UP;
787 /* 2. joined a new INFRA network, start from authentication */
790 /* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */
791 if ((pAd->StaCfg.AuthMode ==
792 Ndis802_11AuthModeShared)
793 || (pAd->StaCfg.AuthMode ==
794 Ndis802_11AuthModeAutoSwitch)) {
795 AuthParmFill(pAd, &AuthReq,
799 AuthParmFill(pAd, &AuthReq,
803 MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
806 (struct rt_mlme_auth_req),
810 pAd->Mlme.CntlMachine.CurrState =
814 /* 3. failed, try next BSS */
815 pAd->MlmeAux.BssIdx++;
816 IterateOnBssTab(pAd);
822 ==========================================================================
825 IRQL = DISPATCH_LEVEL
827 ==========================================================================
829 void CntlWaitStartProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
833 if (Elem->MsgType == MT2_START_CONF) {
834 NdisMoveMemory(&Result, Elem->Msg, sizeof(u16));
835 if (Result == MLME_SUCCESS) {
837 /* 5G bands rules of Japan: */
838 /* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */
840 if ((pAd->CommonCfg.bIEEE80211H == 1) &&
841 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
843 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
844 DBGPRINT(RT_DEBUG_TRACE,
845 ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n",
846 pAd->CommonCfg.Channel));
849 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.
851 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
854 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo,
855 &pAd->CommonCfg.AddHTInfo,
856 sizeof(struct rt_add_ht_info_ie));
857 RTMPCheckHt(pAd, BSSID_WCID,
858 &pAd->CommonCfg.HtCapability,
859 &pAd->CommonCfg.AddHTInfo);
860 pAd->StaActive.SupportedPhyInfo.bHtEnable =
862 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.
864 &pAd->CommonCfg.HtCapability.
866 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG
869 if ((pAd->CommonCfg.HtCapability.HtCapInfo.
870 ChannelWidth == BW_40)
871 && (pAd->CommonCfg.AddHTInfo.AddHtInfo.
872 ExtChanOffset == EXTCHA_ABOVE)) {
873 pAd->MlmeAux.CentralChannel =
874 pAd->CommonCfg.Channel + 2;
876 if ((pAd->CommonCfg.HtCapability.HtCapInfo.
877 ChannelWidth == BW_40)
878 && (pAd->CommonCfg.AddHTInfo.AddHtInfo.
879 ExtChanOffset == EXTCHA_BELOW)) {
880 pAd->MlmeAux.CentralChannel =
881 pAd->CommonCfg.Channel - 2;
884 pAd->StaActive.SupportedPhyInfo.bHtEnable =
887 LinkUp(pAd, BSS_ADHOC);
888 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
889 /* Before send beacon, driver need do radar detection */
890 if ((pAd->CommonCfg.Channel > 14)
891 && (pAd->CommonCfg.bIEEE80211H == 1)
892 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) {
893 pAd->CommonCfg.RadarDetect.RDMode =
895 pAd->CommonCfg.RadarDetect.RDCount = 0;
898 DBGPRINT(RT_DEBUG_TRACE,
899 ("CNTL - start a new IBSS = %pM ...\n",
900 pAd->CommonCfg.Bssid));
902 DBGPRINT(RT_DEBUG_TRACE,
903 ("CNTL - Start IBSS fail. BUG!\n"));
904 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
910 ==========================================================================
913 IRQL = DISPATCH_LEVEL
915 ==========================================================================
917 void CntlWaitAuthProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
920 struct rt_mlme_assoc_req AssocReq;
921 struct rt_mlme_auth_req AuthReq;
923 if (Elem->MsgType == MT2_AUTH_CONF) {
924 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
925 if (Reason == MLME_SUCCESS) {
926 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
927 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid,
928 pAd->MlmeAux.CapabilityInfo,
930 pAd->StaCfg.DefaultListenCount);
933 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
935 sizeof(struct rt_mlme_assoc_req),
938 pAd->Mlme.CntlMachine.CurrState =
942 /* This fail may because of the AP already keep us in its MAC table without */
943 /* ageing-out. The previous authentication attempt must have let it remove us. */
944 /* so try Authentication again may help. For D-Link DWL-900AP+ compatibility. */
945 DBGPRINT(RT_DEBUG_TRACE,
946 ("CNTL - AUTH FAIL, try again...\n"));
949 if ((pAd->StaCfg.AuthMode ==
950 Ndis802_11AuthModeShared)
951 || (pAd->StaCfg.AuthMode ==
952 Ndis802_11AuthModeAutoSwitch)) {
953 /* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */
954 AuthParmFill(pAd, &AuthReq,
958 AuthParmFill(pAd, &AuthReq,
962 MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
964 sizeof(struct rt_mlme_auth_req),
968 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
974 ==========================================================================
977 IRQL = DISPATCH_LEVEL
979 ==========================================================================
981 void CntlWaitAuthProc2(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
984 struct rt_mlme_assoc_req AssocReq;
985 struct rt_mlme_auth_req AuthReq;
987 if (Elem->MsgType == MT2_AUTH_CONF) {
988 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
989 if (Reason == MLME_SUCCESS) {
990 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
991 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid,
992 pAd->MlmeAux.CapabilityInfo,
994 pAd->StaCfg.DefaultListenCount);
996 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
998 sizeof(struct rt_mlme_assoc_req),
1001 pAd->Mlme.CntlMachine.CurrState =
1005 if ((pAd->StaCfg.AuthMode ==
1006 Ndis802_11AuthModeAutoSwitch)
1007 && (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared)) {
1008 DBGPRINT(RT_DEBUG_TRACE,
1009 ("CNTL - AUTH FAIL, try OPEN system...\n"));
1010 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid,
1011 Ndis802_11AuthModeOpen);
1012 MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
1014 sizeof(struct rt_mlme_auth_req),
1017 pAd->Mlme.CntlMachine.CurrState =
1020 /* not success, try next BSS */
1021 DBGPRINT(RT_DEBUG_TRACE,
1022 ("CNTL - AUTH FAIL, give up; try next BSS\n"));
1023 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; /*??????? */
1024 pAd->MlmeAux.BssIdx++;
1025 IterateOnBssTab(pAd);
1032 ==========================================================================
1035 IRQL = DISPATCH_LEVEL
1037 ==========================================================================
1039 void CntlWaitAssocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1043 if (Elem->MsgType == MT2_ASSOC_CONF) {
1044 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
1045 if (Reason == MLME_SUCCESS) {
1046 if (pAd->CommonCfg.bWirelessEvent) {
1047 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG,
1049 Content[BSSID_WCID].Addr,
1053 LinkUp(pAd, BSS_INFRA);
1054 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1055 DBGPRINT(RT_DEBUG_TRACE,
1056 ("CNTL - Association successful on BSS #%ld\n",
1057 pAd->MlmeAux.BssIdx));
1059 /* not success, try next BSS */
1060 DBGPRINT(RT_DEBUG_TRACE,
1061 ("CNTL - Association fails on BSS #%ld\n",
1062 pAd->MlmeAux.BssIdx));
1063 pAd->MlmeAux.BssIdx++;
1064 IterateOnBssTab(pAd);
1070 ==========================================================================
1073 IRQL = DISPATCH_LEVEL
1075 ==========================================================================
1077 void CntlWaitReassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1081 if (Elem->MsgType == MT2_REASSOC_CONF) {
1082 NdisMoveMemory(&Result, Elem->Msg, sizeof(u16));
1083 if (Result == MLME_SUCCESS) {
1084 /* send wireless event - for association */
1085 if (pAd->CommonCfg.bWirelessEvent)
1086 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG,
1088 Content[BSSID_WCID].Addr,
1092 /* NDIS requires a new Link UP indication but no Link Down for RE-ASSOC */
1094 LinkUp(pAd, BSS_INFRA);
1096 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1097 DBGPRINT(RT_DEBUG_TRACE,
1098 ("CNTL - Re-assocition successful on BSS #%ld\n",
1099 pAd->MlmeAux.RoamIdx));
1101 /* reassoc failed, try to pick next BSS in the BSS Table */
1102 DBGPRINT(RT_DEBUG_TRACE,
1103 ("CNTL - Re-assocition fails on BSS #%ld\n",
1104 pAd->MlmeAux.RoamIdx));
1106 pAd->MlmeAux.RoamIdx++;
1107 IterateOnBssTab2(pAd);
1113 void AdhocTurnOnQos(struct rt_rtmp_adapter *pAd)
1115 #define AC0_DEF_TXOP 0
1116 #define AC1_DEF_TXOP 0
1117 #define AC2_DEF_TXOP 94
1118 #define AC3_DEF_TXOP 47
1120 /* Turn on QOs if use HT rate. */
1121 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) {
1122 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1123 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1124 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1125 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1126 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1128 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1129 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1130 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1131 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1133 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1134 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1135 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1136 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1138 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1139 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1140 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1141 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1143 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1147 ==========================================================================
1150 IRQL = DISPATCH_LEVEL
1152 ==========================================================================
1154 void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType)
1159 u8 Value = 0, idx = 0, HashIdx = 0;
1160 struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry = NULL;
1162 /* Init ChannelQuality to prevent DEAD_CQI at initial LinkUp */
1163 pAd->Mlme.ChannelQuality = 50;
1165 pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid);
1167 MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
1171 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1174 /* ASSOC - DisassocTimeoutAction */
1175 /* CNTL - Dis-associate successful */
1177 /* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */
1179 /* To prevent DisassocTimeoutAction to call Link down after we link up, */
1180 /* cancel the DisassocTimer no matter what it start or not. */
1182 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1184 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1186 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1189 /* Before power save before link up function, We will force use 1R. */
1190 /* So after link up, check Rx antenna # again. */
1191 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1192 if (pAd->Antenna.field.RxPath == 3) {
1194 } else if (pAd->Antenna.field.RxPath == 2) {
1196 } else if (pAd->Antenna.field.RxPath == 1) {
1199 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1200 pAd->StaCfg.BBPR3 = Value;
1201 #endif /* RTMP_MAC_PCI // */
1203 if (BssType == BSS_ADHOC) {
1204 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1205 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1207 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1208 AdhocTurnOnQos(pAd);
1210 DBGPRINT(RT_DEBUG_TRACE, ("Adhoc LINK UP!\n"));
1212 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1213 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1215 DBGPRINT(RT_DEBUG_TRACE, ("Infra LINK UP!\n"));
1219 /* reset Tx beamforming bit */
1220 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1222 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1223 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1225 /* Change to AP channel */
1226 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
1227 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) {
1228 /* Must use 40MHz. */
1229 pAd->CommonCfg.BBPCurrentBW = BW_40;
1230 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1231 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1233 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1236 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1238 /* RX : control channel at lower */
1239 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1241 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1243 pAd->StaCfg.BBPR3 = Value;
1244 #endif /* RTMP_MAC_PCI // */
1246 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1248 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1250 if (pAd->MACVersion == 0x28600100) {
1251 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1252 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1253 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1254 DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
1257 DBGPRINT(RT_DEBUG_TRACE,
1258 ("40MHz Lower LINK UP! Control Channel at Below. Central = %d \n",
1259 pAd->CommonCfg.CentralChannel));
1260 } else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
1261 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth ==
1263 /* Must use 40MHz. */
1264 pAd->CommonCfg.BBPCurrentBW = BW_40;
1265 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1266 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1268 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1271 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1273 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1275 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1277 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1279 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1281 pAd->StaCfg.BBPR3 = Value;
1282 #endif /* RTMP_MAC_PCI // */
1284 if (pAd->MACVersion == 0x28600100) {
1285 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1286 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1287 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1288 DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
1291 DBGPRINT(RT_DEBUG_TRACE,
1292 ("40MHz Upper LINK UP! Control Channel at UpperCentral = %d \n",
1293 pAd->CommonCfg.CentralChannel));
1295 pAd->CommonCfg.BBPCurrentBW = BW_20;
1296 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1297 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1298 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1300 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1302 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1304 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1306 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1308 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1310 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1312 pAd->StaCfg.BBPR3 = Value;
1313 #endif /* RTMP_MAC_PCI // */
1315 if (pAd->MACVersion == 0x28600100) {
1316 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1317 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1318 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1319 DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
1322 DBGPRINT(RT_DEBUG_TRACE, ("20MHz LINK UP!\n"));
1325 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1328 /* Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission */
1330 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66,
1331 &pAd->BbpTuning.R66CurrentValue);
1333 DBGPRINT(RT_DEBUG_TRACE,
1334 ("LINK UP! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1335 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid,
1336 pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1338 DBGPRINT(RT_DEBUG_TRACE,
1339 ("LINK UP! (Density =%d, )\n",
1340 pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1342 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1344 AsicSetSlotTime(pAd, TRUE);
1345 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1347 /* Call this for RTS protection for legacy rate, we will always enable RTS threshold, but normally it will not hit */
1348 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE,
1351 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)) {
1352 /* Update HT protection for based on AP's operating mode. */
1353 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) {
1354 AsicUpdateProtect(pAd,
1355 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1356 OperaionMode, ALLN_SETPROTECT, FALSE,
1359 AsicUpdateProtect(pAd,
1360 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1361 OperaionMode, ALLN_SETPROTECT, FALSE,
1365 NdisZeroMemory(&pAd->DrsCounters, sizeof(struct rt_counter_drs));
1367 NdisGetSystemUpTime(&Now);
1368 pAd->StaCfg.LastBeaconRxTime = Now; /* last RX timestamp */
1370 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1371 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo)) {
1372 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1375 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1377 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE) {
1379 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1381 if (BssType == BSS_ADHOC) {
1382 MakeIbssBeacon(pAd);
1383 if ((pAd->CommonCfg.Channel > 14)
1384 && (pAd->CommonCfg.bIEEE80211H == 1)
1385 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) {
1388 AsicEnableIbssSync(pAd);
1391 /* In ad hoc mode, use MAC table from index 1. */
1392 /* 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. */
1393 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1394 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1396 /* If WEP is enabled, add key material and cipherAlg into Asic */
1397 /* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */
1399 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) {
1403 for (idx = 0; idx < SHARE_KEY_NUM; idx++) {
1404 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1405 Key = pAd->SharedKey[BSS0][idx].Key;
1407 if (pAd->SharedKey[BSS0][idx].KeyLen > 0) {
1408 /* Set key material and cipherAlg to Asic */
1409 AsicAddSharedKeyEntry(pAd, BSS0, idx,
1413 if (idx == pAd->StaCfg.DefaultKeyId) {
1414 /* Update WCID attribute table and IVEIV table for this group key table */
1415 RTMPAddWcidAttributeEntry(pAd,
1425 /* If WPANone is enabled, add key material and cipherAlg into Asic */
1426 /* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */
1427 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
1428 pAd->StaCfg.DefaultKeyId = 0; /* always be zero */
1430 NdisZeroMemory(&pAd->SharedKey[BSS0][0],
1431 sizeof(struct rt_cipher_key));
1432 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1433 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key,
1434 pAd->StaCfg.PMK, LEN_TKIP_EK);
1436 if (pAd->StaCfg.PairCipher ==
1437 Ndis802_11Encryption2Enabled) {
1438 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic,
1439 &pAd->StaCfg.PMK[16],
1441 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic,
1442 &pAd->StaCfg.PMK[16],
1445 /* Decide its ChiperAlg */
1446 if (pAd->StaCfg.PairCipher ==
1447 Ndis802_11Encryption2Enabled)
1448 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1449 else if (pAd->StaCfg.PairCipher ==
1450 Ndis802_11Encryption3Enabled)
1451 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1453 DBGPRINT(RT_DEBUG_TRACE,
1454 ("Unknow Cipher (=%d), set Cipher to AES\n",
1455 pAd->StaCfg.PairCipher));
1456 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1459 /* Set key material and cipherAlg to Asic */
1460 AsicAddSharedKeyEntry(pAd,
1463 pAd->SharedKey[BSS0][0].CipherAlg,
1464 pAd->SharedKey[BSS0][0].Key,
1465 pAd->SharedKey[BSS0][0].TxMic,
1466 pAd->SharedKey[BSS0][0].RxMic);
1468 /* Update WCID attribute table and IVEIV table for this group key table */
1469 RTMPAddWcidAttributeEntry(pAd, BSS0, 0,
1470 pAd->SharedKey[BSS0][0].
1475 } else /* BSS_INFRA */
1477 /* Check the new SSID with last SSID */
1478 while (Cancelled == TRUE) {
1479 if (pAd->CommonCfg.LastSsidLen ==
1480 pAd->CommonCfg.SsidLen) {
1481 if (RTMPCompareMemory
1482 (pAd->CommonCfg.LastSsid,
1483 pAd->CommonCfg.Ssid,
1484 pAd->CommonCfg.LastSsidLen) == 0) {
1485 /* Link to the old one no linkdown is required. */
1489 /* Send link down event before set to link up */
1490 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1491 RTMP_IndicateMediaState(pAd);
1492 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1493 DBGPRINT(RT_DEBUG_TRACE,
1494 ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1499 /* On WPA mode, Remove All Keys if not connect to the last BSSID */
1500 /* Key will be set after 4-way handshake. */
1502 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
1505 /* Remove all WPA keys */
1506 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1507 RTMPWPARemoveAllKeys(pAd);
1508 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1509 pAd->StaCfg.PrivacyFilter =
1510 Ndis802_11PrivFilter8021xWEP;
1512 /* Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP */
1513 /* If IV related values are too large in GroupMsg2, AP would ignore this message. */
1515 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1516 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1519 /* the decision of using "short slot time" or not may change dynamically due to */
1520 /* new STA association to the AP. so we have to decide that upon parsing BEACON, not here */
1523 /* the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically */
1524 /* due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here */
1527 ComposeNullFrame(pAd);
1529 AsicEnableBssSync(pAd);
1531 /* Add BSSID to WCID search table */
1532 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1534 /* If WEP is enabled, add pairwise and shared key */
1535 if (((pAd->StaCfg.WpaSupplicantUP) &&
1536 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1537 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1538 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) &&
1539 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled))) {
1543 for (idx = 0; idx < SHARE_KEY_NUM; idx++) {
1544 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1545 Key = pAd->SharedKey[BSS0][idx].Key;
1547 if (pAd->SharedKey[BSS0][idx].KeyLen > 0) {
1548 /* Set key material and cipherAlg to Asic */
1549 AsicAddSharedKeyEntry(pAd, BSS0, idx,
1553 if (idx == pAd->StaCfg.DefaultKeyId) {
1554 /* Assign group key info */
1555 RTMPAddWcidAttributeEntry(pAd,
1561 pEntry->Aid = BSSID_WCID;
1562 /* Assign pairwise key info */
1563 RTMPAddWcidAttributeEntry(pAd,
1572 /* only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode */
1573 /* should wait until at least 2 active nodes in this BSSID. */
1574 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1577 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) {
1578 pAd->IndicateMediaState = NdisMediaStateConnected;
1579 pAd->ExtraInfo = GENERAL_LINK_UP;
1580 RTMP_IndicateMediaState(pAd);
1581 } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1582 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1584 if (pAd->StaCfg.WpaSupplicantUP ==
1585 WPA_SUPPLICANT_DISABLE)
1586 RTMPSetTimer(&pAd->Mlme.LinkDownTimer,
1591 /* Add BSSID in my MAC Table. */
1592 NdisAcquireSpinLock(&pAd->MacTabLock);
1593 /* add this MAC entry into HASH table */
1595 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1596 if (pAd->MacTab.Hash[HashIdx] == NULL) {
1597 pAd->MacTab.Hash[HashIdx] = pEntry;
1599 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1600 while (pCurrEntry->pNext != NULL) {
1601 pCurrEntry = pCurrEntry->pNext;
1603 pCurrEntry->pNext = pEntry;
1606 RTMPMoveMemory(pEntry->Addr, pAd->CommonCfg.Bssid,
1608 pEntry->Aid = BSSID_WCID;
1610 pEntry->ValidAsCLI = TRUE; /*Although this is bssid..still set ValidAsCl */
1611 pAd->MacTab.Size = 1; /* infra mode always set MACtab size =1. */
1612 pEntry->Sst = SST_ASSOC;
1613 pEntry->AuthState = SST_ASSOC;
1614 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1615 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1616 if (pEntry->AuthMode < Ndis802_11AuthModeWPA) {
1617 pEntry->WpaState = AS_NOTUSE;
1618 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1620 pEntry->WpaState = AS_PTKSTART;
1621 pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1623 NdisReleaseSpinLock(&pAd->MacTabLock);
1625 DBGPRINT(RT_DEBUG_TRACE,
1626 ("LINK UP! ClientStatusFlags=%lx)\n",
1627 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1629 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1630 MlmeUpdateHtTxRates(pAd, BSS0);
1631 DBGPRINT(RT_DEBUG_TRACE,
1632 ("LINK UP! (StaActive.bHtEnable =%d, )\n",
1633 pAd->StaActive.SupportedPhyInfo.bHtEnable));
1635 if (pAd->CommonCfg.bAggregationCapable) {
1636 if ((pAd->CommonCfg.bPiggyBackCapable)
1637 && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3) {
1638 OPSTATUS_SET_FLAG(pAd,
1639 fOP_STATUS_PIGGYBACK_INUSED);
1640 OPSTATUS_SET_FLAG(pAd,
1641 fOP_STATUS_AGGREGATION_INUSED);
1642 CLIENT_STATUS_SET_FLAG(pEntry,
1643 fCLIENT_STATUS_AGGREGATION_CAPABLE);
1644 CLIENT_STATUS_SET_FLAG(pEntry,
1645 fCLIENT_STATUS_PIGGYBACK_CAPABLE);
1646 RTMPSetPiggyBack(pAd, TRUE);
1647 DBGPRINT(RT_DEBUG_TRACE,
1648 ("Turn on Piggy-Back\n"));
1649 } else if (pAd->MlmeAux.APRalinkIe & 0x00000001) {
1650 OPSTATUS_SET_FLAG(pAd,
1651 fOP_STATUS_AGGREGATION_INUSED);
1652 CLIENT_STATUS_SET_FLAG(pEntry,
1653 fCLIENT_STATUS_AGGREGATION_CAPABLE);
1654 DBGPRINT(RT_DEBUG_TRACE,
1655 ("Ralink Aggregation\n"));
1659 if (pAd->MlmeAux.APRalinkIe != 0x0) {
1660 if (CLIENT_STATUS_TEST_FLAG
1661 (pEntry, fCLIENT_STATUS_RDG_CAPABLE)) {
1664 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1665 CLIENT_STATUS_SET_FLAG(pEntry,
1666 fCLIENT_STATUS_RALINK_CHIPSET);
1668 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1669 CLIENT_STATUS_CLEAR_FLAG(pEntry,
1670 fCLIENT_STATUS_RALINK_CHIPSET);
1674 DBGPRINT(RT_DEBUG_TRACE,
1675 ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n",
1676 pAd->CommonCfg.BACapability.word,
1677 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1680 RTMPSetLED(pAd, LED_LINK_UP);
1682 pAd->Mlme.PeriodicRound = 0;
1683 pAd->Mlme.OneSecPeriodicRound = 0;
1684 pAd->bConfigChanged = FALSE; /* Reset config flag */
1685 pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information after link is up */
1687 /* Set basic auto fall back */
1692 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID],
1693 &pTable, &TableSize,
1694 &pAd->CommonCfg.TxRateIndex);
1695 AsicUpdateAutoFallBackTable(pAd, pTable);
1698 NdisAcquireSpinLock(&pAd->MacTabLock);
1699 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1700 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1701 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE) {
1702 pEntry->bAutoTxRateSwitch = FALSE;
1704 if (pEntry->HTPhyMode.field.MCS == 32)
1705 pEntry->HTPhyMode.field.ShortGI = GI_800;
1707 if ((pEntry->HTPhyMode.field.MCS > MCS_7)
1708 || (pEntry->HTPhyMode.field.MCS == 32))
1709 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1711 /* If the legacy mode is set, overwrite the transmit setting of this entry. */
1712 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1713 RTMPUpdateLegacyTxSetting((u8)pAd->StaCfg.
1714 DesiredTransmitSetting.field.
1715 FixedTxMode, pEntry);
1717 pEntry->bAutoTxRateSwitch = TRUE;
1718 NdisReleaseSpinLock(&pAd->MacTabLock);
1720 /* Let Link Status Page display first initial rate. */
1721 pAd->LastTxRate = (u16)(pEntry->HTPhyMode.word);
1722 /* Select DAC according to HT or Legacy */
1723 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00) {
1724 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1726 if (pAd->Antenna.field.TxPath == 2) {
1729 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1731 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1733 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1736 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) {
1737 } else if (pEntry->MaxRAmpduFactor == 0) {
1738 /* If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0. */
1739 /* Because our Init value is 1 at MACRegTable. */
1740 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1742 /* Patch for Marvel AP to gain high throughput */
1743 /* Need to set as following, */
1744 /* 1. Set txop in register-EDCA_AC0_CFG as 0x60 */
1745 /* 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero */
1746 /* 3. PBF_MAX_PCNT as 0x1F3FBF9F */
1747 /* 4. kick per two packets when dequeue */
1749 /* Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable */
1751 /* if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is. */
1752 if (!((pAd->CommonCfg.RxStream == 1) && (pAd->CommonCfg.TxStream == 1))
1753 && (pAd->StaCfg.bForceTxBurst == FALSE)
1755 (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1756 && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
1757 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)
1758 && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))) {
1759 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1761 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1763 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1764 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1765 } else if (pAd->CommonCfg.bEnableTxBurst) {
1766 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1769 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1770 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1772 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1773 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1775 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1777 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1779 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1780 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1783 /* Re-check to turn on TX burst or not. */
1784 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE)
1785 && ((STA_WEP_ON(pAd)) || (STA_TKIP_ON(pAd)))) {
1786 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1787 if (pAd->CommonCfg.bEnableTxBurst) {
1789 /* Force disable TXOP value in this case. The same action in MLMEUpdateProtect too. */
1790 /* I didn't change PBF_MAX_PCNT setting. */
1791 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1792 MACValue &= 0xFFFFFF00;
1793 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1794 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1797 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1800 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1801 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1802 DBGPRINT(RT_DEBUG_TRACE,
1803 ("pAd->bNextDisableRxBA= %d \n",
1804 pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1805 /* BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap */
1806 /* Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver. */
1807 /* Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same. */
1809 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled) {
1810 if (pAd->StaCfg.WpaSupplicantUP &&
1811 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1812 (pAd->StaCfg.IEEE8021X == TRUE)) ;
1814 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1815 pAd->StaCfg.PrivacyFilter =
1816 Ndis802_11PrivFilterAcceptAll;
1820 NdisAcquireSpinLock(&pAd->MacTabLock);
1821 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1822 NdisReleaseSpinLock(&pAd->MacTabLock);
1825 /* Patch Atheros AP TX will breakdown issue. */
1826 /* AP Model: DLink DWL-8200AP */
1828 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)
1829 && STA_TKIP_ON(pAd)) {
1830 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1832 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1835 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1837 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1841 ==========================================================================
1843 Routine Description:
1844 Disconnect current BSSID
1847 pAd - Pointer to our adapter
1848 IsReqFromAP - Request from AP
1853 IRQL = DISPATCH_LEVEL
1856 We need more information to know it's this requst from AP.
1857 If yes! we need to do extra handling, for example, remove the WPA key.
1858 Otherwise on 4-way handshaking will fail, since the WPA key didn't get
1859 removed while auto reconnect.
1860 Disconnect request from AP, it means we will start afresh 4-way handshaking
1863 ==========================================================================
1865 void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP)
1867 u8 i, ByteValue = 0;
1869 /* Do nothing if monitor mode is on */
1870 if (MONITOR_ON(pAd))
1873 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1874 /* Comment the codes, because the line 2291 call the same function. */
1875 /* RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); */
1876 /* Not allowed go to sleep within the linkdown function. */
1877 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1879 if (pAd->CommonCfg.bWirelessEvent) {
1880 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
1881 pAd->MacTab.Content[BSSID_WCID].Addr,
1885 DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN!\n"));
1886 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1889 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
1891 pAd->Mlme.bPsPollTimerRunning = FALSE;
1892 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1895 pAd->bPCIclkOff = FALSE;
1896 #endif /* RTMP_MAC_PCI // */
1898 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
1899 || RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)
1900 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) {
1901 AUTO_WAKEUP_STRUC AutoWakeupCfg;
1902 AsicForceWakeup(pAd, TRUE);
1903 AutoWakeupCfg.word = 0;
1904 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1905 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1908 pAd->bPCIclkOff = FALSE;
1909 #endif /* RTMP_MAC_PCI // */
1911 if (ADHOC_ON(pAd)) /* Adhoc mode link down */
1913 DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 1!\n"));
1915 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1916 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1917 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1918 RTMP_IndicateMediaState(pAd);
1919 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1920 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid,
1921 pAd->CommonCfg.Channel);
1922 DBGPRINT(RT_DEBUG_TRACE,
1923 (" MacTab.Size=%d !\n", pAd->MacTab.Size));
1924 } else /* Infra structure mode */
1926 DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 2!\n"));
1928 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1929 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1931 /* Saved last SSID for linkup comparison */
1932 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1933 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid,
1934 pAd->CommonCfg.LastSsidLen);
1935 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1936 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE) {
1937 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1938 RTMP_IndicateMediaState(pAd);
1939 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1940 DBGPRINT(RT_DEBUG_TRACE,
1941 ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1942 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1945 /* If disassociation request is from NDIS, then we don't need to delete BSSID from entry. */
1946 /* Otherwise lost beacon or receive De-Authentication from AP, */
1947 /* then we should delete BSSID from BssTable. */
1948 /* If we don't delete from entry, roaming will fail. */
1950 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid,
1951 pAd->CommonCfg.Channel);
1954 /* restore back to - */
1955 /* 1. long slot (20 us) or short slot (9 us) time */
1956 /* 2. turn on/off RTS/CTS and/or CTS-to-self protection */
1957 /* 3. short preamble */
1958 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1962 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
1963 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1964 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid,
1965 pAd->MacTab.Content[i].Addr);
1968 AsicSetSlotTime(pAd, TRUE); /*FALSE); */
1969 AsicSetEdcaParm(pAd, NULL);
1972 RTMPSetLED(pAd, LED_LINK_DOWN);
1973 pAd->LedIndicatorStrength = 0xF0;
1974 RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, firmware has not done it. */
1976 AsicDisableSync(pAd);
1978 pAd->Mlme.PeriodicRound = 0;
1979 pAd->Mlme.OneSecPeriodicRound = 0;
1981 if (pAd->StaCfg.BssType == BSS_INFRA) {
1982 /* Remove StaCfg Information after link down */
1983 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1984 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1985 pAd->CommonCfg.SsidLen = 0;
1988 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(struct rt_ht_capability_ie));
1989 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(struct rt_add_ht_info_ie));
1990 pAd->MlmeAux.HtCapabilityLen = 0;
1991 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1993 /* Reset WPA-PSK state. Only reset when supplicant enabled */
1994 if (pAd->StaCfg.WpaState != SS_NOTUSE) {
1995 pAd->StaCfg.WpaState = SS_START;
1996 /* Clear Replay counter */
1997 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2001 /* if link down come from AP, we need to remove all WPA keys on WPA mode. */
2002 /* otherwise will cause 4-way handshaking failed, since the WPA key not empty. */
2004 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)) {
2005 /* Remove all WPA keys */
2006 RTMPWPARemoveAllKeys(pAd);
2008 /* 802.1x port control */
2010 /* Prevent clear PortSecured here with static WEP */
2011 /* NetworkManger set security policy first then set SSID to connect AP. */
2012 if (pAd->StaCfg.WpaSupplicantUP &&
2013 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
2014 (pAd->StaCfg.IEEE8021X == FALSE)) {
2015 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2017 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2018 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2021 NdisAcquireSpinLock(&pAd->MacTabLock);
2022 NdisZeroMemory(&pAd->MacTab, sizeof(struct rt_mac_table));
2023 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2024 NdisReleaseSpinLock(&pAd->MacTabLock);
2026 pAd->StaCfg.MicErrCnt = 0;
2028 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2029 /* Update extra information to link is up */
2030 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2032 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2035 pAd->bUsbTxBulkAggre = FALSE;
2036 #endif /* RTMP_MAC_USB // */
2038 /* Clean association information */
2039 NdisZeroMemory(&pAd->StaCfg.AssocInfo,
2040 sizeof(struct rt_ndis_802_11_association_information));
2041 pAd->StaCfg.AssocInfo.Length =
2042 sizeof(struct rt_ndis_802_11_association_information);
2043 pAd->StaCfg.ReqVarIELen = 0;
2044 pAd->StaCfg.ResVarIELen = 0;
2047 /* Reset RSSI value after link down */
2049 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2050 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2051 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2052 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2053 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2054 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2056 /* Restore MlmeRate */
2057 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2058 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2061 /* After Link down, reset piggy-back setting in ASIC. Disable RDG. */
2063 if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
2064 pAd->CommonCfg.BBPCurrentBW = BW_20;
2065 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2066 ByteValue &= (~0x18);
2067 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2070 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2071 ByteValue &= (~0x18);
2072 if (pAd->Antenna.field.TxPath == 2) {
2075 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2077 RTMPSetPiggyBack(pAd, FALSE);
2078 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2080 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2082 /* Restore all settings in the following. */
2083 AsicUpdateProtect(pAd, 0,
2084 (ALLN_SETPROTECT | CCKSETPROTECT | OFDMSETPROTECT),
2086 AsicDisableRDG(pAd);
2087 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2088 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2090 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2091 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2093 /* Allow go to sleep after linkdown steps. */
2094 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
2096 RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
2099 if ((IS_RT30xx(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd))
2100 && (pAd->Antenna.field.RxPath > 1 || pAd->Antenna.field.TxPath > 1)) {
2101 RTMP_ASIC_MMPS_DISABLE(pAd);
2103 #endif /* RT30xx // */
2107 ==========================================================================
2110 IRQL = DISPATCH_LEVEL
2112 ==========================================================================
2114 void IterateOnBssTab(struct rt_rtmp_adapter *pAd)
2116 struct rt_mlme_start_req StartReq;
2117 struct rt_mlme_join_req JoinReq;
2118 unsigned long BssIdx;
2120 /* Change the wepstatus to original wepstatus */
2121 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2122 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2123 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2125 BssIdx = pAd->MlmeAux.BssIdx;
2126 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr) {
2127 /* Check cipher suite, AP must have more secured cipher than station setting */
2128 /* Set the Pairwise and Group cipher to match the intended AP setting */
2129 /* We can only connect to AP with less secured cipher setting */
2130 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
2131 || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) {
2132 pAd->StaCfg.GroupCipher =
2133 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
2136 if (pAd->StaCfg.WepStatus ==
2137 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
2139 pAd->StaCfg.PairCipher =
2140 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
2142 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
2143 PairCipherAux != Ndis802_11WEPDisabled)
2144 pAd->StaCfg.PairCipher =
2145 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
2147 else /* There is no PairCipher Aux, downgrade our capability to TKIP */
2148 pAd->StaCfg.PairCipher =
2149 Ndis802_11Encryption2Enabled;
2150 } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
2151 || (pAd->StaCfg.AuthMode ==
2152 Ndis802_11AuthModeWPA2PSK)) {
2153 pAd->StaCfg.GroupCipher =
2154 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
2157 if (pAd->StaCfg.WepStatus ==
2158 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
2160 pAd->StaCfg.PairCipher =
2161 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
2163 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
2164 PairCipherAux != Ndis802_11WEPDisabled)
2165 pAd->StaCfg.PairCipher =
2166 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
2168 else /* There is no PairCipher Aux, downgrade our capability to TKIP */
2169 pAd->StaCfg.PairCipher =
2170 Ndis802_11Encryption2Enabled;
2172 /* RSN capability */
2173 pAd->StaCfg.RsnCapability =
2174 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
2177 /* Set Mix cipher flag */
2178 pAd->StaCfg.bMixCipher =
2179 (pAd->StaCfg.PairCipher ==
2180 pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2181 /*if (pAd->StaCfg.bMixCipher == TRUE)
2183 // If mix cipher, re-build RSNIE
2184 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2187 DBGPRINT(RT_DEBUG_TRACE,
2188 ("CNTL - iterate BSS %ld of %d\n", BssIdx,
2189 pAd->MlmeAux.SsidBssTab.BssNr));
2190 JoinParmFill(pAd, &JoinReq, BssIdx);
2191 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ,
2192 sizeof(struct rt_mlme_join_req), &JoinReq);
2193 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2194 } else if (pAd->StaCfg.BssType == BSS_ADHOC) {
2195 DBGPRINT(RT_DEBUG_TRACE,
2196 ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",
2197 pAd->MlmeAux.Ssid));
2198 StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid,
2199 pAd->MlmeAux.SsidLen);
2200 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
2201 sizeof(struct rt_mlme_start_req), &StartReq);
2202 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2203 } else /* no more BSS */
2207 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2208 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2209 DBGPRINT(RT_DEBUG_TRACE,
2210 ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",
2211 pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
2214 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2218 /* for re-association only */
2219 /* IRQL = DISPATCH_LEVEL */
2220 void IterateOnBssTab2(struct rt_rtmp_adapter *pAd)
2222 struct rt_mlme_assoc_req ReassocReq;
2223 unsigned long BssIdx;
2224 struct rt_bss_entry *pBss;
2226 BssIdx = pAd->MlmeAux.RoamIdx;
2227 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2229 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr) {
2230 DBGPRINT(RT_DEBUG_TRACE,
2231 ("CNTL - iterate BSS %ld of %d\n", BssIdx,
2232 pAd->MlmeAux.RoamTab.BssNr));
2234 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2235 AsicLockChannel(pAd, pBss->Channel);
2237 /* reassociate message has the same structure as associate message */
2238 AssocParmFill(pAd, &ReassocReq, pBss->Bssid,
2239 pBss->CapabilityInfo, ASSOC_TIMEOUT,
2240 pAd->StaCfg.DefaultListenCount);
2241 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2242 sizeof(struct rt_mlme_assoc_req), &ReassocReq);
2244 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2245 } else /* no more BSS */
2249 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2250 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2251 DBGPRINT(RT_DEBUG_TRACE,
2252 ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",
2253 pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
2256 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2261 ==========================================================================
2264 IRQL = DISPATCH_LEVEL
2266 ==========================================================================
2268 void JoinParmFill(struct rt_rtmp_adapter *pAd,
2269 struct rt_mlme_join_req *JoinReq, unsigned long BssIdx)
2271 JoinReq->BssIdx = BssIdx;
2275 ==========================================================================
2278 IRQL = DISPATCH_LEVEL
2280 ==========================================================================
2282 void ScanParmFill(struct rt_rtmp_adapter *pAd,
2283 struct rt_mlme_scan_req *ScanReq,
2285 u8 SsidLen, u8 BssType, u8 ScanType)
2287 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2288 ScanReq->SsidLen = SsidLen;
2289 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2290 ScanReq->BssType = BssType;
2291 ScanReq->ScanType = ScanType;
2295 ==========================================================================
2298 IRQL = DISPATCH_LEVEL
2300 ==========================================================================
2302 void StartParmFill(struct rt_rtmp_adapter *pAd,
2303 struct rt_mlme_start_req *StartReq,
2304 char Ssid[], u8 SsidLen)
2306 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2307 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2308 StartReq->SsidLen = SsidLen;
2312 ==========================================================================
2315 IRQL = DISPATCH_LEVEL
2317 ==========================================================================
2319 void AuthParmFill(struct rt_rtmp_adapter *pAd,
2320 struct rt_mlme_auth_req *AuthReq,
2323 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2325 AuthReq->Timeout = AUTH_TIMEOUT;
2329 ==========================================================================
2332 IRQL = DISPATCH_LEVEL
2334 ==========================================================================
2337 void ComposePsPoll(struct rt_rtmp_adapter *pAd)
2339 NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
2340 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2341 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2342 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2343 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2344 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2347 /* IRQL = DISPATCH_LEVEL */
2348 void ComposeNullFrame(struct rt_rtmp_adapter *pAd)
2350 NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11));
2351 pAd->NullFrame.FC.Type = BTYPE_DATA;
2352 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2353 pAd->NullFrame.FC.ToDs = 1;
2354 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2355 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2356 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2358 #endif /* RTMP_MAC_PCI // */
2360 void MlmeCntlConfirm(struct rt_rtmp_adapter *pAd, unsigned long MsgType, u16 Msg)
2362 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(u16),
2366 void ComposePsPoll(struct rt_rtmp_adapter *pAd)
2368 struct rt_txinfo *pTxInfo;
2369 struct rt_txwi * pTxWI;
2371 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2372 NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
2374 pAd->PsPollFrame.FC.PwrMgmt = 0;
2375 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2376 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2377 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2378 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2379 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2381 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.
2382 WirelessPacket[0], 100);
2384 (struct rt_txinfo *)& pAd->PsPollContext.TransferBuffer->field.
2386 RTMPWriteTxInfo(pAd, pTxInfo,
2387 (u16)(sizeof(struct rt_pspoll_frame) + TXWI_SIZE), TRUE,
2388 EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2390 (struct rt_txwi *) & pAd->PsPollContext.TransferBuffer->field.
2391 WirelessPacket[TXINFO_SIZE];
2392 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0,
2393 BSSID_WCID, (sizeof(struct rt_pspoll_frame)), 0, 0,
2394 (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
2395 IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2396 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.
2397 WirelessPacket[TXWI_SIZE + TXINFO_SIZE],
2398 &pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
2399 /* Append 4 extra zero bytes. */
2400 pAd->PsPollContext.BulkOutSize =
2401 TXINFO_SIZE + TXWI_SIZE + sizeof(struct rt_pspoll_frame) + 4;
2404 /* IRQL = DISPATCH_LEVEL */
2405 void ComposeNullFrame(struct rt_rtmp_adapter *pAd)
2407 struct rt_txinfo *pTxInfo;
2408 struct rt_txwi * pTxWI;
2410 NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11));
2411 pAd->NullFrame.FC.Type = BTYPE_DATA;
2412 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2413 pAd->NullFrame.FC.ToDs = 1;
2414 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2415 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2416 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2417 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.
2418 WirelessPacket[0], 100);
2420 (struct rt_txinfo *)& pAd->NullContext.TransferBuffer->field.
2422 RTMPWriteTxInfo(pAd, pTxInfo,
2423 (u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE), TRUE,
2424 EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2426 (struct rt_txwi *) & pAd->NullContext.TransferBuffer->field.
2427 WirelessPacket[TXINFO_SIZE];
2428 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0,
2429 BSSID_WCID, (sizeof(struct rt_header_802_11)), 0, 0,
2430 (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
2431 IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2432 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.
2433 WirelessPacket[TXWI_SIZE + TXINFO_SIZE], &pAd->NullFrame,
2434 sizeof(struct rt_header_802_11));
2435 pAd->NullContext.BulkOutSize =
2436 TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2438 #endif /* RTMP_MAC_USB // */
2441 ==========================================================================
2443 Pre-build a BEACON frame in the shared memory
2445 IRQL = PASSIVE_LEVEL
2446 IRQL = DISPATCH_LEVEL
2448 ==========================================================================
2450 unsigned long MakeIbssBeacon(struct rt_rtmp_adapter *pAd)
2452 u8 DsLen = 1, IbssLen = 2;
2453 u8 LocalErpIe[3] = { IE_ERP, 1, 0x04 };
2454 struct rt_header_802_11 BcnHdr;
2456 LARGE_INTEGER FakeTimestamp;
2457 unsigned long FrameLen = 0;
2458 struct rt_txwi * pTxWI = &pAd->BeaconTxWI;
2459 u8 *pBeaconFrame = pAd->BeaconBuf;
2461 u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2463 u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2467 if ((pAd->CommonCfg.PhyMode == PHY_11B)
2468 && (pAd->CommonCfg.Channel <= 14)) {
2469 SupRate[0] = 0x82; /* 1 mbps */
2470 SupRate[1] = 0x84; /* 2 mbps */
2471 SupRate[2] = 0x8b; /* 5.5 mbps */
2472 SupRate[3] = 0x96; /* 11 mbps */
2475 } else if (pAd->CommonCfg.Channel > 14) {
2476 SupRate[0] = 0x8C; /* 6 mbps, in units of 0.5 Mbps, basic rate */
2477 SupRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */
2478 SupRate[2] = 0x98; /* 12 mbps, in units of 0.5 Mbps, basic rate */
2479 SupRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */
2480 SupRate[4] = 0xb0; /* 24 mbps, in units of 0.5 Mbps, basic rate */
2481 SupRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */
2482 SupRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */
2483 SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */
2488 /* Also Update MlmeRate & RtsRate for G only & A only */
2490 pAd->CommonCfg.MlmeRate = RATE_6;
2491 pAd->CommonCfg.RtsRate = RATE_6;
2492 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2493 pAd->CommonCfg.MlmeTransmit.field.MCS =
2494 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2495 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
2497 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
2498 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2500 SupRate[0] = 0x82; /* 1 mbps */
2501 SupRate[1] = 0x84; /* 2 mbps */
2502 SupRate[2] = 0x8b; /* 5.5 mbps */
2503 SupRate[3] = 0x96; /* 11 mbps */
2506 ExtRate[0] = 0x0C; /* 6 mbps, in units of 0.5 Mbps, */
2507 ExtRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */
2508 ExtRate[2] = 0x18; /* 12 mbps, in units of 0.5 Mbps, */
2509 ExtRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */
2510 ExtRate[4] = 0x30; /* 24 mbps, in units of 0.5 Mbps, */
2511 ExtRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */
2512 ExtRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */
2513 ExtRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */
2517 pAd->StaActive.SupRateLen = SupRateLen;
2518 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2519 pAd->StaActive.ExtRateLen = ExtRateLen;
2520 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2522 /* compose IBSS beacon frame */
2523 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR,
2524 pAd->CommonCfg.Bssid);
2525 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
2526 || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2527 || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2529 CAP_GENERATE(0, 1, Privacy,
2530 (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort),
2533 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2534 sizeof(struct rt_header_802_11), &BcnHdr,
2535 TIMESTAMP_LEN, &FakeTimestamp,
2536 2, &pAd->CommonCfg.BeaconPeriod,
2539 1, &pAd->CommonCfg.SsidLen,
2540 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2543 SupRateLen, SupRate,
2546 1, &pAd->CommonCfg.Channel,
2548 1, &IbssLen, 2, &pAd->StaActive.AtimWin, END_OF_ARGS);
2550 /* add ERP_IE and EXT_RAE IE of in 802.11g */
2554 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2558 ExtRateLen, ExtRate, END_OF_ARGS);
2561 /* If adhoc secruity is set for WPA-None, append the cipher suite IE */
2562 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
2564 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus,
2567 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2569 1, &pAd->StaCfg.RSNIE_Len,
2570 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2575 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) {
2576 unsigned long TmpLen;
2579 /* add HT Capability IE */
2580 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2581 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2583 MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
2586 HtLen, &pAd->CommonCfg.HtCapability,
2589 HtLen1, &pAd->CommonCfg.AddHTInfo,
2594 /*beacon use reserved WCID 0xff */
2595 if (pAd->CommonCfg.Channel > 14) {
2596 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE,
2597 TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON,
2598 RATE_1, IFS_HTTXOP, FALSE,
2599 &pAd->CommonCfg.MlmeTransmit);
2601 /* Set to use 1Mbps for Adhoc beacon. */
2602 HTTRANSMIT_SETTING Transmit;
2604 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE,
2605 TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON,
2606 RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2609 DBGPRINT(RT_DEBUG_TRACE,
2610 ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2611 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel,
2612 pAd->CommonCfg.PhyMode));