1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 5 * 6 ******************************************************************************/ 7 #include <linux/etherdevice.h> 8 #include <drv_types.h> 9 #include <hal_btcoex.h> 10 #include <linux/jiffies.h> 11 12 static void _dynamic_check_timer_handler(struct timer_list *t) 13 { 14 struct adapter *adapter = 15 timer_container_of(adapter, t, mlmepriv.dynamic_chk_timer); 16 17 rtw_dynamic_check_timer_handler(adapter); 18 19 _set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000); 20 } 21 22 static void _rtw_set_scan_deny_timer_hdl(struct timer_list *t) 23 { 24 struct adapter *adapter = 25 timer_container_of(adapter, t, mlmepriv.set_scan_deny_timer); 26 27 rtw_clear_scan_deny(adapter); 28 } 29 30 static void rtw_init_mlme_timer(struct adapter *padapter) 31 { 32 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 33 34 timer_setup(&pmlmepriv->assoc_timer, _rtw_join_timeout_handler, 0); 35 timer_setup(&pmlmepriv->scan_to_timer, rtw_scan_timeout_handler, 0); 36 timer_setup(&pmlmepriv->dynamic_chk_timer, 37 _dynamic_check_timer_handler, 0); 38 timer_setup(&pmlmepriv->set_scan_deny_timer, 39 _rtw_set_scan_deny_timer_hdl, 0); 40 } 41 42 int rtw_init_mlme_priv(struct adapter *padapter) 43 { 44 int i; 45 u8 *pbuf; 46 struct wlan_network *pnetwork; 47 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 48 int res = _SUCCESS; 49 50 pmlmepriv->nic_hdl = (u8 *)padapter; 51 52 pmlmepriv->pscanned = NULL; 53 pmlmepriv->fw_state = WIFI_STATION_STATE; /* Must sync with rtw_wdev_alloc() */ 54 pmlmepriv->cur_network.network.infrastructure_mode = Ndis802_11AutoUnknown; 55 pmlmepriv->scan_mode = SCAN_ACTIVE;/* 1: active, 0: passive. Maybe someday we should rename this varable to "active_mode" (Jeff) */ 56 57 spin_lock_init(&pmlmepriv->lock); 58 INIT_LIST_HEAD(&pmlmepriv->free_bss_pool.queue); 59 spin_lock_init(&pmlmepriv->free_bss_pool.lock); 60 INIT_LIST_HEAD(&pmlmepriv->scanned_queue.queue); 61 spin_lock_init(&pmlmepriv->scanned_queue.lock); 62 63 memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid)); 64 65 pbuf = vzalloc(array_size(MAX_BSS_CNT, sizeof(struct wlan_network))); 66 67 if (!pbuf) { 68 res = _FAIL; 69 goto exit; 70 } 71 pmlmepriv->free_bss_buf = pbuf; 72 73 pnetwork = (struct wlan_network *)pbuf; 74 75 for (i = 0; i < MAX_BSS_CNT; i++) { 76 INIT_LIST_HEAD(&pnetwork->list); 77 78 list_add_tail(&pnetwork->list, &pmlmepriv->free_bss_pool.queue); 79 80 pnetwork++; 81 } 82 83 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ 84 85 rtw_clear_scan_deny(padapter); 86 87 #define RTW_ROAM_SCAN_RESULT_EXP_MS 5000 88 #define RTW_ROAM_RSSI_DIFF_TH 10 89 #define RTW_ROAM_SCAN_INTERVAL_MS 10000 90 91 pmlmepriv->roam_flags = 0 92 | RTW_ROAM_ON_EXPIRED 93 | RTW_ROAM_ON_RESUME 94 ; 95 96 pmlmepriv->roam_scanr_exp_ms = RTW_ROAM_SCAN_RESULT_EXP_MS; 97 pmlmepriv->roam_rssi_diff_th = RTW_ROAM_RSSI_DIFF_TH; 98 pmlmepriv->roam_scan_int_ms = RTW_ROAM_SCAN_INTERVAL_MS; 99 100 rtw_init_mlme_timer(padapter); 101 102 exit: 103 104 return res; 105 } 106 107 static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen) 108 { 109 if (*ppie) { 110 kfree(*ppie); 111 *plen = 0; 112 *ppie = NULL; 113 } 114 } 115 116 void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv) 117 { 118 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len); 119 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len); 120 rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len); 121 rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len); 122 rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len); 123 rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len); 124 125 rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len); 126 rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len); 127 rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len); 128 rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len); 129 rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len); 130 } 131 132 void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) 133 { 134 if (pmlmepriv) { 135 rtw_free_mlme_priv_ie_data(pmlmepriv); 136 vfree(pmlmepriv->free_bss_buf); 137 } 138 } 139 140 struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv) 141 { 142 struct wlan_network *pnetwork; 143 struct __queue *free_queue = &pmlmepriv->free_bss_pool; 144 struct list_head *plist = NULL; 145 146 spin_lock_bh(&free_queue->lock); 147 148 if (list_empty(&free_queue->queue)) { 149 pnetwork = NULL; 150 goto exit; 151 } 152 plist = get_next(&free_queue->queue); 153 154 pnetwork = container_of(plist, struct wlan_network, list); 155 156 list_del_init(&pnetwork->list); 157 158 pnetwork->network_type = 0; 159 pnetwork->fixed = false; 160 pnetwork->last_scanned = jiffies; 161 pnetwork->aid = 0; 162 pnetwork->join_res = 0; 163 164 exit: 165 spin_unlock_bh(&free_queue->lock); 166 167 return pnetwork; 168 } 169 170 void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall) 171 { 172 unsigned int delta_time; 173 u32 lifetime = SCANQUEUE_LIFETIME; 174 struct __queue *free_queue = &pmlmepriv->free_bss_pool; 175 176 if (!pnetwork) 177 return; 178 179 if (pnetwork->fixed) 180 return; 181 182 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || 183 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) 184 lifetime = 1; 185 186 if (!isfreeall) { 187 delta_time = jiffies_to_msecs(jiffies - pnetwork->last_scanned); 188 if (delta_time < lifetime)/* unit:msec */ 189 return; 190 } 191 192 spin_lock_bh(&free_queue->lock); 193 194 list_del_init(&pnetwork->list); 195 196 list_add_tail(&pnetwork->list, &free_queue->queue); 197 198 spin_unlock_bh(&free_queue->lock); 199 } 200 201 void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork) 202 { 203 struct __queue *free_queue = &pmlmepriv->free_bss_pool; 204 205 if (!pnetwork) 206 return; 207 208 if (pnetwork->fixed) 209 return; 210 211 list_del_init(&pnetwork->list); 212 213 list_add_tail(&pnetwork->list, get_list_head(free_queue)); 214 } 215 216 /* 217 * return the wlan_network with the matching addr 218 * 219 * Shall be called under atomic context... to avoid possible racing condition... 220 */ 221 struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr) 222 { 223 struct list_head *phead, *plist; 224 struct wlan_network *pnetwork = NULL; 225 226 if (is_zero_ether_addr(addr)) { 227 pnetwork = NULL; 228 goto exit; 229 } 230 231 phead = get_list_head(scanned_queue); 232 list_for_each(plist, phead) { 233 pnetwork = list_entry(plist, struct wlan_network, list); 234 235 if (!memcmp(addr, pnetwork->network.mac_address, ETH_ALEN)) 236 break; 237 } 238 239 if (plist == phead) 240 pnetwork = NULL; 241 242 exit: 243 return pnetwork; 244 } 245 246 void rtw_free_network_queue(struct adapter *padapter, u8 isfreeall) 247 { 248 struct list_head *phead, *plist, *tmp; 249 struct wlan_network *pnetwork; 250 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 251 struct __queue *scanned_queue = &pmlmepriv->scanned_queue; 252 253 spin_lock_bh(&scanned_queue->lock); 254 255 phead = get_list_head(scanned_queue); 256 list_for_each_safe(plist, tmp, phead) { 257 pnetwork = list_entry(plist, struct wlan_network, list); 258 259 _rtw_free_network(pmlmepriv, pnetwork, isfreeall); 260 } 261 262 spin_unlock_bh(&scanned_queue->lock); 263 } 264 265 bool rtw_if_up(struct adapter *padapter) 266 { 267 if (padapter->bDriverStopped || padapter->bSurpriseRemoved || 268 !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) 269 return false; 270 271 return true; 272 } 273 274 void rtw_generate_random_ibss(u8 *pibss) 275 { 276 unsigned long curtime = jiffies; 277 278 pibss[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */ 279 pibss[1] = 0x11; 280 pibss[2] = 0x87; 281 pibss[3] = (u8)(curtime & 0xff) ;/* p[0]; */ 282 pibss[4] = (u8)((curtime >> 8) & 0xff) ;/* p[1]; */ 283 pibss[5] = (u8)((curtime >> 16) & 0xff) ;/* p[2]; */ 284 } 285 286 u8 *rtw_get_capability_from_ie(u8 *ie) 287 { 288 return ie + 8 + 2; 289 } 290 291 u16 rtw_get_capability(struct wlan_bssid_ex *bss) 292 { 293 __le16 val; 294 295 memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->ies), 2); 296 297 return le16_to_cpu(val); 298 } 299 300 u8 *rtw_get_beacon_interval_from_ie(u8 *ie) 301 { 302 return ie + 8; 303 } 304 305 void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) 306 { 307 _rtw_free_mlme_priv(pmlmepriv); 308 } 309 310 void rtw_free_network_nolock(struct adapter *padapter, struct wlan_network *pnetwork); 311 void rtw_free_network_nolock(struct adapter *padapter, struct wlan_network *pnetwork) 312 { 313 _rtw_free_network_nolock(&padapter->mlmepriv, pnetwork); 314 rtw_cfg80211_unlink_bss(padapter, pnetwork); 315 } 316 317 /* 318 * return the wlan_network with the matching addr 319 * 320 * Shall be called under atomic context... to avoid possible racing condition... 321 */ 322 struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr) 323 { 324 struct wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr); 325 326 return pnetwork; 327 } 328 329 bool rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork) 330 { 331 struct security_priv *psecuritypriv = &adapter->securitypriv; 332 333 if ((psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_) && 334 (pnetwork->network.privacy == 0)) 335 return false; 336 else if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) && 337 (pnetwork->network.privacy == 1)) 338 return false; 339 340 return true; 341 } 342 343 inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b) 344 { 345 return (a->ssid.ssid_length == b->ssid.ssid_length) 346 && !memcmp(a->ssid.ssid, b->ssid.ssid, a->ssid.ssid_length); 347 } 348 349 int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst, u8 feature) 350 { 351 u16 s_cap, d_cap; 352 __le16 tmps, tmpd; 353 354 memcpy((u8 *)&tmps, rtw_get_capability_from_ie(src->ies), 2); 355 memcpy((u8 *)&tmpd, rtw_get_capability_from_ie(dst->ies), 2); 356 357 s_cap = le16_to_cpu(tmps); 358 d_cap = le16_to_cpu(tmpd); 359 360 return (src->ssid.ssid_length == dst->ssid.ssid_length) && 361 ((!memcmp(src->mac_address, dst->mac_address, ETH_ALEN))) && 362 ((!memcmp(src->ssid.ssid, dst->ssid.ssid, src->ssid.ssid_length))) && 363 ((s_cap & WLAN_CAPABILITY_IBSS) == 364 (d_cap & WLAN_CAPABILITY_IBSS)) && 365 ((s_cap & WLAN_CAPABILITY_ESS) == 366 (d_cap & WLAN_CAPABILITY_ESS)); 367 } 368 369 struct wlan_network *_rtw_find_same_network(struct __queue *scanned_queue, struct wlan_network *network) 370 { 371 struct list_head *phead, *plist; 372 struct wlan_network *found = NULL; 373 374 phead = get_list_head(scanned_queue); 375 list_for_each(plist, phead) { 376 found = list_entry(plist, struct wlan_network, list); 377 378 if (is_same_network(&network->network, &found->network, 0)) 379 break; 380 } 381 382 if (plist == phead) 383 found = NULL; 384 385 return found; 386 } 387 388 struct wlan_network *rtw_get_oldest_wlan_network(struct __queue *scanned_queue) 389 { 390 struct list_head *plist, *phead; 391 392 struct wlan_network *pwlan = NULL; 393 struct wlan_network *oldest = NULL; 394 395 phead = get_list_head(scanned_queue); 396 397 list_for_each(plist, phead) { 398 pwlan = list_entry(plist, struct wlan_network, list); 399 400 if (!pwlan->fixed) { 401 if (!oldest || time_after(oldest->last_scanned, pwlan->last_scanned)) 402 oldest = pwlan; 403 } 404 } 405 return oldest; 406 } 407 408 void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, 409 struct adapter *padapter, bool update_ie) 410 { 411 long rssi_ori = dst->rssi; 412 413 u8 sq_smp = src->phy_info.signal_quality; 414 415 u8 ss_final; 416 u8 sq_final; 417 long rssi_final; 418 419 /* The rule below is 1/5 for sample value, 4/5 for history value */ 420 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&padapter->mlmepriv.cur_network.network, src, 0)) { 421 /* Take the recvpriv's value for the connected AP*/ 422 ss_final = padapter->recvpriv.signal_strength; 423 sq_final = padapter->recvpriv.signal_qual; 424 /* the rssi value here is undecorated, and will be used for antenna diversity */ 425 if (sq_smp != 101) /* from the right channel */ 426 rssi_final = (src->rssi + dst->rssi * 4) / 5; 427 else 428 rssi_final = rssi_ori; 429 } else { 430 if (sq_smp != 101) { /* from the right channel */ 431 ss_final = ((u32)(src->phy_info.signal_strength) + (u32)(dst->phy_info.signal_strength) * 4) / 5; 432 sq_final = ((u32)(src->phy_info.signal_quality) + (u32)(dst->phy_info.signal_quality) * 4) / 5; 433 rssi_final = (src->rssi + dst->rssi * 4) / 5; 434 } else { 435 /* bss info not receiving from the right channel, use the original RX signal infos */ 436 ss_final = dst->phy_info.signal_strength; 437 sq_final = dst->phy_info.signal_quality; 438 rssi_final = dst->rssi; 439 } 440 } 441 442 if (update_ie) { 443 dst->reserved[0] = src->reserved[0]; 444 dst->reserved[1] = src->reserved[1]; 445 memcpy((u8 *)dst, (u8 *)src, get_wlan_bssid_ex_sz(src)); 446 } 447 448 dst->phy_info.signal_strength = ss_final; 449 dst->phy_info.signal_quality = sq_final; 450 dst->rssi = rssi_final; 451 } 452 453 static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork) 454 { 455 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 456 457 if (check_fwstate(pmlmepriv, _FW_LINKED) && (is_same_network(&pmlmepriv->cur_network.network, pnetwork, 0))) { 458 update_network(&pmlmepriv->cur_network.network, pnetwork, adapter, true); 459 if (pmlmepriv->cur_network.network.ie_length < sizeof(struct ndis_802_11_fix_ie)) 460 return; 461 462 rtw_update_protection(adapter, (pmlmepriv->cur_network.network.ies) + sizeof(struct ndis_802_11_fix_ie), 463 pmlmepriv->cur_network.network.ie_length - sizeof(struct ndis_802_11_fix_ie)); 464 } 465 } 466 467 /* Caller must hold pmlmepriv->lock first. */ 468 void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *target) 469 { 470 struct list_head *plist, *phead; 471 u32 bssid_ex_sz; 472 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 473 struct __queue *queue = &pmlmepriv->scanned_queue; 474 struct wlan_network *pnetwork = NULL; 475 struct wlan_network *oldest = NULL; 476 int target_find = 0; 477 u8 feature = 0; 478 479 spin_lock_bh(&queue->lock); 480 phead = get_list_head(queue); 481 list_for_each(plist, phead) { 482 pnetwork = list_entry(plist, struct wlan_network, list); 483 484 if (is_same_network(&pnetwork->network, target, feature)) { 485 target_find = 1; 486 break; 487 } 488 489 if (rtw_roam_flags(adapter)) { 490 /* TODO: don't select network in the same ess as oldest if it's new enough*/ 491 } 492 493 if (!oldest || time_after(oldest->last_scanned, pnetwork->last_scanned)) 494 oldest = pnetwork; 495 } 496 497 /* 498 * If we didn't find a match, then get a new network slot to initialize 499 * with this beacon's information 500 */ 501 if (!target_find) { 502 if (list_empty(&pmlmepriv->free_bss_pool.queue)) { 503 /* If there are no more slots, expire the oldest */ 504 /* list_del_init(&oldest->list); */ 505 pnetwork = oldest; 506 if (!pnetwork) 507 goto exit; 508 509 memcpy(&pnetwork->network, target, get_wlan_bssid_ex_sz(target)); 510 /* variable initialize */ 511 pnetwork->fixed = false; 512 pnetwork->last_scanned = jiffies; 513 514 pnetwork->network_type = 0; 515 pnetwork->aid = 0; 516 pnetwork->join_res = 0; 517 518 /* bss info not receiving from the right channel */ 519 if (pnetwork->network.phy_info.signal_quality == 101) 520 pnetwork->network.phy_info.signal_quality = 0; 521 } else { 522 /* Otherwise just pull from the free list */ 523 524 pnetwork = rtw_alloc_network(pmlmepriv); /* will update scan_time */ 525 526 if (!pnetwork) 527 goto exit; 528 529 bssid_ex_sz = get_wlan_bssid_ex_sz(target); 530 target->length = bssid_ex_sz; 531 memcpy(&pnetwork->network, target, bssid_ex_sz); 532 533 pnetwork->last_scanned = jiffies; 534 535 /* bss info not receiving from the right channel */ 536 if (pnetwork->network.phy_info.signal_quality == 101) 537 pnetwork->network.phy_info.signal_quality = 0; 538 539 list_add_tail(&pnetwork->list, &queue->queue); 540 } 541 } else { 542 /* we have an entry and we are going to update it. But this entry may 543 * be already expired. In this case we do the same as we found a new 544 * net and call the new_net handler 545 */ 546 bool update_ie = true; 547 548 pnetwork->last_scanned = jiffies; 549 550 /* target.reserved[0]== 1, means that scanned network is a bcn frame. */ 551 if (pnetwork->network.ie_length > target->ie_length && target->reserved[0] == 1) 552 update_ie = false; 553 554 /* probe resp(3) > beacon(1) > probe req(2) */ 555 if (target->reserved[0] != 2 && 556 target->reserved[0] >= pnetwork->network.reserved[0]) { 557 update_ie = true; 558 } else { 559 update_ie = false; 560 } 561 562 update_network(&pnetwork->network, target, adapter, update_ie); 563 } 564 565 exit: 566 spin_unlock_bh(&queue->lock); 567 } 568 569 void rtw_add_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork); 570 void rtw_add_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork) 571 { 572 update_current_network(adapter, pnetwork); 573 rtw_update_scanned_network(adapter, pnetwork); 574 } 575 576 /* select the desired network based on the capability of the (i)bss. 577 * check items: 578 * (1) security 579 * (2) network_type 580 * (3) WMM 581 * (4) HT 582 * (5) others 583 */ 584 static bool rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwork) 585 { 586 struct security_priv *psecuritypriv = &adapter->securitypriv; 587 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 588 u32 desired_encmode; 589 u32 privacy; 590 uint wps_ielen; 591 bool bselected = true; 592 593 desired_encmode = psecuritypriv->ndisencryptstatus; 594 privacy = pnetwork->network.privacy; 595 596 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { 597 if (pnetwork->network.ie_length < _FIXED_IE_LENGTH_) 598 return false; 599 if (rtw_get_wps_ie(pnetwork->network.ies + _FIXED_IE_LENGTH_, pnetwork->network.ie_length - _FIXED_IE_LENGTH_, NULL, &wps_ielen)) 600 return true; 601 else 602 return false; 603 } 604 605 if (adapter->registrypriv.wifi_spec == 1) { /* for correct flow of 8021X to do.... */ 606 u8 *p = NULL; 607 uint ie_len = 0; 608 609 if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0)) 610 bselected = false; 611 612 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) { 613 if (pnetwork->network.ie_length < _BEACON_IE_OFFSET_) { 614 bselected = false; 615 } else { 616 p = rtw_get_ie(pnetwork->network.ies + _BEACON_IE_OFFSET_, WLAN_EID_RSN, &ie_len, (pnetwork->network.ie_length - _BEACON_IE_OFFSET_)); 617 if (p && ie_len > 0) 618 bselected = true; 619 else 620 bselected = false; 621 } 622 } 623 } 624 625 if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0)) 626 bselected = false; 627 628 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 629 if (pnetwork->network.infrastructure_mode != pmlmepriv->cur_network.network.infrastructure_mode) 630 bselected = false; 631 } 632 633 return bselected; 634 } 635 636 /* TODO: Perry : For Power Management */ 637 void rtw_atimdone_event_callback(struct adapter *adapter, u8 *pbuf) 638 { 639 } 640 641 void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf) 642 { 643 u32 len; 644 struct wlan_bssid_ex *pnetwork; 645 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 646 647 pnetwork = (struct wlan_bssid_ex *)pbuf; 648 649 len = get_wlan_bssid_ex_sz(pnetwork); 650 if (len > (sizeof(struct wlan_bssid_ex))) 651 return; 652 653 spin_lock_bh(&pmlmepriv->lock); 654 655 /* update IBSS_network 's timestamp */ 656 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { 657 if (!memcmp(&pmlmepriv->cur_network.network.mac_address, pnetwork->mac_address, ETH_ALEN)) { 658 struct wlan_network *ibss_wlan = NULL; 659 660 memcpy(pmlmepriv->cur_network.network.ies, pnetwork->ies, 8); 661 spin_lock_bh(&pmlmepriv->scanned_queue.lock); 662 ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->mac_address); 663 if (ibss_wlan) { 664 memcpy(ibss_wlan->network.ies, pnetwork->ies, 8); 665 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 666 goto exit; 667 } 668 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 669 } 670 } 671 672 /* lock pmlmepriv->lock when you accessing network_q */ 673 if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { 674 if (pnetwork->ssid.ssid[0] == 0) 675 pnetwork->ssid.ssid_length = 0; 676 rtw_add_network(adapter, pnetwork); 677 } 678 679 exit: 680 681 spin_unlock_bh(&pmlmepriv->lock); 682 } 683 684 void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) 685 { 686 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 687 688 spin_lock_bh(&pmlmepriv->lock); 689 if (pmlmepriv->wps_probe_req_ie) { 690 pmlmepriv->wps_probe_req_ie_len = 0; 691 kfree(pmlmepriv->wps_probe_req_ie); 692 pmlmepriv->wps_probe_req_ie = NULL; 693 } 694 695 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { 696 spin_unlock_bh(&pmlmepriv->lock); 697 timer_delete_sync(&pmlmepriv->scan_to_timer); 698 spin_lock_bh(&pmlmepriv->lock); 699 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); 700 } 701 702 rtw_set_signal_stat_timer(&adapter->recvpriv); 703 704 if (pmlmepriv->to_join) { 705 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 706 if (!check_fwstate(pmlmepriv, _FW_LINKED)) { 707 set_fwstate(pmlmepriv, _FW_UNDER_LINKING); 708 709 if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) { 710 _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); 711 } else { 712 u8 ret = _SUCCESS; 713 struct wlan_bssid_ex *pdev_network = &adapter->registrypriv.dev_network; 714 u8 *pibss = adapter->registrypriv.dev_network.mac_address; 715 716 /* pmlmepriv->fw_state ^= _FW_UNDER_SURVEY;because don't set assoc_timer */ 717 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); 718 719 memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); 720 721 rtw_update_registrypriv_dev_network(adapter); 722 rtw_generate_random_ibss(pibss); 723 724 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; 725 726 pmlmepriv->to_join = false; 727 728 ret = rtw_createbss_cmd(adapter); 729 if (ret != _SUCCESS) 730 goto unlock; 731 } 732 } 733 } else { 734 int s_ret; 735 736 set_fwstate(pmlmepriv, _FW_UNDER_LINKING); 737 pmlmepriv->to_join = false; 738 s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv); 739 if (s_ret == _SUCCESS) { 740 _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); 741 } else if (s_ret == 2) {/* there is no need to wait for join */ 742 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 743 rtw_indicate_connect(adapter); 744 } else { 745 if (rtw_to_roam(adapter) != 0) { 746 if (rtw_dec_to_roam(adapter) == 0 || 747 rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 748 1, NULL, 0) != _SUCCESS) { 749 rtw_set_to_roam(adapter, 0); 750 rtw_free_assoc_resources(adapter, 1); 751 rtw_indicate_disconnect(adapter); 752 } else { 753 pmlmepriv->to_join = true; 754 } 755 } else { 756 rtw_indicate_disconnect(adapter); 757 } 758 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 759 } 760 } 761 } else { 762 if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) { 763 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) 764 && check_fwstate(pmlmepriv, _FW_LINKED)) { 765 if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) { 766 receive_disconnect(adapter, pmlmepriv->cur_network.network.mac_address 767 , WLAN_REASON_ACTIVE_ROAM); 768 } 769 } 770 } 771 } 772 773 unlock: 774 spin_unlock_bh(&pmlmepriv->lock); 775 776 rtw_os_xmit_schedule(adapter); 777 778 rtw_cfg80211_surveydone_event_callback(adapter); 779 780 rtw_indicate_scan_done(adapter, false); 781 } 782 783 void rtw_dummy_event_callback(struct adapter *adapter, u8 *pbuf) 784 { 785 } 786 787 void rtw_fwdbg_event_callback(struct adapter *adapter, u8 *pbuf) 788 { 789 } 790 791 static void free_scanqueue(struct mlme_priv *pmlmepriv) 792 { 793 struct __queue *free_queue = &pmlmepriv->free_bss_pool; 794 struct __queue *scan_queue = &pmlmepriv->scanned_queue; 795 struct list_head *plist, *phead, *ptemp; 796 797 spin_lock_bh(&scan_queue->lock); 798 spin_lock_bh(&free_queue->lock); 799 800 phead = get_list_head(scan_queue); 801 plist = get_next(phead); 802 803 while (plist != phead) { 804 ptemp = get_next(plist); 805 list_del_init(plist); 806 list_add_tail(plist, &free_queue->queue); 807 plist = ptemp; 808 } 809 810 spin_unlock_bh(&free_queue->lock); 811 spin_unlock_bh(&scan_queue->lock); 812 } 813 814 static void find_network(struct adapter *adapter) 815 { 816 struct wlan_network *pwlan = NULL; 817 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 818 struct wlan_network *tgt_network = &pmlmepriv->cur_network; 819 820 pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address); 821 if (!pwlan) 822 return; 823 824 pwlan->fixed = false; 825 826 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && 827 (adapter->stapriv.asoc_sta_count == 1)) 828 rtw_free_network_nolock(adapter, pwlan); 829 } 830 831 /* rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock */ 832 void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue) 833 { 834 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 835 struct wlan_network *tgt_network = &pmlmepriv->cur_network; 836 837 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) { 838 struct sta_info *psta; 839 840 psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.mac_address); 841 rtw_free_stainfo(adapter, psta); 842 } 843 844 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) { 845 struct sta_info *psta; 846 847 rtw_free_all_stainfo(adapter); 848 849 psta = rtw_get_bcmc_stainfo(adapter); 850 rtw_free_stainfo(adapter, psta); 851 852 rtw_init_bcmc_stainfo(adapter); 853 } 854 855 find_network(adapter); 856 857 if (lock_scanned_queue) 858 adapter->securitypriv.key_mask = 0; 859 } 860 861 /* rtw_indicate_connect: the caller has to lock pmlmepriv->lock */ 862 void rtw_indicate_connect(struct adapter *padapter) 863 { 864 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 865 866 pmlmepriv->to_join = false; 867 868 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { 869 set_fwstate(pmlmepriv, _FW_LINKED); 870 871 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || 872 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) 873 rtw_cfg80211_ibss_indicate_connect(padapter); 874 else 875 rtw_cfg80211_indicate_connect(padapter); 876 877 netif_carrier_on(padapter->pnetdev); 878 879 if (padapter->pid[2] != 0) 880 rtw_signal_process(padapter->pid[2], SIGALRM); 881 } 882 883 rtw_set_to_roam(padapter, 0); 884 rtw_set_scan_deny(padapter, 3000); 885 } 886 887 /* rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock */ 888 void rtw_indicate_disconnect(struct adapter *padapter) 889 { 890 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 891 892 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING | WIFI_UNDER_WPS); 893 894 if (rtw_to_roam(padapter) > 0) 895 _clr_fwstate_(pmlmepriv, _FW_LINKED); 896 897 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) || rtw_to_roam(padapter) <= 0) { 898 /* Do it first for tx broadcast pkt after disconnection issue! */ 899 netif_carrier_off(padapter->pnetdev); 900 901 rtw_cfg80211_indicate_disconnect(padapter); 902 903 /* modify for CONFIG_IEEE80211W, none 11w also can use the same command */ 904 rtw_reset_securitypriv_cmd(padapter); 905 906 /* set ips_deny_time to avoid enter IPS before LPS leave */ 907 rtw_set_ips_deny(padapter, 3000); 908 909 _clr_fwstate_(pmlmepriv, _FW_LINKED); 910 911 rtw_clear_scan_deny(padapter); 912 } 913 914 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1); 915 } 916 917 inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted) 918 { 919 rtw_cfg80211_indicate_scan_done(padapter, aborted); 920 921 if ((!adapter_to_pwrctl(padapter)->bInSuspend) && 922 (!check_fwstate(&padapter->mlmepriv, 923 WIFI_ASOC_STATE | WIFI_UNDER_LINKING))) { 924 rtw_set_ips_deny(padapter, 0); 925 _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 1); 926 } 927 } 928 929 void rtw_scan_abort(struct adapter *adapter) 930 { 931 unsigned long start; 932 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 933 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; 934 935 start = jiffies; 936 pmlmeext->scan_abort = true; 937 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) 938 && jiffies_to_msecs(start) <= 200) { 939 if (adapter->bDriverStopped || adapter->bSurpriseRemoved) 940 break; 941 942 msleep(20); 943 } 944 945 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) 946 rtw_indicate_scan_done(adapter, true); 947 948 pmlmeext->scan_abort = false; 949 } 950 951 static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, struct wlan_network *pnetwork) 952 { 953 int i; 954 struct sta_info *bmc_sta, *psta = NULL; 955 struct recv_reorder_ctrl *preorder_ctrl; 956 struct sta_priv *pstapriv = &padapter->stapriv; 957 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 958 959 psta = rtw_get_stainfo(pstapriv, pnetwork->network.mac_address); 960 if (!psta) 961 psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.mac_address); 962 963 if (psta) { /* update ptarget_sta */ 964 965 psta->aid = pnetwork->join_res; 966 967 update_sta_info(padapter, psta); 968 969 /* update station supportRate */ 970 psta->bssratelen = rtw_get_rateset_len(pnetwork->network.supported_rates); 971 memcpy(psta->bssrateset, pnetwork->network.supported_rates, psta->bssratelen); 972 rtw_hal_update_sta_rate_mask(padapter, psta); 973 974 psta->wireless_mode = pmlmeext->cur_wireless_mode; 975 psta->raid = networktype_to_raid_ex(padapter, psta); 976 977 /* sta mode */ 978 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true); 979 980 /* security related */ 981 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { 982 padapter->securitypriv.binstallGrpkey = false; 983 padapter->securitypriv.busetkipkey = false; 984 padapter->securitypriv.bgrpkey_handshake = false; 985 986 psta->ieee8021x_blocked = true; 987 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; 988 989 memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype)); 990 991 memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype)); 992 memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype)); 993 994 memset((u8 *)&psta->dot11txpn, 0, sizeof(union pn48)); 995 psta->dot11txpn.val = psta->dot11txpn.val + 1; 996 memset((u8 *)&psta->dot11wtxpn, 0, sizeof(union pn48)); 997 memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48)); 998 } 999 1000 /* When doing the WPS, the wps_ie_len won't equal to 0 */ 1001 /* And the Wi-Fi driver shouldn't allow the data packet to be transmitted. */ 1002 if (padapter->securitypriv.wps_ie_len != 0) { 1003 psta->ieee8021x_blocked = true; 1004 padapter->securitypriv.wps_ie_len = 0; 1005 } 1006 1007 /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */ 1008 /* if A-MPDU Rx is enabled, resetting rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */ 1009 /* todo: check if AP can send A-MPDU packets */ 1010 for (i = 0; i < 16 ; i++) { 1011 preorder_ctrl = &psta->recvreorder_ctrl[i]; 1012 preorder_ctrl->enable = false; 1013 preorder_ctrl->indicate_seq = 0xffff; 1014 preorder_ctrl->wend_b = 0xffff; 1015 preorder_ctrl->wsize_b = 64;/* max_ampdu_sz;ex. 32(kbytes) -> wsize_b =32 */ 1016 } 1017 1018 bmc_sta = rtw_get_bcmc_stainfo(padapter); 1019 if (bmc_sta) { 1020 for (i = 0; i < 16 ; i++) { 1021 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; 1022 preorder_ctrl->enable = false; 1023 preorder_ctrl->indicate_seq = 0xffff; 1024 preorder_ctrl->wend_b = 0xffff; 1025 preorder_ctrl->wsize_b = 64;/* max_ampdu_sz;ex. 32(kbytes) -> wsize_b =32 */ 1026 } 1027 } 1028 } 1029 1030 return psta; 1031 } 1032 1033 /* pnetwork : returns from rtw_joinbss_event_callback */ 1034 /* ptarget_wlan: found from scanned_queue */ 1035 static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network *pnetwork) 1036 { 1037 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1038 struct wlan_network *cur_network = &pmlmepriv->cur_network; 1039 1040 /* why not use ptarget_wlan?? */ 1041 memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.length); 1042 /* some ies in pnetwork is wrong, so we should use ptarget_wlan ies */ 1043 cur_network->network.ie_length = ptarget_wlan->network.ie_length; 1044 memcpy(&cur_network->network.ies[0], &ptarget_wlan->network.ies[0], MAX_IE_SZ); 1045 1046 cur_network->aid = pnetwork->join_res; 1047 1048 rtw_set_signal_stat_timer(&padapter->recvpriv); 1049 1050 padapter->recvpriv.signal_strength = ptarget_wlan->network.phy_info.signal_strength; 1051 padapter->recvpriv.signal_qual = ptarget_wlan->network.phy_info.signal_quality; 1052 /* the ptarget_wlan->network.rssi is raw data, we use ptarget_wlan->network.phy_info.signal_strength instead (has scaled) */ 1053 padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.phy_info.signal_strength); 1054 1055 rtw_set_signal_stat_timer(&padapter->recvpriv); 1056 1057 /* update fw_state will clr _FW_UNDER_LINKING here indirectly */ 1058 switch (pnetwork->network.infrastructure_mode) { 1059 case Ndis802_11Infrastructure: 1060 1061 if (pmlmepriv->fw_state & WIFI_UNDER_WPS) 1062 pmlmepriv->fw_state = WIFI_STATION_STATE | WIFI_UNDER_WPS; 1063 else 1064 pmlmepriv->fw_state = WIFI_STATION_STATE; 1065 1066 break; 1067 case Ndis802_11IBSS: 1068 pmlmepriv->fw_state = WIFI_ADHOC_STATE; 1069 break; 1070 default: 1071 pmlmepriv->fw_state = WIFI_NULL_STATE; 1072 break; 1073 } 1074 1075 if (cur_network->network.ie_length < sizeof(struct ndis_802_11_fix_ie)) 1076 return; 1077 1078 rtw_update_protection(padapter, (cur_network->network.ies) + sizeof(struct ndis_802_11_fix_ie), 1079 (cur_network->network.ie_length - sizeof(struct ndis_802_11_fix_ie))); 1080 1081 rtw_update_ht_cap(padapter, cur_network->network.ies, cur_network->network.ie_length, (u8) cur_network->network.configuration.ds_config); 1082 } 1083 1084 static struct rt_pmkid_list backupPMKIDList[NUM_PMKID_CACHE]; 1085 void rtw_reset_securitypriv(struct adapter *adapter) 1086 { 1087 u8 backupPMKIDIndex = 0; 1088 u8 backupTKIPCountermeasure = 0x00; 1089 u32 backupTKIPcountermeasure_time = 0; 1090 /* add for CONFIG_IEEE80211W, none 11w also can use */ 1091 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; 1092 1093 spin_lock_bh(&adapter->security_key_mutex); 1094 1095 if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { 1096 /* 802.1x */ 1097 /* Added by Albert 2009/02/18 */ 1098 /* We have to backup the PMK information for WiFi PMK Caching test item. */ 1099 /* */ 1100 /* Backup the btkip_countermeasure information. */ 1101 /* When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds. */ 1102 1103 memcpy(&backupPMKIDList[0], &adapter->securitypriv.PMKIDList[0], sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); 1104 backupPMKIDIndex = adapter->securitypriv.PMKIDIndex; 1105 backupTKIPCountermeasure = adapter->securitypriv.btkip_countermeasure; 1106 backupTKIPcountermeasure_time = adapter->securitypriv.btkip_countermeasure_time; 1107 1108 /* reset RX BIP packet number */ 1109 pmlmeext->mgnt_80211w_IPN_rx = 0; 1110 1111 memset((unsigned char *)&adapter->securitypriv, 0, sizeof(struct security_priv)); 1112 1113 /* Added by Albert 2009/02/18 */ 1114 /* Restore the PMK information to securitypriv structure for the following connection. */ 1115 memcpy(&adapter->securitypriv.PMKIDList[0], &backupPMKIDList[0], sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); 1116 adapter->securitypriv.PMKIDIndex = backupPMKIDIndex; 1117 adapter->securitypriv.btkip_countermeasure = backupTKIPCountermeasure; 1118 adapter->securitypriv.btkip_countermeasure_time = backupTKIPcountermeasure_time; 1119 1120 adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; 1121 adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; 1122 1123 } else { 1124 /* reset values in securitypriv */ 1125 /* if (adapter->mlmepriv.fw_state & WIFI_STATION_STATE) */ 1126 /* */ 1127 struct security_priv *psec_priv = &adapter->securitypriv; 1128 1129 psec_priv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ 1130 psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_; 1131 psec_priv->dot11PrivacyKeyIndex = 0; 1132 1133 psec_priv->dot118021XGrpPrivacy = _NO_PRIVACY_; 1134 psec_priv->dot118021XGrpKeyid = 1; 1135 1136 psec_priv->ndisauthtype = Ndis802_11AuthModeOpen; 1137 psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled; 1138 /* */ 1139 } 1140 /* add for CONFIG_IEEE80211W, none 11w also can use */ 1141 spin_unlock_bh(&adapter->security_key_mutex); 1142 } 1143 1144 /* Notes: the function could be > passive_level (the same context as Rx tasklet) */ 1145 /* pnetwork : returns from rtw_joinbss_event_callback */ 1146 /* ptarget_wlan: found from scanned_queue */ 1147 /* if join_res > 0, for (fw_state ==WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist. */ 1148 /* if join_res > 0, for (fw_state ==WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */ 1149 /* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan != NULL). */ 1150 /* */ 1151 void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) 1152 { 1153 struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL; 1154 struct sta_priv *pstapriv = &adapter->stapriv; 1155 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1156 struct wlan_network *pnetwork = (struct wlan_network *)pbuf; 1157 struct wlan_network *cur_network = &pmlmepriv->cur_network; 1158 struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL; 1159 unsigned int the_same_macaddr = false; 1160 1161 the_same_macaddr = !memcmp(pnetwork->network.mac_address, cur_network->network.mac_address, ETH_ALEN); 1162 1163 pnetwork->network.length = get_wlan_bssid_ex_sz(&pnetwork->network); 1164 if (pnetwork->network.length > sizeof(struct wlan_bssid_ex)) 1165 return; 1166 1167 spin_lock_bh(&pmlmepriv->lock); 1168 1169 pmlmepriv->link_detect_info.traffic_transition_count = 0; 1170 pmlmepriv->link_detect_info.low_power_transition_count = 0; 1171 1172 if (pnetwork->join_res == -4) { 1173 rtw_reset_securitypriv(adapter); 1174 _set_timer(&pmlmepriv->assoc_timer, 1); 1175 1176 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) 1177 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 1178 1179 spin_unlock_bh(&pmlmepriv->lock); 1180 return; 1181 } 1182 1183 if (pnetwork->join_res <= 0) { /* if join_res < 0 (join fails), then try again */ 1184 _set_timer(&pmlmepriv->assoc_timer, 1); 1185 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 1186 spin_unlock_bh(&pmlmepriv->lock); 1187 return; 1188 } 1189 1190 spin_lock_bh(&pmlmepriv->scanned_queue.lock); 1191 1192 if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { 1193 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1194 spin_unlock_bh(&pmlmepriv->lock); 1195 return; 1196 } 1197 1198 /* s1. find ptarget_wlan */ 1199 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 1200 if (the_same_macaddr) { 1201 ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.mac_address); 1202 } else { 1203 pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.mac_address); 1204 if (pcur_wlan) 1205 pcur_wlan->fixed = false; 1206 1207 pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.mac_address); 1208 if (pcur_sta) 1209 rtw_free_stainfo(adapter, pcur_sta); 1210 1211 ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.mac_address); 1212 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 1213 if (ptarget_wlan) 1214 ptarget_wlan->fixed = true; 1215 } 1216 } 1217 } else { 1218 ptarget_wlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, pnetwork); 1219 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 1220 if (ptarget_wlan) 1221 ptarget_wlan->fixed = true; 1222 } 1223 } 1224 1225 /* s2. update cur_network */ 1226 if (!ptarget_wlan) { 1227 netdev_dbg(adapter->pnetdev, 1228 "Can't find ptarget_wlan when joinbss_event callback\n"); 1229 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1230 spin_unlock_bh(&pmlmepriv->lock); 1231 return; 1232 } 1233 1234 rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork); 1235 1236 /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */ 1237 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 1238 ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork); 1239 if (!ptarget_sta) { 1240 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1241 spin_unlock_bh(&pmlmepriv->lock); 1242 return; 1243 } 1244 } 1245 1246 /* s4. indicate connect */ 1247 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 1248 pmlmepriv->cur_network_scanned = ptarget_wlan; 1249 rtw_indicate_connect(adapter); 1250 } 1251 1252 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1253 1254 spin_unlock_bh(&pmlmepriv->lock); 1255 /* s5. Cancel assoc_timer */ 1256 timer_delete_sync(&pmlmepriv->assoc_timer); 1257 } 1258 1259 void rtw_joinbss_event_callback(struct adapter *adapter, u8 *pbuf) 1260 { 1261 struct wlan_network *pnetwork = (struct wlan_network *)pbuf; 1262 1263 mlmeext_joinbss_event_callback(adapter, pnetwork->join_res); 1264 1265 rtw_os_xmit_schedule(adapter); 1266 } 1267 1268 /* FOR STA, AP , AD-HOC mode */ 1269 void rtw_sta_media_status_rpt(struct adapter *adapter, struct sta_info *psta, u32 mstatus) 1270 { 1271 u16 media_status_rpt; 1272 1273 if (!psta) 1274 return; 1275 1276 media_status_rpt = (u16)((psta->mac_id << 8) | mstatus); /* MACID|OPMODE:1 connect */ 1277 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status_rpt); 1278 } 1279 1280 void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf) 1281 { 1282 struct sta_info *psta; 1283 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1284 struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf; 1285 struct wlan_network *cur_network = &pmlmepriv->cur_network; 1286 struct wlan_network *ptarget_wlan = NULL; 1287 1288 if (!rtw_access_ctrl(adapter, pstassoc->macaddr)) 1289 return; 1290 1291 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1292 psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr); 1293 if (psta) { 1294 u8 *passoc_req = NULL; 1295 u32 assoc_req_len = 0; 1296 1297 rtw_sta_media_status_rpt(adapter, psta, 1); 1298 1299 ap_sta_info_defer_update(adapter, psta); 1300 1301 /* report to upper layer */ 1302 spin_lock_bh(&psta->lock); 1303 if (psta->passoc_req && psta->assoc_req_len > 0) { 1304 passoc_req = kmemdup(psta->passoc_req, psta->assoc_req_len, GFP_ATOMIC); 1305 if (passoc_req) { 1306 assoc_req_len = psta->assoc_req_len; 1307 1308 kfree(psta->passoc_req); 1309 psta->passoc_req = NULL; 1310 psta->assoc_req_len = 0; 1311 } 1312 } 1313 spin_unlock_bh(&psta->lock); 1314 1315 if (passoc_req && assoc_req_len > 0) { 1316 rtw_cfg80211_indicate_sta_assoc(adapter, passoc_req, assoc_req_len); 1317 1318 kfree(passoc_req); 1319 } 1320 } 1321 return; 1322 } 1323 1324 /* for AD-HOC mode */ 1325 psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr); 1326 if (psta) { 1327 /* the sta have been in sta_info_queue => do nothing */ 1328 1329 return; /* between drv has received this event before and fw have not yet to set key to CAM_ENTRY) */ 1330 } 1331 1332 psta = rtw_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr); 1333 if (!psta) 1334 return; 1335 1336 /* to do : init sta_info variable */ 1337 psta->qos_option = 0; 1338 psta->mac_id = (uint)pstassoc->cam_id; 1339 1340 /* for ad-hoc mode */ 1341 rtw_hal_set_odm_var(adapter, HAL_ODM_STA_INFO, psta, true); 1342 1343 rtw_sta_media_status_rpt(adapter, psta, 1); 1344 1345 if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) 1346 psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm; 1347 1348 psta->ieee8021x_blocked = false; 1349 1350 spin_lock_bh(&pmlmepriv->lock); 1351 1352 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || 1353 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 1354 if (adapter->stapriv.asoc_sta_count == 2) { 1355 spin_lock_bh(&pmlmepriv->scanned_queue.lock); 1356 ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.mac_address); 1357 pmlmepriv->cur_network_scanned = ptarget_wlan; 1358 if (ptarget_wlan) 1359 ptarget_wlan->fixed = true; 1360 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1361 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */ 1362 rtw_indicate_connect(adapter); 1363 } 1364 } 1365 1366 spin_unlock_bh(&pmlmepriv->lock); 1367 1368 mlmeext_sta_add_event_callback(adapter, psta); 1369 } 1370 1371 void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) 1372 { 1373 int mac_id = (-1); 1374 struct sta_info *psta; 1375 struct wlan_network *pwlan = NULL; 1376 struct wlan_bssid_ex *pdev_network = NULL; 1377 u8 *pibss = NULL; 1378 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1379 struct stadel_event *pstadel = (struct stadel_event *)pbuf; 1380 struct wlan_network *tgt_network = &pmlmepriv->cur_network; 1381 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; 1382 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 1383 1384 psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr); 1385 if (psta) 1386 mac_id = psta->mac_id; 1387 else 1388 mac_id = pstadel->mac_id; 1389 1390 if (mac_id >= 0) { 1391 u16 media_status; 1392 1393 media_status = (mac_id << 8) | 0; /* MACID|OPMODE:0 means disconnect */ 1394 /* for STA, AP, ADHOC mode, report disconnect status to FW */ 1395 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status); 1396 } 1397 1398 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) */ 1399 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) 1400 return; 1401 1402 mlmeext_sta_del_event_callback(adapter); 1403 1404 spin_lock_bh(&pmlmepriv->lock); 1405 1406 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 1407 u16 reason = *((unsigned short *)(pstadel->rsvd)); 1408 bool roam = false; 1409 struct wlan_network *roam_target = NULL; 1410 1411 if (adapter->registrypriv.wifi_spec == 1) { 1412 roam = false; 1413 } else if (reason == WLAN_REASON_EXPIRATION_CHK && rtw_chk_roam_flags(adapter, RTW_ROAM_ON_EXPIRED)) { 1414 roam = true; 1415 } else if (reason == WLAN_REASON_ACTIVE_ROAM && rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) { 1416 roam = true; 1417 roam_target = pmlmepriv->roam_network; 1418 } 1419 1420 if (roam) { 1421 if (rtw_to_roam(adapter) > 0) 1422 rtw_dec_to_roam(adapter); /* this stadel_event is caused by roaming, decrease to_roam */ 1423 else if (rtw_to_roam(adapter) == 0) 1424 rtw_set_to_roam(adapter, adapter->registrypriv.max_roaming_times); 1425 } else { 1426 rtw_set_to_roam(adapter, 0); 1427 } 1428 1429 rtw_free_uc_swdec_pending_queue(adapter); 1430 1431 rtw_free_assoc_resources(adapter, 1); 1432 rtw_indicate_disconnect(adapter); 1433 1434 spin_lock_bh(&pmlmepriv->scanned_queue.lock); 1435 /* remove the network entry in scanned_queue */ 1436 pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address); 1437 if (pwlan) { 1438 pwlan->fixed = false; 1439 rtw_free_network_nolock(adapter, pwlan); 1440 } 1441 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1442 1443 _rtw_roaming(adapter, roam_target); 1444 } 1445 1446 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || 1447 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 1448 rtw_free_stainfo(adapter, psta); 1449 1450 if (adapter->stapriv.asoc_sta_count == 1) {/* a sta + bc/mc_stainfo (not Ibss_stainfo) */ 1451 u8 ret = _SUCCESS; 1452 1453 spin_lock_bh(&pmlmepriv->scanned_queue.lock); 1454 /* free old ibss network */ 1455 pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address); 1456 if (pwlan) { 1457 pwlan->fixed = false; 1458 rtw_free_network_nolock(adapter, pwlan); 1459 } 1460 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1461 /* re-create ibss */ 1462 pdev_network = &adapter->registrypriv.dev_network; 1463 pibss = adapter->registrypriv.dev_network.mac_address; 1464 1465 memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network)); 1466 1467 memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); 1468 1469 rtw_update_registrypriv_dev_network(adapter); 1470 1471 rtw_generate_random_ibss(pibss); 1472 1473 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 1474 set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE); 1475 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE); 1476 } 1477 1478 ret = rtw_createbss_cmd(adapter); 1479 if (ret != _SUCCESS) 1480 goto unlock; 1481 } 1482 } 1483 1484 unlock: 1485 spin_unlock_bh(&pmlmepriv->lock); 1486 } 1487 1488 void rtw_cpwm_event_callback(struct adapter *padapter, u8 *pbuf) 1489 { 1490 struct reportpwrstate_parm *preportpwrstate; 1491 1492 preportpwrstate = (struct reportpwrstate_parm *)pbuf; 1493 preportpwrstate->state |= (u8)(adapter_to_pwrctl(padapter)->cpwm_tog + 0x80); 1494 cpwm_int_hdl(padapter, preportpwrstate); 1495 } 1496 1497 void rtw_wmm_event_callback(struct adapter *padapter, u8 *pbuf) 1498 { 1499 WMMOnAssocRsp(padapter); 1500 } 1501 1502 /* 1503 * _rtw_join_timeout_handler - Timeout/failure handler for CMD JoinBss 1504 * @adapter: pointer to struct adapter structure 1505 */ 1506 void _rtw_join_timeout_handler(struct timer_list *t) 1507 { 1508 struct adapter *adapter = timer_container_of(adapter, t, 1509 mlmepriv.assoc_timer); 1510 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1511 1512 if (adapter->bDriverStopped || adapter->bSurpriseRemoved) 1513 return; 1514 1515 spin_lock_bh(&pmlmepriv->lock); 1516 1517 if (rtw_to_roam(adapter) > 0) { /* join timeout caused by roaming */ 1518 while (1) { 1519 rtw_dec_to_roam(adapter); 1520 if (rtw_to_roam(adapter) != 0) { /* try another */ 1521 int do_join_r; 1522 1523 do_join_r = rtw_do_join(adapter); 1524 if (do_join_r != _SUCCESS) 1525 continue; 1526 1527 break; 1528 } 1529 1530 rtw_indicate_disconnect(adapter); 1531 break; 1532 } 1533 1534 } else { 1535 rtw_indicate_disconnect(adapter); 1536 free_scanqueue(pmlmepriv);/* */ 1537 1538 /* indicate disconnect for the case that join_timeout and check_fwstate != FW_LINKED */ 1539 rtw_cfg80211_indicate_disconnect(adapter); 1540 } 1541 1542 spin_unlock_bh(&pmlmepriv->lock); 1543 } 1544 1545 /* 1546 * rtw_scan_timeout_handler - Timeout/Failure handler for CMD SiteSurvey 1547 * @adapter: pointer to struct adapter structure 1548 */ 1549 void rtw_scan_timeout_handler(struct timer_list *t) 1550 { 1551 struct adapter *adapter = timer_container_of(adapter, t, 1552 mlmepriv.scan_to_timer); 1553 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1554 1555 spin_lock_bh(&pmlmepriv->lock); 1556 1557 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); 1558 1559 spin_unlock_bh(&pmlmepriv->lock); 1560 1561 rtw_indicate_scan_done(adapter, true); 1562 } 1563 1564 void rtw_mlme_reset_auto_scan_int(struct adapter *adapter) 1565 { 1566 struct mlme_priv *mlme = &adapter->mlmepriv; 1567 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; 1568 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 1569 1570 if (pmlmeinfo->VHT_enable) { 1571 /* disable auto scan when connect to 11AC AP */ 1572 mlme->auto_scan_int_ms = 0; 1573 } else if (adapter->registrypriv.wifi_spec && is_client_associated_to_ap(adapter)) { 1574 mlme->auto_scan_int_ms = 60 * 1000; 1575 } else if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) { 1576 if (check_fwstate(mlme, WIFI_STATION_STATE) && check_fwstate(mlme, _FW_LINKED)) 1577 mlme->auto_scan_int_ms = mlme->roam_scan_int_ms; 1578 } else { 1579 mlme->auto_scan_int_ms = 0; /* disabled */ 1580 } 1581 } 1582 1583 static void rtw_auto_scan_handler(struct adapter *padapter) 1584 { 1585 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1586 1587 rtw_mlme_reset_auto_scan_int(padapter); 1588 1589 if (pmlmepriv->auto_scan_int_ms != 0 1590 && jiffies_to_msecs(jiffies - pmlmepriv->scan_start_time) > pmlmepriv->auto_scan_int_ms) { 1591 if (!padapter->registrypriv.wifi_spec) { 1592 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) 1593 goto exit; 1594 1595 if (pmlmepriv->link_detect_info.busy_traffic) 1596 goto exit; 1597 } 1598 1599 rtw_set_802_11_bssid_list_scan(padapter, NULL, 0); 1600 } 1601 1602 exit: 1603 return; 1604 } 1605 1606 void rtw_dynamic_check_timer_handler(struct adapter *adapter) 1607 { 1608 if (!adapter) 1609 return; 1610 1611 if (!adapter->hw_init_completed) 1612 return; 1613 1614 if (adapter->bDriverStopped || adapter->bSurpriseRemoved) 1615 return; 1616 1617 if (adapter->net_closed) 1618 return; 1619 1620 if ((adapter_to_pwrctl(adapter)->fw_current_in_ps_mode) 1621 && !(hal_btcoex_IsBtControlLps(adapter)) 1622 ) { 1623 bool should_enter_ps; 1624 1625 linked_status_chk(adapter); 1626 1627 should_enter_ps = traffic_status_watchdog(adapter, true); 1628 if (should_enter_ps) { 1629 /* rtw_lps_ctrl_wk_cmd(adapter, LPS_CTRL_ENTER, 1); */ 1630 rtw_hal_dm_watchdog_in_lps(adapter); 1631 } else { 1632 /* call rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1) in traffic_status_watchdog() */ 1633 } 1634 1635 } else { 1636 rtw_dynamic_chk_wk_cmd(adapter); 1637 } 1638 1639 /* auto site survey */ 1640 rtw_auto_scan_handler(adapter); 1641 } 1642 1643 inline bool rtw_is_scan_deny(struct adapter *adapter) 1644 { 1645 struct mlme_priv *mlmepriv = &adapter->mlmepriv; 1646 1647 return (atomic_read(&mlmepriv->set_scan_deny) != 0) ? true : false; 1648 } 1649 1650 inline void rtw_clear_scan_deny(struct adapter *adapter) 1651 { 1652 struct mlme_priv *mlmepriv = &adapter->mlmepriv; 1653 1654 atomic_set(&mlmepriv->set_scan_deny, 0); 1655 } 1656 1657 void rtw_set_scan_deny(struct adapter *adapter, u32 ms) 1658 { 1659 struct mlme_priv *mlmepriv = &adapter->mlmepriv; 1660 1661 atomic_set(&mlmepriv->set_scan_deny, 1); 1662 _set_timer(&mlmepriv->set_scan_deny_timer, ms); 1663 } 1664 1665 /* 1666 * Select a new roaming candidate from the original @param candidate and @param competitor 1667 * @return true: candidate is updated 1668 * @return false: candidate is not updated 1669 */ 1670 static int rtw_check_roaming_candidate(struct mlme_priv *mlme 1671 , struct wlan_network **candidate, struct wlan_network *competitor) 1672 { 1673 int updated = false; 1674 struct adapter *adapter = container_of(mlme, struct adapter, mlmepriv); 1675 1676 if (!is_same_ess(&competitor->network, &mlme->cur_network.network)) 1677 goto exit; 1678 1679 if (!rtw_is_desired_network(adapter, competitor)) 1680 goto exit; 1681 1682 /* got specific addr to roam */ 1683 if (!is_zero_ether_addr(mlme->roam_tgt_addr)) { 1684 if (!memcmp(mlme->roam_tgt_addr, competitor->network.mac_address, ETH_ALEN)) 1685 goto update; 1686 else 1687 goto exit; 1688 } 1689 if (jiffies_to_msecs(jiffies - competitor->last_scanned) >= mlme->roam_scanr_exp_ms) 1690 goto exit; 1691 1692 if (competitor->network.rssi - mlme->cur_network_scanned->network.rssi < mlme->roam_rssi_diff_th) 1693 goto exit; 1694 1695 if (*candidate && (*candidate)->network.rssi >= competitor->network.rssi) 1696 goto exit; 1697 1698 update: 1699 *candidate = competitor; 1700 updated = true; 1701 1702 exit: 1703 return updated; 1704 } 1705 1706 int rtw_select_roaming_candidate(struct mlme_priv *mlme) 1707 { 1708 int ret = _FAIL; 1709 struct list_head *phead; 1710 struct __queue *queue = &mlme->scanned_queue; 1711 struct wlan_network *pnetwork = NULL; 1712 struct wlan_network *candidate = NULL; 1713 1714 if (!mlme->cur_network_scanned) { 1715 WARN_ON(1); 1716 return ret; 1717 } 1718 1719 spin_lock_bh(&mlme->scanned_queue.lock); 1720 phead = get_list_head(queue); 1721 1722 list_for_each(mlme->pscanned, phead) { 1723 pnetwork = list_entry(mlme->pscanned, struct wlan_network, 1724 list); 1725 1726 rtw_check_roaming_candidate(mlme, &candidate, pnetwork); 1727 } 1728 1729 if (!candidate) { 1730 ret = _FAIL; 1731 goto exit; 1732 } else { 1733 mlme->roam_network = candidate; 1734 1735 if (!memcmp(candidate->network.mac_address, mlme->roam_tgt_addr, ETH_ALEN)) 1736 eth_zero_addr(mlme->roam_tgt_addr); 1737 } 1738 1739 ret = _SUCCESS; 1740 exit: 1741 spin_unlock_bh(&mlme->scanned_queue.lock); 1742 1743 return ret; 1744 } 1745 1746 /* 1747 * Select a new join candidate from the original @param candidate and @param competitor 1748 * @return true: candidate is updated 1749 * @return false: candidate is not updated 1750 */ 1751 static int rtw_check_join_candidate(struct mlme_priv *mlme 1752 , struct wlan_network **candidate, struct wlan_network *competitor) 1753 { 1754 int updated = false; 1755 struct adapter *adapter = container_of(mlme, struct adapter, mlmepriv); 1756 1757 /* check bssid, if needed */ 1758 if (mlme->assoc_by_bssid) { 1759 if (memcmp(competitor->network.mac_address, mlme->assoc_bssid, ETH_ALEN)) 1760 goto exit; 1761 } 1762 1763 /* check ssid, if needed */ 1764 if (mlme->assoc_ssid.ssid[0] && mlme->assoc_ssid.ssid_length) { 1765 if (competitor->network.ssid.ssid_length != mlme->assoc_ssid.ssid_length 1766 || memcmp(competitor->network.ssid.ssid, mlme->assoc_ssid.ssid, mlme->assoc_ssid.ssid_length) 1767 ) 1768 goto exit; 1769 } 1770 1771 if (!rtw_is_desired_network(adapter, competitor)) 1772 goto exit; 1773 1774 if (rtw_to_roam(adapter) > 0) { 1775 if (jiffies_to_msecs(jiffies - competitor->last_scanned) >= 1776 mlme->roam_scanr_exp_ms || 1777 !is_same_ess(&competitor->network, &mlme->cur_network.network)) 1778 goto exit; 1779 } 1780 1781 if (!*candidate || (*candidate)->network.rssi < competitor->network.rssi) { 1782 *candidate = competitor; 1783 updated = true; 1784 } 1785 1786 exit: 1787 return updated; 1788 } 1789 1790 /* 1791 * Calling context: 1792 * The caller of the sub-routine will be in critical section... 1793 * The caller must hold the following spinlock 1794 * pmlmepriv->lock 1795 */ 1796 1797 int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv) 1798 { 1799 int ret; 1800 struct list_head *phead; 1801 struct adapter *adapter; 1802 struct __queue *queue = &pmlmepriv->scanned_queue; 1803 struct wlan_network *pnetwork = NULL; 1804 struct wlan_network *candidate = NULL; 1805 1806 adapter = (struct adapter *)pmlmepriv->nic_hdl; 1807 1808 spin_lock_bh(&pmlmepriv->scanned_queue.lock); 1809 1810 if (pmlmepriv->roam_network) { 1811 candidate = pmlmepriv->roam_network; 1812 pmlmepriv->roam_network = NULL; 1813 goto candidate_exist; 1814 } 1815 1816 phead = get_list_head(queue); 1817 list_for_each(pmlmepriv->pscanned, phead) { 1818 pnetwork = list_entry(pmlmepriv->pscanned, 1819 struct wlan_network, list); 1820 1821 rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork); 1822 } 1823 1824 if (!candidate) { 1825 ret = _FAIL; 1826 goto exit; 1827 } else { 1828 goto candidate_exist; 1829 } 1830 1831 candidate_exist: 1832 1833 /* check for situation of _FW_LINKED */ 1834 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 1835 rtw_disassoc_cmd(adapter, 0, true); 1836 rtw_indicate_disconnect(adapter); 1837 rtw_free_assoc_resources(adapter, 0); 1838 } 1839 1840 set_fwstate(pmlmepriv, _FW_UNDER_LINKING); 1841 ret = rtw_joinbss_cmd(adapter, candidate); 1842 1843 exit: 1844 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1845 return ret; 1846 } 1847 1848 signed int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv) 1849 { 1850 struct cmd_obj *pcmd; 1851 struct setauth_parm *psetauthparm; 1852 struct cmd_priv *pcmdpriv = &adapter->cmdpriv; 1853 signed int res = _SUCCESS; 1854 1855 pcmd = kzalloc_obj(*pcmd); 1856 if (!pcmd) { 1857 res = _FAIL; /* try again */ 1858 goto exit; 1859 } 1860 1861 psetauthparm = kzalloc_obj(*psetauthparm); 1862 if (!psetauthparm) { 1863 kfree(pcmd); 1864 res = _FAIL; 1865 goto exit; 1866 } 1867 1868 psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm; 1869 1870 pcmd->cmdcode = _SetAuth_CMD_; 1871 pcmd->parmbuf = (unsigned char *)psetauthparm; 1872 pcmd->cmdsz = (sizeof(struct setauth_parm)); 1873 pcmd->rsp = NULL; 1874 pcmd->rspsz = 0; 1875 1876 INIT_LIST_HEAD(&pcmd->list); 1877 1878 res = rtw_enqueue_cmd(pcmdpriv, pcmd); 1879 1880 exit: 1881 return res; 1882 } 1883 1884 signed int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, signed int keyid, u8 set_tx, bool enqueue) 1885 { 1886 u8 keylen; 1887 struct cmd_obj *pcmd; 1888 struct setkey_parm *psetkeyparm; 1889 struct cmd_priv *pcmdpriv = &adapter->cmdpriv; 1890 signed int res = _SUCCESS; 1891 1892 psetkeyparm = kzalloc_obj(*psetkeyparm); 1893 if (!psetkeyparm) { 1894 res = _FAIL; 1895 goto exit; 1896 } 1897 1898 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) 1899 psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy; 1900 else 1901 psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm; 1902 1903 psetkeyparm->keyid = (u8)keyid;/* 0~3 */ 1904 psetkeyparm->set_tx = set_tx; 1905 if (is_wep_enc(psetkeyparm->algorithm)) 1906 adapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid); 1907 1908 switch (psetkeyparm->algorithm) { 1909 case _WEP40_: 1910 keylen = 5; 1911 memcpy(&psetkeyparm->key[0], &psecuritypriv->dot11DefKey[keyid].skey[0], keylen); 1912 break; 1913 case _WEP104_: 1914 keylen = 13; 1915 memcpy(&psetkeyparm->key[0], &psecuritypriv->dot11DefKey[keyid].skey[0], keylen); 1916 break; 1917 case _TKIP_: 1918 keylen = 16; 1919 memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); 1920 psetkeyparm->grpkey = 1; 1921 break; 1922 case _AES_: 1923 keylen = 16; 1924 memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); 1925 psetkeyparm->grpkey = 1; 1926 break; 1927 default: 1928 res = _FAIL; 1929 kfree(psetkeyparm); 1930 goto exit; 1931 } 1932 1933 if (enqueue) { 1934 pcmd = kzalloc_obj(*pcmd); 1935 if (!pcmd) { 1936 kfree(psetkeyparm); 1937 res = _FAIL; /* try again */ 1938 goto exit; 1939 } 1940 1941 pcmd->cmdcode = _SetKey_CMD_; 1942 pcmd->parmbuf = (u8 *)psetkeyparm; 1943 pcmd->cmdsz = (sizeof(struct setkey_parm)); 1944 pcmd->rsp = NULL; 1945 pcmd->rspsz = 0; 1946 1947 INIT_LIST_HEAD(&pcmd->list); 1948 1949 res = rtw_enqueue_cmd(pcmdpriv, pcmd); 1950 } else { 1951 setkey_hdl(adapter, (u8 *)psetkeyparm); 1952 kfree(psetkeyparm); 1953 } 1954 exit: 1955 return res; 1956 } 1957 1958 /* adjust ies for rtw_joinbss_cmd in WMM */ 1959 int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len) 1960 { 1961 unsigned int ielength = 0; 1962 unsigned int i, j; 1963 1964 i = 12; /* after the fixed IE */ 1965 while (i < in_len) { 1966 ielength = initial_out_len; 1967 1968 if (i + 5 < in_len && 1969 in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 && 1970 in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 && 1971 in_ie[i + 5] == 0x02) { 1972 for (j = i; j < i + 9; j++) { 1973 out_ie[ielength] = in_ie[j]; 1974 ielength++; 1975 } 1976 out_ie[initial_out_len + 1] = 0x07; 1977 out_ie[initial_out_len + 6] = 0x00; 1978 out_ie[initial_out_len + 8] = 0x00; 1979 1980 break; 1981 } 1982 1983 i += (in_ie[i + 1] + 2); /* to the next IE element */ 1984 } 1985 1986 return ielength; 1987 } 1988 1989 /* Ported from 8185: IsInPreAuthKeyList(). 1990 * (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) 1991 * Added by Annie, 2006-05-07. 1992 * 1993 * Search by BSSID, 1994 * 1995 * Return Value: 1996 * -1: if there is no pre-auth key in the table 1997 * >=0: if there is pre-auth key, and return the entry id 1998 */ 1999 static int SecIsInPMKIDList(struct adapter *Adapter, u8 *bssid) 2000 { 2001 struct security_priv *p = &Adapter->securitypriv; 2002 int i; 2003 2004 for (i = 0; i < NUM_PMKID_CACHE; i++) 2005 if ((p->PMKIDList[i].bUsed) && 2006 (!memcmp(p->PMKIDList[i].Bssid, bssid, ETH_ALEN))) 2007 return i; 2008 return -1; 2009 } 2010 2011 /* */ 2012 /* Check the RSN IE length */ 2013 /* If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */ 2014 /* 0-11th element in the array are the fixed IE */ 2015 /* 12th element in the array is the IE */ 2016 /* 13th element in the array is the IE length */ 2017 /* */ 2018 2019 static int rtw_append_pmkid(struct adapter *Adapter, int iEntry, u8 *ie, uint ie_len) 2020 { 2021 struct security_priv *psecuritypriv = &Adapter->securitypriv; 2022 2023 if (ie[13] <= 20) { 2024 /* The RSN IE didn't include the PMK ID, append the PMK information */ 2025 ie[ie_len] = 1; 2026 ie_len++; 2027 ie[ie_len] = 0; /* PMKID count = 0x0100 */ 2028 ie_len++; 2029 memcpy(&ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16); 2030 ie_len += 16; 2031 ie[13] += 18;/* PMKID length = 2+16 */ 2032 } 2033 return ie_len; 2034 } 2035 2036 static void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie) 2037 { 2038 uint len; 2039 u8 *buff, *p; 2040 union iwreq_data wrqu; 2041 2042 buff = NULL; 2043 if (authmode == WLAN_EID_VENDOR_SPECIFIC) { 2044 buff = kzalloc(IW_CUSTOM_MAX, GFP_ATOMIC); 2045 if (!buff) 2046 return; 2047 2048 p = buff; 2049 2050 p += scnprintf(p, IW_CUSTOM_MAX - (p - buff), "ASSOCINFO(ReqIEs ="); 2051 2052 len = sec_ie[1] + 2; 2053 len = (len < IW_CUSTOM_MAX) ? len : IW_CUSTOM_MAX; 2054 2055 p += scnprintf(p, IW_CUSTOM_MAX - (p - buff), " %*ph", len, sec_ie); 2056 2057 p += scnprintf(p, IW_CUSTOM_MAX - (p - buff), ")"); 2058 2059 memset(&wrqu, 0, sizeof(wrqu)); 2060 2061 wrqu.data.length = p - buff; 2062 2063 wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ? wrqu.data.length : IW_CUSTOM_MAX; 2064 2065 kfree(buff); 2066 } 2067 } 2068 2069 signed int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len) 2070 { 2071 u8 authmode = 0x0; 2072 uint ielength; 2073 int iEntry; 2074 2075 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 2076 struct security_priv *psecuritypriv = &adapter->securitypriv; 2077 uint ndisauthmode = psecuritypriv->ndisauthtype; 2078 2079 /* copy fixed ie only */ 2080 memcpy(out_ie, in_ie, 12); 2081 ielength = 12; 2082 if ((ndisauthmode == Ndis802_11AuthModeWPA) || (ndisauthmode == Ndis802_11AuthModeWPAPSK)) 2083 authmode = WLAN_EID_VENDOR_SPECIFIC; 2084 if ((ndisauthmode == Ndis802_11AuthModeWPA2) || (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) 2085 authmode = WLAN_EID_RSN; 2086 2087 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { 2088 memcpy(out_ie + ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len); 2089 2090 ielength += psecuritypriv->wps_ie_len; 2091 } else if ((authmode == WLAN_EID_VENDOR_SPECIFIC) || (authmode == WLAN_EID_RSN)) { 2092 /* copy RSN or SSN */ 2093 memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1] + 2); 2094 ielength += psecuritypriv->supplicant_ie[1] + 2; 2095 rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie); 2096 } 2097 2098 iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid); 2099 if (iEntry < 0) 2100 return ielength; 2101 2102 if (authmode == WLAN_EID_RSN) 2103 ielength = rtw_append_pmkid(adapter, iEntry, out_ie, ielength); 2104 2105 return ielength; 2106 } 2107 2108 void rtw_init_registrypriv_dev_network(struct adapter *adapter) 2109 { 2110 struct registry_priv *pregistrypriv = &adapter->registrypriv; 2111 struct eeprom_priv *peepriv = &adapter->eeprompriv; 2112 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; 2113 u8 *myhwaddr = myid(peepriv); 2114 2115 memcpy(pdev_network->mac_address, myhwaddr, ETH_ALEN); 2116 2117 memcpy(&pdev_network->ssid, &pregistrypriv->ssid, sizeof(struct ndis_802_11_ssid)); 2118 2119 pdev_network->configuration.length = sizeof(struct ndis_802_11_conf); 2120 pdev_network->configuration.beacon_period = 100; 2121 } 2122 2123 void rtw_update_registrypriv_dev_network(struct adapter *adapter) 2124 { 2125 int sz = 0; 2126 struct registry_priv *pregistrypriv = &adapter->registrypriv; 2127 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; 2128 struct security_priv *psecuritypriv = &adapter->securitypriv; 2129 struct wlan_network *cur_network = &adapter->mlmepriv.cur_network; 2130 2131 pdev_network->privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0) ; /* adhoc no 802.1x */ 2132 2133 pdev_network->rssi = 0; 2134 2135 switch (pregistrypriv->wireless_mode) { 2136 case WIRELESS_11B: 2137 pdev_network->network_type_in_use = (Ndis802_11DS); 2138 break; 2139 case WIRELESS_11G: 2140 case WIRELESS_11BG: 2141 case WIRELESS_11_24N: 2142 case WIRELESS_11G_24N: 2143 case WIRELESS_11BG_24N: 2144 pdev_network->network_type_in_use = (Ndis802_11OFDM24); 2145 break; 2146 default: 2147 /* TODO */ 2148 break; 2149 } 2150 2151 pdev_network->configuration.ds_config = (pregistrypriv->channel); 2152 2153 if (cur_network->network.infrastructure_mode == Ndis802_11IBSS) 2154 pdev_network->configuration.atim_window = (0); 2155 2156 pdev_network->infrastructure_mode = (cur_network->network.infrastructure_mode); 2157 2158 /* 1. Supported rates */ 2159 /* 2. IE */ 2160 2161 /* rtw_set_supported_rate(pdev_network->supported_rates, pregistrypriv->wireless_mode) ; will be called in rtw_generate_ie */ 2162 sz = rtw_generate_ie(pregistrypriv); 2163 2164 pdev_network->ie_length = sz; 2165 2166 pdev_network->length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network); 2167 2168 /* notes: translate ie_length & length after assign the length to cmdsz in createbss_cmd(); */ 2169 /* pdev_network->ie_length = cpu_to_le32(sz); */ 2170 } 2171 2172 /* the function is at passive_level */ 2173 void rtw_joinbss_reset(struct adapter *padapter) 2174 { 2175 u8 threshold; 2176 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2177 2178 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 2179 2180 /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */ 2181 2182 pmlmepriv->num_FortyMHzIntolerant = 0; 2183 2184 pmlmepriv->num_sta_no_ht = 0; 2185 2186 phtpriv->ampdu_enable = false;/* reset to disabled */ 2187 2188 /* TH = 1 => means that invalidate usb rx aggregation */ 2189 /* TH = 0 => means that validate usb rx aggregation, use init value. */ 2190 if (phtpriv->ht_option) { 2191 if (padapter->registrypriv.wifi_spec == 1) 2192 threshold = 1; 2193 else 2194 threshold = 0; 2195 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); 2196 } else { 2197 threshold = 1; 2198 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); 2199 } 2200 } 2201 2202 void rtw_ht_use_default_setting(struct adapter *padapter) 2203 { 2204 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2205 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 2206 struct registry_priv *pregistrypriv = &padapter->registrypriv; 2207 bool bHwLDPCSupport = false, bHwSTBCSupport = false; 2208 bool bHwSupportBeamformer = false, bHwSupportBeamformee = false; 2209 2210 if (pregistrypriv->wifi_spec) 2211 phtpriv->bss_coexist = 1; 2212 else 2213 phtpriv->bss_coexist = 0; 2214 2215 phtpriv->sgi_40m = TEST_FLAG(pregistrypriv->short_gi, BIT(1)) ? true : false; 2216 phtpriv->sgi_20m = TEST_FLAG(pregistrypriv->short_gi, BIT(0)) ? true : false; 2217 2218 /* LDPC support */ 2219 rtw_hal_get_def_var(padapter, HAL_DEF_RX_LDPC, (u8 *)&bHwLDPCSupport); 2220 CLEAR_FLAGS(phtpriv->ldpc_cap); 2221 if (bHwLDPCSupport) { 2222 if (TEST_FLAG(pregistrypriv->ldpc_cap, BIT(4))) 2223 SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX); 2224 } 2225 rtw_hal_get_def_var(padapter, HAL_DEF_TX_LDPC, (u8 *)&bHwLDPCSupport); 2226 if (bHwLDPCSupport) { 2227 if (TEST_FLAG(pregistrypriv->ldpc_cap, BIT(5))) 2228 SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX); 2229 } 2230 2231 /* STBC */ 2232 rtw_hal_get_def_var(padapter, HAL_DEF_TX_STBC, (u8 *)&bHwSTBCSupport); 2233 CLEAR_FLAGS(phtpriv->stbc_cap); 2234 if (bHwSTBCSupport) { 2235 if (TEST_FLAG(pregistrypriv->stbc_cap, BIT(5))) 2236 SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX); 2237 } 2238 rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)&bHwSTBCSupport); 2239 if (bHwSTBCSupport) { 2240 if (TEST_FLAG(pregistrypriv->stbc_cap, BIT(4))) 2241 SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX); 2242 } 2243 2244 /* Beamforming setting */ 2245 rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer); 2246 rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&bHwSupportBeamformee); 2247 CLEAR_FLAGS(phtpriv->beamform_cap); 2248 if (TEST_FLAG(pregistrypriv->beamform_cap, BIT(4)) && bHwSupportBeamformer) 2249 SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE); 2250 2251 if (TEST_FLAG(pregistrypriv->beamform_cap, BIT(5)) && bHwSupportBeamformee) 2252 SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE); 2253 } 2254 2255 void rtw_build_wmm_ie_ht(struct adapter *padapter, u8 *out_ie, uint *pout_len) 2256 { 2257 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; 2258 int out_len; 2259 2260 if (padapter->mlmepriv.qospriv.qos_option == 0) { 2261 out_len = *pout_len; 2262 rtw_set_ie(out_ie + out_len, WLAN_EID_VENDOR_SPECIFIC, 2263 _WMM_IE_Length_, WMM_IE, pout_len); 2264 2265 padapter->mlmepriv.qospriv.qos_option = 1; 2266 } 2267 } 2268 2269 /* the function is >= passive_level */ 2270 unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel) 2271 { 2272 u32 ielen, out_len; 2273 enum ieee80211_max_ampdu_length_exp max_rx_ampdu_factor; 2274 unsigned char *p; 2275 struct ieee80211_ht_cap ht_capie; 2276 u8 cbw40_enable = 0, stbc_rx_enable = 0, operation_bw = 0; 2277 struct registry_priv *pregistrypriv = &padapter->registrypriv; 2278 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2279 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 2280 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 2281 2282 phtpriv->ht_option = false; 2283 2284 out_len = *pout_len; 2285 2286 memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap)); 2287 2288 ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_DSSSCCK40); 2289 2290 if (phtpriv->sgi_20m) 2291 ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SGI_20); 2292 2293 /* Get HT BW */ 2294 if (!in_ie) { 2295 /* TDLS: TODO 20/40 issue */ 2296 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 2297 operation_bw = padapter->mlmeextpriv.cur_bwmode; 2298 if (operation_bw > CHANNEL_WIDTH_40) 2299 operation_bw = CHANNEL_WIDTH_40; 2300 } else { 2301 /* TDLS: TODO 40? */ 2302 operation_bw = CHANNEL_WIDTH_40; 2303 } 2304 } else { 2305 p = rtw_get_ie(in_ie, WLAN_EID_HT_OPERATION, &ielen, in_len); 2306 if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) { 2307 struct HT_info_element *pht_info = (struct HT_info_element *)(p + 2); 2308 2309 if (pht_info->infos[0] & BIT(2)) { 2310 switch (pht_info->infos[0] & 0x3) { 2311 case 1: 2312 case 3: 2313 operation_bw = CHANNEL_WIDTH_40; 2314 break; 2315 default: 2316 operation_bw = CHANNEL_WIDTH_20; 2317 break; 2318 } 2319 } else { 2320 operation_bw = CHANNEL_WIDTH_20; 2321 } 2322 } 2323 } 2324 2325 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */ 2326 if ((pregistrypriv->bw_mode & 0x0f) > 0) 2327 cbw40_enable = 1; 2328 2329 if ((cbw40_enable == 1) && (operation_bw == CHANNEL_WIDTH_40)) { 2330 ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH); 2331 if (phtpriv->sgi_40m) 2332 ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SGI_40); 2333 } 2334 2335 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX)) 2336 ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_TX_STBC); 2337 2338 /* todo: disable SM power save mode */ 2339 ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SM_PS); 2340 2341 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) { 2342 if ((channel <= 14 && pregistrypriv->rx_stbc == 0x1) || /* enable for 2.4GHz */ 2343 (pregistrypriv->wifi_spec == 1)) 2344 stbc_rx_enable = 1; 2345 } 2346 2347 /* fill default supported_mcs_set */ 2348 memcpy(&ht_capie.mcs, pmlmeext->default_supported_mcs_set, 16); 2349 2350 /* update default supported_mcs_set */ 2351 if (stbc_rx_enable) 2352 ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_RX_STBC_1R);/* RX STBC One spatial stream */ 2353 2354 set_mcs_rate_by_mask(ht_capie.mcs.rx_mask, MCS_RATE_1R); 2355 2356 { 2357 u32 rx_packet_offset, max_recvbuf_sz; 2358 2359 rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset); 2360 rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz); 2361 } 2362 2363 if (padapter->driver_rx_ampdu_factor != 0xFF) 2364 max_rx_ampdu_factor = 2365 (enum ieee80211_max_ampdu_length_exp)padapter->driver_rx_ampdu_factor; 2366 else 2367 rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, 2368 &max_rx_ampdu_factor); 2369 2370 ht_capie.ampdu_params_info = (max_rx_ampdu_factor & 0x03); 2371 2372 if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) 2373 ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (0x07 << 2)); 2374 else 2375 ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00); 2376 2377 rtw_set_ie(out_ie + out_len, WLAN_EID_HT_CAPABILITY, 2378 sizeof(struct ieee80211_ht_cap), (unsigned char *)&ht_capie, pout_len); 2379 2380 phtpriv->ht_option = true; 2381 2382 if (in_ie) { 2383 p = rtw_get_ie(in_ie, WLAN_EID_HT_OPERATION, &ielen, in_len); 2384 if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) { 2385 out_len = *pout_len; 2386 rtw_set_ie(out_ie + out_len, WLAN_EID_HT_OPERATION, ielen, p + 2, pout_len); 2387 } 2388 } 2389 2390 return phtpriv->ht_option; 2391 } 2392 2393 /* the function is > passive_level (in critical_section) */ 2394 void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len, u8 channel) 2395 { 2396 u8 *p, max_ampdu_sz; 2397 int len; 2398 struct ieee80211_ht_cap *pht_capie; 2399 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2400 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 2401 struct registry_priv *pregistrypriv = &padapter->registrypriv; 2402 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 2403 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 2404 u8 cbw40_enable = 0; 2405 2406 if (!phtpriv->ht_option) 2407 return; 2408 2409 if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable)) 2410 return; 2411 2412 /* maybe needs check if ap supports rx ampdu. */ 2413 if (!(phtpriv->ampdu_enable) && pregistrypriv->ampdu_enable == 1) 2414 phtpriv->ampdu_enable = true; 2415 2416 /* check Max Rx A-MPDU Size */ 2417 len = 0; 2418 p = rtw_get_ie(pie + sizeof(struct ndis_802_11_fix_ie), WLAN_EID_HT_CAPABILITY, &len, ie_len - sizeof(struct ndis_802_11_fix_ie)); 2419 if (p && len > 0) { 2420 pht_capie = (struct ieee80211_ht_cap *)(p + 2); 2421 max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR); 2422 max_ampdu_sz = 1 << (max_ampdu_sz + 3); /* max_ampdu_sz (kbytes); */ 2423 2424 phtpriv->rx_ampdu_maxlen = max_ampdu_sz; 2425 } 2426 2427 len = 0; 2428 p = rtw_get_ie(pie + sizeof(struct ndis_802_11_fix_ie), WLAN_EID_HT_OPERATION, &len, ie_len - sizeof(struct ndis_802_11_fix_ie)); 2429 if (p && len > 0) { 2430 /* todo: */ 2431 } 2432 2433 if ((pregistrypriv->bw_mode & 0x0f) > 0) 2434 cbw40_enable = 1; 2435 2436 /* update cur_bwmode & cur_ch_offset */ 2437 if ((cbw40_enable) && 2438 (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & 2439 BIT(1)) && (pmlmeinfo->HT_info.infos[0] & BIT(2))) { 2440 int i; 2441 2442 /* update the MCS set */ 2443 for (i = 0; i < 16; i++) 2444 pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i]; 2445 2446 /* update the MCS rates */ 2447 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R); 2448 2449 /* switch to the 40M Hz mode according to the AP */ 2450 /* pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; */ 2451 switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) { 2452 case EXTCHNL_OFFSET_UPPER: 2453 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; 2454 break; 2455 2456 case EXTCHNL_OFFSET_LOWER: 2457 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; 2458 break; 2459 2460 default: 2461 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 2462 break; 2463 } 2464 } 2465 2466 /* */ 2467 /* Config SM Power Save setting */ 2468 /* */ 2469 pmlmeinfo->SM_PS = 2470 (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & 2471 0x0C) >> 2; 2472 2473 /* */ 2474 /* Config current HT Protection mode. */ 2475 /* */ 2476 pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3; 2477 } 2478 2479 void rtw_issue_addbareq_cmd(struct adapter *padapter, struct xmit_frame *pxmitframe) 2480 { 2481 u8 issued; 2482 int priority; 2483 struct sta_info *psta; 2484 struct ht_priv *phtpriv; 2485 struct pkt_attrib *pattrib = &pxmitframe->attrib; 2486 s32 bmcst = is_multicast_ether_addr(pattrib->ra); 2487 2488 if (bmcst || (padapter->mlmepriv.link_detect_info.num_tx_ok_in_period < 100)) 2489 return; 2490 2491 priority = pattrib->priority; 2492 2493 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); 2494 if (pattrib->psta != psta) 2495 return; 2496 2497 if (!psta) 2498 return; 2499 2500 if (!(psta->state & _FW_LINKED)) 2501 return; 2502 2503 phtpriv = &psta->htpriv; 2504 2505 if (phtpriv->ht_option && phtpriv->ampdu_enable) { 2506 issued = (phtpriv->agg_enable_bitmap >> priority) & 0x1; 2507 issued |= (phtpriv->candidate_tid_bitmap >> priority) & 0x1; 2508 2509 if (issued == 0) { 2510 psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority); 2511 rtw_addbareq_cmd(padapter, (u8) priority, pattrib->ra); 2512 } 2513 } 2514 } 2515 2516 void rtw_append_exented_cap(struct adapter *padapter, u8 *out_ie, uint *pout_len) 2517 { 2518 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2519 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 2520 u8 cap_content[8] = {0}; 2521 2522 if (phtpriv->bss_coexist) 2523 SET_EXT_CAPABILITY_ELE_BSS_COEXIST(cap_content, 1); 2524 2525 rtw_set_ie(out_ie + *pout_len, WLAN_EID_EXT_CAPABILITY, 8, cap_content, pout_len); 2526 } 2527 2528 inline void rtw_set_to_roam(struct adapter *adapter, u8 to_roam) 2529 { 2530 if (to_roam == 0) 2531 adapter->mlmepriv.to_join = false; 2532 adapter->mlmepriv.to_roam = to_roam; 2533 } 2534 2535 inline u8 rtw_dec_to_roam(struct adapter *adapter) 2536 { 2537 adapter->mlmepriv.to_roam--; 2538 return adapter->mlmepriv.to_roam; 2539 } 2540 2541 inline u8 rtw_to_roam(struct adapter *adapter) 2542 { 2543 return adapter->mlmepriv.to_roam; 2544 } 2545 2546 void rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network) 2547 { 2548 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2549 2550 spin_lock_bh(&pmlmepriv->lock); 2551 _rtw_roaming(padapter, tgt_network); 2552 spin_unlock_bh(&pmlmepriv->lock); 2553 } 2554 2555 void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network) 2556 { 2557 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2558 struct wlan_network *cur_network = &pmlmepriv->cur_network; 2559 2560 if (rtw_to_roam(padapter) > 0) { 2561 memcpy(&pmlmepriv->assoc_ssid, &cur_network->network.ssid, sizeof(struct ndis_802_11_ssid)); 2562 2563 pmlmepriv->assoc_by_bssid = false; 2564 2565 while (rtw_do_join(padapter) != _SUCCESS) { 2566 rtw_dec_to_roam(padapter); 2567 if (rtw_to_roam(padapter) <= 0) { 2568 rtw_indicate_disconnect(padapter); 2569 break; 2570 } 2571 } 2572 } 2573 } 2574 2575 bool rtw_linked_check(struct adapter *padapter) 2576 { 2577 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) || 2578 check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) { 2579 if (padapter->stapriv.asoc_sta_count > 2) 2580 return true; 2581 } else { /* Station mode */ 2582 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) 2583 return true; 2584 } 2585 return false; 2586 } 2587