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 30 static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len); 31 32 int 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 73 struct 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 91 static 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 113 static 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 */ 131 static 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 153 void 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 172 sint 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 185 void 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 197 uint r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss) 198 { 199 return sizeof(*bss) + bss->IELength - MAX_IE_SZ; 200 } 201 202 u8 *r8712_get_capability_from_ie(u8 *ie) 203 { 204 return ie + 8 + 2; 205 } 206 207 void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv) 208 { 209 kfree(pmlmepriv->free_bss_buf); 210 } 211 212 static struct wlan_network *alloc_network(struct mlme_priv *pmlmepriv) 213 { 214 return _r8712_alloc_network(pmlmepriv); 215 } 216 217 int 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 234 static 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 256 struct 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 280 static 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 315 static 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 */ 331 static 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 394 static 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 */ 414 static 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. 435 InfrastructureMode) 436 bselected = false; 437 } 438 return bselected; 439 } 440 441 /* TODO: Perry : For Power Management */ 442 void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf) 443 { 444 } 445 446 void r8712_survey_event_callback(struct _adapter *adapter, u8 *pbuf) 447 { 448 unsigned long flags; 449 u32 len; 450 struct wlan_bssid_ex *pnetwork; 451 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 452 453 pnetwork = (struct wlan_bssid_ex *)pbuf; 454 #ifdef __BIG_ENDIAN 455 /* endian_convert */ 456 pnetwork->Length = le32_to_cpu(pnetwork->Length); 457 pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength); 458 pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy); 459 pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi); 460 pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse); 461 pnetwork->Configuration.ATIMWindow = 462 le32_to_cpu(pnetwork->Configuration.ATIMWindow); 463 pnetwork->Configuration.BeaconPeriod = 464 le32_to_cpu(pnetwork->Configuration.BeaconPeriod); 465 pnetwork->Configuration.DSConfig = 466 le32_to_cpu(pnetwork->Configuration.DSConfig); 467 pnetwork->Configuration.FHConfig.DwellTime = 468 le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime); 469 pnetwork->Configuration.FHConfig.HopPattern = 470 le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern); 471 pnetwork->Configuration.FHConfig.HopSet = 472 le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet); 473 pnetwork->Configuration.FHConfig.Length = 474 le32_to_cpu(pnetwork->Configuration.FHConfig.Length); 475 pnetwork->Configuration.Length = 476 le32_to_cpu(pnetwork->Configuration.Length); 477 pnetwork->InfrastructureMode = 478 le32_to_cpu(pnetwork->InfrastructureMode); 479 pnetwork->IELength = le32_to_cpu(pnetwork->IELength); 480 #endif 481 len = r8712_get_wlan_bssid_ex_sz(pnetwork); 482 if (len > sizeof(struct wlan_bssid_ex)) 483 return; 484 spin_lock_irqsave(&pmlmepriv->lock2, flags); 485 /* update IBSS_network 's timestamp */ 486 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { 487 if (!memcmp(&(pmlmepriv->cur_network.network.MacAddress), 488 pnetwork->MacAddress, ETH_ALEN)) { 489 struct wlan_network *ibss_wlan = NULL; 490 491 memcpy(pmlmepriv->cur_network.network.IEs, 492 pnetwork->IEs, 8); 493 ibss_wlan = r8712_find_network( 494 &pmlmepriv->scanned_queue, 495 pnetwork->MacAddress); 496 if (ibss_wlan) { 497 memcpy(ibss_wlan->network.IEs, 498 pnetwork->IEs, 8); 499 goto exit; 500 } 501 } 502 } 503 /* lock pmlmepriv->lock when you accessing network_q */ 504 if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { 505 if (pnetwork->Ssid.Ssid[0] != 0) { 506 rtl8711_add_network(adapter, pnetwork); 507 } else { 508 pnetwork->Ssid.SsidLength = 8; 509 memcpy(pnetwork->Ssid.Ssid, "<hidden>", 8); 510 rtl8711_add_network(adapter, pnetwork); 511 } 512 } 513 exit: 514 spin_unlock_irqrestore(&pmlmepriv->lock2, flags); 515 } 516 517 void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf) 518 { 519 unsigned long irqL; 520 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 521 522 spin_lock_irqsave(&pmlmepriv->lock, irqL); 523 524 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { 525 del_timer(&pmlmepriv->scan_to_timer); 526 527 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); 528 } 529 530 if (pmlmepriv->to_join) { 531 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 532 if (!check_fwstate(pmlmepriv, _FW_LINKED)) { 533 set_fwstate(pmlmepriv, _FW_UNDER_LINKING); 534 535 if (!r8712_select_and_join_from_scan(pmlmepriv)) { 536 mod_timer(&pmlmepriv->assoc_timer, jiffies + 537 msecs_to_jiffies(MAX_JOIN_TIMEOUT)); 538 } else { 539 struct wlan_bssid_ex *pdev_network = 540 &(adapter->registrypriv.dev_network); 541 u8 *pibss = 542 adapter->registrypriv. 543 dev_network.MacAddress; 544 pmlmepriv->fw_state ^= _FW_UNDER_SURVEY; 545 memcpy(&pdev_network->Ssid, 546 &pmlmepriv->assoc_ssid, 547 sizeof(struct 548 ndis_802_11_ssid)); 549 r8712_update_registrypriv_dev_network 550 (adapter); 551 r8712_generate_random_ibss(pibss); 552 pmlmepriv->fw_state = 553 WIFI_ADHOC_MASTER_STATE; 554 pmlmepriv->to_join = false; 555 } 556 } 557 } else { 558 pmlmepriv->to_join = false; 559 set_fwstate(pmlmepriv, _FW_UNDER_LINKING); 560 if (!r8712_select_and_join_from_scan(pmlmepriv)) 561 mod_timer(&pmlmepriv->assoc_timer, jiffies + 562 msecs_to_jiffies(MAX_JOIN_TIMEOUT)); 563 else 564 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 565 } 566 } 567 spin_unlock_irqrestore(&pmlmepriv->lock, irqL); 568 } 569 570 /* 571 *r8712_free_assoc_resources: the caller has to lock pmlmepriv->lock 572 */ 573 void r8712_free_assoc_resources(struct _adapter *adapter) 574 { 575 unsigned long irqL; 576 struct wlan_network *pwlan = NULL; 577 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 578 struct sta_priv *pstapriv = &adapter->stapriv; 579 struct wlan_network *tgt_network = &pmlmepriv->cur_network; 580 581 pwlan = r8712_find_network(&pmlmepriv->scanned_queue, 582 tgt_network->network.MacAddress); 583 584 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) { 585 struct sta_info *psta; 586 587 psta = r8712_get_stainfo(&adapter->stapriv, 588 tgt_network->network.MacAddress); 589 590 spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); 591 r8712_free_stainfo(adapter, psta); 592 spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); 593 } 594 595 if (check_fwstate(pmlmepriv, 596 WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) 597 r8712_free_all_stainfo(adapter); 598 if (pwlan) 599 pwlan->fixed = false; 600 601 if (((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) && 602 (adapter->stapriv.asoc_sta_count == 1))) 603 free_network_nolock(pmlmepriv, pwlan); 604 } 605 606 /* 607 * r8712_indicate_connect: the caller has to lock pmlmepriv->lock 608 */ 609 void r8712_indicate_connect(struct _adapter *padapter) 610 { 611 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 612 613 pmlmepriv->to_join = false; 614 set_fwstate(pmlmepriv, _FW_LINKED); 615 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_LINK); 616 r8712_os_indicate_connect(padapter); 617 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) 618 mod_timer(&pmlmepriv->dhcp_timer, 619 jiffies + msecs_to_jiffies(60000)); 620 } 621 622 /* 623 * r8712_ind_disconnect: the caller has to lock pmlmepriv->lock 624 */ 625 void r8712_ind_disconnect(struct _adapter *padapter) 626 { 627 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 628 629 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 630 _clr_fwstate_(pmlmepriv, _FW_LINKED); 631 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK); 632 r8712_os_indicate_disconnect(padapter); 633 } 634 if (padapter->pwrctrlpriv.pwr_mode != 635 padapter->registrypriv.power_mgnt) { 636 del_timer(&pmlmepriv->dhcp_timer); 637 r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt, 638 padapter->registrypriv.smart_ps); 639 } 640 } 641 642 /*Notes: 643 *pnetwork : returns from r8712_joinbss_event_callback 644 *ptarget_wlan: found from scanned_queue 645 *if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if 646 * "ptarget_sta" & "ptarget_wlan" exist. 647 *if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check 648 * if "ptarget_wlan" exist. 649 *if join_res > 0, update "cur_network->network" from 650 * "pnetwork->network" if (ptarget_wlan !=NULL). 651 */ 652 void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf) 653 { 654 unsigned long irqL = 0, irqL2; 655 struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL; 656 struct sta_priv *pstapriv = &adapter->stapriv; 657 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 658 struct wlan_network *cur_network = &pmlmepriv->cur_network; 659 struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL; 660 unsigned int the_same_macaddr = false; 661 struct wlan_network *pnetwork; 662 663 if (sizeof(struct list_head) == 4 * sizeof(u32)) { 664 pnetwork = kmalloc(sizeof(struct wlan_network), GFP_ATOMIC); 665 if (!pnetwork) 666 return; 667 memcpy((u8 *)pnetwork + 16, (u8 *)pbuf + 8, 668 sizeof(struct wlan_network) - 16); 669 } else { 670 pnetwork = (struct wlan_network *)pbuf; 671 } 672 673 #ifdef __BIG_ENDIAN 674 /* endian_convert */ 675 pnetwork->join_res = le32_to_cpu(pnetwork->join_res); 676 pnetwork->network_type = le32_to_cpu(pnetwork->network_type); 677 pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length); 678 pnetwork->network.Ssid.SsidLength = 679 le32_to_cpu(pnetwork->network.Ssid.SsidLength); 680 pnetwork->network.Privacy = le32_to_cpu(pnetwork->network.Privacy); 681 pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi); 682 pnetwork->network.NetworkTypeInUse = 683 le32_to_cpu(pnetwork->network.NetworkTypeInUse); 684 pnetwork->network.Configuration.ATIMWindow = 685 le32_to_cpu(pnetwork->network.Configuration.ATIMWindow); 686 pnetwork->network.Configuration.BeaconPeriod = 687 le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod); 688 pnetwork->network.Configuration.DSConfig = 689 le32_to_cpu(pnetwork->network.Configuration.DSConfig); 690 pnetwork->network.Configuration.FHConfig.DwellTime = 691 le32_to_cpu(pnetwork->network.Configuration.FHConfig. 692 DwellTime); 693 pnetwork->network.Configuration.FHConfig.HopPattern = 694 le32_to_cpu(pnetwork->network.Configuration. 695 FHConfig.HopPattern); 696 pnetwork->network.Configuration.FHConfig.HopSet = 697 le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet); 698 pnetwork->network.Configuration.FHConfig.Length = 699 le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length); 700 pnetwork->network.Configuration.Length = 701 le32_to_cpu(pnetwork->network.Configuration.Length); 702 pnetwork->network.InfrastructureMode = 703 le32_to_cpu(pnetwork->network.InfrastructureMode); 704 pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength); 705 #endif 706 707 the_same_macaddr = !memcmp(pnetwork->network.MacAddress, 708 cur_network->network.MacAddress, ETH_ALEN); 709 pnetwork->network.Length = 710 r8712_get_wlan_bssid_ex_sz(&pnetwork->network); 711 spin_lock_irqsave(&pmlmepriv->lock, irqL); 712 if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) 713 goto ignore_joinbss_callback; 714 if (pnetwork->join_res > 0) { 715 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { 716 /*s1. find ptarget_wlan*/ 717 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 718 if (the_same_macaddr) { 719 ptarget_wlan = 720 r8712_find_network(&pmlmepriv-> 721 scanned_queue, 722 cur_network->network.MacAddress); 723 } else { 724 pcur_wlan = 725 r8712_find_network(&pmlmepriv-> 726 scanned_queue, 727 cur_network->network.MacAddress); 728 if (pcur_wlan) 729 pcur_wlan->fixed = false; 730 731 pcur_sta = r8712_get_stainfo(pstapriv, 732 cur_network->network.MacAddress); 733 spin_lock_irqsave(&pstapriv-> 734 sta_hash_lock, irqL2); 735 r8712_free_stainfo(adapter, pcur_sta); 736 spin_unlock_irqrestore(&(pstapriv-> 737 sta_hash_lock), irqL2); 738 739 ptarget_wlan = 740 r8712_find_network(&pmlmepriv-> 741 scanned_queue, 742 pnetwork->network. 743 MacAddress); 744 if (ptarget_wlan) 745 ptarget_wlan->fixed = true; 746 } 747 } else { 748 ptarget_wlan = r8712_find_network(&pmlmepriv-> 749 scanned_queue, 750 pnetwork->network.MacAddress); 751 if (ptarget_wlan) 752 ptarget_wlan->fixed = true; 753 } 754 755 if (!ptarget_wlan) { 756 if (check_fwstate(pmlmepriv, 757 _FW_UNDER_LINKING)) 758 pmlmepriv->fw_state ^= 759 _FW_UNDER_LINKING; 760 goto ignore_joinbss_callback; 761 } 762 763 /*s2. find ptarget_sta & update ptarget_sta*/ 764 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 765 if (the_same_macaddr) { 766 ptarget_sta = 767 r8712_get_stainfo(pstapriv, 768 pnetwork->network.MacAddress); 769 if (!ptarget_sta) 770 ptarget_sta = 771 r8712_alloc_stainfo(pstapriv, 772 pnetwork->network.MacAddress); 773 } else { 774 ptarget_sta = 775 r8712_alloc_stainfo(pstapriv, 776 pnetwork->network.MacAddress); 777 } 778 if (ptarget_sta) /*update ptarget_sta*/ { 779 ptarget_sta->aid = pnetwork->join_res; 780 ptarget_sta->qos_option = 1; 781 ptarget_sta->mac_id = 5; 782 if (adapter->securitypriv. 783 AuthAlgrthm == 2) { 784 adapter->securitypriv. 785 binstallGrpkey = 786 false; 787 adapter->securitypriv. 788 busetkipkey = 789 false; 790 adapter->securitypriv. 791 bgrpkey_handshake = 792 false; 793 ptarget_sta->ieee8021x_blocked 794 = true; 795 ptarget_sta->XPrivacy = 796 adapter->securitypriv. 797 PrivacyAlgrthm; 798 memset((u8 *)&ptarget_sta-> 799 x_UncstKey, 800 0, 801 sizeof(union Keytype)); 802 memset((u8 *)&ptarget_sta-> 803 tkiprxmickey, 804 0, 805 sizeof(union Keytype)); 806 memset((u8 *)&ptarget_sta-> 807 tkiptxmickey, 808 0, 809 sizeof(union Keytype)); 810 memset((u8 *)&ptarget_sta-> 811 txpn, 0, 812 sizeof(union pn48)); 813 memset((u8 *)&ptarget_sta-> 814 rxpn, 0, 815 sizeof(union pn48)); 816 } 817 } else { 818 if (check_fwstate(pmlmepriv, 819 _FW_UNDER_LINKING)) 820 pmlmepriv->fw_state ^= 821 _FW_UNDER_LINKING; 822 goto ignore_joinbss_callback; 823 } 824 } 825 826 /*s3. update cur_network & indicate connect*/ 827 memcpy(&cur_network->network, &pnetwork->network, 828 pnetwork->network.Length); 829 cur_network->aid = pnetwork->join_res; 830 /*update fw_state will clr _FW_UNDER_LINKING*/ 831 switch (pnetwork->network.InfrastructureMode) { 832 case Ndis802_11Infrastructure: 833 pmlmepriv->fw_state = WIFI_STATION_STATE; 834 break; 835 case Ndis802_11IBSS: 836 pmlmepriv->fw_state = WIFI_ADHOC_STATE; 837 break; 838 default: 839 pmlmepriv->fw_state = WIFI_NULL_STATE; 840 break; 841 } 842 r8712_update_protection(adapter, 843 (cur_network->network.IEs) + 844 sizeof(struct NDIS_802_11_FIXED_IEs), 845 (cur_network->network.IELength)); 846 /*TODO: update HT_Capability*/ 847 update_ht_cap(adapter, cur_network->network.IEs, 848 cur_network->network.IELength); 849 /*indicate connect*/ 850 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) 851 r8712_indicate_connect(adapter); 852 del_timer(&pmlmepriv->assoc_timer); 853 } else { 854 goto ignore_joinbss_callback; 855 } 856 } else { 857 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { 858 mod_timer(&pmlmepriv->assoc_timer, 859 jiffies + msecs_to_jiffies(1)); 860 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 861 } 862 } 863 ignore_joinbss_callback: 864 spin_unlock_irqrestore(&pmlmepriv->lock, irqL); 865 if (sizeof(struct list_head) == 4 * sizeof(u32)) 866 kfree(pnetwork); 867 } 868 869 void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf) 870 { 871 unsigned long irqL; 872 struct sta_info *psta; 873 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); 874 struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf; 875 876 /* to do: */ 877 if (!r8712_access_ctrl(&adapter->acl_list, pstassoc->macaddr)) 878 return; 879 psta = r8712_get_stainfo(&adapter->stapriv, pstassoc->macaddr); 880 if (psta) { 881 /*the sta have been in sta_info_queue => do nothing 882 *(between drv has received this event before and 883 * fw have not yet to set key to CAM_ENTRY) 884 */ 885 return; 886 } 887 888 psta = r8712_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr); 889 if (!psta) 890 return; 891 /* to do : init sta_info variable */ 892 psta->qos_option = 0; 893 psta->mac_id = le32_to_cpu(pstassoc->cam_id); 894 /* psta->aid = (uint)pstassoc->cam_id; */ 895 896 if (adapter->securitypriv.AuthAlgrthm == 2) 897 psta->XPrivacy = adapter->securitypriv.PrivacyAlgrthm; 898 psta->ieee8021x_blocked = false; 899 spin_lock_irqsave(&pmlmepriv->lock, irqL); 900 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || 901 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 902 if (adapter->stapriv.asoc_sta_count == 2) { 903 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */ 904 r8712_indicate_connect(adapter); 905 } 906 } 907 spin_unlock_irqrestore(&pmlmepriv->lock, irqL); 908 } 909 910 void r8712_stadel_event_callback(struct _adapter *adapter, u8 *pbuf) 911 { 912 unsigned long irqL, irqL2; 913 struct sta_info *psta; 914 struct wlan_network *pwlan = NULL; 915 struct wlan_bssid_ex *pdev_network = NULL; 916 u8 *pibss = NULL; 917 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 918 struct stadel_event *pstadel = (struct stadel_event *)pbuf; 919 struct sta_priv *pstapriv = &adapter->stapriv; 920 struct wlan_network *tgt_network = &pmlmepriv->cur_network; 921 922 spin_lock_irqsave(&pmlmepriv->lock, irqL2); 923 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 924 r8712_ind_disconnect(adapter); 925 r8712_free_assoc_resources(adapter); 926 } 927 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | 928 WIFI_ADHOC_STATE)) { 929 psta = r8712_get_stainfo(&adapter->stapriv, pstadel->macaddr); 930 spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); 931 r8712_free_stainfo(adapter, psta); 932 spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); 933 if (adapter->stapriv.asoc_sta_count == 1) { 934 /*a sta + bc/mc_stainfo (not Ibss_stainfo) */ 935 pwlan = r8712_find_network(&pmlmepriv->scanned_queue, 936 tgt_network->network.MacAddress); 937 if (pwlan) { 938 pwlan->fixed = false; 939 free_network_nolock(pmlmepriv, pwlan); 940 } 941 /*re-create ibss*/ 942 pdev_network = &(adapter->registrypriv.dev_network); 943 pibss = adapter->registrypriv.dev_network.MacAddress; 944 memcpy(pdev_network, &tgt_network->network, 945 r8712_get_wlan_bssid_ex_sz(&tgt_network-> 946 network)); 947 memcpy(&pdev_network->Ssid, 948 &pmlmepriv->assoc_ssid, 949 sizeof(struct ndis_802_11_ssid)); 950 r8712_update_registrypriv_dev_network(adapter); 951 r8712_generate_random_ibss(pibss); 952 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 953 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE); 954 set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE); 955 } 956 } 957 } 958 spin_unlock_irqrestore(&pmlmepriv->lock, irqL2); 959 } 960 961 void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf) 962 { 963 struct reportpwrstate_parm *preportpwrstate = 964 (struct reportpwrstate_parm *)pbuf; 965 966 preportpwrstate->state |= (u8)(adapter->pwrctrlpriv.cpwm_tog + 0x80); 967 r8712_cpwm_int_hdl(adapter, preportpwrstate); 968 } 969 970 /* When the Netgear 3500 AP is with WPA2PSK-AES mode, it will send 971 * the ADDBA req frame with start seq control = 0 to wifi client after 972 * the WPA handshake and the seqence number of following data packet 973 * will be 0. In this case, the Rx reorder sequence is not longer than 0 974 * and the WiFi client will drop the data with seq number 0. 975 * So, the 8712 firmware has to inform driver with receiving the 976 * ADDBA-Req frame so that the driver can reset the 977 * sequence value of Rx reorder control. 978 */ 979 void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf) 980 { 981 struct ADDBA_Req_Report_parm *pAddbareq_pram = 982 (struct ADDBA_Req_Report_parm *)pbuf; 983 struct sta_info *psta; 984 struct sta_priv *pstapriv = &adapter->stapriv; 985 struct recv_reorder_ctrl *precvreorder_ctrl = NULL; 986 987 psta = r8712_get_stainfo(pstapriv, pAddbareq_pram->MacAddress); 988 if (psta) { 989 precvreorder_ctrl = 990 &psta->recvreorder_ctrl[pAddbareq_pram->tid]; 991 /* set the indicate_seq to 0xffff so that the rx reorder 992 * can store any following data packet. 993 */ 994 precvreorder_ctrl->indicate_seq = 0xffff; 995 } 996 } 997 998 void r8712_wpspbc_event_callback(struct _adapter *adapter, u8 *pbuf) 999 { 1000 if (!adapter->securitypriv.wps_hw_pbc_pressed) 1001 adapter->securitypriv.wps_hw_pbc_pressed = true; 1002 } 1003 1004 void _r8712_sitesurvey_ctrl_handler(struct _adapter *adapter) 1005 { 1006 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1007 struct sitesurvey_ctrl *psitesurveyctrl = &pmlmepriv->sitesurveyctrl; 1008 struct registry_priv *pregistrypriv = &adapter->registrypriv; 1009 u64 current_tx_pkts; 1010 uint current_rx_pkts; 1011 1012 current_tx_pkts = (adapter->xmitpriv.tx_pkts) - 1013 (psitesurveyctrl->last_tx_pkts); 1014 current_rx_pkts = (adapter->recvpriv.rx_pkts) - 1015 (psitesurveyctrl->last_rx_pkts); 1016 psitesurveyctrl->last_tx_pkts = adapter->xmitpriv.tx_pkts; 1017 psitesurveyctrl->last_rx_pkts = adapter->recvpriv.rx_pkts; 1018 if ((current_tx_pkts > pregistrypriv->busy_thresh) || 1019 (current_rx_pkts > pregistrypriv->busy_thresh)) 1020 psitesurveyctrl->traffic_busy = true; 1021 else 1022 psitesurveyctrl->traffic_busy = false; 1023 } 1024 1025 void _r8712_join_timeout_handler(struct _adapter *adapter) 1026 { 1027 unsigned long irqL; 1028 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1029 1030 if (adapter->driver_stopped || adapter->surprise_removed) 1031 return; 1032 spin_lock_irqsave(&pmlmepriv->lock, irqL); 1033 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 1034 pmlmepriv->to_join = false; 1035 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 1036 r8712_os_indicate_disconnect(adapter); 1037 _clr_fwstate_(pmlmepriv, _FW_LINKED); 1038 } 1039 if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt) { 1040 r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt, 1041 adapter->registrypriv.smart_ps); 1042 } 1043 spin_unlock_irqrestore(&pmlmepriv->lock, irqL); 1044 } 1045 1046 void r8712_scan_timeout_handler (struct _adapter *adapter) 1047 { 1048 unsigned long irqL; 1049 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1050 1051 spin_lock_irqsave(&pmlmepriv->lock, irqL); 1052 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); 1053 pmlmepriv->to_join = false; /* scan fail, so clear to_join flag */ 1054 spin_unlock_irqrestore(&pmlmepriv->lock, irqL); 1055 } 1056 1057 void _r8712_dhcp_timeout_handler (struct _adapter *adapter) 1058 { 1059 if (adapter->driver_stopped || adapter->surprise_removed) 1060 return; 1061 if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt) 1062 r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt, 1063 adapter->registrypriv.smart_ps); 1064 } 1065 1066 int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv) 1067 { 1068 struct list_head *phead; 1069 unsigned char *dst_ssid, *src_ssid; 1070 struct _adapter *adapter; 1071 struct __queue *queue = NULL; 1072 struct wlan_network *pnetwork = NULL; 1073 struct wlan_network *pnetwork_max_rssi = NULL; 1074 1075 adapter = (struct _adapter *)pmlmepriv->nic_hdl; 1076 queue = &pmlmepriv->scanned_queue; 1077 phead = &queue->queue; 1078 pmlmepriv->pscanned = phead->next; 1079 while (1) { 1080 if (end_of_queue_search(phead, pmlmepriv->pscanned)) { 1081 if (pmlmepriv->assoc_by_rssi && pnetwork_max_rssi) { 1082 pnetwork = pnetwork_max_rssi; 1083 goto ask_for_joinbss; 1084 } 1085 return -EINVAL; 1086 } 1087 pnetwork = container_of(pmlmepriv->pscanned, 1088 struct wlan_network, list); 1089 pmlmepriv->pscanned = pmlmepriv->pscanned->next; 1090 if (pmlmepriv->assoc_by_bssid) { 1091 dst_ssid = pnetwork->network.MacAddress; 1092 src_ssid = pmlmepriv->assoc_bssid; 1093 if (!memcmp(dst_ssid, src_ssid, ETH_ALEN)) { 1094 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 1095 if (is_same_network(&pmlmepriv-> 1096 cur_network.network, 1097 &pnetwork->network)) { 1098 _clr_fwstate_(pmlmepriv, 1099 _FW_UNDER_LINKING); 1100 /*r8712_indicate_connect again*/ 1101 r8712_indicate_connect(adapter); 1102 return 2; 1103 } 1104 r8712_disassoc_cmd(adapter); 1105 r8712_ind_disconnect(adapter); 1106 r8712_free_assoc_resources(adapter); 1107 } 1108 goto ask_for_joinbss; 1109 } 1110 } else if (pmlmepriv->assoc_ssid.SsidLength == 0) { 1111 goto ask_for_joinbss; 1112 } 1113 dst_ssid = pnetwork->network.Ssid.Ssid; 1114 src_ssid = pmlmepriv->assoc_ssid.Ssid; 1115 if ((pnetwork->network.Ssid.SsidLength == 1116 pmlmepriv->assoc_ssid.SsidLength) && 1117 (!memcmp(dst_ssid, src_ssid, 1118 pmlmepriv->assoc_ssid.SsidLength))) { 1119 if (pmlmepriv->assoc_by_rssi) { 1120 /* if the ssid is the same, select the bss 1121 * which has the max rssi 1122 */ 1123 if (pnetwork_max_rssi) { 1124 if (pnetwork->network.Rssi > 1125 pnetwork_max_rssi->network.Rssi) 1126 pnetwork_max_rssi = pnetwork; 1127 } else { 1128 pnetwork_max_rssi = pnetwork; 1129 } 1130 } else if (is_desired_network(adapter, pnetwork)) { 1131 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 1132 r8712_disassoc_cmd(adapter); 1133 r8712_free_assoc_resources(adapter); 1134 } 1135 goto ask_for_joinbss; 1136 } 1137 } 1138 } 1139 1140 ask_for_joinbss: 1141 return r8712_joinbss_cmd(adapter, pnetwork); 1142 } 1143 1144 int r8712_set_auth(struct _adapter *adapter, 1145 struct security_priv *psecuritypriv) 1146 { 1147 struct cmd_priv *pcmdpriv = &adapter->cmdpriv; 1148 struct cmd_obj *pcmd; 1149 struct setauth_parm *psetauthparm; 1150 1151 pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); 1152 if (!pcmd) 1153 return -ENOMEM; 1154 1155 psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC); 1156 if (!psetauthparm) { 1157 kfree(pcmd); 1158 return -ENOMEM; 1159 } 1160 psetauthparm->mode = (u8)psecuritypriv->AuthAlgrthm; 1161 pcmd->cmdcode = _SetAuth_CMD_; 1162 pcmd->parmbuf = (unsigned char *)psetauthparm; 1163 pcmd->cmdsz = sizeof(struct setauth_parm); 1164 pcmd->rsp = NULL; 1165 pcmd->rspsz = 0; 1166 INIT_LIST_HEAD(&pcmd->list); 1167 r8712_enqueue_cmd(pcmdpriv, pcmd); 1168 return 0; 1169 } 1170 1171 int r8712_set_key(struct _adapter *adapter, 1172 struct security_priv *psecuritypriv, 1173 sint keyid) 1174 { 1175 struct cmd_priv *pcmdpriv = &adapter->cmdpriv; 1176 struct cmd_obj *pcmd; 1177 struct setkey_parm *psetkeyparm; 1178 u8 keylen; 1179 int ret; 1180 1181 pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); 1182 if (!pcmd) 1183 return -ENOMEM; 1184 psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_ATOMIC); 1185 if (!psetkeyparm) { 1186 ret = -ENOMEM; 1187 goto err_free_cmd; 1188 } 1189 if (psecuritypriv->AuthAlgrthm == 2) { /* 802.1X */ 1190 psetkeyparm->algorithm = 1191 (u8)psecuritypriv->XGrpPrivacy; 1192 } else { /* WEP */ 1193 psetkeyparm->algorithm = 1194 (u8)psecuritypriv->PrivacyAlgrthm; 1195 } 1196 psetkeyparm->keyid = (u8)keyid; 1197 1198 switch (psetkeyparm->algorithm) { 1199 case _WEP40_: 1200 keylen = 5; 1201 memcpy(psetkeyparm->key, 1202 psecuritypriv->DefKey[keyid].skey, keylen); 1203 break; 1204 case _WEP104_: 1205 keylen = 13; 1206 memcpy(psetkeyparm->key, 1207 psecuritypriv->DefKey[keyid].skey, keylen); 1208 break; 1209 case _TKIP_: 1210 if (keyid < 1 || keyid > 2) { 1211 ret = -EINVAL; 1212 goto err_free_parm; 1213 } 1214 keylen = 16; 1215 memcpy(psetkeyparm->key, 1216 &psecuritypriv->XGrpKey[keyid - 1], keylen); 1217 psetkeyparm->grpkey = 1; 1218 break; 1219 case _AES_: 1220 if (keyid < 1 || keyid > 2) { 1221 ret = -EINVAL; 1222 goto err_free_parm; 1223 } 1224 keylen = 16; 1225 memcpy(psetkeyparm->key, 1226 &psecuritypriv->XGrpKey[keyid - 1], keylen); 1227 psetkeyparm->grpkey = 1; 1228 break; 1229 default: 1230 ret = -EINVAL; 1231 goto err_free_parm; 1232 } 1233 pcmd->cmdcode = _SetKey_CMD_; 1234 pcmd->parmbuf = (u8 *)psetkeyparm; 1235 pcmd->cmdsz = (sizeof(struct setkey_parm)); 1236 pcmd->rsp = NULL; 1237 pcmd->rspsz = 0; 1238 INIT_LIST_HEAD(&pcmd->list); 1239 r8712_enqueue_cmd(pcmdpriv, pcmd); 1240 return 0; 1241 1242 err_free_parm: 1243 kfree(psetkeyparm); 1244 err_free_cmd: 1245 kfree(pcmd); 1246 return ret; 1247 } 1248 1249 /* adjust IEs for r8712_joinbss_cmd in WMM */ 1250 int r8712_restruct_wmm_ie(struct _adapter *adapter, u8 *in_ie, u8 *out_ie, 1251 uint in_len, uint initial_out_len) 1252 { 1253 unsigned int ielength = 0; 1254 unsigned int i, j; 1255 1256 i = 12; /* after the fixed IE */ 1257 while (i < in_len) { 1258 ielength = initial_out_len; 1259 if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 && 1260 in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 && 1261 in_ie[i + 5] == 0x02 && i + 5 < in_len) { 1262 /*WMM element ID and OUI*/ 1263 for (j = i; j < i + 9; j++) { 1264 out_ie[ielength] = in_ie[j]; 1265 ielength++; 1266 } 1267 out_ie[initial_out_len + 1] = 0x07; 1268 out_ie[initial_out_len + 6] = 0x00; 1269 out_ie[initial_out_len + 8] = 0x00; 1270 break; 1271 } 1272 i += (in_ie[i + 1] + 2); /* to the next IE element */ 1273 } 1274 return ielength; 1275 } 1276 1277 /* 1278 * Ported from 8185: IsInPreAuthKeyList(). 1279 * 1280 * Search by BSSID, 1281 * Return Value: 1282 * -1 :if there is no pre-auth key in the table 1283 * >=0 :if there is pre-auth key, and return the entry id 1284 */ 1285 static int SecIsInPMKIDList(struct _adapter *Adapter, u8 *bssid) 1286 { 1287 struct security_priv *psecuritypriv = &Adapter->securitypriv; 1288 int i = 0; 1289 1290 do { 1291 if (psecuritypriv->PMKIDList[i].bUsed && 1292 (!memcmp(psecuritypriv->PMKIDList[i].Bssid, 1293 bssid, ETH_ALEN))) 1294 break; 1295 i++; 1296 1297 } while (i < NUM_PMKID_CACHE); 1298 1299 if (i == NUM_PMKID_CACHE) { 1300 i = -1; /* Could not find. */ 1301 } else { 1302 ; /* There is one Pre-Authentication Key for the 1303 * specific BSSID. 1304 */ 1305 } 1306 return i; 1307 } 1308 1309 sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie, 1310 u8 *out_ie, uint in_len) 1311 { 1312 u8 authmode = 0, match; 1313 u8 sec_ie[IW_CUSTOM_MAX], uncst_oui[4], bkup_ie[255]; 1314 u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; 1315 uint ielength, cnt, remove_cnt; 1316 int iEntry; 1317 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1318 struct security_priv *psecuritypriv = &adapter->securitypriv; 1319 uint ndisauthmode = psecuritypriv->ndisauthtype; 1320 uint ndissecuritytype = psecuritypriv->ndisencryptstatus; 1321 1322 if ((ndisauthmode == Ndis802_11AuthModeWPA) || 1323 (ndisauthmode == Ndis802_11AuthModeWPAPSK)) { 1324 authmode = _WPA_IE_ID_; 1325 uncst_oui[0] = 0x0; 1326 uncst_oui[1] = 0x50; 1327 uncst_oui[2] = 0xf2; 1328 } 1329 if ((ndisauthmode == Ndis802_11AuthModeWPA2) || 1330 (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) { 1331 authmode = _WPA2_IE_ID_; 1332 uncst_oui[0] = 0x0; 1333 uncst_oui[1] = 0x0f; 1334 uncst_oui[2] = 0xac; 1335 } 1336 switch (ndissecuritytype) { 1337 case Ndis802_11Encryption1Enabled: 1338 case Ndis802_11Encryption1KeyAbsent: 1339 uncst_oui[3] = 0x1; 1340 break; 1341 case Ndis802_11Encryption2Enabled: 1342 case Ndis802_11Encryption2KeyAbsent: 1343 uncst_oui[3] = 0x2; 1344 break; 1345 case Ndis802_11Encryption3Enabled: 1346 case Ndis802_11Encryption3KeyAbsent: 1347 uncst_oui[3] = 0x4; 1348 break; 1349 default: 1350 break; 1351 } 1352 /*Search required WPA or WPA2 IE and copy to sec_ie[] */ 1353 cnt = 12; 1354 match = false; 1355 while (cnt < in_len) { 1356 if (in_ie[cnt] == authmode) { 1357 if ((authmode == _WPA_IE_ID_) && 1358 (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) { 1359 memcpy(&sec_ie[0], &in_ie[cnt], 1360 in_ie[cnt + 1] + 2); 1361 match = true; 1362 break; 1363 } 1364 if (authmode == _WPA2_IE_ID_) { 1365 memcpy(&sec_ie[0], &in_ie[cnt], 1366 in_ie[cnt + 1] + 2); 1367 match = true; 1368 break; 1369 } 1370 if (((authmode == _WPA_IE_ID_) && 1371 (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) || 1372 (authmode == _WPA2_IE_ID_)) 1373 memcpy(&bkup_ie[0], &in_ie[cnt], 1374 in_ie[cnt + 1] + 2); 1375 } 1376 cnt += in_ie[cnt + 1] + 2; /*get next*/ 1377 } 1378 /*restruct WPA IE or WPA2 IE in sec_ie[] */ 1379 if (match) { 1380 if (sec_ie[0] == _WPA_IE_ID_) { 1381 /* parsing SSN IE to select required encryption 1382 * algorithm, and set the bc/mc encryption algorithm 1383 */ 1384 while (true) { 1385 /*check wpa_oui tag*/ 1386 if (memcmp(&sec_ie[2], &wpa_oui[0], 4)) { 1387 match = false; 1388 break; 1389 } 1390 if ((sec_ie[6] != 0x01) || (sec_ie[7] != 0x0)) { 1391 /*IE Ver error*/ 1392 match = false; 1393 break; 1394 } 1395 if (!memcmp(&sec_ie[8], &wpa_oui[0], 3)) { 1396 /* get bc/mc encryption type (group 1397 * key type) 1398 */ 1399 switch (sec_ie[11]) { 1400 case 0x0: /*none*/ 1401 psecuritypriv->XGrpPrivacy = 1402 _NO_PRIVACY_; 1403 break; 1404 case 0x1: /*WEP_40*/ 1405 psecuritypriv->XGrpPrivacy = 1406 _WEP40_; 1407 break; 1408 case 0x2: /*TKIP*/ 1409 psecuritypriv->XGrpPrivacy = 1410 _TKIP_; 1411 break; 1412 case 0x3: /*AESCCMP*/ 1413 case 0x4: 1414 psecuritypriv->XGrpPrivacy = 1415 _AES_; 1416 break; 1417 case 0x5: /*WEP_104*/ 1418 psecuritypriv->XGrpPrivacy = 1419 _WEP104_; 1420 break; 1421 } 1422 } else { 1423 match = false; 1424 break; 1425 } 1426 if (sec_ie[12] == 0x01) { 1427 /*check the unicast encryption type*/ 1428 if (memcmp(&sec_ie[14], 1429 &uncst_oui[0], 4)) { 1430 match = false; 1431 break; 1432 1433 } /*else the uncst_oui is match*/ 1434 } else { /*mixed mode, unicast_enc_type > 1*/ 1435 /*select the uncst_oui and remove 1436 * the other uncst_oui 1437 */ 1438 cnt = sec_ie[12]; 1439 remove_cnt = (cnt - 1) * 4; 1440 sec_ie[12] = 0x01; 1441 memcpy(&sec_ie[14], &uncst_oui[0], 4); 1442 /*remove the other unicast suit*/ 1443 memcpy(&sec_ie[18], 1444 &sec_ie[18 + remove_cnt], 1445 sec_ie[1] - 18 + 2 - 1446 remove_cnt); 1447 sec_ie[1] = sec_ie[1] - remove_cnt; 1448 } 1449 break; 1450 } 1451 } 1452 if (authmode == _WPA2_IE_ID_) { 1453 /* parsing RSN IE to select required encryption 1454 * algorithm, and set the bc/mc encryption algorithm 1455 */ 1456 while (true) { 1457 if ((sec_ie[2] != 0x01) || (sec_ie[3] != 0x0)) { 1458 /*IE Ver error*/ 1459 match = false; 1460 break; 1461 } 1462 if (!memcmp(&sec_ie[4], &uncst_oui[0], 3)) { 1463 /*get bc/mc encryption type*/ 1464 switch (sec_ie[7]) { 1465 case 0x1: /*WEP_40*/ 1466 psecuritypriv->XGrpPrivacy = 1467 _WEP40_; 1468 break; 1469 case 0x2: /*TKIP*/ 1470 psecuritypriv->XGrpPrivacy = 1471 _TKIP_; 1472 break; 1473 case 0x4: /*AESWRAP*/ 1474 psecuritypriv->XGrpPrivacy = 1475 _AES_; 1476 break; 1477 case 0x5: /*WEP_104*/ 1478 psecuritypriv->XGrpPrivacy = 1479 _WEP104_; 1480 break; 1481 default: /*one*/ 1482 psecuritypriv->XGrpPrivacy = 1483 _NO_PRIVACY_; 1484 break; 1485 } 1486 } else { 1487 match = false; 1488 break; 1489 } 1490 if (sec_ie[8] == 0x01) { 1491 /*check the unicast encryption type*/ 1492 if (memcmp(&sec_ie[10], 1493 &uncst_oui[0], 4)) { 1494 match = false; 1495 break; 1496 } /*else the uncst_oui is match*/ 1497 } else { /*mixed mode, unicast_enc_type > 1*/ 1498 /*select the uncst_oui and remove the 1499 * other uncst_oui 1500 */ 1501 cnt = sec_ie[8]; 1502 remove_cnt = (cnt - 1) * 4; 1503 sec_ie[8] = 0x01; 1504 memcpy(&sec_ie[10], &uncst_oui[0], 4); 1505 /*remove the other unicast suit*/ 1506 memcpy(&sec_ie[14], 1507 &sec_ie[14 + remove_cnt], 1508 (sec_ie[1] - 14 + 2 - 1509 remove_cnt)); 1510 sec_ie[1] = sec_ie[1] - remove_cnt; 1511 } 1512 break; 1513 } 1514 } 1515 } 1516 if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) { 1517 /*copy fixed ie*/ 1518 memcpy(out_ie, in_ie, 12); 1519 ielength = 12; 1520 /*copy RSN or SSN*/ 1521 if (match) { 1522 memcpy(&out_ie[ielength], &sec_ie[0], sec_ie[1] + 2); 1523 ielength += sec_ie[1] + 2; 1524 if (authmode == _WPA2_IE_ID_) { 1525 /*the Pre-Authentication bit should be zero*/ 1526 out_ie[ielength - 1] = 0; 1527 out_ie[ielength - 2] = 0; 1528 } 1529 r8712_report_sec_ie(adapter, authmode, sec_ie); 1530 } 1531 } else { 1532 /*copy fixed ie only*/ 1533 memcpy(out_ie, in_ie, 12); 1534 ielength = 12; 1535 if (psecuritypriv->wps_phase) { 1536 memcpy(out_ie + ielength, psecuritypriv->wps_ie, 1537 psecuritypriv->wps_ie_len); 1538 ielength += psecuritypriv->wps_ie_len; 1539 } 1540 } 1541 iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid); 1542 if (iEntry < 0) 1543 return ielength; 1544 if (authmode == _WPA2_IE_ID_) { 1545 out_ie[ielength] = 1; 1546 ielength++; 1547 out_ie[ielength] = 0; /*PMKID count = 0x0100*/ 1548 ielength++; 1549 memcpy(&out_ie[ielength], 1550 &psecuritypriv->PMKIDList[iEntry].PMKID, 16); 1551 ielength += 16; 1552 out_ie[13] += 18;/*PMKID length = 2+16*/ 1553 } 1554 return ielength; 1555 } 1556 1557 void r8712_init_registrypriv_dev_network(struct _adapter *adapter) 1558 { 1559 struct registry_priv *pregistrypriv = &adapter->registrypriv; 1560 struct eeprom_priv *peepriv = &adapter->eeprompriv; 1561 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; 1562 u8 *myhwaddr = myid(peepriv); 1563 1564 memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN); 1565 memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, 1566 sizeof(struct ndis_802_11_ssid)); 1567 pdev_network->Configuration.Length = 1568 sizeof(struct NDIS_802_11_CONFIGURATION); 1569 pdev_network->Configuration.BeaconPeriod = 100; 1570 pdev_network->Configuration.FHConfig.Length = 0; 1571 pdev_network->Configuration.FHConfig.HopPattern = 0; 1572 pdev_network->Configuration.FHConfig.HopSet = 0; 1573 pdev_network->Configuration.FHConfig.DwellTime = 0; 1574 } 1575 1576 void r8712_update_registrypriv_dev_network(struct _adapter *adapter) 1577 { 1578 int sz = 0; 1579 struct registry_priv *pregistrypriv = &adapter->registrypriv; 1580 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; 1581 struct security_priv *psecuritypriv = &adapter->securitypriv; 1582 struct wlan_network *cur_network = &adapter->mlmepriv.cur_network; 1583 1584 pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm 1585 > 0 ? 1 : 0); /* adhoc no 802.1x */ 1586 pdev_network->Rssi = 0; 1587 switch (pregistrypriv->wireless_mode) { 1588 case WIRELESS_11B: 1589 pdev_network->NetworkTypeInUse = Ndis802_11DS; 1590 break; 1591 case WIRELESS_11G: 1592 case WIRELESS_11BG: 1593 pdev_network->NetworkTypeInUse = Ndis802_11OFDM24; 1594 break; 1595 case WIRELESS_11A: 1596 pdev_network->NetworkTypeInUse = Ndis802_11OFDM5; 1597 break; 1598 default: 1599 /* TODO */ 1600 break; 1601 } 1602 pdev_network->Configuration.DSConfig = pregistrypriv->channel; 1603 if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) 1604 pdev_network->Configuration.ATIMWindow = 3; 1605 pdev_network->InfrastructureMode = cur_network->network.InfrastructureMode; 1606 /* 1. Supported rates 1607 * 2. IE 1608 */ 1609 sz = r8712_generate_ie(pregistrypriv); 1610 pdev_network->IELength = sz; 1611 pdev_network->Length = r8712_get_wlan_bssid_ex_sz(pdev_network); 1612 } 1613 1614 /*the function is at passive_level*/ 1615 void r8712_joinbss_reset(struct _adapter *padapter) 1616 { 1617 int i; 1618 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1619 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 1620 1621 /* todo: if you want to do something io/reg/hw setting before join_bss, 1622 * please add code here 1623 */ 1624 phtpriv->ampdu_enable = false;/*reset to disabled*/ 1625 for (i = 0; i < 16; i++) 1626 phtpriv->baddbareq_issued[i] = false;/*reset it*/ 1627 if (phtpriv->ht_option) { 1628 /* validate usb rx aggregation */ 1629 r8712_write8(padapter, 0x102500D9, 48);/*TH = 48 pages, 6k*/ 1630 } else { 1631 /* invalidate usb rx aggregation */ 1632 /* TH=1 => means that invalidate usb rx aggregation */ 1633 r8712_write8(padapter, 0x102500D9, 1); 1634 } 1635 } 1636 1637 /*the function is >= passive_level*/ 1638 unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, 1639 u8 *out_ie, uint in_len, uint *pout_len) 1640 { 1641 u32 ielen, out_len; 1642 unsigned char *p; 1643 struct ieee80211_ht_cap ht_capie; 1644 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; 1645 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1646 struct qos_priv *pqospriv = &pmlmepriv->qospriv; 1647 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 1648 1649 phtpriv->ht_option = 0; 1650 p = r8712_get_ie(in_ie + 12, WLAN_EID_HT_CAPABILITY, &ielen, in_len - 12); 1651 if (p && (ielen > 0)) { 1652 if (pqospriv->qos_option == 0) { 1653 out_len = *pout_len; 1654 r8712_set_ie(out_ie + out_len, WLAN_EID_VENDOR_SPECIFIC, 1655 _WMM_IE_Length_, WMM_IE, pout_len); 1656 pqospriv->qos_option = 1; 1657 } 1658 out_len = *pout_len; 1659 memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap)); 1660 ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 1661 IEEE80211_HT_CAP_SGI_20 | 1662 IEEE80211_HT_CAP_SGI_40 | 1663 IEEE80211_HT_CAP_TX_STBC | 1664 IEEE80211_HT_CAP_MAX_AMSDU | 1665 IEEE80211_HT_CAP_DSSSCCK40); 1666 ht_capie.ampdu_params_info = (IEEE80211_HT_AMPDU_PARM_FACTOR & 1667 0x03) | (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00); 1668 r8712_set_ie(out_ie + out_len, WLAN_EID_HT_CAPABILITY, 1669 sizeof(struct ieee80211_ht_cap), 1670 (unsigned char *)&ht_capie, pout_len); 1671 phtpriv->ht_option = 1; 1672 } 1673 return phtpriv->ht_option; 1674 } 1675 1676 /* the function is > passive_level (in critical_section) */ 1677 static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len) 1678 { 1679 u8 *p, max_ampdu_sz; 1680 int i; 1681 uint len; 1682 struct sta_info *bmc_sta, *psta; 1683 struct ieee80211_ht_cap *pht_capie; 1684 struct recv_reorder_ctrl *preorder_ctrl; 1685 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1686 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 1687 struct registry_priv *pregistrypriv = &padapter->registrypriv; 1688 struct wlan_network *pcur_network = &(pmlmepriv->cur_network); 1689 1690 if (!phtpriv->ht_option) 1691 return; 1692 /* maybe needs check if ap supports rx ampdu. */ 1693 if (!phtpriv->ampdu_enable && 1694 (pregistrypriv->ampdu_enable == 1)) 1695 phtpriv->ampdu_enable = true; 1696 /*check Max Rx A-MPDU Size*/ 1697 len = 0; 1698 p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs), 1699 WLAN_EID_HT_CAPABILITY, 1700 &len, ie_len - 1701 sizeof(struct NDIS_802_11_FIXED_IEs)); 1702 if (p && len > 0) { 1703 pht_capie = (struct ieee80211_ht_cap *)(p + 2); 1704 max_ampdu_sz = (pht_capie->ampdu_params_info & 1705 IEEE80211_HT_AMPDU_PARM_FACTOR); 1706 /* max_ampdu_sz (kbytes); */ 1707 max_ampdu_sz = 1 << (max_ampdu_sz + 3); 1708 phtpriv->rx_ampdu_maxlen = max_ampdu_sz; 1709 } 1710 /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info 1711 * if A-MPDU Rx is enabled, resetting rx_ordering_ctrl 1712 * wstart_b(indicate_seq) to default value=0xffff 1713 * todo: check if AP can send A-MPDU packets 1714 */ 1715 bmc_sta = r8712_get_bcmc_stainfo(padapter); 1716 if (bmc_sta) { 1717 for (i = 0; i < 16; i++) { 1718 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; 1719 preorder_ctrl->indicate_seq = 0xffff; 1720 preorder_ctrl->wend_b = 0xffff; 1721 } 1722 } 1723 psta = r8712_get_stainfo(&padapter->stapriv, 1724 pcur_network->network.MacAddress); 1725 if (psta) { 1726 for (i = 0; i < 16; i++) { 1727 preorder_ctrl = &psta->recvreorder_ctrl[i]; 1728 preorder_ctrl->indicate_seq = 0xffff; 1729 preorder_ctrl->wend_b = 0xffff; 1730 } 1731 } 1732 len = 0; 1733 p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs), 1734 WLAN_EID_HT_OPERATION, &len, 1735 ie_len - sizeof(struct NDIS_802_11_FIXED_IEs)); 1736 } 1737 1738 void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority) 1739 { 1740 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1741 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 1742 1743 if ((phtpriv->ht_option == 1) && (phtpriv->ampdu_enable)) { 1744 if (!phtpriv->baddbareq_issued[priority]) { 1745 r8712_addbareq_cmd(padapter, (u8)priority); 1746 phtpriv->baddbareq_issued[priority] = true; 1747 } 1748 } 1749 } 1750