2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 John 2004-08-08 Major modification from RT2560
37 #include "../rt_config.h"
39 u8 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 */
49 u8 CipherSuiteWpaNoneTkipLen =
50 (sizeof(CipherSuiteWpaNoneTkip) / sizeof(u8));
52 u8 CipherSuiteWpaNoneAes[] = {
53 0x00, 0x50, 0xf2, 0x01, /* oui */
54 0x01, 0x00, /* Version */
55 0x00, 0x50, 0xf2, 0x04, /* Multicast */
56 0x01, 0x00, /* Number of unicast */
57 0x00, 0x50, 0xf2, 0x04, /* unicast */
58 0x01, 0x00, /* number of authentication method */
59 0x00, 0x50, 0xf2, 0x00 /* authentication */
62 u8 CipherSuiteWpaNoneAesLen =
63 (sizeof(CipherSuiteWpaNoneAes) / sizeof(u8));
65 /* The following MACRO is called after 1. starting an new IBSS, 2. successfully JOIN an IBSS, */
66 /* or 3. successfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */
67 /* All settings successfuly negotiated furing MLME state machines become final settings */
68 /* and are copied to pAd->StaActive */
69 #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
71 NdisZeroMemory((_pAd)->CommonCfg.Ssid, MAX_LEN_OF_SSID); \
72 (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \
73 NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
74 COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \
75 (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel; \
76 (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel; \
77 (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid; \
78 (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin; \
79 (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo; \
80 (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod; \
81 (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration; \
82 (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod; \
83 (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen; \
84 NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
85 (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen; \
86 NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
87 NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(struct rt_edca_parm));\
88 NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(struct rt_qos_capability_parm));\
89 NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(struct rt_qbss_load_parm));\
90 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid); \
91 (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid; \
92 (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
93 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
94 (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
98 ==========================================================================
103 ==========================================================================
105 void MlmeCntlInit(struct rt_rtmp_adapter *pAd,
106 struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
108 /* Control state machine differs from other state machines, the interface */
109 /* follows the standard interface */
110 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
114 ==========================================================================
117 IRQL = DISPATCH_LEVEL
119 ==========================================================================
121 void MlmeCntlMachinePerformAction(struct rt_rtmp_adapter *pAd,
122 struct rt_state_machine *S,
123 struct rt_mlme_queue_elem *Elem)
125 switch (pAd->Mlme.CntlMachine.CurrState) {
127 CntlIdleProc(pAd, Elem);
129 case CNTL_WAIT_DISASSOC:
130 CntlWaitDisassocProc(pAd, Elem);
133 CntlWaitJoinProc(pAd, Elem);
136 /* CNTL_WAIT_REASSOC is the only state in CNTL machine that does */
137 /* not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)". */
138 /* Therefore not protected by NDIS's "only one outstanding OID request" */
139 /* rule. Which means NDIS may SET OID in the middle of ROAMing attempts. */
140 /* Current approach is to block new SET request at RTMPSetInformation() */
141 /* when CntlMachine.CurrState is not CNTL_IDLE */
142 case CNTL_WAIT_REASSOC:
143 CntlWaitReassocProc(pAd, Elem);
146 case CNTL_WAIT_START:
147 CntlWaitStartProc(pAd, Elem);
150 CntlWaitAuthProc(pAd, Elem);
152 case CNTL_WAIT_AUTH2:
153 CntlWaitAuthProc2(pAd, Elem);
155 case CNTL_WAIT_ASSOC:
156 CntlWaitAssocProc(pAd, Elem);
159 case CNTL_WAIT_OID_LIST_SCAN:
160 if (Elem->MsgType == MT2_SCAN_CONF) {
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);
165 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
168 /* Set LED status to previous status. */
170 if (pAd->bLedOnScanning) {
171 pAd->bLedOnScanning = FALSE;
172 RTMPSetLED(pAd, pAd->LedStatus);
177 case CNTL_WAIT_OID_DISASSOC:
178 if (Elem->MsgType == MT2_DISASSOC_CONF) {
179 LinkDown(pAd, FALSE);
180 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
185 /* This state is for that we want to connect to an AP but */
186 /* it didn't find on BSS List table. So we need to scan the air first, */
187 /* after that we can try to connect to the desired AP if available. */
189 case CNTL_WAIT_SCAN_FOR_CONNECT:
190 if (Elem->MsgType == MT2_SCAN_CONF) {
191 /* Resume TxRing after SCANING complete. We hope the out-of-service time */
192 /* won't be too long to let upper layer time-out the waiting frames */
193 RTMPResumeMsduTransmission(pAd);
195 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) {
196 /* Cisco scan request is finished, prepare beacon report */
197 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE,
198 MT2_AIRONET_SCAN_DONE, 0, NULL);
200 #endif /* CCX_SUPPORT // */
201 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
204 /* Check if we can connect to. */
206 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab,
207 (char *) pAd->MlmeAux.
209 pAd->MlmeAux.AutoReconnectSsidLen);
210 if (pAd->MlmeAux.SsidBssTab.BssNr > 0) {
211 MlmeAutoReconnectLastSSID(pAd);
215 #endif /* RTMP_MAC_USB // */
217 DBGPRINT_ERR(("ERROR! CNTL - Illegal message type(=%ld)",
224 ==========================================================================
227 IRQL = DISPATCH_LEVEL
229 ==========================================================================
231 void CntlIdleProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
233 struct rt_mlme_disassoc_req DisassocReq;
235 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
238 switch (Elem->MsgType) {
239 case OID_802_11_SSID:
240 CntlOidSsidProc(pAd, Elem);
243 case OID_802_11_BSSID:
244 CntlOidRTBssidProc(pAd, Elem);
247 case OID_802_11_BSSID_LIST_SCAN:
248 CntlOidScanProc(pAd, Elem);
251 case OID_802_11_DISASSOCIATE:
252 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid,
253 REASON_DISASSOC_STA_LEAVING);
254 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
255 sizeof(struct rt_mlme_disassoc_req), &DisassocReq);
256 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
258 if (pAd->StaCfg.WpaSupplicantUP !=
259 WPA_SUPPLICANT_ENABLE_WITH_WEB_UI) {
260 /* Set the AutoReconnectSsid to prevent it reconnect to old SSID */
261 /* Since calling this indicate user don't want to connect to that SSID anymore. */
262 pAd->MlmeAux.AutoReconnectSsidLen = 32;
263 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid,
264 pAd->MlmeAux.AutoReconnectSsidLen);
268 case MT2_MLME_ROAMING_REQ:
269 CntlMlmeRoamingProc(pAd, Elem);
272 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
273 WpaMicFailureReportFrame(pAd, Elem);
277 DBGPRINT(RT_DEBUG_TRACE,
278 ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",
284 void CntlOidScanProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
286 struct rt_mlme_scan_req ScanReq;
287 unsigned long BssIdx = BSS_NOT_FOUND;
288 struct rt_bss_entry CurrBss;
290 /* record current BSS if network is connected. */
291 /* 2003-2-13 do not include current IBSS if this is the only STA in this IBSS. */
292 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
294 BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid,
295 (u8 *)pAd->CommonCfg.Ssid,
296 pAd->CommonCfg.SsidLen,
297 pAd->CommonCfg.Channel);
298 if (BssIdx != BSS_NOT_FOUND) {
299 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx],
300 sizeof(struct rt_bss_entry));
303 /* clean up previous SCAN result, add current BSS back to table if any */
304 BssTableInit(&pAd->ScanTab);
305 if (BssIdx != BSS_NOT_FOUND) {
306 /* DDK Note: If the NIC is associated with a particular BSSID and SSID */
307 /* that are not contained in the list of BSSIDs generated by this scan, the */
308 /* BSSID description of the currently associated BSSID and SSID should be */
309 /* appended to the list of BSSIDs in the NIC's database. */
310 /* To ensure this, we append this BSS as the first entry in SCAN result */
311 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss,
312 sizeof(struct rt_bss_entry));
313 pAd->ScanTab.BssNr = 1;
316 ScanParmFill(pAd, &ScanReq, (char *)Elem->Msg, Elem->MsgLen, BSS_ANY,
318 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
319 sizeof(struct rt_mlme_scan_req), &ScanReq);
320 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
324 ==========================================================================
326 Before calling this routine, user desired SSID should already been
327 recorded in CommonCfg.Ssid[]
328 IRQL = DISPATCH_LEVEL
330 ==========================================================================
332 void CntlOidSsidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
334 struct rt_ndis_802_11_ssid * pOidSsid = (struct rt_ndis_802_11_ssid *) Elem->Msg;
335 struct rt_mlme_disassoc_req DisassocReq;
338 /* Step 1. record the desired user settings to MlmeAux */
339 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
340 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
341 pAd->MlmeAux.SsidLen = (u8)pOidSsid->SsidLength;
342 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
343 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
345 pAd->StaCfg.bAutoConnectByBssid = FALSE;
348 /* Update Reconnect Ssid, that user desired to connect. */
350 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
351 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid,
352 pAd->MlmeAux.SsidLen);
353 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
355 /* step 2. find all matching BSS in the lastest SCAN result (inBssTab) */
356 /* & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order */
357 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab,
358 (char *)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
360 DBGPRINT(RT_DEBUG_TRACE,
361 ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
362 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr,
363 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
364 NdisGetSystemUpTime(&Now);
366 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
367 (pAd->CommonCfg.SsidLen ==
368 pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen)
369 && NdisEqualMemory(pAd->CommonCfg.Ssid,
370 pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid,
371 pAd->CommonCfg.SsidLen)
372 && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid,
373 pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid)) {
374 /* Case 1. already connected with an AP who has the desired SSID */
375 /* with highest RSSI */
377 /* Add checking Mode "LEAP" for CCX 1.0 */
378 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
379 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
380 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
381 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
383 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) {
384 /* case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo */
385 /* connection process */
386 DBGPRINT(RT_DEBUG_TRACE,
387 ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
388 DisassocParmFill(pAd, &DisassocReq,
389 pAd->CommonCfg.Bssid,
390 REASON_DISASSOC_STA_LEAVING);
391 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
392 MT2_MLME_DISASSOC_REQ,
393 sizeof(struct rt_mlme_disassoc_req),
395 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
396 } else if (pAd->bConfigChanged == TRUE) {
397 /* case 1.2 Important Config has changed, we have to reconnect to the same AP */
398 DBGPRINT(RT_DEBUG_TRACE,
399 ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
400 DisassocParmFill(pAd, &DisassocReq,
401 pAd->CommonCfg.Bssid,
402 REASON_DISASSOC_STA_LEAVING);
403 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
404 MT2_MLME_DISASSOC_REQ,
405 sizeof(struct rt_mlme_disassoc_req),
407 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
409 /* case 1.3. already connected to the SSID with highest RSSI. */
410 DBGPRINT(RT_DEBUG_TRACE,
411 ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
413 /* (HCT 12.1) 1c_wlan_mediaevents required */
414 /* media connect events are indicated when associating with the same AP */
418 /* Since MediaState already is NdisMediaStateConnected */
419 /* We just indicate the connect event again to meet the WHQL required. */
421 pAd->IndicateMediaState =
422 NdisMediaStateConnected;
423 RTMP_IndicateMediaState(pAd);
424 pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information to link is up */
427 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
428 RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1,
429 &pAd->MlmeAux.Bssid[0], NULL,
432 } else if (INFRA_ON(pAd)) {
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. */
440 (pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen,
441 pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)) {
443 /* Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event. */
445 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
447 /* case 2. active INFRA association existent */
448 /* roaming is done within miniport driver, nothing to do with configuration */
449 /* utility. so upon a new SET(OID_802_11_SSID) is received, we just */
450 /* disassociate with the current associated AP, */
451 /* then perform a new association with this new SSID, no matter the */
452 /* new/old SSID are the same or not. */
453 DBGPRINT(RT_DEBUG_TRACE,
454 ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
455 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid,
456 REASON_DISASSOC_STA_LEAVING);
457 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
458 sizeof(struct rt_mlme_disassoc_req), &DisassocReq);
459 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
462 DBGPRINT(RT_DEBUG_TRACE,
463 ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
464 LinkDown(pAd, FALSE);
465 OPSTATUS_CLEAR_FLAG(pAd,
466 fOP_STATUS_MEDIA_STATE_CONNECTED);
467 pAd->IndicateMediaState = NdisMediaStateDisconnected;
468 RTMP_IndicateMediaState(pAd);
469 pAd->ExtraInfo = GENERAL_LINK_DOWN;
470 DBGPRINT(RT_DEBUG_TRACE,
471 ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
474 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
475 (pAd->StaCfg.bAutoReconnect == TRUE) &&
476 (pAd->MlmeAux.BssType == BSS_INFRA) &&
477 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)
480 struct rt_mlme_scan_req ScanReq;
482 DBGPRINT(RT_DEBUG_TRACE,
483 ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
484 ScanParmFill(pAd, &ScanReq, (char *)pAd->MlmeAux.Ssid,
485 pAd->MlmeAux.SsidLen, BSS_ANY,
487 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
488 sizeof(struct rt_mlme_scan_req), &ScanReq);
489 pAd->Mlme.CntlMachine.CurrState =
490 CNTL_WAIT_OID_LIST_SCAN;
491 /* Reset Missed scan number */
492 pAd->StaCfg.LastScanTime = Now;
494 pAd->MlmeAux.BssIdx = 0;
495 IterateOnBssTab(pAd);
501 ==========================================================================
504 IRQL = DISPATCH_LEVEL
506 ==========================================================================
508 void CntlOidRTBssidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
510 unsigned long BssIdx;
511 u8 *pOidBssid = (u8 *)Elem->Msg;
512 struct rt_mlme_disassoc_req DisassocReq;
513 struct rt_mlme_join_req JoinReq;
515 /* record user desired settings */
516 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
517 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
519 /* find the desired BSS in the latest SCAN result table */
520 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
521 if (BssIdx == BSS_NOT_FOUND) {
522 struct rt_mlme_scan_req ScanReq;
524 DBGPRINT(RT_DEBUG_TRACE,
525 ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
526 /*pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; */
528 DBGPRINT(RT_DEBUG_TRACE,
529 ("CNTL - BSSID not found. start a new scan\n"));
530 ScanParmFill(pAd, &ScanReq, (char *)pAd->MlmeAux.Ssid,
531 pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
532 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
533 sizeof(struct rt_mlme_scan_req), &ScanReq);
534 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
535 /* Reset Missed scan number */
536 NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
540 /* Update Reconnect Ssid, that user desired to connect. */
542 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
543 pAd->MlmeAux.AutoReconnectSsidLen =
544 pAd->ScanTab.BssEntry[BssIdx].SsidLen;
545 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid,
546 pAd->ScanTab.BssEntry[BssIdx].Ssid,
547 pAd->ScanTab.BssEntry[BssIdx].SsidLen);
549 /* copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why? */
550 /* Because we need this entry to become the JOIN target in later on SYNC state machine */
551 pAd->MlmeAux.BssIdx = 0;
552 pAd->MlmeAux.SsidBssTab.BssNr = 1;
553 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0],
554 &pAd->ScanTab.BssEntry[BssIdx], sizeof(struct rt_bss_entry));
556 /* Add SSID into MlmeAux for site surey joining hidden SSID */
557 pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
558 NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid,
559 pAd->MlmeAux.SsidLen);
563 /* disassoc from current AP first */
564 DBGPRINT(RT_DEBUG_TRACE,
565 ("CNTL - disassociate with current AP ...\n"));
566 DisassocParmFill(pAd, &DisassocReq,
567 pAd->CommonCfg.Bssid,
568 REASON_DISASSOC_STA_LEAVING);
569 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
570 MT2_MLME_DISASSOC_REQ,
571 sizeof(struct rt_mlme_disassoc_req),
574 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
577 DBGPRINT(RT_DEBUG_TRACE,
578 ("CNTL - drop current ADHOC\n"));
579 LinkDown(pAd, FALSE);
580 OPSTATUS_CLEAR_FLAG(pAd,
581 fOP_STATUS_MEDIA_STATE_CONNECTED);
582 pAd->IndicateMediaState =
583 NdisMediaStateDisconnected;
584 RTMP_IndicateMediaState(pAd);
585 pAd->ExtraInfo = GENERAL_LINK_DOWN;
586 DBGPRINT(RT_DEBUG_TRACE,
587 ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
589 /* Change the wepstatus to original wepstatus */
590 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
591 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
592 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
594 /* Check cipher suite, AP must have more secured cipher than station setting */
595 /* Set the Pairwise and Group cipher to match the intended AP setting */
596 /* We can only connect to AP with less secured cipher setting */
597 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
598 || (pAd->StaCfg.AuthMode ==
599 Ndis802_11AuthModeWPAPSK)) {
600 pAd->StaCfg.GroupCipher =
601 pAd->ScanTab.BssEntry[BssIdx].WPA.
604 if (pAd->StaCfg.WepStatus ==
605 pAd->ScanTab.BssEntry[BssIdx].WPA.
607 pAd->StaCfg.PairCipher =
608 pAd->ScanTab.BssEntry[BssIdx].WPA.
610 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.
611 PairCipherAux != Ndis802_11WEPDisabled)
612 pAd->StaCfg.PairCipher =
613 pAd->ScanTab.BssEntry[BssIdx].WPA.
615 else /* There is no PairCipher Aux, downgrade our capability to TKIP */
616 pAd->StaCfg.PairCipher =
617 Ndis802_11Encryption2Enabled;
619 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
620 || (pAd->StaCfg.AuthMode ==
621 Ndis802_11AuthModeWPA2PSK)) {
622 pAd->StaCfg.GroupCipher =
623 pAd->ScanTab.BssEntry[BssIdx].WPA2.
626 if (pAd->StaCfg.WepStatus ==
627 pAd->ScanTab.BssEntry[BssIdx].WPA2.
629 pAd->StaCfg.PairCipher =
630 pAd->ScanTab.BssEntry[BssIdx].WPA2.
632 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.
633 PairCipherAux != Ndis802_11WEPDisabled)
634 pAd->StaCfg.PairCipher =
635 pAd->ScanTab.BssEntry[BssIdx].WPA2.
637 else /* There is no PairCipher Aux, downgrade our capability to TKIP */
638 pAd->StaCfg.PairCipher =
639 Ndis802_11Encryption2Enabled;
642 pAd->StaCfg.RsnCapability =
643 pAd->ScanTab.BssEntry[BssIdx].WPA2.
646 /* Set Mix cipher flag */
647 pAd->StaCfg.bMixCipher =
648 (pAd->StaCfg.PairCipher ==
649 pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
650 /*if (pAd->StaCfg.bMixCipher == TRUE)
652 // If mix cipher, re-build RSNIE
653 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
655 /* No active association, join the BSS immediately */
656 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %pM ...\n",
659 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
660 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ,
661 sizeof(struct rt_mlme_join_req), &JoinReq);
663 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
668 /* Roaming is the only external request triggering CNTL state machine */
669 /* despite of other "SET OID" operation. All "SET OID" related oerations */
670 /* happen in sequence, because no other SET OID will be sent to this device */
671 /* until the the previous SET operation is complete (successful o failed). */
672 /* So, how do we quarantee this ROAMING request won't corrupt other "SET OID"? */
673 /* or been corrupted by other "SET OID"? */
675 /* IRQL = DISPATCH_LEVEL */
676 void CntlMlmeRoamingProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
680 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Roaming in MlmeAux.RoamTab...\n"));
683 /*Let BBP register at 20MHz to do (fast) roaming. */
684 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
686 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
688 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab,
689 sizeof(pAd->MlmeAux.RoamTab));
690 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
692 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
693 pAd->MlmeAux.BssIdx = 0;
694 IterateOnBssTab(pAd);
699 ==========================================================================
702 IRQL = DISPATCH_LEVEL
704 ==========================================================================
706 void CntlWaitDisassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
708 struct rt_mlme_start_req StartReq;
710 if (Elem->MsgType == MT2_DISASSOC_CONF) {
711 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
713 if (pAd->CommonCfg.bWirelessEvent) {
714 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG,
715 pAd->MacTab.Content[BSSID_WCID].
719 LinkDown(pAd, FALSE);
721 /* case 1. no matching BSS, and user wants ADHOC, so we just start a new one */
722 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0)
723 && (pAd->StaCfg.BssType == BSS_ADHOC)) {
724 DBGPRINT(RT_DEBUG_TRACE,
725 ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",
727 StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid,
728 pAd->MlmeAux.SsidLen);
729 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
730 sizeof(struct rt_mlme_start_req), &StartReq);
731 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
733 /* case 2. try each matched BSS */
735 pAd->MlmeAux.BssIdx = 0;
737 IterateOnBssTab(pAd);
743 ==========================================================================
746 IRQL = DISPATCH_LEVEL
748 ==========================================================================
750 void CntlWaitJoinProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
753 struct rt_mlme_auth_req AuthReq;
755 if (Elem->MsgType == MT2_JOIN_CONF) {
756 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
757 if (Reason == MLME_SUCCESS) {
758 /* 1. joined an IBSS, we are pretty much done here */
759 if (pAd->MlmeAux.BssType == BSS_ADHOC) {
761 /* 5G bands rules of Japan: */
762 /* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */
764 if ((pAd->CommonCfg.bIEEE80211H == 1) &&
765 RadarChannelCheck(pAd,
766 pAd->CommonCfg.Channel)
768 pAd->Mlme.CntlMachine.CurrState =
770 DBGPRINT(RT_DEBUG_TRACE,
771 ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n",
772 pAd->CommonCfg.Channel));
776 LinkUp(pAd, BSS_ADHOC);
777 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
778 DBGPRINT(RT_DEBUG_TRACE,
779 ("CNTL - join the IBSS = %pM ...\n",
780 pAd->CommonCfg.Bssid));
782 pAd->IndicateMediaState =
783 NdisMediaStateConnected;
784 pAd->ExtraInfo = GENERAL_LINK_UP;
786 /* 2. joined a new INFRA network, start from authentication */
789 /* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */
790 if ((pAd->StaCfg.AuthMode ==
791 Ndis802_11AuthModeShared)
792 || (pAd->StaCfg.AuthMode ==
793 Ndis802_11AuthModeAutoSwitch)) {
794 AuthParmFill(pAd, &AuthReq,
798 AuthParmFill(pAd, &AuthReq,
802 MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
805 (struct rt_mlme_auth_req),
809 pAd->Mlme.CntlMachine.CurrState =
813 /* 3. failed, try next BSS */
814 pAd->MlmeAux.BssIdx++;
815 IterateOnBssTab(pAd);
821 ==========================================================================
824 IRQL = DISPATCH_LEVEL
826 ==========================================================================
828 void CntlWaitStartProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
832 if (Elem->MsgType == MT2_START_CONF) {
833 NdisMoveMemory(&Result, Elem->Msg, sizeof(u16));
834 if (Result == MLME_SUCCESS) {
836 /* 5G bands rules of Japan: */
837 /* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */
839 if ((pAd->CommonCfg.bIEEE80211H == 1) &&
840 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
842 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
843 DBGPRINT(RT_DEBUG_TRACE,
844 ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n",
845 pAd->CommonCfg.Channel));
848 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.
850 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
853 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo,
854 &pAd->CommonCfg.AddHTInfo,
855 sizeof(struct rt_add_ht_info_ie));
856 RTMPCheckHt(pAd, BSSID_WCID,
857 &pAd->CommonCfg.HtCapability,
858 &pAd->CommonCfg.AddHTInfo);
859 pAd->StaActive.SupportedPhyInfo.bHtEnable =
861 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.
863 &pAd->CommonCfg.HtCapability.
865 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG
868 if ((pAd->CommonCfg.HtCapability.HtCapInfo.
869 ChannelWidth == BW_40)
870 && (pAd->CommonCfg.AddHTInfo.AddHtInfo.
871 ExtChanOffset == EXTCHA_ABOVE)) {
872 pAd->MlmeAux.CentralChannel =
873 pAd->CommonCfg.Channel + 2;
875 if ((pAd->CommonCfg.HtCapability.HtCapInfo.
876 ChannelWidth == BW_40)
877 && (pAd->CommonCfg.AddHTInfo.AddHtInfo.
878 ExtChanOffset == EXTCHA_BELOW)) {
879 pAd->MlmeAux.CentralChannel =
880 pAd->CommonCfg.Channel - 2;
883 pAd->StaActive.SupportedPhyInfo.bHtEnable =
886 LinkUp(pAd, BSS_ADHOC);
887 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
888 /* Before send beacon, driver need do radar detection */
889 if ((pAd->CommonCfg.Channel > 14)
890 && (pAd->CommonCfg.bIEEE80211H == 1)
891 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) {
892 pAd->CommonCfg.RadarDetect.RDMode =
894 pAd->CommonCfg.RadarDetect.RDCount = 0;
897 DBGPRINT(RT_DEBUG_TRACE,
898 ("CNTL - start a new IBSS = %pM ...\n",
899 pAd->CommonCfg.Bssid));
901 DBGPRINT(RT_DEBUG_TRACE,
902 ("CNTL - Start IBSS fail. BUG!\n"));
903 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
909 ==========================================================================
912 IRQL = DISPATCH_LEVEL
914 ==========================================================================
916 void CntlWaitAuthProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
919 struct rt_mlme_assoc_req AssocReq;
920 struct rt_mlme_auth_req AuthReq;
922 if (Elem->MsgType == MT2_AUTH_CONF) {
923 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
924 if (Reason == MLME_SUCCESS) {
925 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
926 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid,
927 pAd->MlmeAux.CapabilityInfo,
929 pAd->StaCfg.DefaultListenCount);
932 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
934 sizeof(struct rt_mlme_assoc_req),
937 pAd->Mlme.CntlMachine.CurrState =
941 /* This fail may because of the AP already keep us in its MAC table without */
942 /* ageing-out. The previous authentication attempt must have let it remove us. */
943 /* so try Authentication again may help. For D-Link DWL-900AP+ compatibility. */
944 DBGPRINT(RT_DEBUG_TRACE,
945 ("CNTL - AUTH FAIL, try again...\n"));
948 if ((pAd->StaCfg.AuthMode ==
949 Ndis802_11AuthModeShared)
950 || (pAd->StaCfg.AuthMode ==
951 Ndis802_11AuthModeAutoSwitch)) {
952 /* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */
953 AuthParmFill(pAd, &AuthReq,
957 AuthParmFill(pAd, &AuthReq,
961 MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
963 sizeof(struct rt_mlme_auth_req),
967 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
973 ==========================================================================
976 IRQL = DISPATCH_LEVEL
978 ==========================================================================
980 void CntlWaitAuthProc2(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
983 struct rt_mlme_assoc_req AssocReq;
984 struct rt_mlme_auth_req AuthReq;
986 if (Elem->MsgType == MT2_AUTH_CONF) {
987 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
988 if (Reason == MLME_SUCCESS) {
989 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
990 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid,
991 pAd->MlmeAux.CapabilityInfo,
993 pAd->StaCfg.DefaultListenCount);
995 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
997 sizeof(struct rt_mlme_assoc_req),
1000 pAd->Mlme.CntlMachine.CurrState =
1004 if ((pAd->StaCfg.AuthMode ==
1005 Ndis802_11AuthModeAutoSwitch)
1006 && (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared)) {
1007 DBGPRINT(RT_DEBUG_TRACE,
1008 ("CNTL - AUTH FAIL, try OPEN system...\n"));
1009 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid,
1010 Ndis802_11AuthModeOpen);
1011 MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
1013 sizeof(struct rt_mlme_auth_req),
1016 pAd->Mlme.CntlMachine.CurrState =
1019 /* not success, try next BSS */
1020 DBGPRINT(RT_DEBUG_TRACE,
1021 ("CNTL - AUTH FAIL, give up; try next BSS\n"));
1022 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; /*??????? */
1023 pAd->MlmeAux.BssIdx++;
1024 IterateOnBssTab(pAd);
1031 ==========================================================================
1034 IRQL = DISPATCH_LEVEL
1036 ==========================================================================
1038 void CntlWaitAssocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1042 if (Elem->MsgType == MT2_ASSOC_CONF) {
1043 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
1044 if (Reason == MLME_SUCCESS) {
1045 if (pAd->CommonCfg.bWirelessEvent) {
1046 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG,
1048 Content[BSSID_WCID].Addr,
1052 LinkUp(pAd, BSS_INFRA);
1053 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1054 DBGPRINT(RT_DEBUG_TRACE,
1055 ("CNTL - Association successful on BSS #%ld\n",
1056 pAd->MlmeAux.BssIdx));
1058 /* not success, try next BSS */
1059 DBGPRINT(RT_DEBUG_TRACE,
1060 ("CNTL - Association fails on BSS #%ld\n",
1061 pAd->MlmeAux.BssIdx));
1062 pAd->MlmeAux.BssIdx++;
1063 IterateOnBssTab(pAd);
1069 ==========================================================================
1072 IRQL = DISPATCH_LEVEL
1074 ==========================================================================
1076 void CntlWaitReassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1080 if (Elem->MsgType == MT2_REASSOC_CONF) {
1081 NdisMoveMemory(&Result, Elem->Msg, sizeof(u16));
1082 if (Result == MLME_SUCCESS) {
1083 /* send wireless event - for association */
1084 if (pAd->CommonCfg.bWirelessEvent)
1085 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG,
1087 Content[BSSID_WCID].Addr,
1091 /* NDIS requires a new Link UP indication but no Link Down for RE-ASSOC */
1093 LinkUp(pAd, BSS_INFRA);
1095 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1096 DBGPRINT(RT_DEBUG_TRACE,
1097 ("CNTL - Re-assocition successful on BSS #%ld\n",
1098 pAd->MlmeAux.RoamIdx));
1100 /* reassoc failed, try to pick next BSS in the BSS Table */
1101 DBGPRINT(RT_DEBUG_TRACE,
1102 ("CNTL - Re-assocition fails on BSS #%ld\n",
1103 pAd->MlmeAux.RoamIdx));
1105 pAd->MlmeAux.RoamIdx++;
1106 IterateOnBssTab2(pAd);
1112 void AdhocTurnOnQos(struct rt_rtmp_adapter *pAd)
1114 #define AC0_DEF_TXOP 0
1115 #define AC1_DEF_TXOP 0
1116 #define AC2_DEF_TXOP 94
1117 #define AC3_DEF_TXOP 47
1119 /* Turn on QOs if use HT rate. */
1120 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) {
1121 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1122 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1123 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1124 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1125 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1127 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1128 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1129 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1130 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1132 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1133 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1134 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1135 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1137 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1138 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1139 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1140 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1142 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1146 ==========================================================================
1149 IRQL = DISPATCH_LEVEL
1151 ==========================================================================
1153 void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType)
1158 u8 Value = 0, idx = 0, HashIdx = 0;
1159 struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry = NULL;
1161 /* Init ChannelQuality to prevent DEAD_CQI at initial LinkUp */
1162 pAd->Mlme.ChannelQuality = 50;
1164 pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid);
1166 MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
1170 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1173 /* ASSOC - DisassocTimeoutAction */
1174 /* CNTL - Dis-associate successful */
1176 /* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */
1178 /* To prevent DisassocTimeoutAction to call Link down after we link up, */
1179 /* cancel the DisassocTimer no matter what it start or not. */
1181 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1183 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1185 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1188 /* Before power save before link up function, We will force use 1R. */
1189 /* So after link up, check Rx antenna # again. */
1190 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1191 if (pAd->Antenna.field.RxPath == 3) {
1193 } else if (pAd->Antenna.field.RxPath == 2) {
1195 } else if (pAd->Antenna.field.RxPath == 1) {
1198 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1199 pAd->StaCfg.BBPR3 = Value;
1200 #endif /* RTMP_MAC_PCI // */
1202 if (BssType == BSS_ADHOC) {
1203 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1204 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1206 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1207 AdhocTurnOnQos(pAd);
1209 DBGPRINT(RT_DEBUG_TRACE, ("Adhoc LINK UP!\n"));
1211 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1212 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1214 DBGPRINT(RT_DEBUG_TRACE, ("Infra LINK UP!\n"));
1218 /* reset Tx beamforming bit */
1219 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1221 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1222 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1224 /* Change to AP channel */
1225 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
1226 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) {
1227 /* Must using 40MHz. */
1228 pAd->CommonCfg.BBPCurrentBW = BW_40;
1229 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1230 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1232 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1235 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1237 /* RX : control channel at lower */
1238 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1240 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1242 pAd->StaCfg.BBPR3 = Value;
1243 #endif /* RTMP_MAC_PCI // */
1245 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1247 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1249 if (pAd->MACVersion == 0x28600100) {
1250 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1251 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1252 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1253 DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
1256 DBGPRINT(RT_DEBUG_TRACE,
1257 ("40MHz Lower LINK UP! Control Channel at Below. Central = %d \n",
1258 pAd->CommonCfg.CentralChannel));
1259 } else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
1260 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth ==
1262 /* Must using 40MHz. */
1263 pAd->CommonCfg.BBPCurrentBW = BW_40;
1264 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1265 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1267 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1270 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1272 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1274 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1276 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1278 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1280 pAd->StaCfg.BBPR3 = Value;
1281 #endif /* RTMP_MAC_PCI // */
1283 if (pAd->MACVersion == 0x28600100) {
1284 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1285 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1286 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1287 DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
1290 DBGPRINT(RT_DEBUG_TRACE,
1291 ("40MHz Upper LINK UP! Control Channel at UpperCentral = %d \n",
1292 pAd->CommonCfg.CentralChannel));
1294 pAd->CommonCfg.BBPCurrentBW = BW_20;
1295 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1296 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1297 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1299 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1301 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1303 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1305 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1307 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1309 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1311 pAd->StaCfg.BBPR3 = Value;
1312 #endif /* RTMP_MAC_PCI // */
1314 if (pAd->MACVersion == 0x28600100) {
1315 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1316 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1317 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1318 DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
1321 DBGPRINT(RT_DEBUG_TRACE, ("20MHz LINK UP!\n"));
1324 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1327 /* Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission */
1329 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66,
1330 &pAd->BbpTuning.R66CurrentValue);
1332 DBGPRINT(RT_DEBUG_TRACE,
1333 ("LINK UP! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1334 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid,
1335 pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1337 DBGPRINT(RT_DEBUG_TRACE,
1338 ("LINK UP! (Density =%d, )\n",
1339 pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1341 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1343 AsicSetSlotTime(pAd, TRUE);
1344 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1346 /* Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit */
1347 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE,
1350 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)) {
1351 /* Update HT protectionfor based on AP's operating mode. */
1352 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) {
1353 AsicUpdateProtect(pAd,
1354 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1355 OperaionMode, ALLN_SETPROTECT, FALSE,
1358 AsicUpdateProtect(pAd,
1359 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1360 OperaionMode, ALLN_SETPROTECT, FALSE,
1364 NdisZeroMemory(&pAd->DrsCounters, sizeof(struct rt_counter_drs));
1366 NdisGetSystemUpTime(&Now);
1367 pAd->StaCfg.LastBeaconRxTime = Now; /* last RX timestamp */
1369 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1370 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo)) {
1371 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1374 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1376 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE) {
1378 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1380 if (BssType == BSS_ADHOC) {
1381 MakeIbssBeacon(pAd);
1382 if ((pAd->CommonCfg.Channel > 14)
1383 && (pAd->CommonCfg.bIEEE80211H == 1)
1384 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) {
1387 AsicEnableIbssSync(pAd);
1390 /* In ad hoc mode, use MAC table from index 1. */
1391 /* 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. */
1392 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1393 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1395 /* If WEP is enabled, add key material and cipherAlg into Asic */
1396 /* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */
1398 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) {
1402 for (idx = 0; idx < SHARE_KEY_NUM; idx++) {
1403 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1404 Key = pAd->SharedKey[BSS0][idx].Key;
1406 if (pAd->SharedKey[BSS0][idx].KeyLen > 0) {
1407 /* Set key material and cipherAlg to Asic */
1408 AsicAddSharedKeyEntry(pAd, BSS0, idx,
1412 if (idx == pAd->StaCfg.DefaultKeyId) {
1413 /* Update WCID attribute table and IVEIV table for this group key table */
1414 RTMPAddWcidAttributeEntry(pAd,
1424 /* If WPANone is enabled, add key material and cipherAlg into Asic */
1425 /* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */
1426 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
1427 pAd->StaCfg.DefaultKeyId = 0; /* always be zero */
1429 NdisZeroMemory(&pAd->SharedKey[BSS0][0],
1430 sizeof(struct rt_cipher_key));
1431 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1432 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key,
1433 pAd->StaCfg.PMK, LEN_TKIP_EK);
1435 if (pAd->StaCfg.PairCipher ==
1436 Ndis802_11Encryption2Enabled) {
1437 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic,
1438 &pAd->StaCfg.PMK[16],
1440 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic,
1441 &pAd->StaCfg.PMK[16],
1444 /* Decide its ChiperAlg */
1445 if (pAd->StaCfg.PairCipher ==
1446 Ndis802_11Encryption2Enabled)
1447 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1448 else if (pAd->StaCfg.PairCipher ==
1449 Ndis802_11Encryption3Enabled)
1450 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1452 DBGPRINT(RT_DEBUG_TRACE,
1453 ("Unknow Cipher (=%d), set Cipher to AES\n",
1454 pAd->StaCfg.PairCipher));
1455 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1458 /* Set key material and cipherAlg to Asic */
1459 AsicAddSharedKeyEntry(pAd,
1462 pAd->SharedKey[BSS0][0].CipherAlg,
1463 pAd->SharedKey[BSS0][0].Key,
1464 pAd->SharedKey[BSS0][0].TxMic,
1465 pAd->SharedKey[BSS0][0].RxMic);
1467 /* Update WCID attribute table and IVEIV table for this group key table */
1468 RTMPAddWcidAttributeEntry(pAd, BSS0, 0,
1469 pAd->SharedKey[BSS0][0].
1474 } else /* BSS_INFRA */
1476 /* Check the new SSID with last SSID */
1477 while (Cancelled == TRUE) {
1478 if (pAd->CommonCfg.LastSsidLen ==
1479 pAd->CommonCfg.SsidLen) {
1480 if (RTMPCompareMemory
1481 (pAd->CommonCfg.LastSsid,
1482 pAd->CommonCfg.Ssid,
1483 pAd->CommonCfg.LastSsidLen) == 0) {
1484 /* Link to the old one no linkdown is required. */
1488 /* Send link down event before set to link up */
1489 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1490 RTMP_IndicateMediaState(pAd);
1491 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1492 DBGPRINT(RT_DEBUG_TRACE,
1493 ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1498 /* On WPA mode, Remove All Keys if not connect to the last BSSID */
1499 /* Key will be set after 4-way handshake. */
1501 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
1504 /* Remove all WPA keys */
1505 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1506 RTMPWPARemoveAllKeys(pAd);
1507 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1508 pAd->StaCfg.PrivacyFilter =
1509 Ndis802_11PrivFilter8021xWEP;
1511 /* Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP */
1512 /* If IV related values are too large in GroupMsg2, AP would ignore this message. */
1514 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1515 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1518 /* the decision of using "short slot time" or not may change dynamically due to */
1519 /* new STA association to the AP. so we have to decide that upon parsing BEACON, not here */
1522 /* the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically */
1523 /* due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here */
1526 ComposeNullFrame(pAd);
1528 AsicEnableBssSync(pAd);
1530 /* Add BSSID to WCID search table */
1531 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1533 /* If WEP is enabled, add paiewise and shared key */
1534 if (((pAd->StaCfg.WpaSupplicantUP) &&
1535 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1536 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1537 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) &&
1538 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled))) {
1542 for (idx = 0; idx < SHARE_KEY_NUM; idx++) {
1543 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1544 Key = pAd->SharedKey[BSS0][idx].Key;
1546 if (pAd->SharedKey[BSS0][idx].KeyLen > 0) {
1547 /* Set key material and cipherAlg to Asic */
1548 AsicAddSharedKeyEntry(pAd, BSS0, idx,
1552 if (idx == pAd->StaCfg.DefaultKeyId) {
1553 /* Assign group key info */
1554 RTMPAddWcidAttributeEntry(pAd,
1560 pEntry->Aid = BSSID_WCID;
1561 /* Assign pairwise key info */
1562 RTMPAddWcidAttributeEntry(pAd,
1571 /* only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode */
1572 /* should wait until at least 2 active nodes in this BSSID. */
1573 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1576 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) {
1577 pAd->IndicateMediaState = NdisMediaStateConnected;
1578 pAd->ExtraInfo = GENERAL_LINK_UP;
1579 RTMP_IndicateMediaState(pAd);
1580 } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1581 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1583 if (pAd->StaCfg.WpaSupplicantUP ==
1584 WPA_SUPPLICANT_DISABLE)
1585 RTMPSetTimer(&pAd->Mlme.LinkDownTimer,
1590 /* Add BSSID in my MAC Table. */
1591 NdisAcquireSpinLock(&pAd->MacTabLock);
1592 /* add this MAC entry into HASH table */
1594 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1595 if (pAd->MacTab.Hash[HashIdx] == NULL) {
1596 pAd->MacTab.Hash[HashIdx] = pEntry;
1598 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1599 while (pCurrEntry->pNext != NULL) {
1600 pCurrEntry = pCurrEntry->pNext;
1602 pCurrEntry->pNext = pEntry;
1605 RTMPMoveMemory(pEntry->Addr, pAd->CommonCfg.Bssid,
1607 pEntry->Aid = BSSID_WCID;
1609 pEntry->ValidAsCLI = TRUE; /*Although this is bssid..still set ValidAsCl */
1610 pAd->MacTab.Size = 1; /* infra mode always set MACtab size =1. */
1611 pEntry->Sst = SST_ASSOC;
1612 pEntry->AuthState = SST_ASSOC;
1613 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1614 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1615 if (pEntry->AuthMode < Ndis802_11AuthModeWPA) {
1616 pEntry->WpaState = AS_NOTUSE;
1617 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1619 pEntry->WpaState = AS_PTKSTART;
1620 pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1622 NdisReleaseSpinLock(&pAd->MacTabLock);
1624 DBGPRINT(RT_DEBUG_TRACE,
1625 ("LINK UP! ClientStatusFlags=%lx)\n",
1626 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1628 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1629 MlmeUpdateHtTxRates(pAd, BSS0);
1630 DBGPRINT(RT_DEBUG_TRACE,
1631 ("LINK UP! (StaActive.bHtEnable =%d, )\n",
1632 pAd->StaActive.SupportedPhyInfo.bHtEnable));
1634 if (pAd->CommonCfg.bAggregationCapable) {
1635 if ((pAd->CommonCfg.bPiggyBackCapable)
1636 && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3) {
1637 OPSTATUS_SET_FLAG(pAd,
1638 fOP_STATUS_PIGGYBACK_INUSED);
1639 OPSTATUS_SET_FLAG(pAd,
1640 fOP_STATUS_AGGREGATION_INUSED);
1641 CLIENT_STATUS_SET_FLAG(pEntry,
1642 fCLIENT_STATUS_AGGREGATION_CAPABLE);
1643 CLIENT_STATUS_SET_FLAG(pEntry,
1644 fCLIENT_STATUS_PIGGYBACK_CAPABLE);
1645 RTMPSetPiggyBack(pAd, TRUE);
1646 DBGPRINT(RT_DEBUG_TRACE,
1647 ("Turn on Piggy-Back\n"));
1648 } else if (pAd->MlmeAux.APRalinkIe & 0x00000001) {
1649 OPSTATUS_SET_FLAG(pAd,
1650 fOP_STATUS_AGGREGATION_INUSED);
1651 CLIENT_STATUS_SET_FLAG(pEntry,
1652 fCLIENT_STATUS_AGGREGATION_CAPABLE);
1653 DBGPRINT(RT_DEBUG_TRACE,
1654 ("Ralink Aggregation\n"));
1658 if (pAd->MlmeAux.APRalinkIe != 0x0) {
1659 if (CLIENT_STATUS_TEST_FLAG
1660 (pEntry, fCLIENT_STATUS_RDG_CAPABLE)) {
1663 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1664 CLIENT_STATUS_SET_FLAG(pEntry,
1665 fCLIENT_STATUS_RALINK_CHIPSET);
1667 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1668 CLIENT_STATUS_CLEAR_FLAG(pEntry,
1669 fCLIENT_STATUS_RALINK_CHIPSET);
1673 DBGPRINT(RT_DEBUG_TRACE,
1674 ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n",
1675 pAd->CommonCfg.BACapability.word,
1676 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1679 RTMPSetLED(pAd, LED_LINK_UP);
1681 pAd->Mlme.PeriodicRound = 0;
1682 pAd->Mlme.OneSecPeriodicRound = 0;
1683 pAd->bConfigChanged = FALSE; /* Reset config flag */
1684 pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information to link is up */
1686 /* Set asic auto fall back */
1691 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID],
1692 &pTable, &TableSize,
1693 &pAd->CommonCfg.TxRateIndex);
1694 AsicUpdateAutoFallBackTable(pAd, pTable);
1697 NdisAcquireSpinLock(&pAd->MacTabLock);
1698 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1699 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1700 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE) {
1701 pEntry->bAutoTxRateSwitch = FALSE;
1703 if (pEntry->HTPhyMode.field.MCS == 32)
1704 pEntry->HTPhyMode.field.ShortGI = GI_800;
1706 if ((pEntry->HTPhyMode.field.MCS > MCS_7)
1707 || (pEntry->HTPhyMode.field.MCS == 32))
1708 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1710 /* If the legacy mode is set, overwrite the transmit setting of this entry. */
1711 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1712 RTMPUpdateLegacyTxSetting((u8)pAd->StaCfg.
1713 DesiredTransmitSetting.field.
1714 FixedTxMode, pEntry);
1716 pEntry->bAutoTxRateSwitch = TRUE;
1717 NdisReleaseSpinLock(&pAd->MacTabLock);
1719 /* Let Link Status Page display first initial rate. */
1720 pAd->LastTxRate = (u16)(pEntry->HTPhyMode.word);
1721 /* Select DAC according to HT or Legacy */
1722 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00) {
1723 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1725 if (pAd->Antenna.field.TxPath == 2) {
1728 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1730 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1732 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1735 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) {
1736 } else if (pEntry->MaxRAmpduFactor == 0) {
1737 /* If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0. */
1738 /* Because our Init value is 1 at MACRegTable. */
1739 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1741 /* Patch for Marvel AP to gain high throughput */
1742 /* Need to set as following, */
1743 /* 1. Set txop in register-EDCA_AC0_CFG as 0x60 */
1744 /* 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero */
1745 /* 3. PBF_MAX_PCNT as 0x1F3FBF9F */
1746 /* 4. kick per two packets when dequeue */
1748 /* Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable */
1750 /* if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is. */
1751 if (!((pAd->CommonCfg.RxStream == 1) && (pAd->CommonCfg.TxStream == 1))
1752 && (pAd->StaCfg.bForceTxBurst == FALSE)
1754 (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1755 && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
1756 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)
1757 && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))) {
1758 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1760 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1762 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1763 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1764 } else if (pAd->CommonCfg.bEnableTxBurst) {
1765 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1768 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1769 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1771 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1772 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1774 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1776 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1778 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1779 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1782 /* Re-check to turn on TX burst or not. */
1783 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE)
1784 && ((STA_WEP_ON(pAd)) || (STA_TKIP_ON(pAd)))) {
1785 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1786 if (pAd->CommonCfg.bEnableTxBurst) {
1788 /* Force disable TXOP value in this case. The same action in MLMEUpdateProtect too. */
1789 /* I didn't change PBF_MAX_PCNT setting. */
1790 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1791 MACValue &= 0xFFFFFF00;
1792 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1793 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1796 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1799 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1800 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1801 DBGPRINT(RT_DEBUG_TRACE,
1802 ("pAd->bNextDisableRxBA= %d \n",
1803 pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1804 /* BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap */
1805 /* Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver. */
1806 /* Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same. */
1808 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled) {
1809 if (pAd->StaCfg.WpaSupplicantUP &&
1810 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1811 (pAd->StaCfg.IEEE8021X == TRUE)) ;
1813 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1814 pAd->StaCfg.PrivacyFilter =
1815 Ndis802_11PrivFilterAcceptAll;
1819 NdisAcquireSpinLock(&pAd->MacTabLock);
1820 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1821 NdisReleaseSpinLock(&pAd->MacTabLock);
1824 /* Patch Atheros AP TX will breakdown issue. */
1825 /* AP Model: DLink DWL-8200AP */
1827 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)
1828 && STA_TKIP_ON(pAd)) {
1829 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1831 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1834 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1836 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1840 ==========================================================================
1842 Routine Description:
1843 Disconnect current BSSID
1846 pAd - Pointer to our adapter
1847 IsReqFromAP - Request from AP
1852 IRQL = DISPATCH_LEVEL
1855 We need more information to know it's this requst from AP.
1856 If yes! we need to do extra handling, for example, remove the WPA key.
1857 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1858 remove while auto reconnect.
1859 Disconnect request from AP, it means we will start afresh 4-way handshaking
1862 ==========================================================================
1864 void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP)
1866 u8 i, ByteValue = 0;
1868 /* Do nothing if monitor mode is on */
1869 if (MONITOR_ON(pAd))
1872 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1873 /*Comment the codes, beasue the line 2291 call the same function. */
1874 /*RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); */
1875 /* Not allow go to sleep within linkdown function. */
1876 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1878 if (pAd->CommonCfg.bWirelessEvent) {
1879 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
1880 pAd->MacTab.Content[BSSID_WCID].Addr,
1884 DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN!\n"));
1885 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1888 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
1890 pAd->Mlme.bPsPollTimerRunning = FALSE;
1891 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1894 pAd->bPCIclkOff = FALSE;
1895 #endif /* RTMP_MAC_PCI // */
1897 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
1898 || RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)
1899 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) {
1900 AUTO_WAKEUP_STRUC AutoWakeupCfg;
1901 AsicForceWakeup(pAd, TRUE);
1902 AutoWakeupCfg.word = 0;
1903 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1904 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1907 pAd->bPCIclkOff = FALSE;
1908 #endif /* RTMP_MAC_PCI // */
1910 if (ADHOC_ON(pAd)) /* Adhoc mode link down */
1912 DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 1!\n"));
1914 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1915 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1916 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1917 RTMP_IndicateMediaState(pAd);
1918 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1919 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid,
1920 pAd->CommonCfg.Channel);
1921 DBGPRINT(RT_DEBUG_TRACE,
1922 (" MacTab.Size=%d !\n", pAd->MacTab.Size));
1923 } else /* Infra structure mode */
1925 DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 2!\n"));
1927 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1928 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1930 /* Saved last SSID for linkup comparison */
1931 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1932 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid,
1933 pAd->CommonCfg.LastSsidLen);
1934 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1935 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE) {
1936 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1937 RTMP_IndicateMediaState(pAd);
1938 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1939 DBGPRINT(RT_DEBUG_TRACE,
1940 ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1941 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1944 /* If disassociation request is from NDIS, then we don't need to delete BSSID from entry. */
1945 /* Otherwise lost beacon or receive De-Authentication from AP, */
1946 /* then we should delete BSSID from BssTable. */
1947 /* If we don't delete from entry, roaming will fail. */
1949 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid,
1950 pAd->CommonCfg.Channel);
1953 /* restore back to - */
1954 /* 1. long slot (20 us) or short slot (9 us) time */
1955 /* 2. turn on/off RTS/CTS and/or CTS-to-self protection */
1956 /* 3. short preamble */
1957 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1961 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
1962 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1963 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid,
1964 pAd->MacTab.Content[i].Addr);
1967 AsicSetSlotTime(pAd, TRUE); /*FALSE); */
1968 AsicSetEdcaParm(pAd, NULL);
1971 RTMPSetLED(pAd, LED_LINK_DOWN);
1972 pAd->LedIndicatorStrength = 0xF0;
1973 RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, firmware is not done it. */
1975 AsicDisableSync(pAd);
1977 pAd->Mlme.PeriodicRound = 0;
1978 pAd->Mlme.OneSecPeriodicRound = 0;
1980 if (pAd->StaCfg.BssType == BSS_INFRA) {
1981 /* Remove StaCfg Information after link down */
1982 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1983 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1984 pAd->CommonCfg.SsidLen = 0;
1987 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(struct rt_ht_capability_ie));
1988 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(struct rt_add_ht_info_ie));
1989 pAd->MlmeAux.HtCapabilityLen = 0;
1990 pAd->MlmeAux.NewExtChannelOffset = 0xff;
1992 /* Reset WPA-PSK state. Only reset when supplicant enabled */
1993 if (pAd->StaCfg.WpaState != SS_NOTUSE) {
1994 pAd->StaCfg.WpaState = SS_START;
1995 /* Clear Replay counter */
1996 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2000 /* if link down come from AP, we need to remove all WPA keys on WPA mode. */
2001 /* otherwise will cause 4-way handshaking failed, since the WPA key not empty. */
2003 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)) {
2004 /* Remove all WPA keys */
2005 RTMPWPARemoveAllKeys(pAd);
2007 /* 802.1x port control */
2009 /* Prevent clear PortSecured here with static WEP */
2010 /* NetworkManger set security policy first then set SSID to connect AP. */
2011 if (pAd->StaCfg.WpaSupplicantUP &&
2012 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
2013 (pAd->StaCfg.IEEE8021X == FALSE)) {
2014 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2016 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2017 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2020 NdisAcquireSpinLock(&pAd->MacTabLock);
2021 NdisZeroMemory(&pAd->MacTab, sizeof(struct rt_mac_table));
2022 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2023 NdisReleaseSpinLock(&pAd->MacTabLock);
2025 pAd->StaCfg.MicErrCnt = 0;
2027 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2028 /* Update extra information to link is up */
2029 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2031 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2034 pAd->bUsbTxBulkAggre = FALSE;
2035 #endif /* RTMP_MAC_USB // */
2037 /* Clean association information */
2038 NdisZeroMemory(&pAd->StaCfg.AssocInfo,
2039 sizeof(struct rt_ndis_802_11_association_information));
2040 pAd->StaCfg.AssocInfo.Length =
2041 sizeof(struct rt_ndis_802_11_association_information);
2042 pAd->StaCfg.ReqVarIELen = 0;
2043 pAd->StaCfg.ResVarIELen = 0;
2046 /* Reset RSSI value after link down */
2048 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2049 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2050 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2051 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2052 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2053 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2055 /* Restore MlmeRate */
2056 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2057 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2060 /* After Link down, reset piggy-back setting in ASIC. Disable RDG. */
2062 if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
2063 pAd->CommonCfg.BBPCurrentBW = BW_20;
2064 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2065 ByteValue &= (~0x18);
2066 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2069 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2070 ByteValue &= (~0x18);
2071 if (pAd->Antenna.field.TxPath == 2) {
2074 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2076 RTMPSetPiggyBack(pAd, FALSE);
2077 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2079 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2081 /* Restore all settings in the following. */
2082 AsicUpdateProtect(pAd, 0,
2083 (ALLN_SETPROTECT | CCKSETPROTECT | OFDMSETPROTECT),
2085 AsicDisableRDG(pAd);
2086 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2087 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2089 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2090 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2092 /* Allow go to sleep after linkdown steps. */
2093 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
2095 RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
2098 if ((IS_RT30xx(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd))
2099 && (pAd->Antenna.field.RxPath > 1 || pAd->Antenna.field.TxPath > 1)) {
2100 RTMP_ASIC_MMPS_DISABLE(pAd);
2102 #endif /* RT30xx // */
2106 ==========================================================================
2109 IRQL = DISPATCH_LEVEL
2111 ==========================================================================
2113 void IterateOnBssTab(struct rt_rtmp_adapter *pAd)
2115 struct rt_mlme_start_req StartReq;
2116 struct rt_mlme_join_req JoinReq;
2117 unsigned long BssIdx;
2119 /* Change the wepstatus to original wepstatus */
2120 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2121 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2122 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2124 BssIdx = pAd->MlmeAux.BssIdx;
2125 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr) {
2126 /* Check cipher suite, AP must have more secured cipher than station setting */
2127 /* Set the Pairwise and Group cipher to match the intended AP setting */
2128 /* We can only connect to AP with less secured cipher setting */
2129 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
2130 || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) {
2131 pAd->StaCfg.GroupCipher =
2132 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
2135 if (pAd->StaCfg.WepStatus ==
2136 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
2138 pAd->StaCfg.PairCipher =
2139 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
2141 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
2142 PairCipherAux != Ndis802_11WEPDisabled)
2143 pAd->StaCfg.PairCipher =
2144 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
2146 else /* There is no PairCipher Aux, downgrade our capability to TKIP */
2147 pAd->StaCfg.PairCipher =
2148 Ndis802_11Encryption2Enabled;
2149 } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
2150 || (pAd->StaCfg.AuthMode ==
2151 Ndis802_11AuthModeWPA2PSK)) {
2152 pAd->StaCfg.GroupCipher =
2153 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
2156 if (pAd->StaCfg.WepStatus ==
2157 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
2159 pAd->StaCfg.PairCipher =
2160 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
2162 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
2163 PairCipherAux != Ndis802_11WEPDisabled)
2164 pAd->StaCfg.PairCipher =
2165 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
2167 else /* There is no PairCipher Aux, downgrade our capability to TKIP */
2168 pAd->StaCfg.PairCipher =
2169 Ndis802_11Encryption2Enabled;
2171 /* RSN capability */
2172 pAd->StaCfg.RsnCapability =
2173 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
2176 /* Set Mix cipher flag */
2177 pAd->StaCfg.bMixCipher =
2178 (pAd->StaCfg.PairCipher ==
2179 pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2180 /*if (pAd->StaCfg.bMixCipher == TRUE)
2182 // If mix cipher, re-build RSNIE
2183 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2186 DBGPRINT(RT_DEBUG_TRACE,
2187 ("CNTL - iterate BSS %ld of %d\n", BssIdx,
2188 pAd->MlmeAux.SsidBssTab.BssNr));
2189 JoinParmFill(pAd, &JoinReq, BssIdx);
2190 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ,
2191 sizeof(struct rt_mlme_join_req), &JoinReq);
2192 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2193 } else if (pAd->StaCfg.BssType == BSS_ADHOC) {
2194 DBGPRINT(RT_DEBUG_TRACE,
2195 ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",
2196 pAd->MlmeAux.Ssid));
2197 StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid,
2198 pAd->MlmeAux.SsidLen);
2199 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
2200 sizeof(struct rt_mlme_start_req), &StartReq);
2201 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2202 } else /* no more BSS */
2206 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2207 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2208 DBGPRINT(RT_DEBUG_TRACE,
2209 ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",
2210 pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
2213 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2217 /* for re-association only */
2218 /* IRQL = DISPATCH_LEVEL */
2219 void IterateOnBssTab2(struct rt_rtmp_adapter *pAd)
2221 struct rt_mlme_assoc_req ReassocReq;
2222 unsigned long BssIdx;
2223 struct rt_bss_entry *pBss;
2225 BssIdx = pAd->MlmeAux.RoamIdx;
2226 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2228 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr) {
2229 DBGPRINT(RT_DEBUG_TRACE,
2230 ("CNTL - iterate BSS %ld of %d\n", BssIdx,
2231 pAd->MlmeAux.RoamTab.BssNr));
2233 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2234 AsicLockChannel(pAd, pBss->Channel);
2236 /* reassociate message has the same structure as associate message */
2237 AssocParmFill(pAd, &ReassocReq, pBss->Bssid,
2238 pBss->CapabilityInfo, ASSOC_TIMEOUT,
2239 pAd->StaCfg.DefaultListenCount);
2240 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2241 sizeof(struct rt_mlme_assoc_req), &ReassocReq);
2243 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2244 } else /* no more BSS */
2248 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2249 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2250 DBGPRINT(RT_DEBUG_TRACE,
2251 ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",
2252 pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
2255 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2260 ==========================================================================
2263 IRQL = DISPATCH_LEVEL
2265 ==========================================================================
2267 void JoinParmFill(struct rt_rtmp_adapter *pAd,
2268 struct rt_mlme_join_req *JoinReq, unsigned long BssIdx)
2270 JoinReq->BssIdx = BssIdx;
2274 ==========================================================================
2277 IRQL = DISPATCH_LEVEL
2279 ==========================================================================
2281 void ScanParmFill(struct rt_rtmp_adapter *pAd,
2282 struct rt_mlme_scan_req *ScanReq,
2284 u8 SsidLen, u8 BssType, u8 ScanType)
2286 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2287 ScanReq->SsidLen = SsidLen;
2288 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2289 ScanReq->BssType = BssType;
2290 ScanReq->ScanType = ScanType;
2294 ==========================================================================
2297 IRQL = DISPATCH_LEVEL
2299 ==========================================================================
2301 void StartParmFill(struct rt_rtmp_adapter *pAd,
2302 struct rt_mlme_start_req *StartReq,
2303 char Ssid[], u8 SsidLen)
2305 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2306 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2307 StartReq->SsidLen = SsidLen;
2311 ==========================================================================
2314 IRQL = DISPATCH_LEVEL
2316 ==========================================================================
2318 void AuthParmFill(struct rt_rtmp_adapter *pAd,
2319 struct rt_mlme_auth_req *AuthReq,
2322 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2324 AuthReq->Timeout = AUTH_TIMEOUT;
2328 ==========================================================================
2331 IRQL = DISPATCH_LEVEL
2333 ==========================================================================
2336 void ComposePsPoll(struct rt_rtmp_adapter *pAd)
2338 NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
2339 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2340 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2341 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2342 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2343 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2346 /* IRQL = DISPATCH_LEVEL */
2347 void ComposeNullFrame(struct rt_rtmp_adapter *pAd)
2349 NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11));
2350 pAd->NullFrame.FC.Type = BTYPE_DATA;
2351 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2352 pAd->NullFrame.FC.ToDs = 1;
2353 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2354 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2355 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2357 #endif /* RTMP_MAC_PCI // */
2359 void MlmeCntlConfirm(struct rt_rtmp_adapter *pAd, unsigned long MsgType, u16 Msg)
2361 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(u16),
2365 void ComposePsPoll(struct rt_rtmp_adapter *pAd)
2367 struct rt_txinfo *pTxInfo;
2368 struct rt_txwi * pTxWI;
2370 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2371 NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
2373 pAd->PsPollFrame.FC.PwrMgmt = 0;
2374 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2375 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2376 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2377 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2378 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2380 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.
2381 WirelessPacket[0], 100);
2383 (struct rt_txinfo *)& pAd->PsPollContext.TransferBuffer->field.
2385 RTMPWriteTxInfo(pAd, pTxInfo,
2386 (u16)(sizeof(struct rt_pspoll_frame) + TXWI_SIZE), TRUE,
2387 EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2389 (struct rt_txwi *) & pAd->PsPollContext.TransferBuffer->field.
2390 WirelessPacket[TXINFO_SIZE];
2391 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0,
2392 BSSID_WCID, (sizeof(struct rt_pspoll_frame)), 0, 0,
2393 (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
2394 IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2395 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.
2396 WirelessPacket[TXWI_SIZE + TXINFO_SIZE],
2397 &pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
2398 /* Append 4 extra zero bytes. */
2399 pAd->PsPollContext.BulkOutSize =
2400 TXINFO_SIZE + TXWI_SIZE + sizeof(struct rt_pspoll_frame) + 4;
2403 /* IRQL = DISPATCH_LEVEL */
2404 void ComposeNullFrame(struct rt_rtmp_adapter *pAd)
2406 struct rt_txinfo *pTxInfo;
2407 struct rt_txwi * pTxWI;
2409 NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11));
2410 pAd->NullFrame.FC.Type = BTYPE_DATA;
2411 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2412 pAd->NullFrame.FC.ToDs = 1;
2413 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2414 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2415 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2416 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.
2417 WirelessPacket[0], 100);
2419 (struct rt_txinfo *)& pAd->NullContext.TransferBuffer->field.
2421 RTMPWriteTxInfo(pAd, pTxInfo,
2422 (u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE), TRUE,
2423 EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2425 (struct rt_txwi *) & pAd->NullContext.TransferBuffer->field.
2426 WirelessPacket[TXINFO_SIZE];
2427 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0,
2428 BSSID_WCID, (sizeof(struct rt_header_802_11)), 0, 0,
2429 (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
2430 IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2431 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.
2432 WirelessPacket[TXWI_SIZE + TXINFO_SIZE], &pAd->NullFrame,
2433 sizeof(struct rt_header_802_11));
2434 pAd->NullContext.BulkOutSize =
2435 TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2437 #endif /* RTMP_MAC_USB // */
2440 ==========================================================================
2442 Pre-build a BEACON frame in the shared memory
2444 IRQL = PASSIVE_LEVEL
2445 IRQL = DISPATCH_LEVEL
2447 ==========================================================================
2449 unsigned long MakeIbssBeacon(struct rt_rtmp_adapter *pAd)
2451 u8 DsLen = 1, IbssLen = 2;
2452 u8 LocalErpIe[3] = { IE_ERP, 1, 0x04 };
2453 struct rt_header_802_11 BcnHdr;
2455 LARGE_INTEGER FakeTimestamp;
2456 unsigned long FrameLen = 0;
2457 struct rt_txwi * pTxWI = &pAd->BeaconTxWI;
2458 u8 *pBeaconFrame = pAd->BeaconBuf;
2460 u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2462 u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2466 if ((pAd->CommonCfg.PhyMode == PHY_11B)
2467 && (pAd->CommonCfg.Channel <= 14)) {
2468 SupRate[0] = 0x82; /* 1 mbps */
2469 SupRate[1] = 0x84; /* 2 mbps */
2470 SupRate[2] = 0x8b; /* 5.5 mbps */
2471 SupRate[3] = 0x96; /* 11 mbps */
2474 } else if (pAd->CommonCfg.Channel > 14) {
2475 SupRate[0] = 0x8C; /* 6 mbps, in units of 0.5 Mbps, basic rate */
2476 SupRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */
2477 SupRate[2] = 0x98; /* 12 mbps, in units of 0.5 Mbps, basic rate */
2478 SupRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */
2479 SupRate[4] = 0xb0; /* 24 mbps, in units of 0.5 Mbps, basic rate */
2480 SupRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */
2481 SupRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */
2482 SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */
2487 /* Also Update MlmeRate & RtsRate for G only & A only */
2489 pAd->CommonCfg.MlmeRate = RATE_6;
2490 pAd->CommonCfg.RtsRate = RATE_6;
2491 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2492 pAd->CommonCfg.MlmeTransmit.field.MCS =
2493 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2494 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
2496 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
2497 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2499 SupRate[0] = 0x82; /* 1 mbps */
2500 SupRate[1] = 0x84; /* 2 mbps */
2501 SupRate[2] = 0x8b; /* 5.5 mbps */
2502 SupRate[3] = 0x96; /* 11 mbps */
2505 ExtRate[0] = 0x0C; /* 6 mbps, in units of 0.5 Mbps, */
2506 ExtRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */
2507 ExtRate[2] = 0x18; /* 12 mbps, in units of 0.5 Mbps, */
2508 ExtRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */
2509 ExtRate[4] = 0x30; /* 24 mbps, in units of 0.5 Mbps, */
2510 ExtRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */
2511 ExtRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */
2512 ExtRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */
2516 pAd->StaActive.SupRateLen = SupRateLen;
2517 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2518 pAd->StaActive.ExtRateLen = ExtRateLen;
2519 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2521 /* compose IBSS beacon frame */
2522 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR,
2523 pAd->CommonCfg.Bssid);
2524 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
2525 || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2526 || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2528 CAP_GENERATE(0, 1, Privacy,
2529 (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort),
2532 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2533 sizeof(struct rt_header_802_11), &BcnHdr,
2534 TIMESTAMP_LEN, &FakeTimestamp,
2535 2, &pAd->CommonCfg.BeaconPeriod,
2538 1, &pAd->CommonCfg.SsidLen,
2539 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2542 SupRateLen, SupRate,
2545 1, &pAd->CommonCfg.Channel,
2547 1, &IbssLen, 2, &pAd->StaActive.AtimWin, END_OF_ARGS);
2549 /* add ERP_IE and EXT_RAE IE of in 802.11g */
2553 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2557 ExtRateLen, ExtRate, END_OF_ARGS);
2560 /* If adhoc secruity is set for WPA-None, append the cipher suite IE */
2561 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
2563 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus,
2566 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2568 1, &pAd->StaCfg.RSNIE_Len,
2569 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2574 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) {
2575 unsigned long TmpLen;
2578 /* add HT Capability IE */
2579 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2580 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2582 MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
2585 HtLen, &pAd->CommonCfg.HtCapability,
2588 HtLen1, &pAd->CommonCfg.AddHTInfo,
2593 /*beacon use reserved WCID 0xff */
2594 if (pAd->CommonCfg.Channel > 14) {
2595 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE,
2596 TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON,
2597 RATE_1, IFS_HTTXOP, FALSE,
2598 &pAd->CommonCfg.MlmeTransmit);
2600 /* Set to use 1Mbps for Adhoc beacon. */
2601 HTTRANSMIT_SETTING Transmit;
2603 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE,
2604 TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON,
2605 RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2608 DBGPRINT(RT_DEBUG_TRACE,
2609 ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2610 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel,
2611 pAd->CommonCfg.PhyMode));