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