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