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