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