1/* 2 ************************************************************************* 3 * Ralink Tech Inc. 4 * 5F., No.36, Taiyuan St., Jhubei City, 5 * Hsinchu County 302, 6 * Taiwan, R.O.C. 7 * 8 * (c) Copyright 2002-2007, Ralink Technology, Inc. 9 * 10 * This program is free software; you can redistribute it and/or modify * 11 * it under the terms of the GNU General Public License as published by * 12 * the Free Software Foundation; either version 2 of the License, or * 13 * (at your option) any later version. * 14 * * 15 * This program is distributed in the hope that it will be useful, * 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 * GNU General Public License for more details. * 19 * * 20 * You should have received a copy of the GNU General Public License * 21 * along with this program; if not, write to the * 22 * Free Software Foundation, Inc., * 23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 24 * * 25 ************************************************************************* 26 27 Module Name: 28 connect.c 29 30 Abstract: 31 32 Revision History: 33 Who When What 34 -------- ---------- ---------------------------------------------- 35 John 2004-08-08 Major modification from RT2560 36*/ 37#include "../rt_config.h" 38 39u8 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 */ 47}; 48 49u8 CipherSuiteWpaNoneTkipLen = 50 (sizeof(CipherSuiteWpaNoneTkip) / sizeof(u8)); 51 52u8 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 */ 60}; 61 62u8 CipherSuiteWpaNoneAesLen = 63 (sizeof(CipherSuiteWpaNoneAes) / sizeof(u8)); 64 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) \ 70{ \ 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;\ 95} 96 97/* 98 ========================================================================== 99 Description: 100 101 IRQL = PASSIVE_LEVEL 102 103 ========================================================================== 104*/ 105void MlmeCntlInit(struct rt_rtmp_adapter *pAd, 106 struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[]) 107{ 108 /* Control state machine differs from other state machines, the interface */ 109 /* follows the standard interface */ 110 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 111} 112 113/* 114 ========================================================================== 115 Description: 116 117 IRQL = DISPATCH_LEVEL 118 119 ========================================================================== 120*/ 121void MlmeCntlMachinePerformAction(struct rt_rtmp_adapter *pAd, 122 struct rt_state_machine *S, 123 struct rt_mlme_queue_elem *Elem) 124{ 125 switch (pAd->Mlme.CntlMachine.CurrState) { 126 case CNTL_IDLE: 127 CntlIdleProc(pAd, Elem); 128 break; 129 case CNTL_WAIT_DISASSOC: 130 CntlWaitDisassocProc(pAd, Elem); 131 break; 132 case CNTL_WAIT_JOIN: 133 CntlWaitJoinProc(pAd, Elem); 134 break; 135 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); 144 break; 145 146 case CNTL_WAIT_START: 147 CntlWaitStartProc(pAd, Elem); 148 break; 149 case CNTL_WAIT_AUTH: 150 CntlWaitAuthProc(pAd, Elem); 151 break; 152 case CNTL_WAIT_AUTH2: 153 CntlWaitAuthProc2(pAd, Elem); 154 break; 155 case CNTL_WAIT_ASSOC: 156 CntlWaitAssocProc(pAd, Elem); 157 break; 158 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); 164 165 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 166 167 /* */ 168 /* Set LED status to previous status. */ 169 /* */ 170 if (pAd->bLedOnScanning) { 171 pAd->bLedOnScanning = FALSE; 172 RTMPSetLED(pAd, pAd->LedStatus); 173 } 174 } 175 break; 176 177 case CNTL_WAIT_OID_DISASSOC: 178 if (Elem->MsgType == MT2_DISASSOC_CONF) { 179 LinkDown(pAd, FALSE); 180 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 181 } 182 break; 183#ifdef RTMP_MAC_USB 184 /* */ 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. */ 188 /* */ 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); 194#ifdef CCX_SUPPORT 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); 199 } 200#endif /* CCX_SUPPORT // */ 201 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 202 203 /* */ 204 /* Check if we can connect to. */ 205 /* */ 206 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, 207 (char *) pAd->MlmeAux. 208 AutoReconnectSsid, 209 pAd->MlmeAux.AutoReconnectSsidLen); 210 if (pAd->MlmeAux.SsidBssTab.BssNr > 0) { 211 MlmeAutoReconnectLastSSID(pAd); 212 } 213 } 214 break; 215#endif /* RTMP_MAC_USB // */ 216 default: 217 DBGPRINT_ERR(("ERROR! CNTL - Illegal message type(=%ld)", 218 Elem->MsgType)); 219 break; 220 } 221} 222 223/* 224 ========================================================================== 225 Description: 226 227 IRQL = DISPATCH_LEVEL 228 229 ========================================================================== 230*/ 231void CntlIdleProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 232{ 233 struct rt_mlme_disassoc_req DisassocReq; 234 235 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) 236 return; 237 238 switch (Elem->MsgType) { 239 case OID_802_11_SSID: 240 CntlOidSsidProc(pAd, Elem); 241 break; 242 243 case OID_802_11_BSSID: 244 CntlOidRTBssidProc(pAd, Elem); 245 break; 246 247 case OID_802_11_BSSID_LIST_SCAN: 248 CntlOidScanProc(pAd, Elem); 249 break; 250 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; 257 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); 265 } 266 break; 267 268 case MT2_MLME_ROAMING_REQ: 269 CntlMlmeRoamingProc(pAd, Elem); 270 break; 271 272 case OID_802_11_MIC_FAILURE_REPORT_FRAME: 273 WpaMicFailureReportFrame(pAd, Elem); 274 break; 275 276 default: 277 DBGPRINT(RT_DEBUG_TRACE, 278 ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n", 279 Elem->MsgType)); 280 break; 281 } 282} 283 284void CntlOidScanProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 285{ 286 struct rt_mlme_scan_req ScanReq; 287 unsigned long BssIdx = BSS_NOT_FOUND; 288 struct rt_bss_entry CurrBss; 289 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)) { 293 BssIdx = 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)); 301 } 302 } 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; 314 } 315 316 ScanParmFill(pAd, &ScanReq, (char *)Elem->Msg, Elem->MsgLen, BSS_ANY, 317 SCAN_ACTIVE); 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; 321} 322 323/* 324 ========================================================================== 325 Description: 326 Before calling this routine, user desired SSID should already been 327 recorded in CommonCfg.Ssid[] 328 IRQL = DISPATCH_LEVEL 329 330 ========================================================================== 331*/ 332void CntlOidSsidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 333{ 334 struct rt_ndis_802_11_ssid * pOidSsid = (struct rt_ndis_802_11_ssid *) Elem->Msg; 335 struct rt_mlme_disassoc_req DisassocReq; 336 unsigned long Now; 337 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; 344 345 pAd->StaCfg.bAutoConnectByBssid = FALSE; 346 347 /* */ 348 /* Update Reconnect Ssid, that user desired to connect. */ 349 /* */ 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; 354 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); 359 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); 365 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 */ 376 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) 382 ) && 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), 394 &DisassocReq); 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), 406 &DisassocReq); 407 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; 408 } else { 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")); 412 /* */ 413 /* (HCT 12.1) 1c_wlan_mediaevents required */ 414 /* media connect events are indicated when associating with the same AP */ 415 /* */ 416 if (INFRA_ON(pAd)) { 417 /* */ 418 /* Since MediaState already is NdisMediaStateConnected */ 419 /* We just indicate the connect event again to meet the WHQL required. */ 420 /* */ 421 pAd->IndicateMediaState = 422 NdisMediaStateConnected; 423 RTMP_IndicateMediaState(pAd); 424 pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information to link is up */ 425 } 426 427 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 428 RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, 429 &pAd->MlmeAux.Bssid[0], NULL, 430 0); 431 } 432 } else if (INFRA_ON(pAd)) { 433 /* */ 434 /* For RT61 */ 435 /* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */ 436 /* RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect */ 437 /* But media status is connected, so the SSID not report correctly. */ 438 /* */ 439 if (!SSID_EQUAL 440 (pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, 441 pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)) { 442 /* */ 443 /* Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event. */ 444 /* */ 445 pAd->MlmeAux.CurrReqIsFromNdis = TRUE; 446 } 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; 460 } else { 461 if (ADHOC_ON(pAd)) { 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")); 472 } 473 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) 478 == TRUE) 479 ) { 480 struct rt_mlme_scan_req ScanReq; 481 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, 486 SCAN_ACTIVE); 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; 493 } else { 494 pAd->MlmeAux.BssIdx = 0; 495 IterateOnBssTab(pAd); 496 } 497 } 498} 499 500/* 501 ========================================================================== 502 Description: 503 504 IRQL = DISPATCH_LEVEL 505 506 ========================================================================== 507*/ 508void CntlOidRTBssidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 509{ 510 unsigned long BssIdx; 511 u8 *pOidBssid = (u8 *)Elem->Msg; 512 struct rt_mlme_disassoc_req DisassocReq; 513 struct rt_mlme_join_req JoinReq; 514 515 /* record user desired settings */ 516 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid); 517 pAd->MlmeAux.BssType = pAd->StaCfg.BssType; 518 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; 523 524 DBGPRINT(RT_DEBUG_TRACE, 525 ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n")); 526 /*pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; */ 527 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); 537 return; 538 } 539 /* */ 540 /* Update Reconnect Ssid, that user desired to connect. */ 541 /* */ 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); 548 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)); 555 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); 560 561 { 562 if (INFRA_ON(pAd)) { 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), 572 &DisassocReq); 573 574 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; 575 } else { 576 if (ADHOC_ON(pAd)) { 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")); 588 } 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; 593 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. 602 GroupCipher; 603 604 if (pAd->StaCfg.WepStatus == 605 pAd->ScanTab.BssEntry[BssIdx].WPA. 606 PairCipher) 607 pAd->StaCfg.PairCipher = 608 pAd->ScanTab.BssEntry[BssIdx].WPA. 609 PairCipher; 610 else if (pAd->ScanTab.BssEntry[BssIdx].WPA. 611 PairCipherAux != Ndis802_11WEPDisabled) 612 pAd->StaCfg.PairCipher = 613 pAd->ScanTab.BssEntry[BssIdx].WPA. 614 PairCipherAux; 615 else /* There is no PairCipher Aux, downgrade our capability to TKIP */ 616 pAd->StaCfg.PairCipher = 617 Ndis802_11Encryption2Enabled; 618 } else 619 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) 620 || (pAd->StaCfg.AuthMode == 621 Ndis802_11AuthModeWPA2PSK)) { 622 pAd->StaCfg.GroupCipher = 623 pAd->ScanTab.BssEntry[BssIdx].WPA2. 624 GroupCipher; 625 626 if (pAd->StaCfg.WepStatus == 627 pAd->ScanTab.BssEntry[BssIdx].WPA2. 628 PairCipher) 629 pAd->StaCfg.PairCipher = 630 pAd->ScanTab.BssEntry[BssIdx].WPA2. 631 PairCipher; 632 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2. 633 PairCipherAux != Ndis802_11WEPDisabled) 634 pAd->StaCfg.PairCipher = 635 pAd->ScanTab.BssEntry[BssIdx].WPA2. 636 PairCipherAux; 637 else /* There is no PairCipher Aux, downgrade our capability to TKIP */ 638 pAd->StaCfg.PairCipher = 639 Ndis802_11Encryption2Enabled; 640 641 /* RSN capability */ 642 pAd->StaCfg.RsnCapability = 643 pAd->ScanTab.BssEntry[BssIdx].WPA2. 644 RsnCapability; 645 } 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) 651 { 652 // If mix cipher, re-build RSNIE 653 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0); 654 } */ 655 /* No active association, join the BSS immediately */ 656 DBGPRINT(RT_DEBUG_TRACE, 657 ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n", 658 pOidBssid[0], pOidBssid[1], pOidBssid[2], 659 pOidBssid[3], pOidBssid[4], pOidBssid[5])); 660 661 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx); 662 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, 663 sizeof(struct rt_mlme_join_req), &JoinReq); 664 665 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN; 666 } 667 } 668} 669 670/* Roaming is the only external request triggering CNTL state machine */ 671/* despite of other "SET OID" operation. All "SET OID" related oerations */ 672/* happen in sequence, because no other SET OID will be sent to this device */ 673/* until the the previous SET operation is complete (successful o failed). */ 674/* So, how do we quarantee this ROAMING request won't corrupt other "SET OID"? */ 675/* or been corrupted by other "SET OID"? */ 676/* */ 677/* IRQL = DISPATCH_LEVEL */ 678void CntlMlmeRoamingProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 679{ 680 u8 BBPValue = 0; 681 682 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Roaming in MlmeAux.RoamTab...\n")); 683 684 { 685 /*Let BBP register at 20MHz to do (fast) roaming. */ 686 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); 687 BBPValue &= (~0x18); 688 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); 689 690 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, 691 sizeof(pAd->MlmeAux.RoamTab)); 692 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr; 693 694 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab); 695 pAd->MlmeAux.BssIdx = 0; 696 IterateOnBssTab(pAd); 697 } 698} 699 700/* 701 ========================================================================== 702 Description: 703 704 IRQL = DISPATCH_LEVEL 705 706 ========================================================================== 707*/ 708void CntlWaitDisassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 709{ 710 struct rt_mlme_start_req StartReq; 711 712 if (Elem->MsgType == MT2_DISASSOC_CONF) { 713 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n")); 714 715 if (pAd->CommonCfg.bWirelessEvent) { 716 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, 717 pAd->MacTab.Content[BSSID_WCID]. 718 Addr, BSS0, 0); 719 } 720 721 LinkDown(pAd, FALSE); 722 723 /* case 1. no matching BSS, and user wants ADHOC, so we just start a new one */ 724 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) 725 && (pAd->StaCfg.BssType == BSS_ADHOC)) { 726 DBGPRINT(RT_DEBUG_TRACE, 727 ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n", 728 pAd->MlmeAux.Ssid)); 729 StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid, 730 pAd->MlmeAux.SsidLen); 731 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, 732 sizeof(struct rt_mlme_start_req), &StartReq); 733 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START; 734 } 735 /* case 2. try each matched BSS */ 736 else { 737 pAd->MlmeAux.BssIdx = 0; 738 739 IterateOnBssTab(pAd); 740 } 741 } 742} 743 744/* 745 ========================================================================== 746 Description: 747 748 IRQL = DISPATCH_LEVEL 749 750 ========================================================================== 751*/ 752void CntlWaitJoinProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 753{ 754 u16 Reason; 755 struct rt_mlme_auth_req AuthReq; 756 757 if (Elem->MsgType == MT2_JOIN_CONF) { 758 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16)); 759 if (Reason == MLME_SUCCESS) { 760 /* 1. joined an IBSS, we are pretty much done here */ 761 if (pAd->MlmeAux.BssType == BSS_ADHOC) { 762 /* */ 763 /* 5G bands rules of Japan: */ 764 /* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */ 765 /* */ 766 if ((pAd->CommonCfg.bIEEE80211H == 1) && 767 RadarChannelCheck(pAd, 768 pAd->CommonCfg.Channel) 769 ) { 770 pAd->Mlme.CntlMachine.CurrState = 771 CNTL_IDLE; 772 DBGPRINT(RT_DEBUG_TRACE, 773 ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", 774 pAd->CommonCfg.Channel)); 775 return; 776 } 777 778 LinkUp(pAd, BSS_ADHOC); 779 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 780 DBGPRINT(RT_DEBUG_TRACE, 781 ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n", 782 pAd->CommonCfg.Bssid[0], 783 pAd->CommonCfg.Bssid[1], 784 pAd->CommonCfg.Bssid[2], 785 pAd->CommonCfg.Bssid[3], 786 pAd->CommonCfg.Bssid[4], 787 pAd->CommonCfg.Bssid[5])); 788 789 pAd->IndicateMediaState = 790 NdisMediaStateConnected; 791 pAd->ExtraInfo = GENERAL_LINK_UP; 792 } 793 /* 2. joined a new INFRA network, start from authentication */ 794 else { 795 { 796 /* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */ 797 if ((pAd->StaCfg.AuthMode == 798 Ndis802_11AuthModeShared) 799 || (pAd->StaCfg.AuthMode == 800 Ndis802_11AuthModeAutoSwitch)) { 801 AuthParmFill(pAd, &AuthReq, 802 pAd->MlmeAux.Bssid, 803 AUTH_MODE_KEY); 804 } else { 805 AuthParmFill(pAd, &AuthReq, 806 pAd->MlmeAux.Bssid, 807 AUTH_MODE_OPEN); 808 } 809 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, 810 MT2_MLME_AUTH_REQ, 811 sizeof 812 (struct rt_mlme_auth_req), 813 &AuthReq); 814 } 815 816 pAd->Mlme.CntlMachine.CurrState = 817 CNTL_WAIT_AUTH; 818 } 819 } else { 820 /* 3. failed, try next BSS */ 821 pAd->MlmeAux.BssIdx++; 822 IterateOnBssTab(pAd); 823 } 824 } 825} 826 827/* 828 ========================================================================== 829 Description: 830 831 IRQL = DISPATCH_LEVEL 832 833 ========================================================================== 834*/ 835void CntlWaitStartProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 836{ 837 u16 Result; 838 839 if (Elem->MsgType == MT2_START_CONF) { 840 NdisMoveMemory(&Result, Elem->Msg, sizeof(u16)); 841 if (Result == MLME_SUCCESS) { 842 /* */ 843 /* 5G bands rules of Japan: */ 844 /* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */ 845 /* */ 846 if ((pAd->CommonCfg.bIEEE80211H == 1) && 847 RadarChannelCheck(pAd, pAd->CommonCfg.Channel) 848 ) { 849 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 850 DBGPRINT(RT_DEBUG_TRACE, 851 ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", 852 pAd->CommonCfg.Channel)); 853 return; 854 } 855 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo. 856 MCSSet[0], 16); 857 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) { 858 N_ChannelCheck(pAd); 859 SetCommonHT(pAd); 860 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, 861 &pAd->CommonCfg.AddHTInfo, 862 sizeof(struct rt_add_ht_info_ie)); 863 RTMPCheckHt(pAd, BSSID_WCID, 864 &pAd->CommonCfg.HtCapability, 865 &pAd->CommonCfg.AddHTInfo); 866 pAd->StaActive.SupportedPhyInfo.bHtEnable = 867 TRUE; 868 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo. 869 MCSSet[0], 870 &pAd->CommonCfg.HtCapability. 871 MCSSet[0], 16); 872 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG 873 (pAd); 874 875 if ((pAd->CommonCfg.HtCapability.HtCapInfo. 876 ChannelWidth == BW_40) 877 && (pAd->CommonCfg.AddHTInfo.AddHtInfo. 878 ExtChanOffset == EXTCHA_ABOVE)) { 879 pAd->MlmeAux.CentralChannel = 880 pAd->CommonCfg.Channel + 2; 881 } else 882 if ((pAd->CommonCfg.HtCapability.HtCapInfo. 883 ChannelWidth == BW_40) 884 && (pAd->CommonCfg.AddHTInfo.AddHtInfo. 885 ExtChanOffset == EXTCHA_BELOW)) { 886 pAd->MlmeAux.CentralChannel = 887 pAd->CommonCfg.Channel - 2; 888 } 889 } else { 890 pAd->StaActive.SupportedPhyInfo.bHtEnable = 891 FALSE; 892 } 893 LinkUp(pAd, BSS_ADHOC); 894 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 895 /* Before send beacon, driver need do radar detection */ 896 if ((pAd->CommonCfg.Channel > 14) 897 && (pAd->CommonCfg.bIEEE80211H == 1) 898 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) { 899 pAd->CommonCfg.RadarDetect.RDMode = 900 RD_SILENCE_MODE; 901 pAd->CommonCfg.RadarDetect.RDCount = 0; 902 } 903 904 DBGPRINT(RT_DEBUG_TRACE, 905 ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n", 906 pAd->CommonCfg.Bssid[0], 907 pAd->CommonCfg.Bssid[1], 908 pAd->CommonCfg.Bssid[2], 909 pAd->CommonCfg.Bssid[3], 910 pAd->CommonCfg.Bssid[4], 911 pAd->CommonCfg.Bssid[5])); 912 } else { 913 DBGPRINT(RT_DEBUG_TRACE, 914 ("CNTL - Start IBSS fail. BUG!\n")); 915 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 916 } 917 } 918} 919 920/* 921 ========================================================================== 922 Description: 923 924 IRQL = DISPATCH_LEVEL 925 926 ========================================================================== 927*/ 928void CntlWaitAuthProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 929{ 930 u16 Reason; 931 struct rt_mlme_assoc_req AssocReq; 932 struct rt_mlme_auth_req AuthReq; 933 934 if (Elem->MsgType == MT2_AUTH_CONF) { 935 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16)); 936 if (Reason == MLME_SUCCESS) { 937 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n")); 938 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, 939 pAd->MlmeAux.CapabilityInfo, 940 ASSOC_TIMEOUT, 941 pAd->StaCfg.DefaultListenCount); 942 943 { 944 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, 945 MT2_MLME_ASSOC_REQ, 946 sizeof(struct rt_mlme_assoc_req), 947 &AssocReq); 948 949 pAd->Mlme.CntlMachine.CurrState = 950 CNTL_WAIT_ASSOC; 951 } 952 } else { 953 /* This fail may because of the AP already keep us in its MAC table without */ 954 /* ageing-out. The previous authentication attempt must have let it remove us. */ 955 /* so try Authentication again may help. For D-Link DWL-900AP+ compatibility. */ 956 DBGPRINT(RT_DEBUG_TRACE, 957 ("CNTL - AUTH FAIL, try again...\n")); 958 959 { 960 if ((pAd->StaCfg.AuthMode == 961 Ndis802_11AuthModeShared) 962 || (pAd->StaCfg.AuthMode == 963 Ndis802_11AuthModeAutoSwitch)) { 964 /* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */ 965 AuthParmFill(pAd, &AuthReq, 966 pAd->MlmeAux.Bssid, 967 AUTH_MODE_KEY); 968 } else { 969 AuthParmFill(pAd, &AuthReq, 970 pAd->MlmeAux.Bssid, 971 AUTH_MODE_OPEN); 972 } 973 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, 974 MT2_MLME_AUTH_REQ, 975 sizeof(struct rt_mlme_auth_req), 976 &AuthReq); 977 978 } 979 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2; 980 } 981 } 982} 983 984/* 985 ========================================================================== 986 Description: 987 988 IRQL = DISPATCH_LEVEL 989 990 ========================================================================== 991*/ 992void CntlWaitAuthProc2(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 993{ 994 u16 Reason; 995 struct rt_mlme_assoc_req AssocReq; 996 struct rt_mlme_auth_req AuthReq; 997 998 if (Elem->MsgType == MT2_AUTH_CONF) { 999 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16)); 1000 if (Reason == MLME_SUCCESS) { 1001 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n")); 1002 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, 1003 pAd->MlmeAux.CapabilityInfo, 1004 ASSOC_TIMEOUT, 1005 pAd->StaCfg.DefaultListenCount); 1006 { 1007 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, 1008 MT2_MLME_ASSOC_REQ, 1009 sizeof(struct rt_mlme_assoc_req), 1010 &AssocReq); 1011 1012 pAd->Mlme.CntlMachine.CurrState = 1013 CNTL_WAIT_ASSOC; 1014 } 1015 } else { 1016 if ((pAd->StaCfg.AuthMode == 1017 Ndis802_11AuthModeAutoSwitch) 1018 && (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared)) { 1019 DBGPRINT(RT_DEBUG_TRACE, 1020 ("CNTL - AUTH FAIL, try OPEN system...\n")); 1021 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, 1022 Ndis802_11AuthModeOpen); 1023 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, 1024 MT2_MLME_AUTH_REQ, 1025 sizeof(struct rt_mlme_auth_req), 1026 &AuthReq); 1027 1028 pAd->Mlme.CntlMachine.CurrState = 1029 CNTL_WAIT_AUTH2; 1030 } else { 1031 /* not success, try next BSS */ 1032 DBGPRINT(RT_DEBUG_TRACE, 1033 ("CNTL - AUTH FAIL, give up; try next BSS\n")); 1034 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; /*??????? */ 1035 pAd->MlmeAux.BssIdx++; 1036 IterateOnBssTab(pAd); 1037 } 1038 } 1039 } 1040} 1041 1042/* 1043 ========================================================================== 1044 Description: 1045 1046 IRQL = DISPATCH_LEVEL 1047 1048 ========================================================================== 1049*/ 1050void CntlWaitAssocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 1051{ 1052 u16 Reason; 1053 1054 if (Elem->MsgType == MT2_ASSOC_CONF) { 1055 NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16)); 1056 if (Reason == MLME_SUCCESS) { 1057 if (pAd->CommonCfg.bWirelessEvent) { 1058 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, 1059 pAd->MacTab. 1060 Content[BSSID_WCID].Addr, 1061 BSS0, 0); 1062 } 1063 1064 LinkUp(pAd, BSS_INFRA); 1065 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 1066 DBGPRINT(RT_DEBUG_TRACE, 1067 ("CNTL - Association successful on BSS #%ld\n", 1068 pAd->MlmeAux.BssIdx)); 1069 } else { 1070 /* not success, try next BSS */ 1071 DBGPRINT(RT_DEBUG_TRACE, 1072 ("CNTL - Association fails on BSS #%ld\n", 1073 pAd->MlmeAux.BssIdx)); 1074 pAd->MlmeAux.BssIdx++; 1075 IterateOnBssTab(pAd); 1076 } 1077 } 1078} 1079 1080/* 1081 ========================================================================== 1082 Description: 1083 1084 IRQL = DISPATCH_LEVEL 1085 1086 ========================================================================== 1087*/ 1088void CntlWaitReassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) 1089{ 1090 u16 Result; 1091 1092 if (Elem->MsgType == MT2_REASSOC_CONF) { 1093 NdisMoveMemory(&Result, Elem->Msg, sizeof(u16)); 1094 if (Result == MLME_SUCCESS) { 1095 /* send wireless event - for association */ 1096 if (pAd->CommonCfg.bWirelessEvent) 1097 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, 1098 pAd->MacTab. 1099 Content[BSSID_WCID].Addr, 1100 BSS0, 0); 1101 1102 /* */ 1103 /* NDIS requires a new Link UP indication but no Link Down for RE-ASSOC */ 1104 /* */ 1105 LinkUp(pAd, BSS_INFRA); 1106 1107 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 1108 DBGPRINT(RT_DEBUG_TRACE, 1109 ("CNTL - Re-assocition successful on BSS #%ld\n", 1110 pAd->MlmeAux.RoamIdx)); 1111 } else { 1112 /* reassoc failed, try to pick next BSS in the BSS Table */ 1113 DBGPRINT(RT_DEBUG_TRACE, 1114 ("CNTL - Re-assocition fails on BSS #%ld\n", 1115 pAd->MlmeAux.RoamIdx)); 1116 { 1117 pAd->MlmeAux.RoamIdx++; 1118 IterateOnBssTab2(pAd); 1119 } 1120 } 1121 } 1122} 1123 1124void AdhocTurnOnQos(struct rt_rtmp_adapter *pAd) 1125{ 1126#define AC0_DEF_TXOP 0 1127#define AC1_DEF_TXOP 0 1128#define AC2_DEF_TXOP 94 1129#define AC3_DEF_TXOP 47 1130 1131 /* Turn on QOs if use HT rate. */ 1132 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) { 1133 pAd->CommonCfg.APEdcaParm.bValid = TRUE; 1134 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3; 1135 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7; 1136 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1; 1137 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1; 1138 1139 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4; 1140 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4; 1141 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3; 1142 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2; 1143 1144 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10; 1145 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6; 1146 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4; 1147 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3; 1148 1149 pAd->CommonCfg.APEdcaParm.Txop[0] = 0; 1150 pAd->CommonCfg.APEdcaParm.Txop[1] = 0; 1151 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP; 1152 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP; 1153 } 1154 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); 1155} 1156 1157/* 1158 ========================================================================== 1159 Description: 1160 1161 IRQL = DISPATCH_LEVEL 1162 1163 ========================================================================== 1164*/ 1165void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType) 1166{ 1167 unsigned long Now; 1168 u32 Data; 1169 BOOLEAN Cancelled; 1170 u8 Value = 0, idx = 0, HashIdx = 0; 1171 struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry = NULL; 1172 1173 /* Init ChannelQuality to prevent DEAD_CQI at initial LinkUp */ 1174 pAd->Mlme.ChannelQuality = 50; 1175 1176 pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid); 1177 if (pEntry) { 1178 MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); 1179 pEntry = NULL; 1180 } 1181 1182 pEntry = &pAd->MacTab.Content[BSSID_WCID]; 1183 1184 /* */ 1185 /* ASSOC - DisassocTimeoutAction */ 1186 /* CNTL - Dis-associate successful */ 1187 /* ! LINK DOWN ! */ 1188 /* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */ 1189 /* */ 1190 /* To prevent DisassocTimeoutAction to call Link down after we link up, */ 1191 /* cancel the DisassocTimer no matter what it start or not. */ 1192 /* */ 1193 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled); 1194 1195 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd); 1196 1197 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd); 1198 1199#ifdef RTMP_MAC_PCI 1200 /* Before power save before link up function, We will force use 1R. */ 1201 /* So after link up, check Rx antenna # again. */ 1202 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); 1203 if (pAd->Antenna.field.RxPath == 3) { 1204 Value |= (0x10); 1205 } else if (pAd->Antenna.field.RxPath == 2) { 1206 Value |= (0x8); 1207 } else if (pAd->Antenna.field.RxPath == 1) { 1208 Value |= (0x0); 1209 } 1210 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); 1211 pAd->StaCfg.BBPR3 = Value; 1212#endif /* RTMP_MAC_PCI // */ 1213 1214 if (BssType == BSS_ADHOC) { 1215 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON); 1216 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON); 1217 1218 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) 1219 AdhocTurnOnQos(pAd); 1220 1221 DBGPRINT(RT_DEBUG_TRACE, ("Adhoc LINK UP!\n")); 1222 } else { 1223 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON); 1224 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON); 1225 1226 DBGPRINT(RT_DEBUG_TRACE, ("Infra LINK UP!\n")); 1227 } 1228 1229 /* 3*3 */ 1230 /* reset Tx beamforming bit */ 1231 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); 1232 Value &= (~0x01); 1233 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF; 1234 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); 1235 1236 /* Change to AP channel */ 1237 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) 1238 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) { 1239 /* Must using 40MHz. */ 1240 pAd->CommonCfg.BBPCurrentBW = BW_40; 1241 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); 1242 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); 1243 1244 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); 1245 Value &= (~0x18); 1246 Value |= 0x10; 1247 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); 1248 1249 /* RX : control channel at lower */ 1250 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); 1251 Value &= (~0x20); 1252 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); 1253#ifdef RTMP_MAC_PCI 1254 pAd->StaCfg.BBPR3 = Value; 1255#endif /* RTMP_MAC_PCI // */ 1256 1257 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); 1258 Data &= 0xfffffffe; 1259 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); 1260 1261 if (pAd->MACVersion == 0x28600100) { 1262 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); 1263 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); 1264 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); 1265 DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n")); 1266 } 1267 1268 DBGPRINT(RT_DEBUG_TRACE, 1269 ("40MHz Lower LINK UP! Control Channel at Below. Central = %d \n", 1270 pAd->CommonCfg.CentralChannel)); 1271 } else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) 1272 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == 1273 BW_40)) { 1274 /* Must using 40MHz. */ 1275 pAd->CommonCfg.BBPCurrentBW = BW_40; 1276 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); 1277 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); 1278 1279 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); 1280 Value &= (~0x18); 1281 Value |= 0x10; 1282 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); 1283 1284 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); 1285 Data |= 0x1; 1286 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); 1287 1288 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); 1289 Value |= (0x20); 1290 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); 1291#ifdef RTMP_MAC_PCI 1292 pAd->StaCfg.BBPR3 = Value; 1293#endif /* RTMP_MAC_PCI // */ 1294 1295 if (pAd->MACVersion == 0x28600100) { 1296 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); 1297 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); 1298 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); 1299 DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n")); 1300 } 1301 1302 DBGPRINT(RT_DEBUG_TRACE, 1303 ("40MHz Upper LINK UP! Control Channel at UpperCentral = %d \n", 1304 pAd->CommonCfg.CentralChannel)); 1305 } else { 1306 pAd->CommonCfg.BBPCurrentBW = BW_20; 1307 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; 1308 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); 1309 AsicLockChannel(pAd, pAd->CommonCfg.Channel); 1310 1311 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); 1312 Value &= (~0x18); 1313 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); 1314 1315 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); 1316 Data &= 0xfffffffe; 1317 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); 1318 1319 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); 1320 Value &= (~0x20); 1321 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); 1322#ifdef RTMP_MAC_PCI 1323 pAd->StaCfg.BBPR3 = Value; 1324#endif /* RTMP_MAC_PCI // */ 1325 1326 if (pAd->MACVersion == 0x28600100) { 1327 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); 1328 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08); 1329 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11); 1330 DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n")); 1331 } 1332 1333 DBGPRINT(RT_DEBUG_TRACE, ("20MHz LINK UP!\n")); 1334 } 1335 1336 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); 1337 1338 /* */ 1339 /* Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission */ 1340 /* */ 1341 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, 1342 &pAd->BbpTuning.R66CurrentValue); 1343 1344 DBGPRINT(RT_DEBUG_TRACE, 1345 ("LINK UP! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n", 1346 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, 1347 pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel)); 1348 1349 DBGPRINT(RT_DEBUG_TRACE, 1350 ("LINK UP! (Density =%d, )\n", 1351 pAd->MacTab.Content[BSSID_WCID].MpduDensity)); 1352 1353 AsicSetBssid(pAd, pAd->CommonCfg.Bssid); 1354 1355 AsicSetSlotTime(pAd, TRUE); 1356 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); 1357 1358 /* Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit */ 1359 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, 1360 FALSE); 1361 1362 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)) { 1363 /* Update HT protectionfor based on AP's operating mode. */ 1364 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) { 1365 AsicUpdateProtect(pAd, 1366 pAd->MlmeAux.AddHtInfo.AddHtInfo2. 1367 OperaionMode, ALLN_SETPROTECT, FALSE, 1368 TRUE); 1369 } else 1370 AsicUpdateProtect(pAd, 1371 pAd->MlmeAux.AddHtInfo.AddHtInfo2. 1372 OperaionMode, ALLN_SETPROTECT, FALSE, 1373 FALSE); 1374 } 1375 1376 NdisZeroMemory(&pAd->DrsCounters, sizeof(struct rt_counter_drs)); 1377 1378 NdisGetSystemUpTime(&Now); 1379 pAd->StaCfg.LastBeaconRxTime = Now; /* last RX timestamp */ 1380 1381 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) && 1382 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo)) { 1383 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort); 1384 } 1385 1386 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); 1387 1388 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE) { 1389 } 1390 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE; 1391 1392 if (BssType == BSS_ADHOC) { 1393 MakeIbssBeacon(pAd); 1394 if ((pAd->CommonCfg.Channel > 14) 1395 && (pAd->CommonCfg.bIEEE80211H == 1) 1396 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) { 1397 ; /*Do nothing */ 1398 } else { 1399 AsicEnableIbssSync(pAd); 1400 } 1401 1402 /* In ad hoc mode, use MAC table from index 1. */ 1403 /* 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. */ 1404 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00); 1405 RTMP_IO_WRITE32(pAd, 0x1808, 0x00); 1406 1407 /* If WEP is enabled, add key material and cipherAlg into Asic */ 1408 /* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */ 1409 1410 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) { 1411 u8 *Key; 1412 u8 CipherAlg; 1413 1414 for (idx = 0; idx < SHARE_KEY_NUM; idx++) { 1415 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg; 1416 Key = pAd->SharedKey[BSS0][idx].Key; 1417 1418 if (pAd->SharedKey[BSS0][idx].KeyLen > 0) { 1419 /* Set key material and cipherAlg to Asic */ 1420 AsicAddSharedKeyEntry(pAd, BSS0, idx, 1421 CipherAlg, Key, 1422 NULL, NULL); 1423 1424 if (idx == pAd->StaCfg.DefaultKeyId) { 1425 /* Update WCID attribute table and IVEIV table for this group key table */ 1426 RTMPAddWcidAttributeEntry(pAd, 1427 BSS0, 1428 idx, 1429 CipherAlg, 1430 NULL); 1431 } 1432 } 1433 1434 } 1435 } 1436 /* If WPANone is enabled, add key material and cipherAlg into Asic */ 1437 /* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */ 1438 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) { 1439 pAd->StaCfg.DefaultKeyId = 0; /* always be zero */ 1440 1441 NdisZeroMemory(&pAd->SharedKey[BSS0][0], 1442 sizeof(struct rt_cipher_key)); 1443 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK; 1444 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, 1445 pAd->StaCfg.PMK, LEN_TKIP_EK); 1446 1447 if (pAd->StaCfg.PairCipher == 1448 Ndis802_11Encryption2Enabled) { 1449 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, 1450 &pAd->StaCfg.PMK[16], 1451 LEN_TKIP_RXMICK); 1452 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, 1453 &pAd->StaCfg.PMK[16], 1454 LEN_TKIP_TXMICK); 1455 } 1456 /* Decide its ChiperAlg */ 1457 if (pAd->StaCfg.PairCipher == 1458 Ndis802_11Encryption2Enabled) 1459 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP; 1460 else if (pAd->StaCfg.PairCipher == 1461 Ndis802_11Encryption3Enabled) 1462 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES; 1463 else { 1464 DBGPRINT(RT_DEBUG_TRACE, 1465 ("Unknow Cipher (=%d), set Cipher to AES\n", 1466 pAd->StaCfg.PairCipher)); 1467 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES; 1468 } 1469 1470 /* Set key material and cipherAlg to Asic */ 1471 AsicAddSharedKeyEntry(pAd, 1472 BSS0, 1473 0, 1474 pAd->SharedKey[BSS0][0].CipherAlg, 1475 pAd->SharedKey[BSS0][0].Key, 1476 pAd->SharedKey[BSS0][0].TxMic, 1477 pAd->SharedKey[BSS0][0].RxMic); 1478 1479 /* Update WCID attribute table and IVEIV table for this group key table */ 1480 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, 1481 pAd->SharedKey[BSS0][0]. 1482 CipherAlg, NULL); 1483 1484 } 1485 1486 } else /* BSS_INFRA */ 1487 { 1488 /* Check the new SSID with last SSID */ 1489 while (Cancelled == TRUE) { 1490 if (pAd->CommonCfg.LastSsidLen == 1491 pAd->CommonCfg.SsidLen) { 1492 if (RTMPCompareMemory 1493 (pAd->CommonCfg.LastSsid, 1494 pAd->CommonCfg.Ssid, 1495 pAd->CommonCfg.LastSsidLen) == 0) { 1496 /* Link to the old one no linkdown is required. */ 1497 break; 1498 } 1499 } 1500 /* Send link down event before set to link up */ 1501 pAd->IndicateMediaState = NdisMediaStateDisconnected; 1502 RTMP_IndicateMediaState(pAd); 1503 pAd->ExtraInfo = GENERAL_LINK_DOWN; 1504 DBGPRINT(RT_DEBUG_TRACE, 1505 ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n")); 1506 break; 1507 } 1508 1509 /* */ 1510 /* On WPA mode, Remove All Keys if not connect to the last BSSID */ 1511 /* Key will be set after 4-way handshake. */ 1512 /* */ 1513 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) { 1514 unsigned long IV; 1515 1516 /* Remove all WPA keys */ 1517 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); 1518 RTMPWPARemoveAllKeys(pAd); 1519 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; 1520 pAd->StaCfg.PrivacyFilter = 1521 Ndis802_11PrivFilter8021xWEP; 1522 1523 /* Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP */ 1524 /* If IV related values are too large in GroupMsg2, AP would ignore this message. */ 1525 IV = 1; 1526 IV |= (pAd->StaCfg.DefaultKeyId << 30); 1527 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0); 1528 } 1529 /* NOTE: */ 1530 /* the decision of using "short slot time" or not may change dynamically due to */ 1531 /* new STA association to the AP. so we have to decide that upon parsing BEACON, not here */ 1532 1533 /* NOTE: */ 1534 /* the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically */ 1535 /* due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here */ 1536 1537 ComposePsPoll(pAd); 1538 ComposeNullFrame(pAd); 1539 1540 AsicEnableBssSync(pAd); 1541 1542 /* Add BSSID to WCID search table */ 1543 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid); 1544 1545 /* If WEP is enabled, add paiewise and shared key */ 1546 if (((pAd->StaCfg.WpaSupplicantUP) && 1547 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) && 1548 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) || 1549 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) && 1550 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled))) { 1551 u8 *Key; 1552 u8 CipherAlg; 1553 1554 for (idx = 0; idx < SHARE_KEY_NUM; idx++) { 1555 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg; 1556 Key = pAd->SharedKey[BSS0][idx].Key; 1557 1558 if (pAd->SharedKey[BSS0][idx].KeyLen > 0) { 1559 /* Set key material and cipherAlg to Asic */ 1560 AsicAddSharedKeyEntry(pAd, BSS0, idx, 1561 CipherAlg, Key, 1562 NULL, NULL); 1563 1564 if (idx == pAd->StaCfg.DefaultKeyId) { 1565 /* Assign group key info */ 1566 RTMPAddWcidAttributeEntry(pAd, 1567 BSS0, 1568 idx, 1569 CipherAlg, 1570 NULL); 1571 1572 pEntry->Aid = BSSID_WCID; 1573 /* Assign pairwise key info */ 1574 RTMPAddWcidAttributeEntry(pAd, 1575 BSS0, 1576 idx, 1577 CipherAlg, 1578 pEntry); 1579 } 1580 } 1581 } 1582 } 1583 /* only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode */ 1584 /* should wait until at least 2 active nodes in this BSSID. */ 1585 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); 1586 1587 /* For GUI ++ */ 1588 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) { 1589 pAd->IndicateMediaState = NdisMediaStateConnected; 1590 pAd->ExtraInfo = GENERAL_LINK_UP; 1591 RTMP_IndicateMediaState(pAd); 1592 } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || 1593 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) 1594 { 1595 if (pAd->StaCfg.WpaSupplicantUP == 1596 WPA_SUPPLICANT_DISABLE) 1597 RTMPSetTimer(&pAd->Mlme.LinkDownTimer, 1598 LINK_DOWN_TIMEOUT); 1599 } 1600 /* -- */ 1601 1602 /* Add BSSID in my MAC Table. */ 1603 NdisAcquireSpinLock(&pAd->MacTabLock); 1604 /* add this MAC entry into HASH table */ 1605 if (pEntry) { 1606 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid); 1607 if (pAd->MacTab.Hash[HashIdx] == NULL) { 1608 pAd->MacTab.Hash[HashIdx] = pEntry; 1609 } else { 1610 pCurrEntry = pAd->MacTab.Hash[HashIdx]; 1611 while (pCurrEntry->pNext != NULL) { 1612 pCurrEntry = pCurrEntry->pNext; 1613 } 1614 pCurrEntry->pNext = pEntry; 1615 } 1616 } 1617 RTMPMoveMemory(pEntry->Addr, pAd->CommonCfg.Bssid, 1618 MAC_ADDR_LEN); 1619 pEntry->Aid = BSSID_WCID; 1620 pEntry->pAd = pAd; 1621 pEntry->ValidAsCLI = TRUE; /*Although this is bssid..still set ValidAsCl */ 1622 pAd->MacTab.Size = 1; /* infra mode always set MACtab size =1. */ 1623 pEntry->Sst = SST_ASSOC; 1624 pEntry->AuthState = SST_ASSOC; 1625 pEntry->AuthMode = pAd->StaCfg.AuthMode; 1626 pEntry->WepStatus = pAd->StaCfg.WepStatus; 1627 if (pEntry->AuthMode < Ndis802_11AuthModeWPA) { 1628 pEntry->WpaState = AS_NOTUSE; 1629 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; 1630 } else { 1631 pEntry->WpaState = AS_PTKSTART; 1632 pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; 1633 } 1634 NdisReleaseSpinLock(&pAd->MacTabLock); 1635 1636 DBGPRINT(RT_DEBUG_TRACE, 1637 ("LINK UP! ClientStatusFlags=%lx)\n", 1638 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags)); 1639 1640 MlmeUpdateTxRates(pAd, TRUE, BSS0); 1641 MlmeUpdateHtTxRates(pAd, BSS0); 1642 DBGPRINT(RT_DEBUG_TRACE, 1643 ("LINK UP! (StaActive.bHtEnable =%d, )\n", 1644 pAd->StaActive.SupportedPhyInfo.bHtEnable)); 1645 1646 if (pAd->CommonCfg.bAggregationCapable) { 1647 if ((pAd->CommonCfg.bPiggyBackCapable) 1648 && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3) { 1649 OPSTATUS_SET_FLAG(pAd, 1650 fOP_STATUS_PIGGYBACK_INUSED); 1651 OPSTATUS_SET_FLAG(pAd, 1652 fOP_STATUS_AGGREGATION_INUSED); 1653 CLIENT_STATUS_SET_FLAG(pEntry, 1654 fCLIENT_STATUS_AGGREGATION_CAPABLE); 1655 CLIENT_STATUS_SET_FLAG(pEntry, 1656 fCLIENT_STATUS_PIGGYBACK_CAPABLE); 1657 RTMPSetPiggyBack(pAd, TRUE); 1658 DBGPRINT(RT_DEBUG_TRACE, 1659 ("Turn on Piggy-Back\n")); 1660 } else if (pAd->MlmeAux.APRalinkIe & 0x00000001) { 1661 OPSTATUS_SET_FLAG(pAd, 1662 fOP_STATUS_AGGREGATION_INUSED); 1663 CLIENT_STATUS_SET_FLAG(pEntry, 1664 fCLIENT_STATUS_AGGREGATION_CAPABLE); 1665 DBGPRINT(RT_DEBUG_TRACE, 1666 ("Ralink Aggregation\n")); 1667 } 1668 } 1669 1670 if (pAd->MlmeAux.APRalinkIe != 0x0) { 1671 if (CLIENT_STATUS_TEST_FLAG 1672 (pEntry, fCLIENT_STATUS_RDG_CAPABLE)) { 1673 AsicEnableRDG(pAd); 1674 } 1675 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET); 1676 CLIENT_STATUS_SET_FLAG(pEntry, 1677 fCLIENT_STATUS_RALINK_CHIPSET); 1678 } else { 1679 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET); 1680 CLIENT_STATUS_CLEAR_FLAG(pEntry, 1681 fCLIENT_STATUS_RALINK_CHIPSET); 1682 } 1683 } 1684 1685 DBGPRINT(RT_DEBUG_TRACE, 1686 ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n", 1687 pAd->CommonCfg.BACapability.word, 1688 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags)); 1689 1690 /* Set LED */ 1691 RTMPSetLED(pAd, LED_LINK_UP); 1692 1693 pAd->Mlme.PeriodicRound = 0; 1694 pAd->Mlme.OneSecPeriodicRound = 0; 1695 pAd->bConfigChanged = FALSE; /* Reset config flag */ 1696 pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information to link is up */ 1697 1698 /* Set asic auto fall back */ 1699 { 1700 u8 *pTable; 1701 u8 TableSize = 0; 1702 1703 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], 1704 &pTable, &TableSize, 1705 &pAd->CommonCfg.TxRateIndex); 1706 AsicUpdateAutoFallBackTable(pAd, pTable); 1707 } 1708 1709 NdisAcquireSpinLock(&pAd->MacTabLock); 1710 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word; 1711 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word; 1712 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE) { 1713 pEntry->bAutoTxRateSwitch = FALSE; 1714 1715 if (pEntry->HTPhyMode.field.MCS == 32) 1716 pEntry->HTPhyMode.field.ShortGI = GI_800; 1717 1718 if ((pEntry->HTPhyMode.field.MCS > MCS_7) 1719 || (pEntry->HTPhyMode.field.MCS == 32)) 1720 pEntry->HTPhyMode.field.STBC = STBC_NONE; 1721 1722 /* If the legacy mode is set, overwrite the transmit setting of this entry. */ 1723 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM) 1724 RTMPUpdateLegacyTxSetting((u8)pAd->StaCfg. 1725 DesiredTransmitSetting.field. 1726 FixedTxMode, pEntry); 1727 } else 1728 pEntry->bAutoTxRateSwitch = TRUE; 1729 NdisReleaseSpinLock(&pAd->MacTabLock); 1730 1731 /* Let Link Status Page display first initial rate. */ 1732 pAd->LastTxRate = (u16)(pEntry->HTPhyMode.word); 1733 /* Select DAC according to HT or Legacy */ 1734 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00) { 1735 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value); 1736 Value &= (~0x18); 1737 if (pAd->Antenna.field.TxPath == 2) { 1738 Value |= 0x10; 1739 } 1740 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value); 1741 } else { 1742 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value); 1743 Value &= (~0x18); 1744 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value); 1745 } 1746 1747 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) { 1748 } else if (pEntry->MaxRAmpduFactor == 0) { 1749 /* If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0. */ 1750 /* Because our Init value is 1 at MACRegTable. */ 1751 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff); 1752 } 1753 /* Patch for Marvel AP to gain high throughput */ 1754 /* Need to set as following, */ 1755 /* 1. Set txop in register-EDCA_AC0_CFG as 0x60 */ 1756 /* 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero */ 1757 /* 3. PBF_MAX_PCNT as 0x1F3FBF9F */ 1758 /* 4. kick per two packets when dequeue */ 1759 /* */ 1760 /* Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable */ 1761 /* */ 1762 /* if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is. */ 1763 if (!((pAd->CommonCfg.RxStream == 1) && (pAd->CommonCfg.TxStream == 1)) 1764 && (pAd->StaCfg.bForceTxBurst == FALSE) 1765 && 1766 (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) 1767 && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) 1768 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) 1769 && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))) { 1770 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); 1771 Data &= 0xFFFFFF00; 1772 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); 1773 1774 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F); 1775 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n")); 1776 } else if (pAd->CommonCfg.bEnableTxBurst) { 1777 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); 1778 Data &= 0xFFFFFF00; 1779 Data |= 0x60; 1780 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); 1781 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE; 1782 1783 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F); 1784 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n")); 1785 } else { 1786 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); 1787 Data &= 0xFFFFFF00; 1788 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); 1789 1790 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F); 1791 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n")); 1792 } 1793 1794 /* Re-check to turn on TX burst or not. */ 1795 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) 1796 && ((STA_WEP_ON(pAd)) || (STA_TKIP_ON(pAd)))) { 1797 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE; 1798 if (pAd->CommonCfg.bEnableTxBurst) { 1799 u32 MACValue = 0; 1800 /* Force disable TXOP value in this case. The same action in MLMEUpdateProtect too. */ 1801 /* I didn't change PBF_MAX_PCNT setting. */ 1802 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue); 1803 MACValue &= 0xFFFFFF00; 1804 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue); 1805 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE; 1806 } 1807 } else { 1808 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE; 1809 } 1810 1811 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE; 1812 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid); 1813 DBGPRINT(RT_DEBUG_TRACE, 1814 ("pAd->bNextDisableRxBA= %d \n", 1815 pAd->CommonCfg.IOTestParm.bNextDisableRxBA)); 1816 /* BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap */ 1817 /* Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver. */ 1818 /* Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same. */ 1819 1820 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled) { 1821 if (pAd->StaCfg.WpaSupplicantUP && 1822 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) && 1823 (pAd->StaCfg.IEEE8021X == TRUE)) ; 1824 else { 1825 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; 1826 pAd->StaCfg.PrivacyFilter = 1827 Ndis802_11PrivFilterAcceptAll; 1828 } 1829 } 1830 1831 NdisAcquireSpinLock(&pAd->MacTabLock); 1832 pEntry->PortSecured = pAd->StaCfg.PortSecured; 1833 NdisReleaseSpinLock(&pAd->MacTabLock); 1834 1835 /* */ 1836 /* Patch Atheros AP TX will breakdown issue. */ 1837 /* AP Model: DLink DWL-8200AP */ 1838 /* */ 1839 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) 1840 && STA_TKIP_ON(pAd)) { 1841 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01); 1842 } else { 1843 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00); 1844 } 1845 1846 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); 1847 1848 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); 1849} 1850 1851/* 1852 ========================================================================== 1853 1854 Routine Description: 1855 Disconnect current BSSID 1856 1857 Arguments: 1858 pAd - Pointer to our adapter 1859 IsReqFromAP - Request from AP 1860 1861 Return Value: 1862 None 1863 1864 IRQL = DISPATCH_LEVEL 1865 1866 Note: 1867 We need more information to know it's this requst from AP. 1868 If yes! we need to do extra handling, for example, remove the WPA key. 1869 Otherwise on 4-way handshaking will faied, since the WPA key didn't be 1870 remove while auto reconnect. 1871 Disconnect request from AP, it means we will start afresh 4-way handshaking 1872 on WPA mode. 1873 1874 ========================================================================== 1875*/ 1876void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP) 1877{ 1878 u8 i, ByteValue = 0; 1879 1880 /* Do nothing if monitor mode is on */ 1881 if (MONITOR_ON(pAd)) 1882 return; 1883 1884 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); 1885 /*Comment the codes, beasue the line 2291 call the same function. */ 1886 /*RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); */ 1887 /* Not allow go to sleep within linkdown function. */ 1888 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); 1889 1890 if (pAd->CommonCfg.bWirelessEvent) { 1891 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, 1892 pAd->MacTab.Content[BSSID_WCID].Addr, 1893 BSS0, 0); 1894 } 1895 1896 DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN!\n")); 1897 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); 1898 1899#ifdef RTMP_MAC_PCI 1900 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { 1901 BOOLEAN Cancelled; 1902 pAd->Mlme.bPsPollTimerRunning = FALSE; 1903 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); 1904 } 1905 1906 pAd->bPCIclkOff = FALSE; 1907#endif /* RTMP_MAC_PCI // */ 1908 1909 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) 1910 || RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) 1911 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) { 1912 AUTO_WAKEUP_STRUC AutoWakeupCfg; 1913 AsicForceWakeup(pAd, TRUE); 1914 AutoWakeupCfg.word = 0; 1915 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); 1916 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); 1917 } 1918#ifdef RTMP_MAC_PCI 1919 pAd->bPCIclkOff = FALSE; 1920#endif /* RTMP_MAC_PCI // */ 1921 1922 if (ADHOC_ON(pAd)) /* Adhoc mode link down */ 1923 { 1924 DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 1!\n")); 1925 1926 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON); 1927 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); 1928 pAd->IndicateMediaState = NdisMediaStateDisconnected; 1929 RTMP_IndicateMediaState(pAd); 1930 pAd->ExtraInfo = GENERAL_LINK_DOWN; 1931 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, 1932 pAd->CommonCfg.Channel); 1933 DBGPRINT(RT_DEBUG_TRACE, 1934 (" MacTab.Size=%d !\n", pAd->MacTab.Size)); 1935 } else /* Infra structure mode */ 1936 { 1937 DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 2!\n")); 1938 1939 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON); 1940 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); 1941 1942 /* Saved last SSID for linkup comparison */ 1943 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen; 1944 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, 1945 pAd->CommonCfg.LastSsidLen); 1946 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid); 1947 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE) { 1948 pAd->IndicateMediaState = NdisMediaStateDisconnected; 1949 RTMP_IndicateMediaState(pAd); 1950 pAd->ExtraInfo = GENERAL_LINK_DOWN; 1951 DBGPRINT(RT_DEBUG_TRACE, 1952 ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n")); 1953 pAd->MlmeAux.CurrReqIsFromNdis = FALSE; 1954 } else { 1955 /* */ 1956 /* If disassociation request is from NDIS, then we don't need to delete BSSID from entry. */ 1957 /* Otherwise lost beacon or receive De-Authentication from AP, */ 1958 /* then we should delete BSSID from BssTable. */ 1959 /* If we don't delete from entry, roaming will fail. */ 1960 /* */ 1961 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, 1962 pAd->CommonCfg.Channel); 1963 } 1964 1965 /* restore back to - */ 1966 /* 1. long slot (20 us) or short slot (9 us) time */ 1967 /* 2. turn on/off RTS/CTS and/or CTS-to-self protection */ 1968 /* 3. short preamble */ 1969 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); 1970 1971 } 1972 1973 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) { 1974 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE) 1975 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, 1976 pAd->MacTab.Content[i].Addr); 1977 } 1978 1979 AsicSetSlotTime(pAd, TRUE); /*FALSE); */ 1980 AsicSetEdcaParm(pAd, NULL); 1981 1982 /* Set LED */ 1983 RTMPSetLED(pAd, LED_LINK_DOWN); 1984 pAd->LedIndicatorStrength = 0xF0; 1985 RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, firmware is not done it. */ 1986 1987 AsicDisableSync(pAd); 1988 1989 pAd->Mlme.PeriodicRound = 0; 1990 pAd->Mlme.OneSecPeriodicRound = 0; 1991 1992 if (pAd->StaCfg.BssType == BSS_INFRA) { 1993 /* Remove StaCfg Information after link down */ 1994 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN); 1995 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID); 1996 pAd->CommonCfg.SsidLen = 0; 1997 } 1998 1999 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(struct rt_ht_capability_ie)); 2000 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(struct rt_add_ht_info_ie)); 2001 pAd->MlmeAux.HtCapabilityLen = 0; 2002 pAd->MlmeAux.NewExtChannelOffset = 0xff; 2003 2004 /* Reset WPA-PSK state. Only reset when supplicant enabled */ 2005 if (pAd->StaCfg.WpaState != SS_NOTUSE) { 2006 pAd->StaCfg.WpaState = SS_START; 2007 /* Clear Replay counter */ 2008 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8); 2009 2010 } 2011 /* */ 2012 /* if link down come from AP, we need to remove all WPA keys on WPA mode. */ 2013 /* otherwise will cause 4-way handshaking failed, since the WPA key not empty. */ 2014 /* */ 2015 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)) { 2016 /* Remove all WPA keys */ 2017 RTMPWPARemoveAllKeys(pAd); 2018 } 2019 /* 802.1x port control */ 2020 2021 /* Prevent clear PortSecured here with static WEP */ 2022 /* NetworkManger set security policy first then set SSID to connect AP. */ 2023 if (pAd->StaCfg.WpaSupplicantUP && 2024 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) && 2025 (pAd->StaCfg.IEEE8021X == FALSE)) { 2026 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; 2027 } else { 2028 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; 2029 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP; 2030 } 2031 2032 NdisAcquireSpinLock(&pAd->MacTabLock); 2033 NdisZeroMemory(&pAd->MacTab, sizeof(struct rt_mac_table)); 2034 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured; 2035 NdisReleaseSpinLock(&pAd->MacTabLock); 2036 2037 pAd->StaCfg.MicErrCnt = 0; 2038 2039 pAd->IndicateMediaState = NdisMediaStateDisconnected; 2040 /* Update extra information to link is up */ 2041 pAd->ExtraInfo = GENERAL_LINK_DOWN; 2042 2043 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; 2044 2045#ifdef RTMP_MAC_USB 2046 pAd->bUsbTxBulkAggre = FALSE; 2047#endif /* RTMP_MAC_USB // */ 2048 2049 /* Clean association information */ 2050 NdisZeroMemory(&pAd->StaCfg.AssocInfo, 2051 sizeof(struct rt_ndis_802_11_association_information)); 2052 pAd->StaCfg.AssocInfo.Length = 2053 sizeof(struct rt_ndis_802_11_association_information); 2054 pAd->StaCfg.ReqVarIELen = 0; 2055 pAd->StaCfg.ResVarIELen = 0; 2056 2057 /* */ 2058 /* Reset RSSI value after link down */ 2059 /* */ 2060 pAd->StaCfg.RssiSample.AvgRssi0 = 0; 2061 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0; 2062 pAd->StaCfg.RssiSample.AvgRssi1 = 0; 2063 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0; 2064 pAd->StaCfg.RssiSample.AvgRssi2 = 0; 2065 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0; 2066 2067 /* Restore MlmeRate */ 2068 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate; 2069 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate; 2070 2071 /* */ 2072 /* After Link down, reset piggy-back setting in ASIC. Disable RDG. */ 2073 /* */ 2074 if (pAd->CommonCfg.BBPCurrentBW == BW_40) { 2075 pAd->CommonCfg.BBPCurrentBW = BW_20; 2076 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue); 2077 ByteValue &= (~0x18); 2078 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue); 2079 } 2080 /* Reset DAC */ 2081 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue); 2082 ByteValue &= (~0x18); 2083 if (pAd->Antenna.field.TxPath == 2) { 2084 ByteValue |= 0x10; 2085 } 2086 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue); 2087 2088 RTMPSetPiggyBack(pAd, FALSE); 2089 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED); 2090 2091 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word; 2092 2093 /* Restore all settings in the following. */ 2094 AsicUpdateProtect(pAd, 0, 2095 (ALLN_SETPROTECT | CCKSETPROTECT | OFDMSETPROTECT), 2096 TRUE, FALSE); 2097 AsicDisableRDG(pAd); 2098 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE; 2099 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE; 2100 2101 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff); 2102 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); 2103 2104/* Allow go to sleep after linkdown steps. */ 2105 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); 2106 2107 RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0); 2108 2109#ifdef RT30xx 2110 if ((IS_RT30xx(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd)) 2111 && (pAd->Antenna.field.RxPath > 1 || pAd->Antenna.field.TxPath > 1)) { 2112 RTMP_ASIC_MMPS_DISABLE(pAd); 2113 } 2114#endif /* RT30xx // */ 2115} 2116 2117/* 2118 ========================================================================== 2119 Description: 2120 2121 IRQL = DISPATCH_LEVEL 2122 2123 ========================================================================== 2124*/ 2125void IterateOnBssTab(struct rt_rtmp_adapter *pAd) 2126{ 2127 struct rt_mlme_start_req StartReq; 2128 struct rt_mlme_join_req JoinReq; 2129 unsigned long BssIdx; 2130 2131 /* Change the wepstatus to original wepstatus */ 2132 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus; 2133 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus; 2134 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus; 2135 2136 BssIdx = pAd->MlmeAux.BssIdx; 2137 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr) { 2138 /* Check cipher suite, AP must have more secured cipher than station setting */ 2139 /* Set the Pairwise and Group cipher to match the intended AP setting */ 2140 /* We can only connect to AP with less secured cipher setting */ 2141 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) 2142 || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) { 2143 pAd->StaCfg.GroupCipher = 2144 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA. 2145 GroupCipher; 2146 2147 if (pAd->StaCfg.WepStatus == 2148 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA. 2149 PairCipher) 2150 pAd->StaCfg.PairCipher = 2151 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx]. 2152 WPA.PairCipher; 2153 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA. 2154 PairCipherAux != Ndis802_11WEPDisabled) 2155 pAd->StaCfg.PairCipher = 2156 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx]. 2157 WPA.PairCipherAux; 2158 else /* There is no PairCipher Aux, downgrade our capability to TKIP */ 2159 pAd->StaCfg.PairCipher = 2160 Ndis802_11Encryption2Enabled; 2161 } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) 2162 || (pAd->StaCfg.AuthMode == 2163 Ndis802_11AuthModeWPA2PSK)) { 2164 pAd->StaCfg.GroupCipher = 2165 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2. 2166 GroupCipher; 2167 2168 if (pAd->StaCfg.WepStatus == 2169 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2. 2170 PairCipher) 2171 pAd->StaCfg.PairCipher = 2172 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx]. 2173 WPA2.PairCipher; 2174 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2. 2175 PairCipherAux != Ndis802_11WEPDisabled) 2176 pAd->StaCfg.PairCipher = 2177 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx]. 2178 WPA2.PairCipherAux; 2179 else /* There is no PairCipher Aux, downgrade our capability to TKIP */ 2180 pAd->StaCfg.PairCipher = 2181 Ndis802_11Encryption2Enabled; 2182 2183 /* RSN capability */ 2184 pAd->StaCfg.RsnCapability = 2185 pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2. 2186 RsnCapability; 2187 } 2188 /* Set Mix cipher flag */ 2189 pAd->StaCfg.bMixCipher = 2190 (pAd->StaCfg.PairCipher == 2191 pAd->StaCfg.GroupCipher) ? FALSE : TRUE; 2192 /*if (pAd->StaCfg.bMixCipher == TRUE) 2193 { 2194 // If mix cipher, re-build RSNIE 2195 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0); 2196 } */ 2197 2198 DBGPRINT(RT_DEBUG_TRACE, 2199 ("CNTL - iterate BSS %ld of %d\n", BssIdx, 2200 pAd->MlmeAux.SsidBssTab.BssNr)); 2201 JoinParmFill(pAd, &JoinReq, BssIdx); 2202 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, 2203 sizeof(struct rt_mlme_join_req), &JoinReq); 2204 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN; 2205 } else if (pAd->StaCfg.BssType == BSS_ADHOC) { 2206 DBGPRINT(RT_DEBUG_TRACE, 2207 ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n", 2208 pAd->MlmeAux.Ssid)); 2209 StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid, 2210 pAd->MlmeAux.SsidLen); 2211 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, 2212 sizeof(struct rt_mlme_start_req), &StartReq); 2213 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START; 2214 } else /* no more BSS */ 2215 { 2216 2217 { 2218 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); 2219 AsicLockChannel(pAd, pAd->CommonCfg.Channel); 2220 DBGPRINT(RT_DEBUG_TRACE, 2221 ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n", 2222 pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); 2223 } 2224 2225 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 2226 } 2227} 2228 2229/* for re-association only */ 2230/* IRQL = DISPATCH_LEVEL */ 2231void IterateOnBssTab2(struct rt_rtmp_adapter *pAd) 2232{ 2233 struct rt_mlme_assoc_req ReassocReq; 2234 unsigned long BssIdx; 2235 struct rt_bss_entry *pBss; 2236 2237 BssIdx = pAd->MlmeAux.RoamIdx; 2238 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx]; 2239 2240 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr) { 2241 DBGPRINT(RT_DEBUG_TRACE, 2242 ("CNTL - iterate BSS %ld of %d\n", BssIdx, 2243 pAd->MlmeAux.RoamTab.BssNr)); 2244 2245 AsicSwitchChannel(pAd, pBss->Channel, FALSE); 2246 AsicLockChannel(pAd, pBss->Channel); 2247 2248 /* reassociate message has the same structure as associate message */ 2249 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, 2250 pBss->CapabilityInfo, ASSOC_TIMEOUT, 2251 pAd->StaCfg.DefaultListenCount); 2252 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ, 2253 sizeof(struct rt_mlme_assoc_req), &ReassocReq); 2254 2255 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC; 2256 } else /* no more BSS */ 2257 { 2258 2259 { 2260 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); 2261 AsicLockChannel(pAd, pAd->CommonCfg.Channel); 2262 DBGPRINT(RT_DEBUG_TRACE, 2263 ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n", 2264 pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); 2265 } 2266 2267 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; 2268 } 2269} 2270 2271/* 2272 ========================================================================== 2273 Description: 2274 2275 IRQL = DISPATCH_LEVEL 2276 2277 ========================================================================== 2278*/ 2279void JoinParmFill(struct rt_rtmp_adapter *pAd, 2280 struct rt_mlme_join_req *JoinReq, unsigned long BssIdx) 2281{ 2282 JoinReq->BssIdx = BssIdx; 2283} 2284 2285/* 2286 ========================================================================== 2287 Description: 2288 2289 IRQL = DISPATCH_LEVEL 2290 2291 ========================================================================== 2292*/ 2293void ScanParmFill(struct rt_rtmp_adapter *pAd, 2294 struct rt_mlme_scan_req *ScanReq, 2295 char Ssid[], 2296 u8 SsidLen, u8 BssType, u8 ScanType) 2297{ 2298 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID); 2299 ScanReq->SsidLen = SsidLen; 2300 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen); 2301 ScanReq->BssType = BssType; 2302 ScanReq->ScanType = ScanType; 2303} 2304 2305/* 2306 ========================================================================== 2307 Description: 2308 2309 IRQL = DISPATCH_LEVEL 2310 2311 ========================================================================== 2312*/ 2313void StartParmFill(struct rt_rtmp_adapter *pAd, 2314 struct rt_mlme_start_req *StartReq, 2315 char Ssid[], u8 SsidLen) 2316{ 2317 ASSERT(SsidLen <= MAX_LEN_OF_SSID); 2318 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen); 2319 StartReq->SsidLen = SsidLen; 2320} 2321 2322/* 2323 ========================================================================== 2324 Description: 2325 2326 IRQL = DISPATCH_LEVEL 2327 2328 ========================================================================== 2329*/ 2330void AuthParmFill(struct rt_rtmp_adapter *pAd, 2331 struct rt_mlme_auth_req *AuthReq, 2332 u8 *pAddr, u16 Alg) 2333{ 2334 COPY_MAC_ADDR(AuthReq->Addr, pAddr); 2335 AuthReq->Alg = Alg; 2336 AuthReq->Timeout = AUTH_TIMEOUT; 2337} 2338 2339/* 2340 ========================================================================== 2341 Description: 2342 2343 IRQL = DISPATCH_LEVEL 2344 2345 ========================================================================== 2346 */ 2347#ifdef RTMP_MAC_PCI 2348void ComposePsPoll(struct rt_rtmp_adapter *pAd) 2349{ 2350 NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame)); 2351 pAd->PsPollFrame.FC.Type = BTYPE_CNTL; 2352 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL; 2353 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000; 2354 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid); 2355 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress); 2356} 2357 2358/* IRQL = DISPATCH_LEVEL */ 2359void ComposeNullFrame(struct rt_rtmp_adapter *pAd) 2360{ 2361 NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11)); 2362 pAd->NullFrame.FC.Type = BTYPE_DATA; 2363 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC; 2364 pAd->NullFrame.FC.ToDs = 1; 2365 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid); 2366 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress); 2367 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid); 2368} 2369#endif /* RTMP_MAC_PCI // */ 2370#ifdef RTMP_MAC_USB 2371void MlmeCntlConfirm(struct rt_rtmp_adapter *pAd, unsigned long MsgType, u16 Msg) 2372{ 2373 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(u16), 2374 &Msg); 2375} 2376 2377void ComposePsPoll(struct rt_rtmp_adapter *pAd) 2378{ 2379 struct rt_txinfo *pTxInfo; 2380 struct rt_txwi * pTxWI; 2381 2382 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n")); 2383 NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame)); 2384 2385 pAd->PsPollFrame.FC.PwrMgmt = 0; 2386 pAd->PsPollFrame.FC.Type = BTYPE_CNTL; 2387 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL; 2388 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000; 2389 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid); 2390 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress); 2391 2392 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field. 2393 WirelessPacket[0], 100); 2394 pTxInfo = 2395 (struct rt_txinfo *)& pAd->PsPollContext.TransferBuffer->field. 2396 WirelessPacket[0]; 2397 RTMPWriteTxInfo(pAd, pTxInfo, 2398 (u16)(sizeof(struct rt_pspoll_frame) + TXWI_SIZE), TRUE, 2399 EpToQueue[MGMTPIPEIDX], FALSE, FALSE); 2400 pTxWI = 2401 (struct rt_txwi *) & pAd->PsPollContext.TransferBuffer->field. 2402 WirelessPacket[TXINFO_SIZE]; 2403 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, 2404 BSSID_WCID, (sizeof(struct rt_pspoll_frame)), 0, 0, 2405 (u8)pAd->CommonCfg.MlmeTransmit.field.MCS, 2406 IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); 2407 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field. 2408 WirelessPacket[TXWI_SIZE + TXINFO_SIZE], 2409 &pAd->PsPollFrame, sizeof(struct rt_pspoll_frame)); 2410 /* Append 4 extra zero bytes. */ 2411 pAd->PsPollContext.BulkOutSize = 2412 TXINFO_SIZE + TXWI_SIZE + sizeof(struct rt_pspoll_frame) + 4; 2413} 2414 2415/* IRQL = DISPATCH_LEVEL */ 2416void ComposeNullFrame(struct rt_rtmp_adapter *pAd) 2417{ 2418 struct rt_txinfo *pTxInfo; 2419 struct rt_txwi * pTxWI; 2420 2421 NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11)); 2422 pAd->NullFrame.FC.Type = BTYPE_DATA; 2423 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC; 2424 pAd->NullFrame.FC.ToDs = 1; 2425 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid); 2426 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress); 2427 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid); 2428 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field. 2429 WirelessPacket[0], 100); 2430 pTxInfo = 2431 (struct rt_txinfo *)& pAd->NullContext.TransferBuffer->field. 2432 WirelessPacket[0]; 2433 RTMPWriteTxInfo(pAd, pTxInfo, 2434 (u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE), TRUE, 2435 EpToQueue[MGMTPIPEIDX], FALSE, FALSE); 2436 pTxWI = 2437 (struct rt_txwi *) & pAd->NullContext.TransferBuffer->field. 2438 WirelessPacket[TXINFO_SIZE]; 2439 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, 2440 BSSID_WCID, (sizeof(struct rt_header_802_11)), 0, 0, 2441 (u8)pAd->CommonCfg.MlmeTransmit.field.MCS, 2442 IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); 2443 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field. 2444 WirelessPacket[TXWI_SIZE + TXINFO_SIZE], &pAd->NullFrame, 2445 sizeof(struct rt_header_802_11)); 2446 pAd->NullContext.BulkOutSize = 2447 TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4; 2448} 2449#endif /* RTMP_MAC_USB // */ 2450 2451/* 2452 ========================================================================== 2453 Description: 2454 Pre-build a BEACON frame in the shared memory 2455 2456 IRQL = PASSIVE_LEVEL 2457 IRQL = DISPATCH_LEVEL 2458 2459 ========================================================================== 2460*/ 2461unsigned long MakeIbssBeacon(struct rt_rtmp_adapter *pAd) 2462{ 2463 u8 DsLen = 1, IbssLen = 2; 2464 u8 LocalErpIe[3] = { IE_ERP, 1, 0x04 }; 2465 struct rt_header_802_11 BcnHdr; 2466 u16 CapabilityInfo; 2467 LARGE_INTEGER FakeTimestamp; 2468 unsigned long FrameLen = 0; 2469 struct rt_txwi * pTxWI = &pAd->BeaconTxWI; 2470 u8 *pBeaconFrame = pAd->BeaconBuf; 2471 BOOLEAN Privacy; 2472 u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES]; 2473 u8 SupRateLen = 0; 2474 u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; 2475 u8 ExtRateLen = 0; 2476 u8 RSNIe = IE_WPA; 2477 2478 if ((pAd->CommonCfg.PhyMode == PHY_11B) 2479 && (pAd->CommonCfg.Channel <= 14)) { 2480 SupRate[0] = 0x82; /* 1 mbps */ 2481 SupRate[1] = 0x84; /* 2 mbps */ 2482 SupRate[2] = 0x8b; /* 5.5 mbps */ 2483 SupRate[3] = 0x96; /* 11 mbps */ 2484 SupRateLen = 4; 2485 ExtRateLen = 0; 2486 } else if (pAd->CommonCfg.Channel > 14) { 2487 SupRate[0] = 0x8C; /* 6 mbps, in units of 0.5 Mbps, basic rate */ 2488 SupRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */ 2489 SupRate[2] = 0x98; /* 12 mbps, in units of 0.5 Mbps, basic rate */ 2490 SupRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */ 2491 SupRate[4] = 0xb0; /* 24 mbps, in units of 0.5 Mbps, basic rate */ 2492 SupRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */ 2493 SupRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */ 2494 SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */ 2495 SupRateLen = 8; 2496 ExtRateLen = 0; 2497 2498 /* */ 2499 /* Also Update MlmeRate & RtsRate for G only & A only */ 2500 /* */ 2501 pAd->CommonCfg.MlmeRate = RATE_6; 2502 pAd->CommonCfg.RtsRate = RATE_6; 2503 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; 2504 pAd->CommonCfg.MlmeTransmit.field.MCS = 2505 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; 2506 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = 2507 MODE_OFDM; 2508 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = 2509 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; 2510 } else { 2511 SupRate[0] = 0x82; /* 1 mbps */ 2512 SupRate[1] = 0x84; /* 2 mbps */ 2513 SupRate[2] = 0x8b; /* 5.5 mbps */ 2514 SupRate[3] = 0x96; /* 11 mbps */ 2515 SupRateLen = 4; 2516 2517 ExtRate[0] = 0x0C; /* 6 mbps, in units of 0.5 Mbps, */ 2518 ExtRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */ 2519 ExtRate[2] = 0x18; /* 12 mbps, in units of 0.5 Mbps, */ 2520 ExtRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */ 2521 ExtRate[4] = 0x30; /* 24 mbps, in units of 0.5 Mbps, */ 2522 ExtRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */ 2523 ExtRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */ 2524 ExtRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */ 2525 ExtRateLen = 8; 2526 } 2527 2528 pAd->StaActive.SupRateLen = SupRateLen; 2529 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen); 2530 pAd->StaActive.ExtRateLen = ExtRateLen; 2531 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen); 2532 2533 /* compose IBSS beacon frame */ 2534 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, 2535 pAd->CommonCfg.Bssid); 2536 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) 2537 || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) 2538 || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled); 2539 CapabilityInfo = 2540 CAP_GENERATE(0, 1, Privacy, 2541 (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 2542 0, 0); 2543 2544 MakeOutgoingFrame(pBeaconFrame, &FrameLen, 2545 sizeof(struct rt_header_802_11), &BcnHdr, 2546 TIMESTAMP_LEN, &FakeTimestamp, 2547 2, &pAd->CommonCfg.BeaconPeriod, 2548 2, &CapabilityInfo, 2549 1, &SsidIe, 2550 1, &pAd->CommonCfg.SsidLen, 2551 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid, 2552 1, &SupRateIe, 2553 1, &SupRateLen, 2554 SupRateLen, SupRate, 2555 1, &DsIe, 2556 1, &DsLen, 2557 1, &pAd->CommonCfg.Channel, 2558 1, &IbssIe, 2559 1, &IbssLen, 2, &pAd->StaActive.AtimWin, END_OF_ARGS); 2560 2561 /* add ERP_IE and EXT_RAE IE of in 802.11g */ 2562 if (ExtRateLen) { 2563 unsigned long tmp; 2564 2565 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp, 2566 3, LocalErpIe, 2567 1, &ExtRateIe, 2568 1, &ExtRateLen, 2569 ExtRateLen, ExtRate, END_OF_ARGS); 2570 FrameLen += tmp; 2571 } 2572 /* If adhoc secruity is set for WPA-None, append the cipher suite IE */ 2573 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) { 2574 unsigned long tmp; 2575 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 2576 BSS0); 2577 2578 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp, 2579 1, &RSNIe, 2580 1, &pAd->StaCfg.RSNIE_Len, 2581 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE, 2582 END_OF_ARGS); 2583 FrameLen += tmp; 2584 } 2585 2586 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { 2587 unsigned long TmpLen; 2588 u8 HtLen, HtLen1; 2589 2590 /* add HT Capability IE */ 2591 HtLen = sizeof(pAd->CommonCfg.HtCapability); 2592 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo); 2593 2594 MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 2595 1, &HtCapIe, 2596 1, &HtLen, 2597 HtLen, &pAd->CommonCfg.HtCapability, 2598 1, &AddHtInfoIe, 2599 1, &HtLen1, 2600 HtLen1, &pAd->CommonCfg.AddHTInfo, 2601 END_OF_ARGS); 2602 2603 FrameLen += TmpLen; 2604 } 2605 /*beacon use reserved WCID 0xff */ 2606 if (pAd->CommonCfg.Channel > 14) { 2607 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, 2608 TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON, 2609 RATE_1, IFS_HTTXOP, FALSE, 2610 &pAd->CommonCfg.MlmeTransmit); 2611 } else { 2612 /* Set to use 1Mbps for Adhoc beacon. */ 2613 HTTRANSMIT_SETTING Transmit; 2614 Transmit.word = 0; 2615 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, 2616 TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON, 2617 RATE_1, IFS_HTTXOP, FALSE, &Transmit); 2618 } 2619 2620 DBGPRINT(RT_DEBUG_TRACE, 2621 ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n", 2622 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, 2623 pAd->CommonCfg.PhyMode)); 2624 return FrameLen; 2625} 2626