rtl871x_mlme.c (52041B)
1// SPDX-License-Identifier: GPL-2.0 2/****************************************************************************** 3 * rtl871x_mlme.c 4 * 5 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. 6 * Linux device driver for RTL8192SU 7 * 8 * Modifications for inclusion into the Linux staging tree are 9 * Copyright(c) 2010 Larry Finger. All rights reserved. 10 * 11 * Contact information: 12 * WLAN FAE <wlanfae@realtek.com> 13 * Larry Finger <Larry.Finger@lwfinger.net> 14 * 15 ******************************************************************************/ 16 17#define _RTL871X_MLME_C_ 18 19#include <linux/etherdevice.h> 20 21#include "osdep_service.h" 22#include "drv_types.h" 23#include "recv_osdep.h" 24#include "xmit_osdep.h" 25#include "mlme_osdep.h" 26#include "sta_info.h" 27#include "wifi.h" 28#include "wlan_bssdef.h" 29 30static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len); 31 32int r8712_init_mlme_priv(struct _adapter *padapter) 33{ 34 sint i; 35 u8 *pbuf; 36 struct wlan_network *pnetwork; 37 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 38 39 memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv)); 40 pmlmepriv->nic_hdl = (u8 *)padapter; 41 pmlmepriv->pscanned = NULL; 42 pmlmepriv->fw_state = 0; 43 pmlmepriv->cur_network.network.InfrastructureMode = 44 Ndis802_11AutoUnknown; 45 /* Maybe someday we should rename this variable to "active_mode"(Jeff)*/ 46 pmlmepriv->passive_mode = 1; /* 1: active, 0: passive. */ 47 spin_lock_init(&(pmlmepriv->lock)); 48 spin_lock_init(&(pmlmepriv->lock2)); 49 _init_queue(&(pmlmepriv->free_bss_pool)); 50 _init_queue(&(pmlmepriv->scanned_queue)); 51 set_scanned_network_val(pmlmepriv, 0); 52 memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid)); 53 pbuf = kmalloc_array(MAX_BSS_CNT, sizeof(struct wlan_network), 54 GFP_ATOMIC); 55 if (!pbuf) 56 return -ENOMEM; 57 pmlmepriv->free_bss_buf = pbuf; 58 pnetwork = (struct wlan_network *)pbuf; 59 for (i = 0; i < MAX_BSS_CNT; i++) { 60 INIT_LIST_HEAD(&(pnetwork->list)); 61 list_add_tail(&(pnetwork->list), 62 &(pmlmepriv->free_bss_pool.queue)); 63 pnetwork++; 64 } 65 pmlmepriv->sitesurveyctrl.last_rx_pkts = 0; 66 pmlmepriv->sitesurveyctrl.last_tx_pkts = 0; 67 pmlmepriv->sitesurveyctrl.traffic_busy = false; 68 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ 69 r8712_init_mlme_timer(padapter); 70 return 0; 71} 72 73struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv) 74{ 75 unsigned long irqL; 76 struct wlan_network *pnetwork; 77 struct __queue *free_queue = &pmlmepriv->free_bss_pool; 78 79 spin_lock_irqsave(&free_queue->lock, irqL); 80 pnetwork = list_first_entry_or_null(&free_queue->queue, 81 struct wlan_network, list); 82 if (pnetwork) { 83 list_del_init(&pnetwork->list); 84 pnetwork->last_scanned = jiffies; 85 pmlmepriv->num_of_scanned++; 86 } 87 spin_unlock_irqrestore(&free_queue->lock, irqL); 88 return pnetwork; 89} 90 91static void _free_network(struct mlme_priv *pmlmepriv, 92 struct wlan_network *pnetwork) 93{ 94 u32 curr_time, delta_time; 95 unsigned long irqL; 96 struct __queue *free_queue = &(pmlmepriv->free_bss_pool); 97 98 if (!pnetwork) 99 return; 100 if (pnetwork->fixed) 101 return; 102 curr_time = jiffies; 103 delta_time = (curr_time - (u32)pnetwork->last_scanned) / HZ; 104 if (delta_time < SCANQUEUE_LIFETIME) 105 return; 106 spin_lock_irqsave(&free_queue->lock, irqL); 107 list_del_init(&pnetwork->list); 108 list_add_tail(&pnetwork->list, &free_queue->queue); 109 pmlmepriv->num_of_scanned--; 110 spin_unlock_irqrestore(&free_queue->lock, irqL); 111} 112 113static void free_network_nolock(struct mlme_priv *pmlmepriv, 114 struct wlan_network *pnetwork) 115{ 116 struct __queue *free_queue = &pmlmepriv->free_bss_pool; 117 118 if (!pnetwork) 119 return; 120 if (pnetwork->fixed) 121 return; 122 list_del_init(&pnetwork->list); 123 list_add_tail(&pnetwork->list, &free_queue->queue); 124 pmlmepriv->num_of_scanned--; 125} 126 127/* return the wlan_network with the matching addr 128 * Shall be called under atomic context... 129 * to avoid possible racing condition... 130 */ 131static struct wlan_network *r8712_find_network(struct __queue *scanned_queue, 132 u8 *addr) 133{ 134 unsigned long irqL; 135 struct list_head *phead, *plist; 136 struct wlan_network *pnetwork = NULL; 137 138 if (is_zero_ether_addr(addr)) 139 return NULL; 140 spin_lock_irqsave(&scanned_queue->lock, irqL); 141 phead = &scanned_queue->queue; 142 list_for_each(plist, phead) { 143 pnetwork = list_entry(plist, struct wlan_network, list); 144 if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN)) 145 break; 146 } 147 if (plist == phead) 148 pnetwork = NULL; 149 spin_unlock_irqrestore(&scanned_queue->lock, irqL); 150 return pnetwork; 151} 152 153void r8712_free_network_queue(struct _adapter *padapter) 154{ 155 unsigned long irqL; 156 struct list_head *phead, *plist; 157 struct wlan_network *pnetwork; 158 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 159 struct __queue *scanned_queue = &pmlmepriv->scanned_queue; 160 161 spin_lock_irqsave(&scanned_queue->lock, irqL); 162 phead = &scanned_queue->queue; 163 plist = phead->next; 164 while (!end_of_queue_search(phead, plist)) { 165 pnetwork = container_of(plist, struct wlan_network, list); 166 plist = plist->next; 167 _free_network(pmlmepriv, pnetwork); 168 } 169 spin_unlock_irqrestore(&scanned_queue->lock, irqL); 170} 171 172sint r8712_if_up(struct _adapter *padapter) 173{ 174 sint res; 175 176 if (padapter->driver_stopped || padapter->surprise_removed || 177 !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { 178 res = false; 179 } else { 180 res = true; 181 } 182 return res; 183} 184 185void r8712_generate_random_ibss(u8 *pibss) 186{ 187 u32 curtime = jiffies; 188 189 pibss[0] = 0x02; /*in ad-hoc mode bit1 must set to 1 */ 190 pibss[1] = 0x11; 191 pibss[2] = 0x87; 192 pibss[3] = (u8)(curtime & 0xff); 193 pibss[4] = (u8)((curtime >> 8) & 0xff); 194 pibss[5] = (u8)((curtime >> 16) & 0xff); 195} 196 197uint r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss) 198{ 199 return sizeof(*bss) + bss->IELength - MAX_IE_SZ; 200} 201 202u8 *r8712_get_capability_from_ie(u8 *ie) 203{ 204 return ie + 8 + 2; 205} 206 207void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv) 208{ 209 kfree(pmlmepriv->free_bss_buf); 210} 211 212static struct wlan_network *alloc_network(struct mlme_priv *pmlmepriv) 213{ 214 return _r8712_alloc_network(pmlmepriv); 215} 216 217int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork) 218{ 219 int ret = true; 220 struct security_priv *psecuritypriv = &adapter->securitypriv; 221 222 if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) && 223 (pnetwork->network.Privacy == cpu_to_le32(0))) 224 ret = false; 225 else if ((psecuritypriv->PrivacyAlgrthm == _NO_PRIVACY_) && 226 (pnetwork->network.Privacy == cpu_to_le32(1))) 227 ret = false; 228 else 229 ret = true; 230 return ret; 231 232} 233 234static int is_same_network(struct wlan_bssid_ex *src, 235 struct wlan_bssid_ex *dst) 236{ 237 u16 s_cap, d_cap; 238 239 memcpy((u8 *)&s_cap, r8712_get_capability_from_ie(src->IEs), 2); 240 memcpy((u8 *)&d_cap, r8712_get_capability_from_ie(dst->IEs), 2); 241 return (src->Ssid.SsidLength == dst->Ssid.SsidLength) && 242 (src->Configuration.DSConfig == 243 dst->Configuration.DSConfig) && 244 ((!memcmp(src->MacAddress, dst->MacAddress, 245 ETH_ALEN))) && 246 ((!memcmp(src->Ssid.Ssid, 247 dst->Ssid.Ssid, 248 src->Ssid.SsidLength))) && 249 ((s_cap & WLAN_CAPABILITY_IBSS) == 250 (d_cap & WLAN_CAPABILITY_IBSS)) && 251 ((s_cap & WLAN_CAPABILITY_ESS) == 252 (d_cap & WLAN_CAPABILITY_ESS)); 253 254} 255 256struct wlan_network *r8712_get_oldest_wlan_network( 257 struct __queue *scanned_queue) 258{ 259 struct list_head *plist, *phead; 260 struct wlan_network *pwlan = NULL; 261 struct wlan_network *oldest = NULL; 262 263 phead = &scanned_queue->queue; 264 plist = phead->next; 265 while (1) { 266 if (end_of_queue_search(phead, plist)) 267 break; 268 pwlan = container_of(plist, struct wlan_network, list); 269 if (!pwlan->fixed) { 270 if (!oldest || 271 time_after((unsigned long)oldest->last_scanned, 272 (unsigned long)pwlan->last_scanned)) 273 oldest = pwlan; 274 } 275 plist = plist->next; 276 } 277 return oldest; 278} 279 280static void update_network(struct wlan_bssid_ex *dst, 281 struct wlan_bssid_ex *src, 282 struct _adapter *padapter) 283{ 284 u32 last_evm = 0, tmpVal; 285 struct smooth_rssi_data *sqd = &padapter->recvpriv.signal_qual_data; 286 287 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && 288 is_same_network(&(padapter->mlmepriv.cur_network.network), src)) { 289 if (padapter->recvpriv.signal_qual_data.total_num++ >= 290 PHY_LINKQUALITY_SLID_WIN_MAX) { 291 padapter->recvpriv.signal_qual_data.total_num = 292 PHY_LINKQUALITY_SLID_WIN_MAX; 293 last_evm = sqd->elements[sqd->index]; 294 padapter->recvpriv.signal_qual_data.total_val -= 295 last_evm; 296 } 297 padapter->recvpriv.signal_qual_data.total_val += src->Rssi; 298 299 sqd->elements[sqd->index++] = src->Rssi; 300 if (padapter->recvpriv.signal_qual_data.index >= 301 PHY_LINKQUALITY_SLID_WIN_MAX) 302 padapter->recvpriv.signal_qual_data.index = 0; 303 /* <1> Showed on UI for user, in percentage. */ 304 tmpVal = padapter->recvpriv.signal_qual_data.total_val / 305 padapter->recvpriv.signal_qual_data.total_num; 306 padapter->recvpriv.signal = (u8)tmpVal; 307 308 src->Rssi = padapter->recvpriv.signal; 309 } else { 310 src->Rssi = (src->Rssi + dst->Rssi) / 2; 311 } 312 memcpy((u8 *)dst, (u8 *)src, r8712_get_wlan_bssid_ex_sz(src)); 313} 314 315static void update_current_network(struct _adapter *adapter, 316 struct wlan_bssid_ex *pnetwork) 317{ 318 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 319 320 if (is_same_network(&(pmlmepriv->cur_network.network), pnetwork)) { 321 update_network(&(pmlmepriv->cur_network.network), 322 pnetwork, adapter); 323 r8712_update_protection(adapter, 324 (pmlmepriv->cur_network.network.IEs) + 325 sizeof(struct NDIS_802_11_FIXED_IEs), 326 pmlmepriv->cur_network.network.IELength); 327 } 328} 329 330/* Caller must hold pmlmepriv->lock first */ 331static void update_scanned_network(struct _adapter *adapter, 332 struct wlan_bssid_ex *target) 333{ 334 struct list_head *plist, *phead; 335 336 u32 bssid_ex_sz; 337 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 338 struct __queue *queue = &pmlmepriv->scanned_queue; 339 struct wlan_network *pnetwork = NULL; 340 struct wlan_network *oldest = NULL; 341 342 phead = &queue->queue; 343 plist = phead->next; 344 345 while (1) { 346 if (end_of_queue_search(phead, plist)) 347 break; 348 349 pnetwork = container_of(plist, struct wlan_network, list); 350 if (is_same_network(&pnetwork->network, target)) 351 break; 352 if ((oldest == ((struct wlan_network *)0)) || 353 time_after((unsigned long)oldest->last_scanned, 354 (unsigned long)pnetwork->last_scanned)) 355 oldest = pnetwork; 356 357 plist = plist->next; 358 } 359 360 /* If we didn't find a match, then get a new network slot to initialize 361 * with this beacon's information 362 */ 363 if (end_of_queue_search(phead, plist)) { 364 if (list_empty(&pmlmepriv->free_bss_pool.queue)) { 365 /* If there are no more slots, expire the oldest */ 366 pnetwork = oldest; 367 target->Rssi = (pnetwork->network.Rssi + 368 target->Rssi) / 2; 369 memcpy(&pnetwork->network, target, 370 r8712_get_wlan_bssid_ex_sz(target)); 371 pnetwork->last_scanned = jiffies; 372 } else { 373 /* Otherwise just pull from the free list */ 374 /* update scan_time */ 375 pnetwork = alloc_network(pmlmepriv); 376 if (!pnetwork) 377 return; 378 bssid_ex_sz = r8712_get_wlan_bssid_ex_sz(target); 379 target->Length = bssid_ex_sz; 380 memcpy(&pnetwork->network, target, bssid_ex_sz); 381 list_add_tail(&pnetwork->list, &queue->queue); 382 } 383 } else { 384 /* we have an entry and we are going to update it. But 385 * this entry may be already expired. In this case we 386 * do the same as we found a new net and call the new_net 387 * handler 388 */ 389 update_network(&pnetwork->network, target, adapter); 390 pnetwork->last_scanned = jiffies; 391 } 392} 393 394static void rtl8711_add_network(struct _adapter *adapter, 395 struct wlan_bssid_ex *pnetwork) 396{ 397 unsigned long irqL; 398 struct mlme_priv *pmlmepriv = &(((struct _adapter *)adapter)->mlmepriv); 399 struct __queue *queue = &pmlmepriv->scanned_queue; 400 401 spin_lock_irqsave(&queue->lock, irqL); 402 update_current_network(adapter, pnetwork); 403 update_scanned_network(adapter, pnetwork); 404 spin_unlock_irqrestore(&queue->lock, irqL); 405} 406 407/*select the desired network based on the capability of the (i)bss. 408 * check items: (1) security 409 * (2) network_type 410 * (3) WMM 411 * (4) HT 412 * (5) others 413 */ 414static int is_desired_network(struct _adapter *adapter, 415 struct wlan_network *pnetwork) 416{ 417 u8 wps_ie[512]; 418 uint wps_ielen; 419 int bselected = true; 420 struct security_priv *psecuritypriv = &adapter->securitypriv; 421 422 if (psecuritypriv->wps_phase) { 423 if (r8712_get_wps_ie(pnetwork->network.IEs, 424 pnetwork->network.IELength, wps_ie, 425 &wps_ielen)) 426 return true; 427 return false; 428 } 429 if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) && 430 (pnetwork->network.Privacy == 0)) 431 bselected = false; 432 if (check_fwstate(&adapter->mlmepriv, WIFI_ADHOC_STATE)) { 433 if (pnetwork->network.InfrastructureMode != 434 adapter->mlmepriv.cur_network.network.InfrastructureMode) 435 bselected = false; 436 } 437 return bselected; 438} 439 440/* TODO: Perry : For Power Management */ 441void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf) 442{ 443} 444 445void r8712_survey_event_callback(struct _adapter *adapter, u8 *pbuf) 446{ 447 unsigned long flags; 448 u32 len; 449 struct wlan_bssid_ex *pnetwork; 450 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 451 452 pnetwork = (struct wlan_bssid_ex *)pbuf; 453#ifdef __BIG_ENDIAN 454 /* endian_convert */ 455 pnetwork->Length = le32_to_cpu(pnetwork->Length); 456 pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength); 457 pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy); 458 pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi); 459 pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse); 460 pnetwork->Configuration.ATIMWindow = 461 le32_to_cpu(pnetwork->Configuration.ATIMWindow); 462 pnetwork->Configuration.BeaconPeriod = 463 le32_to_cpu(pnetwork->Configuration.BeaconPeriod); 464 pnetwork->Configuration.DSConfig = 465 le32_to_cpu(pnetwork->Configuration.DSConfig); 466 pnetwork->Configuration.FHConfig.DwellTime = 467 le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime); 468 pnetwork->Configuration.FHConfig.HopPattern = 469 le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern); 470 pnetwork->Configuration.FHConfig.HopSet = 471 le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet); 472 pnetwork->Configuration.FHConfig.Length = 473 le32_to_cpu(pnetwork->Configuration.FHConfig.Length); 474 pnetwork->Configuration.Length = 475 le32_to_cpu(pnetwork->Configuration.Length); 476 pnetwork->InfrastructureMode = 477 le32_to_cpu(pnetwork->InfrastructureMode); 478 pnetwork->IELength = le32_to_cpu(pnetwork->IELength); 479#endif 480 len = r8712_get_wlan_bssid_ex_sz(pnetwork); 481 if (len > sizeof(struct wlan_bssid_ex)) 482 return; 483 spin_lock_irqsave(&pmlmepriv->lock2, flags); 484 /* update IBSS_network 's timestamp */ 485 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { 486 if (!memcmp(&(pmlmepriv->cur_network.network.MacAddress), 487 pnetwork->MacAddress, ETH_ALEN)) { 488 struct wlan_network *ibss_wlan = NULL; 489 490 memcpy(pmlmepriv->cur_network.network.IEs, 491 pnetwork->IEs, 8); 492 ibss_wlan = r8712_find_network( 493 &pmlmepriv->scanned_queue, 494 pnetwork->MacAddress); 495 if (ibss_wlan) { 496 memcpy(ibss_wlan->network.IEs, 497 pnetwork->IEs, 8); 498 goto exit; 499 } 500 } 501 } 502 /* lock pmlmepriv->lock when you accessing network_q */ 503 if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { 504 if (pnetwork->Ssid.Ssid[0] != 0) { 505 rtl8711_add_network(adapter, pnetwork); 506 } else { 507 pnetwork->Ssid.SsidLength = 8; 508 memcpy(pnetwork->Ssid.Ssid, "<hidden>", 8); 509 rtl8711_add_network(adapter, pnetwork); 510 } 511 } 512exit: 513 spin_unlock_irqrestore(&pmlmepriv->lock2, flags); 514} 515 516void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf) 517{ 518 unsigned long irqL; 519 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 520 521 spin_lock_irqsave(&pmlmepriv->lock, irqL); 522 523 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { 524 del_timer(&pmlmepriv->scan_to_timer); 525 526 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); 527 } 528 529 if (pmlmepriv->to_join) { 530 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 531 if (!check_fwstate(pmlmepriv, _FW_LINKED)) { 532 set_fwstate(pmlmepriv, _FW_UNDER_LINKING); 533 534 if (!r8712_select_and_join_from_scan(pmlmepriv)) { 535 mod_timer(&pmlmepriv->assoc_timer, jiffies + 536 msecs_to_jiffies(MAX_JOIN_TIMEOUT)); 537 } else { 538 struct wlan_bssid_ex *pdev_network = 539 &(adapter->registrypriv.dev_network); 540 u8 *pibss = 541 adapter->registrypriv.dev_network.MacAddress; 542 pmlmepriv->fw_state ^= _FW_UNDER_SURVEY; 543 memcpy(&pdev_network->Ssid, 544 &pmlmepriv->assoc_ssid, 545 sizeof(struct 546 ndis_802_11_ssid)); 547 r8712_update_registrypriv_dev_network 548 (adapter); 549 r8712_generate_random_ibss(pibss); 550 pmlmepriv->fw_state = 551 WIFI_ADHOC_MASTER_STATE; 552 pmlmepriv->to_join = false; 553 } 554 } 555 } else { 556 pmlmepriv->to_join = false; 557 set_fwstate(pmlmepriv, _FW_UNDER_LINKING); 558 if (!r8712_select_and_join_from_scan(pmlmepriv)) 559 mod_timer(&pmlmepriv->assoc_timer, jiffies + 560 msecs_to_jiffies(MAX_JOIN_TIMEOUT)); 561 else 562 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 563 } 564 } 565 spin_unlock_irqrestore(&pmlmepriv->lock, irqL); 566} 567 568/* 569 *r8712_free_assoc_resources: the caller has to lock pmlmepriv->lock 570 */ 571void r8712_free_assoc_resources(struct _adapter *adapter) 572{ 573 unsigned long irqL; 574 struct wlan_network *pwlan = NULL; 575 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 576 struct sta_priv *pstapriv = &adapter->stapriv; 577 struct wlan_network *tgt_network = &pmlmepriv->cur_network; 578 579 pwlan = r8712_find_network(&pmlmepriv->scanned_queue, 580 tgt_network->network.MacAddress); 581 582 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) { 583 struct sta_info *psta; 584 585 psta = r8712_get_stainfo(&adapter->stapriv, 586 tgt_network->network.MacAddress); 587 588 spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); 589 r8712_free_stainfo(adapter, psta); 590 spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); 591 } 592 593 if (check_fwstate(pmlmepriv, 594 WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) 595 r8712_free_all_stainfo(adapter); 596 if (pwlan) 597 pwlan->fixed = false; 598 599 if (((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) && 600 (adapter->stapriv.asoc_sta_count == 1))) 601 free_network_nolock(pmlmepriv, pwlan); 602} 603 604/* 605 * r8712_indicate_connect: the caller has to lock pmlmepriv->lock 606 */ 607void r8712_indicate_connect(struct _adapter *padapter) 608{ 609 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 610 611 pmlmepriv->to_join = false; 612 set_fwstate(pmlmepriv, _FW_LINKED); 613 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_LINK); 614 r8712_os_indicate_connect(padapter); 615 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) 616 mod_timer(&pmlmepriv->dhcp_timer, 617 jiffies + msecs_to_jiffies(60000)); 618} 619 620/* 621 * r8712_ind_disconnect: the caller has to lock pmlmepriv->lock 622 */ 623void r8712_ind_disconnect(struct _adapter *padapter) 624{ 625 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 626 627 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 628 _clr_fwstate_(pmlmepriv, _FW_LINKED); 629 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK); 630 r8712_os_indicate_disconnect(padapter); 631 } 632 if (padapter->pwrctrlpriv.pwr_mode != 633 padapter->registrypriv.power_mgnt) { 634 del_timer(&pmlmepriv->dhcp_timer); 635 r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt, 636 padapter->registrypriv.smart_ps); 637 } 638} 639 640/*Notes: 641 *pnetwork : returns from r8712_joinbss_event_callback 642 *ptarget_wlan: found from scanned_queue 643 *if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if 644 * "ptarget_sta" & "ptarget_wlan" exist. 645 *if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check 646 * if "ptarget_wlan" exist. 647 *if join_res > 0, update "cur_network->network" from 648 * "pnetwork->network" if (ptarget_wlan !=NULL). 649 */ 650void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf) 651{ 652 unsigned long irqL = 0, irqL2; 653 struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL; 654 struct sta_priv *pstapriv = &adapter->stapriv; 655 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 656 struct wlan_network *cur_network = &pmlmepriv->cur_network; 657 struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL; 658 unsigned int the_same_macaddr = false; 659 struct wlan_network *pnetwork; 660 661 if (sizeof(struct list_head) == 4 * sizeof(u32)) { 662 pnetwork = kmalloc(sizeof(struct wlan_network), GFP_ATOMIC); 663 if (!pnetwork) 664 return; 665 memcpy((u8 *)pnetwork + 16, (u8 *)pbuf + 8, 666 sizeof(struct wlan_network) - 16); 667 } else { 668 pnetwork = (struct wlan_network *)pbuf; 669 } 670 671#ifdef __BIG_ENDIAN 672 /* endian_convert */ 673 pnetwork->join_res = le32_to_cpu(pnetwork->join_res); 674 pnetwork->network_type = le32_to_cpu(pnetwork->network_type); 675 pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length); 676 pnetwork->network.Ssid.SsidLength = 677 le32_to_cpu(pnetwork->network.Ssid.SsidLength); 678 pnetwork->network.Privacy = le32_to_cpu(pnetwork->network.Privacy); 679 pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi); 680 pnetwork->network.NetworkTypeInUse = 681 le32_to_cpu(pnetwork->network.NetworkTypeInUse); 682 pnetwork->network.Configuration.ATIMWindow = 683 le32_to_cpu(pnetwork->network.Configuration.ATIMWindow); 684 pnetwork->network.Configuration.BeaconPeriod = 685 le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod); 686 pnetwork->network.Configuration.DSConfig = 687 le32_to_cpu(pnetwork->network.Configuration.DSConfig); 688 pnetwork->network.Configuration.FHConfig.DwellTime = 689 le32_to_cpu(pnetwork->network.Configuration.FHConfig.DwellTime); 690 pnetwork->network.Configuration.FHConfig.HopPattern = 691 le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopPattern); 692 pnetwork->network.Configuration.FHConfig.HopSet = 693 le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet); 694 pnetwork->network.Configuration.FHConfig.Length = 695 le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length); 696 pnetwork->network.Configuration.Length = 697 le32_to_cpu(pnetwork->network.Configuration.Length); 698 pnetwork->network.InfrastructureMode = 699 le32_to_cpu(pnetwork->network.InfrastructureMode); 700 pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength); 701#endif 702 703 the_same_macaddr = !memcmp(pnetwork->network.MacAddress, 704 cur_network->network.MacAddress, ETH_ALEN); 705 pnetwork->network.Length = 706 r8712_get_wlan_bssid_ex_sz(&pnetwork->network); 707 spin_lock_irqsave(&pmlmepriv->lock, irqL); 708 if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) 709 goto ignore_joinbss_callback; 710 if (pnetwork->join_res > 0) { 711 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { 712 /*s1. find ptarget_wlan*/ 713 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 714 if (the_same_macaddr) { 715 ptarget_wlan = 716 r8712_find_network(&pmlmepriv->scanned_queue, 717 cur_network->network.MacAddress); 718 } else { 719 pcur_wlan = 720 r8712_find_network(&pmlmepriv->scanned_queue, 721 cur_network->network.MacAddress); 722 if (pcur_wlan) 723 pcur_wlan->fixed = false; 724 725 pcur_sta = r8712_get_stainfo(pstapriv, 726 cur_network->network.MacAddress); 727 spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL2); 728 r8712_free_stainfo(adapter, pcur_sta); 729 spin_unlock_irqrestore(&(pstapriv->sta_hash_lock), irqL2); 730 731 ptarget_wlan = 732 r8712_find_network(&pmlmepriv->scanned_queue, 733 pnetwork->network.MacAddress); 734 if (ptarget_wlan) 735 ptarget_wlan->fixed = true; 736 } 737 } else { 738 ptarget_wlan = r8712_find_network(&pmlmepriv->scanned_queue, 739 pnetwork->network.MacAddress); 740 if (ptarget_wlan) 741 ptarget_wlan->fixed = true; 742 } 743 744 if (!ptarget_wlan) { 745 if (check_fwstate(pmlmepriv, 746 _FW_UNDER_LINKING)) 747 pmlmepriv->fw_state ^= 748 _FW_UNDER_LINKING; 749 goto ignore_joinbss_callback; 750 } 751 752 /*s2. find ptarget_sta & update ptarget_sta*/ 753 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 754 if (the_same_macaddr) { 755 ptarget_sta = 756 r8712_get_stainfo(pstapriv, 757 pnetwork->network.MacAddress); 758 if (!ptarget_sta) 759 ptarget_sta = 760 r8712_alloc_stainfo(pstapriv, 761 pnetwork->network.MacAddress); 762 } else { 763 ptarget_sta = 764 r8712_alloc_stainfo(pstapriv, 765 pnetwork->network.MacAddress); 766 } 767 if (ptarget_sta) /*update ptarget_sta*/ { 768 ptarget_sta->aid = pnetwork->join_res; 769 ptarget_sta->qos_option = 1; 770 ptarget_sta->mac_id = 5; 771 if (adapter->securitypriv.AuthAlgrthm == 2) { 772 adapter->securitypriv.binstallGrpkey = false; 773 adapter->securitypriv.busetkipkey = false; 774 adapter->securitypriv.bgrpkey_handshake = false; 775 ptarget_sta->ieee8021x_blocked = true; 776 ptarget_sta->XPrivacy = adapter-> 777 securitypriv.PrivacyAlgrthm; 778 memset((u8 *)&ptarget_sta->x_UncstKey, 779 0, 780 sizeof(union Keytype)); 781 memset((u8 *)&ptarget_sta->tkiprxmickey, 782 0, 783 sizeof(union Keytype)); 784 memset((u8 *)&ptarget_sta->tkiptxmickey, 785 0, 786 sizeof(union Keytype)); 787 memset((u8 *)&ptarget_sta->txpn, 0, 788 sizeof(union pn48)); 789 memset((u8 *)&ptarget_sta->rxpn, 0, 790 sizeof(union pn48)); 791 } 792 } else { 793 if (check_fwstate(pmlmepriv, 794 _FW_UNDER_LINKING)) 795 pmlmepriv->fw_state ^= 796 _FW_UNDER_LINKING; 797 goto ignore_joinbss_callback; 798 } 799 } 800 801 /*s3. update cur_network & indicate connect*/ 802 memcpy(&cur_network->network, &pnetwork->network, 803 pnetwork->network.Length); 804 cur_network->aid = pnetwork->join_res; 805 /*update fw_state will clr _FW_UNDER_LINKING*/ 806 switch (pnetwork->network.InfrastructureMode) { 807 case Ndis802_11Infrastructure: 808 pmlmepriv->fw_state = WIFI_STATION_STATE; 809 break; 810 case Ndis802_11IBSS: 811 pmlmepriv->fw_state = WIFI_ADHOC_STATE; 812 break; 813 default: 814 pmlmepriv->fw_state = WIFI_NULL_STATE; 815 break; 816 } 817 r8712_update_protection(adapter, 818 (cur_network->network.IEs) + 819 sizeof(struct NDIS_802_11_FIXED_IEs), 820 (cur_network->network.IELength)); 821 /*TODO: update HT_Capability*/ 822 update_ht_cap(adapter, cur_network->network.IEs, 823 cur_network->network.IELength); 824 /*indicate connect*/ 825 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) 826 r8712_indicate_connect(adapter); 827 del_timer(&pmlmepriv->assoc_timer); 828 } else { 829 goto ignore_joinbss_callback; 830 } 831 } else { 832 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { 833 mod_timer(&pmlmepriv->assoc_timer, 834 jiffies + msecs_to_jiffies(1)); 835 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 836 } 837 } 838ignore_joinbss_callback: 839 spin_unlock_irqrestore(&pmlmepriv->lock, irqL); 840 if (sizeof(struct list_head) == 4 * sizeof(u32)) 841 kfree(pnetwork); 842} 843 844void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf) 845{ 846 unsigned long irqL; 847 struct sta_info *psta; 848 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); 849 struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf; 850 851 /* to do: */ 852 if (!r8712_access_ctrl(&adapter->acl_list, pstassoc->macaddr)) 853 return; 854 psta = r8712_get_stainfo(&adapter->stapriv, pstassoc->macaddr); 855 if (psta) { 856 /*the sta have been in sta_info_queue => do nothing 857 *(between drv has received this event before and 858 * fw have not yet to set key to CAM_ENTRY) 859 */ 860 return; 861 } 862 863 psta = r8712_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr); 864 if (!psta) 865 return; 866 /* to do : init sta_info variable */ 867 psta->qos_option = 0; 868 psta->mac_id = le32_to_cpu(pstassoc->cam_id); 869 /* psta->aid = (uint)pstassoc->cam_id; */ 870 871 if (adapter->securitypriv.AuthAlgrthm == 2) 872 psta->XPrivacy = adapter->securitypriv.PrivacyAlgrthm; 873 psta->ieee8021x_blocked = false; 874 spin_lock_irqsave(&pmlmepriv->lock, irqL); 875 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || 876 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 877 if (adapter->stapriv.asoc_sta_count == 2) { 878 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */ 879 r8712_indicate_connect(adapter); 880 } 881 } 882 spin_unlock_irqrestore(&pmlmepriv->lock, irqL); 883} 884 885void r8712_stadel_event_callback(struct _adapter *adapter, u8 *pbuf) 886{ 887 unsigned long irqL, irqL2; 888 struct sta_info *psta; 889 struct wlan_network *pwlan = NULL; 890 struct wlan_bssid_ex *pdev_network = NULL; 891 u8 *pibss = NULL; 892 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 893 struct stadel_event *pstadel = (struct stadel_event *)pbuf; 894 struct sta_priv *pstapriv = &adapter->stapriv; 895 struct wlan_network *tgt_network = &pmlmepriv->cur_network; 896 897 spin_lock_irqsave(&pmlmepriv->lock, irqL2); 898 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 899 r8712_ind_disconnect(adapter); 900 r8712_free_assoc_resources(adapter); 901 } 902 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | 903 WIFI_ADHOC_STATE)) { 904 psta = r8712_get_stainfo(&adapter->stapriv, pstadel->macaddr); 905 spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); 906 r8712_free_stainfo(adapter, psta); 907 spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); 908 if (adapter->stapriv.asoc_sta_count == 1) { 909 /*a sta + bc/mc_stainfo (not Ibss_stainfo) */ 910 pwlan = r8712_find_network(&pmlmepriv->scanned_queue, 911 tgt_network->network.MacAddress); 912 if (pwlan) { 913 pwlan->fixed = false; 914 free_network_nolock(pmlmepriv, pwlan); 915 } 916 /*re-create ibss*/ 917 pdev_network = &(adapter->registrypriv.dev_network); 918 pibss = adapter->registrypriv.dev_network.MacAddress; 919 memcpy(pdev_network, &tgt_network->network, 920 r8712_get_wlan_bssid_ex_sz(&tgt_network->network)); 921 memcpy(&pdev_network->Ssid, 922 &pmlmepriv->assoc_ssid, 923 sizeof(struct ndis_802_11_ssid)); 924 r8712_update_registrypriv_dev_network(adapter); 925 r8712_generate_random_ibss(pibss); 926 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 927 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE); 928 set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE); 929 } 930 } 931 } 932 spin_unlock_irqrestore(&pmlmepriv->lock, irqL2); 933} 934 935void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf) 936{ 937 struct reportpwrstate_parm *preportpwrstate = 938 (struct reportpwrstate_parm *)pbuf; 939 940 preportpwrstate->state |= (u8)(adapter->pwrctrlpriv.cpwm_tog + 0x80); 941 r8712_cpwm_int_hdl(adapter, preportpwrstate); 942} 943 944/* When the Netgear 3500 AP is with WPA2PSK-AES mode, it will send 945 * the ADDBA req frame with start seq control = 0 to wifi client after 946 * the WPA handshake and the seqence number of following data packet 947 * will be 0. In this case, the Rx reorder sequence is not longer than 0 948 * and the WiFi client will drop the data with seq number 0. 949 * So, the 8712 firmware has to inform driver with receiving the 950 * ADDBA-Req frame so that the driver can reset the 951 * sequence value of Rx reorder control. 952 */ 953void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf) 954{ 955 struct ADDBA_Req_Report_parm *pAddbareq_pram = 956 (struct ADDBA_Req_Report_parm *)pbuf; 957 struct sta_info *psta; 958 struct sta_priv *pstapriv = &adapter->stapriv; 959 struct recv_reorder_ctrl *precvreorder_ctrl = NULL; 960 961 psta = r8712_get_stainfo(pstapriv, pAddbareq_pram->MacAddress); 962 if (psta) { 963 precvreorder_ctrl = 964 &psta->recvreorder_ctrl[pAddbareq_pram->tid]; 965 /* set the indicate_seq to 0xffff so that the rx reorder 966 * can store any following data packet. 967 */ 968 precvreorder_ctrl->indicate_seq = 0xffff; 969 } 970} 971 972void r8712_wpspbc_event_callback(struct _adapter *adapter, u8 *pbuf) 973{ 974 if (!adapter->securitypriv.wps_hw_pbc_pressed) 975 adapter->securitypriv.wps_hw_pbc_pressed = true; 976} 977 978void _r8712_sitesurvey_ctrl_handler(struct _adapter *adapter) 979{ 980 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 981 struct sitesurvey_ctrl *psitesurveyctrl = &pmlmepriv->sitesurveyctrl; 982 struct registry_priv *pregistrypriv = &adapter->registrypriv; 983 u64 current_tx_pkts; 984 uint current_rx_pkts; 985 986 current_tx_pkts = (adapter->xmitpriv.tx_pkts) - 987 (psitesurveyctrl->last_tx_pkts); 988 current_rx_pkts = (adapter->recvpriv.rx_pkts) - 989 (psitesurveyctrl->last_rx_pkts); 990 psitesurveyctrl->last_tx_pkts = adapter->xmitpriv.tx_pkts; 991 psitesurveyctrl->last_rx_pkts = adapter->recvpriv.rx_pkts; 992 if ((current_tx_pkts > pregistrypriv->busy_thresh) || 993 (current_rx_pkts > pregistrypriv->busy_thresh)) 994 psitesurveyctrl->traffic_busy = true; 995 else 996 psitesurveyctrl->traffic_busy = false; 997} 998 999void _r8712_join_timeout_handler(struct _adapter *adapter) 1000{ 1001 unsigned long irqL; 1002 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1003 1004 if (adapter->driver_stopped || adapter->surprise_removed) 1005 return; 1006 spin_lock_irqsave(&pmlmepriv->lock, irqL); 1007 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 1008 pmlmepriv->to_join = false; 1009 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 1010 r8712_os_indicate_disconnect(adapter); 1011 _clr_fwstate_(pmlmepriv, _FW_LINKED); 1012 } 1013 if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt) { 1014 r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt, 1015 adapter->registrypriv.smart_ps); 1016 } 1017 spin_unlock_irqrestore(&pmlmepriv->lock, irqL); 1018} 1019 1020void r8712_scan_timeout_handler (struct _adapter *adapter) 1021{ 1022 unsigned long irqL; 1023 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1024 1025 spin_lock_irqsave(&pmlmepriv->lock, irqL); 1026 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); 1027 pmlmepriv->to_join = false; /* scan fail, so clear to_join flag */ 1028 spin_unlock_irqrestore(&pmlmepriv->lock, irqL); 1029} 1030 1031void _r8712_dhcp_timeout_handler (struct _adapter *adapter) 1032{ 1033 if (adapter->driver_stopped || adapter->surprise_removed) 1034 return; 1035 if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt) 1036 r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt, 1037 adapter->registrypriv.smart_ps); 1038} 1039 1040int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv) 1041{ 1042 struct list_head *phead; 1043 unsigned char *dst_ssid, *src_ssid; 1044 struct _adapter *adapter; 1045 struct __queue *queue = NULL; 1046 struct wlan_network *pnetwork = NULL; 1047 struct wlan_network *pnetwork_max_rssi = NULL; 1048 1049 adapter = (struct _adapter *)pmlmepriv->nic_hdl; 1050 queue = &pmlmepriv->scanned_queue; 1051 phead = &queue->queue; 1052 pmlmepriv->pscanned = phead->next; 1053 while (1) { 1054 if (end_of_queue_search(phead, pmlmepriv->pscanned)) { 1055 if (pmlmepriv->assoc_by_rssi && pnetwork_max_rssi) { 1056 pnetwork = pnetwork_max_rssi; 1057 goto ask_for_joinbss; 1058 } 1059 return -EINVAL; 1060 } 1061 pnetwork = container_of(pmlmepriv->pscanned, 1062 struct wlan_network, list); 1063 pmlmepriv->pscanned = pmlmepriv->pscanned->next; 1064 if (pmlmepriv->assoc_by_bssid) { 1065 dst_ssid = pnetwork->network.MacAddress; 1066 src_ssid = pmlmepriv->assoc_bssid; 1067 if (!memcmp(dst_ssid, src_ssid, ETH_ALEN)) { 1068 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 1069 if (is_same_network(&pmlmepriv->cur_network.network, 1070 &pnetwork->network)) { 1071 _clr_fwstate_(pmlmepriv, 1072 _FW_UNDER_LINKING); 1073 /*r8712_indicate_connect again*/ 1074 r8712_indicate_connect(adapter); 1075 return 2; 1076 } 1077 r8712_disassoc_cmd(adapter); 1078 r8712_ind_disconnect(adapter); 1079 r8712_free_assoc_resources(adapter); 1080 } 1081 goto ask_for_joinbss; 1082 } 1083 } else if (pmlmepriv->assoc_ssid.SsidLength == 0) { 1084 goto ask_for_joinbss; 1085 } 1086 dst_ssid = pnetwork->network.Ssid.Ssid; 1087 src_ssid = pmlmepriv->assoc_ssid.Ssid; 1088 if ((pnetwork->network.Ssid.SsidLength == 1089 pmlmepriv->assoc_ssid.SsidLength) && 1090 (!memcmp(dst_ssid, src_ssid, 1091 pmlmepriv->assoc_ssid.SsidLength))) { 1092 if (pmlmepriv->assoc_by_rssi) { 1093 /* if the ssid is the same, select the bss 1094 * which has the max rssi 1095 */ 1096 if (pnetwork_max_rssi) { 1097 if (pnetwork->network.Rssi > 1098 pnetwork_max_rssi->network.Rssi) 1099 pnetwork_max_rssi = pnetwork; 1100 } else { 1101 pnetwork_max_rssi = pnetwork; 1102 } 1103 } else if (is_desired_network(adapter, pnetwork)) { 1104 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 1105 r8712_disassoc_cmd(adapter); 1106 r8712_free_assoc_resources(adapter); 1107 } 1108 goto ask_for_joinbss; 1109 } 1110 } 1111 } 1112 1113ask_for_joinbss: 1114 return r8712_joinbss_cmd(adapter, pnetwork); 1115} 1116 1117int r8712_set_auth(struct _adapter *adapter, 1118 struct security_priv *psecuritypriv) 1119{ 1120 struct cmd_priv *pcmdpriv = &adapter->cmdpriv; 1121 struct cmd_obj *pcmd; 1122 struct setauth_parm *psetauthparm; 1123 1124 pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); 1125 if (!pcmd) 1126 return -ENOMEM; 1127 1128 psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC); 1129 if (!psetauthparm) { 1130 kfree(pcmd); 1131 return -ENOMEM; 1132 } 1133 psetauthparm->mode = (u8)psecuritypriv->AuthAlgrthm; 1134 pcmd->cmdcode = _SetAuth_CMD_; 1135 pcmd->parmbuf = (unsigned char *)psetauthparm; 1136 pcmd->cmdsz = sizeof(struct setauth_parm); 1137 pcmd->rsp = NULL; 1138 pcmd->rspsz = 0; 1139 INIT_LIST_HEAD(&pcmd->list); 1140 r8712_enqueue_cmd(pcmdpriv, pcmd); 1141 return 0; 1142} 1143 1144int r8712_set_key(struct _adapter *adapter, 1145 struct security_priv *psecuritypriv, 1146 sint keyid) 1147{ 1148 struct cmd_priv *pcmdpriv = &adapter->cmdpriv; 1149 struct cmd_obj *pcmd; 1150 struct setkey_parm *psetkeyparm; 1151 u8 keylen; 1152 int ret; 1153 1154 pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); 1155 if (!pcmd) 1156 return -ENOMEM; 1157 psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_ATOMIC); 1158 if (!psetkeyparm) { 1159 ret = -ENOMEM; 1160 goto err_free_cmd; 1161 } 1162 if (psecuritypriv->AuthAlgrthm == 2) { /* 802.1X */ 1163 psetkeyparm->algorithm = 1164 (u8)psecuritypriv->XGrpPrivacy; 1165 } else { /* WEP */ 1166 psetkeyparm->algorithm = 1167 (u8)psecuritypriv->PrivacyAlgrthm; 1168 } 1169 psetkeyparm->keyid = (u8)keyid; 1170 1171 switch (psetkeyparm->algorithm) { 1172 case _WEP40_: 1173 keylen = 5; 1174 memcpy(psetkeyparm->key, 1175 psecuritypriv->DefKey[keyid].skey, keylen); 1176 break; 1177 case _WEP104_: 1178 keylen = 13; 1179 memcpy(psetkeyparm->key, 1180 psecuritypriv->DefKey[keyid].skey, keylen); 1181 break; 1182 case _TKIP_: 1183 if (keyid < 1 || keyid > 2) { 1184 ret = -EINVAL; 1185 goto err_free_parm; 1186 } 1187 keylen = 16; 1188 memcpy(psetkeyparm->key, 1189 &psecuritypriv->XGrpKey[keyid - 1], keylen); 1190 psetkeyparm->grpkey = 1; 1191 break; 1192 case _AES_: 1193 if (keyid < 1 || keyid > 2) { 1194 ret = -EINVAL; 1195 goto err_free_parm; 1196 } 1197 keylen = 16; 1198 memcpy(psetkeyparm->key, 1199 &psecuritypriv->XGrpKey[keyid - 1], keylen); 1200 psetkeyparm->grpkey = 1; 1201 break; 1202 default: 1203 ret = -EINVAL; 1204 goto err_free_parm; 1205 } 1206 pcmd->cmdcode = _SetKey_CMD_; 1207 pcmd->parmbuf = (u8 *)psetkeyparm; 1208 pcmd->cmdsz = (sizeof(struct setkey_parm)); 1209 pcmd->rsp = NULL; 1210 pcmd->rspsz = 0; 1211 INIT_LIST_HEAD(&pcmd->list); 1212 r8712_enqueue_cmd(pcmdpriv, pcmd); 1213 return 0; 1214 1215err_free_parm: 1216 kfree(psetkeyparm); 1217err_free_cmd: 1218 kfree(pcmd); 1219 return ret; 1220} 1221 1222/* adjust IEs for r8712_joinbss_cmd in WMM */ 1223int r8712_restruct_wmm_ie(struct _adapter *adapter, u8 *in_ie, u8 *out_ie, 1224 uint in_len, uint initial_out_len) 1225{ 1226 unsigned int ielength = 0; 1227 unsigned int i, j; 1228 1229 i = 12; /* after the fixed IE */ 1230 while (i < in_len) { 1231 ielength = initial_out_len; 1232 if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 && 1233 in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 && 1234 in_ie[i + 5] == 0x02 && i + 5 < in_len) { 1235 /*WMM element ID and OUI*/ 1236 for (j = i; j < i + 9; j++) { 1237 out_ie[ielength] = in_ie[j]; 1238 ielength++; 1239 } 1240 out_ie[initial_out_len + 1] = 0x07; 1241 out_ie[initial_out_len + 6] = 0x00; 1242 out_ie[initial_out_len + 8] = 0x00; 1243 break; 1244 } 1245 i += (in_ie[i + 1] + 2); /* to the next IE element */ 1246 } 1247 return ielength; 1248} 1249 1250/* 1251 * Ported from 8185: IsInPreAuthKeyList(). 1252 * 1253 * Search by BSSID, 1254 * Return Value: 1255 * -1 :if there is no pre-auth key in the table 1256 * >=0 :if there is pre-auth key, and return the entry id 1257 */ 1258static int SecIsInPMKIDList(struct _adapter *Adapter, u8 *bssid) 1259{ 1260 struct security_priv *p = &Adapter->securitypriv; 1261 int i; 1262 1263 for (i = 0; i < NUM_PMKID_CACHE; i++) 1264 if (p->PMKIDList[i].bUsed && !memcmp(p->PMKIDList[i].Bssid, bssid, ETH_ALEN)) 1265 return i; 1266 return -1; 1267} 1268 1269sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie, 1270 u8 *out_ie, uint in_len) 1271{ 1272 u8 authmode = 0, match; 1273 u8 sec_ie[IW_CUSTOM_MAX], uncst_oui[4], bkup_ie[255]; 1274 u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; 1275 uint ielength, cnt, remove_cnt; 1276 int iEntry; 1277 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1278 struct security_priv *psecuritypriv = &adapter->securitypriv; 1279 uint ndisauthmode = psecuritypriv->ndisauthtype; 1280 uint ndissecuritytype = psecuritypriv->ndisencryptstatus; 1281 1282 if ((ndisauthmode == Ndis802_11AuthModeWPA) || 1283 (ndisauthmode == Ndis802_11AuthModeWPAPSK)) { 1284 authmode = _WPA_IE_ID_; 1285 uncst_oui[0] = 0x0; 1286 uncst_oui[1] = 0x50; 1287 uncst_oui[2] = 0xf2; 1288 } 1289 if ((ndisauthmode == Ndis802_11AuthModeWPA2) || 1290 (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) { 1291 authmode = _WPA2_IE_ID_; 1292 uncst_oui[0] = 0x0; 1293 uncst_oui[1] = 0x0f; 1294 uncst_oui[2] = 0xac; 1295 } 1296 switch (ndissecuritytype) { 1297 case Ndis802_11Encryption1Enabled: 1298 case Ndis802_11Encryption1KeyAbsent: 1299 uncst_oui[3] = 0x1; 1300 break; 1301 case Ndis802_11Encryption2Enabled: 1302 case Ndis802_11Encryption2KeyAbsent: 1303 uncst_oui[3] = 0x2; 1304 break; 1305 case Ndis802_11Encryption3Enabled: 1306 case Ndis802_11Encryption3KeyAbsent: 1307 uncst_oui[3] = 0x4; 1308 break; 1309 default: 1310 break; 1311 } 1312 /*Search required WPA or WPA2 IE and copy to sec_ie[] */ 1313 cnt = 12; 1314 match = false; 1315 while (cnt < in_len) { 1316 if (in_ie[cnt] == authmode) { 1317 if ((authmode == _WPA_IE_ID_) && 1318 (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) { 1319 memcpy(&sec_ie[0], &in_ie[cnt], 1320 in_ie[cnt + 1] + 2); 1321 match = true; 1322 break; 1323 } 1324 if (authmode == _WPA2_IE_ID_) { 1325 memcpy(&sec_ie[0], &in_ie[cnt], 1326 in_ie[cnt + 1] + 2); 1327 match = true; 1328 break; 1329 } 1330 if (((authmode == _WPA_IE_ID_) && 1331 (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) || 1332 (authmode == _WPA2_IE_ID_)) 1333 memcpy(&bkup_ie[0], &in_ie[cnt], 1334 in_ie[cnt + 1] + 2); 1335 } 1336 cnt += in_ie[cnt + 1] + 2; /*get next*/ 1337 } 1338 /*restruct WPA IE or WPA2 IE in sec_ie[] */ 1339 if (match) { 1340 if (sec_ie[0] == _WPA_IE_ID_) { 1341 /* parsing SSN IE to select required encryption 1342 * algorithm, and set the bc/mc encryption algorithm 1343 */ 1344 while (true) { 1345 /*check wpa_oui tag*/ 1346 if (memcmp(&sec_ie[2], &wpa_oui[0], 4)) { 1347 match = false; 1348 break; 1349 } 1350 if ((sec_ie[6] != 0x01) || (sec_ie[7] != 0x0)) { 1351 /*IE Ver error*/ 1352 match = false; 1353 break; 1354 } 1355 if (!memcmp(&sec_ie[8], &wpa_oui[0], 3)) { 1356 /* get bc/mc encryption type (group 1357 * key type) 1358 */ 1359 switch (sec_ie[11]) { 1360 case 0x0: /*none*/ 1361 psecuritypriv->XGrpPrivacy = 1362 _NO_PRIVACY_; 1363 break; 1364 case 0x1: /*WEP_40*/ 1365 psecuritypriv->XGrpPrivacy = 1366 _WEP40_; 1367 break; 1368 case 0x2: /*TKIP*/ 1369 psecuritypriv->XGrpPrivacy = 1370 _TKIP_; 1371 break; 1372 case 0x3: /*AESCCMP*/ 1373 case 0x4: 1374 psecuritypriv->XGrpPrivacy = 1375 _AES_; 1376 break; 1377 case 0x5: /*WEP_104*/ 1378 psecuritypriv->XGrpPrivacy = 1379 _WEP104_; 1380 break; 1381 } 1382 } else { 1383 match = false; 1384 break; 1385 } 1386 if (sec_ie[12] == 0x01) { 1387 /*check the unicast encryption type*/ 1388 if (memcmp(&sec_ie[14], 1389 &uncst_oui[0], 4)) { 1390 match = false; 1391 break; 1392 1393 } /*else the uncst_oui is match*/ 1394 } else { /*mixed mode, unicast_enc_type > 1*/ 1395 /*select the uncst_oui and remove 1396 * the other uncst_oui 1397 */ 1398 cnt = sec_ie[12]; 1399 remove_cnt = (cnt - 1) * 4; 1400 sec_ie[12] = 0x01; 1401 memcpy(&sec_ie[14], &uncst_oui[0], 4); 1402 /*remove the other unicast suit*/ 1403 memcpy(&sec_ie[18], 1404 &sec_ie[18 + remove_cnt], 1405 sec_ie[1] - 18 + 2 - 1406 remove_cnt); 1407 sec_ie[1] = sec_ie[1] - remove_cnt; 1408 } 1409 break; 1410 } 1411 } 1412 if (authmode == _WPA2_IE_ID_) { 1413 /* parsing RSN IE to select required encryption 1414 * algorithm, and set the bc/mc encryption algorithm 1415 */ 1416 while (true) { 1417 if ((sec_ie[2] != 0x01) || (sec_ie[3] != 0x0)) { 1418 /*IE Ver error*/ 1419 match = false; 1420 break; 1421 } 1422 if (!memcmp(&sec_ie[4], &uncst_oui[0], 3)) { 1423 /*get bc/mc encryption type*/ 1424 switch (sec_ie[7]) { 1425 case 0x1: /*WEP_40*/ 1426 psecuritypriv->XGrpPrivacy = 1427 _WEP40_; 1428 break; 1429 case 0x2: /*TKIP*/ 1430 psecuritypriv->XGrpPrivacy = 1431 _TKIP_; 1432 break; 1433 case 0x4: /*AESWRAP*/ 1434 psecuritypriv->XGrpPrivacy = 1435 _AES_; 1436 break; 1437 case 0x5: /*WEP_104*/ 1438 psecuritypriv->XGrpPrivacy = 1439 _WEP104_; 1440 break; 1441 default: /*one*/ 1442 psecuritypriv->XGrpPrivacy = 1443 _NO_PRIVACY_; 1444 break; 1445 } 1446 } else { 1447 match = false; 1448 break; 1449 } 1450 if (sec_ie[8] == 0x01) { 1451 /*check the unicast encryption type*/ 1452 if (memcmp(&sec_ie[10], 1453 &uncst_oui[0], 4)) { 1454 match = false; 1455 break; 1456 } /*else the uncst_oui is match*/ 1457 } else { /*mixed mode, unicast_enc_type > 1*/ 1458 /*select the uncst_oui and remove the 1459 * other uncst_oui 1460 */ 1461 cnt = sec_ie[8]; 1462 remove_cnt = (cnt - 1) * 4; 1463 sec_ie[8] = 0x01; 1464 memcpy(&sec_ie[10], &uncst_oui[0], 4); 1465 /*remove the other unicast suit*/ 1466 memcpy(&sec_ie[14], 1467 &sec_ie[14 + remove_cnt], 1468 (sec_ie[1] - 14 + 2 - 1469 remove_cnt)); 1470 sec_ie[1] = sec_ie[1] - remove_cnt; 1471 } 1472 break; 1473 } 1474 } 1475 } 1476 if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) { 1477 /*copy fixed ie*/ 1478 memcpy(out_ie, in_ie, 12); 1479 ielength = 12; 1480 /*copy RSN or SSN*/ 1481 if (match) { 1482 memcpy(&out_ie[ielength], &sec_ie[0], sec_ie[1] + 2); 1483 ielength += sec_ie[1] + 2; 1484 if (authmode == _WPA2_IE_ID_) { 1485 /*the Pre-Authentication bit should be zero*/ 1486 out_ie[ielength - 1] = 0; 1487 out_ie[ielength - 2] = 0; 1488 } 1489 r8712_report_sec_ie(adapter, authmode, sec_ie); 1490 } 1491 } else { 1492 /*copy fixed ie only*/ 1493 memcpy(out_ie, in_ie, 12); 1494 ielength = 12; 1495 if (psecuritypriv->wps_phase) { 1496 memcpy(out_ie + ielength, psecuritypriv->wps_ie, 1497 psecuritypriv->wps_ie_len); 1498 ielength += psecuritypriv->wps_ie_len; 1499 } 1500 } 1501 iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid); 1502 if (iEntry < 0) 1503 return ielength; 1504 if (authmode == _WPA2_IE_ID_) { 1505 out_ie[ielength] = 1; 1506 ielength++; 1507 out_ie[ielength] = 0; /*PMKID count = 0x0100*/ 1508 ielength++; 1509 memcpy(&out_ie[ielength], 1510 &psecuritypriv->PMKIDList[iEntry].PMKID, 16); 1511 ielength += 16; 1512 out_ie[13] += 18;/*PMKID length = 2+16*/ 1513 } 1514 return ielength; 1515} 1516 1517void r8712_init_registrypriv_dev_network(struct _adapter *adapter) 1518{ 1519 struct registry_priv *pregistrypriv = &adapter->registrypriv; 1520 struct eeprom_priv *peepriv = &adapter->eeprompriv; 1521 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; 1522 u8 *myhwaddr = myid(peepriv); 1523 1524 memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN); 1525 memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, 1526 sizeof(struct ndis_802_11_ssid)); 1527 pdev_network->Configuration.Length = 1528 sizeof(struct NDIS_802_11_CONFIGURATION); 1529 pdev_network->Configuration.BeaconPeriod = 100; 1530 pdev_network->Configuration.FHConfig.Length = 0; 1531 pdev_network->Configuration.FHConfig.HopPattern = 0; 1532 pdev_network->Configuration.FHConfig.HopSet = 0; 1533 pdev_network->Configuration.FHConfig.DwellTime = 0; 1534} 1535 1536void r8712_update_registrypriv_dev_network(struct _adapter *adapter) 1537{ 1538 int sz = 0; 1539 struct registry_priv *pregistrypriv = &adapter->registrypriv; 1540 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; 1541 struct security_priv *psecuritypriv = &adapter->securitypriv; 1542 struct wlan_network *cur_network = &adapter->mlmepriv.cur_network; 1543 1544 pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm 1545 > 0 ? 1 : 0); /* adhoc no 802.1x */ 1546 pdev_network->Rssi = 0; 1547 switch (pregistrypriv->wireless_mode) { 1548 case WIRELESS_11B: 1549 pdev_network->NetworkTypeInUse = Ndis802_11DS; 1550 break; 1551 case WIRELESS_11G: 1552 case WIRELESS_11BG: 1553 pdev_network->NetworkTypeInUse = Ndis802_11OFDM24; 1554 break; 1555 case WIRELESS_11A: 1556 pdev_network->NetworkTypeInUse = Ndis802_11OFDM5; 1557 break; 1558 default: 1559 /* TODO */ 1560 break; 1561 } 1562 pdev_network->Configuration.DSConfig = pregistrypriv->channel; 1563 if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) 1564 pdev_network->Configuration.ATIMWindow = 3; 1565 pdev_network->InfrastructureMode = cur_network->network.InfrastructureMode; 1566 /* 1. Supported rates 1567 * 2. IE 1568 */ 1569 sz = r8712_generate_ie(pregistrypriv); 1570 pdev_network->IELength = sz; 1571 pdev_network->Length = r8712_get_wlan_bssid_ex_sz(pdev_network); 1572} 1573 1574/*the function is at passive_level*/ 1575void r8712_joinbss_reset(struct _adapter *padapter) 1576{ 1577 int i; 1578 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1579 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 1580 1581 /* todo: if you want to do something io/reg/hw setting before join_bss, 1582 * please add code here 1583 */ 1584 phtpriv->ampdu_enable = false;/*reset to disabled*/ 1585 for (i = 0; i < 16; i++) 1586 phtpriv->baddbareq_issued[i] = false;/*reset it*/ 1587 if (phtpriv->ht_option) { 1588 /* validate usb rx aggregation */ 1589 r8712_write8(padapter, 0x102500D9, 48);/*TH = 48 pages, 6k*/ 1590 } else { 1591 /* invalidate usb rx aggregation */ 1592 /* TH=1 => means that invalidate usb rx aggregation */ 1593 r8712_write8(padapter, 0x102500D9, 1); 1594 } 1595} 1596 1597/*the function is >= passive_level*/ 1598unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, 1599 u8 *out_ie, uint in_len, uint *pout_len) 1600{ 1601 u32 ielen, out_len; 1602 unsigned char *p; 1603 struct ieee80211_ht_cap ht_capie; 1604 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; 1605 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1606 struct qos_priv *pqospriv = &pmlmepriv->qospriv; 1607 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 1608 1609 phtpriv->ht_option = 0; 1610 p = r8712_get_ie(in_ie + 12, WLAN_EID_HT_CAPABILITY, &ielen, in_len - 12); 1611 if (p && (ielen > 0)) { 1612 if (pqospriv->qos_option == 0) { 1613 out_len = *pout_len; 1614 r8712_set_ie(out_ie + out_len, WLAN_EID_VENDOR_SPECIFIC, 1615 _WMM_IE_Length_, WMM_IE, pout_len); 1616 pqospriv->qos_option = 1; 1617 } 1618 out_len = *pout_len; 1619 memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap)); 1620 ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 1621 IEEE80211_HT_CAP_SGI_20 | 1622 IEEE80211_HT_CAP_SGI_40 | 1623 IEEE80211_HT_CAP_TX_STBC | 1624 IEEE80211_HT_CAP_MAX_AMSDU | 1625 IEEE80211_HT_CAP_DSSSCCK40); 1626 ht_capie.ampdu_params_info = (IEEE80211_HT_AMPDU_PARM_FACTOR & 1627 0x03) | (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00); 1628 r8712_set_ie(out_ie + out_len, WLAN_EID_HT_CAPABILITY, 1629 sizeof(struct ieee80211_ht_cap), 1630 (unsigned char *)&ht_capie, pout_len); 1631 phtpriv->ht_option = 1; 1632 } 1633 return phtpriv->ht_option; 1634} 1635 1636/* the function is > passive_level (in critical_section) */ 1637static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len) 1638{ 1639 u8 *p, max_ampdu_sz; 1640 int i; 1641 uint len; 1642 struct sta_info *bmc_sta, *psta; 1643 struct ieee80211_ht_cap *pht_capie; 1644 struct recv_reorder_ctrl *preorder_ctrl; 1645 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1646 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 1647 struct registry_priv *pregistrypriv = &padapter->registrypriv; 1648 struct wlan_network *pcur_network = &(pmlmepriv->cur_network); 1649 1650 if (!phtpriv->ht_option) 1651 return; 1652 /* maybe needs check if ap supports rx ampdu. */ 1653 if (!phtpriv->ampdu_enable && 1654 (pregistrypriv->ampdu_enable == 1)) 1655 phtpriv->ampdu_enable = true; 1656 /*check Max Rx A-MPDU Size*/ 1657 len = 0; 1658 p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs), 1659 WLAN_EID_HT_CAPABILITY, 1660 &len, ie_len - 1661 sizeof(struct NDIS_802_11_FIXED_IEs)); 1662 if (p && len > 0) { 1663 pht_capie = (struct ieee80211_ht_cap *)(p + 2); 1664 max_ampdu_sz = (pht_capie->ampdu_params_info & 1665 IEEE80211_HT_AMPDU_PARM_FACTOR); 1666 /* max_ampdu_sz (kbytes); */ 1667 max_ampdu_sz = 1 << (max_ampdu_sz + 3); 1668 phtpriv->rx_ampdu_maxlen = max_ampdu_sz; 1669 } 1670 /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info 1671 * if A-MPDU Rx is enabled, resetting rx_ordering_ctrl 1672 * wstart_b(indicate_seq) to default value=0xffff 1673 * todo: check if AP can send A-MPDU packets 1674 */ 1675 bmc_sta = r8712_get_bcmc_stainfo(padapter); 1676 if (bmc_sta) { 1677 for (i = 0; i < 16; i++) { 1678 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; 1679 preorder_ctrl->indicate_seq = 0xffff; 1680 preorder_ctrl->wend_b = 0xffff; 1681 } 1682 } 1683 psta = r8712_get_stainfo(&padapter->stapriv, 1684 pcur_network->network.MacAddress); 1685 if (psta) { 1686 for (i = 0; i < 16; i++) { 1687 preorder_ctrl = &psta->recvreorder_ctrl[i]; 1688 preorder_ctrl->indicate_seq = 0xffff; 1689 preorder_ctrl->wend_b = 0xffff; 1690 } 1691 } 1692 len = 0; 1693 p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs), 1694 WLAN_EID_HT_OPERATION, &len, 1695 ie_len - sizeof(struct NDIS_802_11_FIXED_IEs)); 1696} 1697 1698void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority) 1699{ 1700 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1701 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 1702 1703 if ((phtpriv->ht_option == 1) && (phtpriv->ampdu_enable)) { 1704 if (!phtpriv->baddbareq_issued[priority]) { 1705 r8712_addbareq_cmd(padapter, (u8)priority); 1706 phtpriv->baddbareq_issued[priority] = true; 1707 } 1708 } 1709}