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