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 u8 timer_cancelled; 586 587 _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled); 588 589 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); 590 } 591 592 if (pmlmepriv->to_join == true) { 593 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) { 594 if (check_fwstate(pmlmepriv, _FW_LINKED) == false) { 595 set_fwstate(pmlmepriv, _FW_UNDER_LINKING); 596 597 if (r8712_select_and_join_from_scan(pmlmepriv) 598 == _SUCCESS) 599 _set_timer(&pmlmepriv->assoc_timer, 600 MAX_JOIN_TIMEOUT); 601 else { 602 struct wlan_bssid_ex *pdev_network = 603 &(adapter->registrypriv.dev_network); 604 u8 *pibss = 605 adapter->registrypriv. 606 dev_network.MacAddress; 607 pmlmepriv->fw_state ^= _FW_UNDER_SURVEY; 608 memcpy(&pdev_network->Ssid, 609 &pmlmepriv->assoc_ssid, 610 sizeof(struct 611 ndis_802_11_ssid)); 612 r8712_update_registrypriv_dev_network 613 (adapter); 614 r8712_generate_random_ibss(pibss); 615 pmlmepriv->fw_state = 616 WIFI_ADHOC_MASTER_STATE; 617 pmlmepriv->to_join = false; 618 } 619 } 620 } else { 621 pmlmepriv->to_join = false; 622 set_fwstate(pmlmepriv, _FW_UNDER_LINKING); 623 if (r8712_select_and_join_from_scan(pmlmepriv) == 624 _SUCCESS) 625 _set_timer(&pmlmepriv->assoc_timer, 626 MAX_JOIN_TIMEOUT); 627 else 628 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 629 } 630 } 631 spin_unlock_irqrestore(&pmlmepriv->lock, irqL); 632} 633 634/* 635 *r8712_free_assoc_resources: the caller has to lock pmlmepriv->lock 636 */ 637void r8712_free_assoc_resources(struct _adapter *adapter) 638{ 639 unsigned long irqL; 640 struct wlan_network *pwlan = NULL; 641 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 642 struct sta_priv *pstapriv = &adapter->stapriv; 643 struct wlan_network *tgt_network = &pmlmepriv->cur_network; 644 645 pwlan = r8712_find_network(&pmlmepriv->scanned_queue, 646 tgt_network->network.MacAddress); 647 648 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE)) { 649 struct sta_info *psta; 650 651 psta = r8712_get_stainfo(&adapter->stapriv, 652 tgt_network->network.MacAddress); 653 654 spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); 655 r8712_free_stainfo(adapter, psta); 656 spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); 657 } 658 659 if (check_fwstate(pmlmepriv, 660 WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) 661 r8712_free_all_stainfo(adapter); 662 if (pwlan) 663 pwlan->fixed = false; 664 665 if (((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) && 666 (adapter->stapriv.asoc_sta_count == 1))) 667 free_network_nolock(pmlmepriv, pwlan); 668} 669 670/* 671*r8712_indicate_connect: the caller has to lock pmlmepriv->lock 672*/ 673void r8712_indicate_connect(struct _adapter *padapter) 674{ 675 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 676 677 pmlmepriv->to_join = false; 678 set_fwstate(pmlmepriv, _FW_LINKED); 679 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_LINK); 680 r8712_os_indicate_connect(padapter); 681 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) 682 _set_timer(&pmlmepriv->dhcp_timer, 60000); 683} 684 685 686/* 687*r8712_ind_disconnect: the caller has to lock pmlmepriv->lock 688*/ 689void r8712_ind_disconnect(struct _adapter *padapter) 690{ 691 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 692 693 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { 694 _clr_fwstate_(pmlmepriv, _FW_LINKED); 695 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK); 696 r8712_os_indicate_disconnect(padapter); 697 } 698 if (padapter->pwrctrlpriv.pwr_mode != 699 padapter->registrypriv.power_mgnt) { 700 _cancel_timer_ex(&pmlmepriv->dhcp_timer); 701 r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt, 702 padapter->registrypriv.smart_ps); 703 } 704} 705 706/*Notes: 707 *pnetwork : returns from r8712_joinbss_event_callback 708 *ptarget_wlan: found from scanned_queue 709 *if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if 710 * "ptarget_sta" & "ptarget_wlan" exist. 711 *if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check 712 * if "ptarget_wlan" exist. 713 *if join_res > 0, update "cur_network->network" from 714 * "pnetwork->network" if (ptarget_wlan !=NULL). 715 */ 716void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf) 717{ 718 unsigned long irqL = 0, irqL2; 719 u8 timer_cancelled; 720 struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL; 721 struct sta_priv *pstapriv = &adapter->stapriv; 722 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 723 struct wlan_network *cur_network = &pmlmepriv->cur_network; 724 struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL; 725 unsigned int the_same_macaddr = false; 726 struct wlan_network *pnetwork; 727 728 if (sizeof(struct list_head) == 4 * sizeof(u32)) { 729 pnetwork = kmalloc(sizeof(struct wlan_network), GFP_ATOMIC); 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 _cancel_timer(&pmlmepriv->assoc_timer, 914 &timer_cancelled); 915 } else 916 goto ignore_joinbss_callback; 917 } else { 918 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) { 919 _set_timer(&pmlmepriv->assoc_timer, 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((u8 *)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((unsigned char *)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, securitytype, 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 securitytype = _WEP40_; 1403 uncst_oui[3] = 0x1; 1404 break; 1405 case Ndis802_11Encryption2Enabled: 1406 case Ndis802_11Encryption2KeyAbsent: 1407 securitytype = _TKIP_; 1408 uncst_oui[3] = 0x2; 1409 break; 1410 case Ndis802_11Encryption3Enabled: 1411 case Ndis802_11Encryption3KeyAbsent: 1412 securitytype = _AES_; 1413 uncst_oui[3] = 0x4; 1414 break; 1415 default: 1416 securitytype = _NO_PRIVACY_; 1417 break; 1418 } 1419 /*Search required WPA or WPA2 IE and copy to sec_ie[] */ 1420 cnt = 12; 1421 match = false; 1422 while (cnt < in_len) { 1423 if (in_ie[cnt] == authmode) { 1424 if ((authmode == _WPA_IE_ID_) && 1425 (!memcmp(&in_ie[cnt+2], &wpa_oui[0], 4))) { 1426 memcpy(&sec_ie[0], &in_ie[cnt], 1427 in_ie[cnt + 1] + 2); 1428 match = true; 1429 break; 1430 } 1431 if (authmode == _WPA2_IE_ID_) { 1432 memcpy(&sec_ie[0], &in_ie[cnt], 1433 in_ie[cnt + 1] + 2); 1434 match = true; 1435 break; 1436 } 1437 if (((authmode == _WPA_IE_ID_) && 1438 (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) || 1439 (authmode == _WPA2_IE_ID_)) 1440 memcpy(&bkup_ie[0], &in_ie[cnt], 1441 in_ie[cnt + 1] + 2); 1442 } 1443 cnt += in_ie[cnt+1] + 2; /*get next*/ 1444 } 1445 /*restruct WPA IE or WPA2 IE in sec_ie[] */ 1446 if (match == true) { 1447 if (sec_ie[0] == _WPA_IE_ID_) { 1448 /* parsing SSN IE to select required encryption 1449 * algorithm, and set the bc/mc encryption algorithm */ 1450 while (true) { 1451 /*check wpa_oui tag*/ 1452 if (memcmp(&sec_ie[2], &wpa_oui[0], 4)) { 1453 match = false; 1454 break; 1455 } 1456 if ((sec_ie[6] != 0x01) || (sec_ie[7] != 0x0)) { 1457 /*IE Ver error*/ 1458 match = false; 1459 break; 1460 } 1461 if (!memcmp(&sec_ie[8], &wpa_oui[0], 3)) { 1462 /* get bc/mc encryption type (group 1463 * key type)*/ 1464 switch (sec_ie[11]) { 1465 case 0x0: /*none*/ 1466 psecuritypriv->XGrpPrivacy = 1467 _NO_PRIVACY_; 1468 break; 1469 case 0x1: /*WEP_40*/ 1470 psecuritypriv->XGrpPrivacy = 1471 _WEP40_; 1472 break; 1473 case 0x2: /*TKIP*/ 1474 psecuritypriv->XGrpPrivacy = 1475 _TKIP_; 1476 break; 1477 case 0x3: /*AESCCMP*/ 1478 case 0x4: 1479 psecuritypriv->XGrpPrivacy = 1480 _AES_; 1481 break; 1482 case 0x5: /*WEP_104*/ 1483 psecuritypriv->XGrpPrivacy = 1484 _WEP104_; 1485 break; 1486 } 1487 } else { 1488 match = false; 1489 break; 1490 } 1491 if (sec_ie[12] == 0x01) { 1492 /*check the unicast encryption type*/ 1493 if (memcmp(&sec_ie[14], 1494 &uncst_oui[0], 4)) { 1495 match = false; 1496 break; 1497 1498 } /*else the uncst_oui is match*/ 1499 } else { /*mixed mode, unicast_enc_type > 1*/ 1500 /*select the uncst_oui and remove 1501 * the other uncst_oui*/ 1502 cnt = sec_ie[12]; 1503 remove_cnt = (cnt-1) * 4; 1504 sec_ie[12] = 0x01; 1505 memcpy(&sec_ie[14], &uncst_oui[0], 4); 1506 /*remove the other unicast suit*/ 1507 memcpy(&sec_ie[18], 1508 &sec_ie[18 + remove_cnt], 1509 sec_ie[1] - 18 + 2 - 1510 remove_cnt); 1511 sec_ie[1] = sec_ie[1] - remove_cnt; 1512 } 1513 break; 1514 } 1515 } 1516 if (authmode == _WPA2_IE_ID_) { 1517 /* parsing RSN IE to select required encryption 1518 * algorithm, and set the bc/mc encryption algorithm */ 1519 while (true) { 1520 if ((sec_ie[2] != 0x01) || (sec_ie[3] != 0x0)) { 1521 /*IE Ver error*/ 1522 match = false; 1523 break; 1524 } 1525 if (!memcmp(&sec_ie[4], &uncst_oui[0], 3)) { 1526 /*get bc/mc encryption type*/ 1527 switch (sec_ie[7]) { 1528 case 0x1: /*WEP_40*/ 1529 psecuritypriv->XGrpPrivacy = 1530 _WEP40_; 1531 break; 1532 case 0x2: /*TKIP*/ 1533 psecuritypriv->XGrpPrivacy = 1534 _TKIP_; 1535 break; 1536 case 0x4: /*AESWRAP*/ 1537 psecuritypriv->XGrpPrivacy = 1538 _AES_; 1539 break; 1540 case 0x5: /*WEP_104*/ 1541 psecuritypriv->XGrpPrivacy = 1542 _WEP104_; 1543 break; 1544 default: /*one*/ 1545 psecuritypriv->XGrpPrivacy = 1546 _NO_PRIVACY_; 1547 break; 1548 } 1549 } else { 1550 match = false; 1551 break; 1552 } 1553 if (sec_ie[8] == 0x01) { 1554 /*check the unicast encryption type*/ 1555 if (memcmp(&sec_ie[10], 1556 &uncst_oui[0], 4)) { 1557 match = false; 1558 break; 1559 } /*else the uncst_oui is match*/ 1560 } else { /*mixed mode, unicast_enc_type > 1*/ 1561 /*select the uncst_oui and remove the 1562 * other uncst_oui*/ 1563 cnt = sec_ie[8]; 1564 remove_cnt = (cnt-1)*4; 1565 sec_ie[8] = 0x01; 1566 memcpy(&sec_ie[10], &uncst_oui[0], 4); 1567 /*remove the other unicast suit*/ 1568 memcpy(&sec_ie[14], 1569 &sec_ie[14 + remove_cnt], 1570 (sec_ie[1] - 14 + 2 - 1571 remove_cnt)); 1572 sec_ie[1] = sec_ie[1]-remove_cnt; 1573 } 1574 break; 1575 } 1576 } 1577 } 1578 if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) { 1579 /*copy fixed ie*/ 1580 memcpy(out_ie, in_ie, 12); 1581 ielength = 12; 1582 /*copy RSN or SSN*/ 1583 if (match == true) { 1584 memcpy(&out_ie[ielength], &sec_ie[0], sec_ie[1]+2); 1585 ielength += sec_ie[1] + 2; 1586 if (authmode == _WPA2_IE_ID_) { 1587 /*the Pre-Authentication bit should be zero*/ 1588 out_ie[ielength - 1] = 0; 1589 out_ie[ielength - 2] = 0; 1590 } 1591 r8712_report_sec_ie(adapter, authmode, sec_ie); 1592 } 1593 } else { 1594 /*copy fixed ie only*/ 1595 memcpy(out_ie, in_ie, 12); 1596 ielength = 12; 1597 if (psecuritypriv->wps_phase == true) { 1598 memcpy(out_ie+ielength, psecuritypriv->wps_ie, 1599 psecuritypriv->wps_ie_len); 1600 ielength += psecuritypriv->wps_ie_len; 1601 } 1602 } 1603 iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid); 1604 if (iEntry < 0) 1605 return ielength; 1606 else { 1607 if (authmode == _WPA2_IE_ID_) { 1608 out_ie[ielength] = 1; 1609 ielength++; 1610 out_ie[ielength] = 0; /*PMKID count = 0x0100*/ 1611 ielength++; 1612 memcpy(&out_ie[ielength], 1613 &psecuritypriv->PMKIDList[iEntry].PMKID, 16); 1614 ielength += 16; 1615 out_ie[13] += 18;/*PMKID length = 2+16*/ 1616 } 1617 } 1618 return ielength; 1619} 1620 1621void r8712_init_registrypriv_dev_network(struct _adapter *adapter) 1622{ 1623 struct registry_priv *pregistrypriv = &adapter->registrypriv; 1624 struct eeprom_priv *peepriv = &adapter->eeprompriv; 1625 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; 1626 u8 *myhwaddr = myid(peepriv); 1627 1628 memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN); 1629 memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, 1630 sizeof(struct ndis_802_11_ssid)); 1631 pdev_network->Configuration.Length = 1632 sizeof(struct NDIS_802_11_CONFIGURATION); 1633 pdev_network->Configuration.BeaconPeriod = 100; 1634 pdev_network->Configuration.FHConfig.Length = 0; 1635 pdev_network->Configuration.FHConfig.HopPattern = 0; 1636 pdev_network->Configuration.FHConfig.HopSet = 0; 1637 pdev_network->Configuration.FHConfig.DwellTime = 0; 1638} 1639 1640void r8712_update_registrypriv_dev_network(struct _adapter *adapter) 1641{ 1642 int sz = 0; 1643 struct registry_priv *pregistrypriv = &adapter->registrypriv; 1644 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; 1645 struct security_priv *psecuritypriv = &adapter->securitypriv; 1646 struct wlan_network *cur_network = &adapter->mlmepriv.cur_network; 1647 1648 pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm 1649 > 0 ? 1 : 0); /* adhoc no 802.1x */ 1650 pdev_network->Rssi = 0; 1651 switch (pregistrypriv->wireless_mode) { 1652 case WIRELESS_11B: 1653 pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11DS); 1654 break; 1655 case WIRELESS_11G: 1656 case WIRELESS_11BG: 1657 pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11OFDM24); 1658 break; 1659 case WIRELESS_11A: 1660 pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11OFDM5); 1661 break; 1662 default: 1663 /* TODO */ 1664 break; 1665 } 1666 pdev_network->Configuration.DSConfig = cpu_to_le32( 1667 pregistrypriv->channel); 1668 if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) 1669 pdev_network->Configuration.ATIMWindow = cpu_to_le32(3); 1670 pdev_network->InfrastructureMode = cpu_to_le32( 1671 cur_network->network.InfrastructureMode); 1672 /* 1. Supported rates 1673 * 2. IE 1674 */ 1675 sz = r8712_generate_ie(pregistrypriv); 1676 pdev_network->IELength = sz; 1677 pdev_network->Length = r8712_get_ndis_wlan_bssid_ex_sz( 1678 (struct ndis_wlan_bssid_ex *)pdev_network); 1679} 1680 1681/*the function is at passive_level*/ 1682void r8712_joinbss_reset(struct _adapter *padapter) 1683{ 1684 int i; 1685 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1686 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 1687 1688 /* todo: if you want to do something io/reg/hw setting before join_bss, 1689 * please add code here */ 1690 phtpriv->ampdu_enable = false;/*reset to disabled*/ 1691 for (i = 0; i < 16; i++) 1692 phtpriv->baddbareq_issued[i] = false;/*reset it*/ 1693 if (phtpriv->ht_option) { 1694 /* validate usb rx aggregation */ 1695 r8712_write8(padapter, 0x102500D9, 48);/*TH = 48 pages, 6k*/ 1696 } else { 1697 /* invalidate usb rx aggregation */ 1698 /* TH=1 => means that invalidate usb rx aggregation */ 1699 r8712_write8(padapter, 0x102500D9, 1); 1700 } 1701} 1702 1703/*the function is >= passive_level*/ 1704unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, 1705 u8 *out_ie, uint in_len, uint *pout_len) 1706{ 1707 u32 ielen, out_len; 1708 unsigned char *p, *pframe; 1709 struct ieee80211_ht_cap ht_capie; 1710 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; 1711 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1712 struct qos_priv *pqospriv = &pmlmepriv->qospriv; 1713 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 1714 1715 phtpriv->ht_option = 0; 1716 p = r8712_get_ie(in_ie+12, _HT_CAPABILITY_IE_, &ielen, in_len-12); 1717 if (p && (ielen > 0)) { 1718 if (pqospriv->qos_option == 0) { 1719 out_len = *pout_len; 1720 pframe = r8712_set_ie(out_ie+out_len, 1721 _VENDOR_SPECIFIC_IE_, 1722 _WMM_IE_Length_, 1723 WMM_IE, pout_len); 1724 pqospriv->qos_option = 1; 1725 } 1726 out_len = *pout_len; 1727 memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap)); 1728 ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH | 1729 IEEE80211_HT_CAP_SGI_20 | 1730 IEEE80211_HT_CAP_SGI_40 | 1731 IEEE80211_HT_CAP_TX_STBC | 1732 IEEE80211_HT_CAP_MAX_AMSDU | 1733 IEEE80211_HT_CAP_DSSSCCK40; 1734 ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR & 1735 0x03) | (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00); 1736 pframe = r8712_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_, 1737 sizeof(struct ieee80211_ht_cap), 1738 (unsigned char *)&ht_capie, pout_len); 1739 phtpriv->ht_option = 1; 1740 } 1741 return phtpriv->ht_option; 1742} 1743 1744/* the function is > passive_level (in critical_section) */ 1745static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len) 1746{ 1747 u8 *p, max_ampdu_sz; 1748 int i, len; 1749 struct sta_info *bmc_sta, *psta; 1750 struct ieee80211_ht_cap *pht_capie; 1751 struct ieee80211_ht_addt_info *pht_addtinfo; 1752 struct recv_reorder_ctrl *preorder_ctrl; 1753 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1754 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 1755 struct registry_priv *pregistrypriv = &padapter->registrypriv; 1756 struct wlan_network *pcur_network = &(pmlmepriv->cur_network); 1757 1758 if (!phtpriv->ht_option) 1759 return; 1760 /* maybe needs check if ap supports rx ampdu. */ 1761 if ((phtpriv->ampdu_enable == false) && 1762 (pregistrypriv->ampdu_enable == 1)) 1763 phtpriv->ampdu_enable = true; 1764 /*check Max Rx A-MPDU Size*/ 1765 len = 0; 1766 p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs), 1767 _HT_CAPABILITY_IE_, 1768 &len, ie_len - 1769 sizeof(struct NDIS_802_11_FIXED_IEs)); 1770 if (p && len > 0) { 1771 pht_capie = (struct ieee80211_ht_cap *)(p+2); 1772 max_ampdu_sz = (pht_capie->ampdu_params_info & 1773 IEEE80211_HT_CAP_AMPDU_FACTOR); 1774 /* max_ampdu_sz (kbytes); */ 1775 max_ampdu_sz = 1 << (max_ampdu_sz+3); 1776 phtpriv->rx_ampdu_maxlen = max_ampdu_sz; 1777 } 1778 /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info 1779 * if A-MPDU Rx is enabled, resetting rx_ordering_ctrl 1780 * wstart_b(indicate_seq) to default value=0xffff 1781 * todo: check if AP can send A-MPDU packets 1782 */ 1783 bmc_sta = r8712_get_bcmc_stainfo(padapter); 1784 if (bmc_sta) { 1785 for (i = 0; i < 16; i++) { 1786 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; 1787 preorder_ctrl->indicate_seq = 0xffff; 1788 preorder_ctrl->wend_b = 0xffff; 1789 } 1790 } 1791 psta = r8712_get_stainfo(&padapter->stapriv, 1792 pcur_network->network.MacAddress); 1793 if (psta) { 1794 for (i = 0; i < 16; i++) { 1795 preorder_ctrl = &psta->recvreorder_ctrl[i]; 1796 preorder_ctrl->indicate_seq = 0xffff; 1797 preorder_ctrl->wend_b = 0xffff; 1798 } 1799 } 1800 len = 0; 1801 p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs), 1802 _HT_ADD_INFO_IE_, &len, 1803 ie_len-sizeof(struct NDIS_802_11_FIXED_IEs)); 1804 if (p && len > 0) 1805 pht_addtinfo = (struct ieee80211_ht_addt_info *)(p + 2); 1806} 1807 1808void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority) 1809{ 1810 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1811 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 1812 1813 if ((phtpriv->ht_option == 1) && (phtpriv->ampdu_enable == true)) { 1814 if (phtpriv->baddbareq_issued[priority] == false) { 1815 r8712_addbareq_cmd(padapter, (u8)priority); 1816 phtpriv->baddbareq_issued[priority] = true; 1817 } 1818 } 1819} 1820