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