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