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