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