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