Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.1 1151 lines 33 kB view raw
1/****************************************************************************** 2 * 3 * Copyright(c) 2009-2010 Realtek Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 17 * 18 * The full GNU General Public License is included in this distribution in the 19 * file called LICENSE. 20 * 21 * Contact Information: 22 * wlanfae <wlanfae@realtek.com> 23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, 24 * Hsinchu 300, Taiwan. 25 * 26 * Larry Finger <Larry.Finger@lwfinger.net> 27 * 28 *****************************************************************************/ 29 30#include "wifi.h" 31#include "core.h" 32#include "cam.h" 33#include "base.h" 34#include "ps.h" 35 36/*mutex for start & stop is must here. */ 37static int rtl_op_start(struct ieee80211_hw *hw) 38{ 39 int err; 40 struct rtl_priv *rtlpriv = rtl_priv(hw); 41 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 42 43 if (!is_hal_stop(rtlhal)) 44 return 0; 45 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) 46 return 0; 47 mutex_lock(&rtlpriv->locks.conf_mutex); 48 err = rtlpriv->intf_ops->adapter_start(hw); 49 if (!err) 50 rtl_watch_dog_timer_callback((unsigned long)hw); 51 mutex_unlock(&rtlpriv->locks.conf_mutex); 52 return err; 53} 54 55static void rtl_op_stop(struct ieee80211_hw *hw) 56{ 57 struct rtl_priv *rtlpriv = rtl_priv(hw); 58 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 59 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 60 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 61 62 if (is_hal_stop(rtlhal)) 63 return; 64 65 if (unlikely(ppsc->rfpwr_state == ERFOFF)) { 66 rtl_ips_nic_on(hw); 67 mdelay(1); 68 } 69 70 mutex_lock(&rtlpriv->locks.conf_mutex); 71 72 mac->link_state = MAC80211_NOLINK; 73 memset(mac->bssid, 0, 6); 74 mac->vendor = PEER_UNKNOWN; 75 76 /*reset sec info */ 77 rtl_cam_reset_sec_info(hw); 78 79 rtl_deinit_deferred_work(hw); 80 rtlpriv->intf_ops->adapter_stop(hw); 81 82 mutex_unlock(&rtlpriv->locks.conf_mutex); 83} 84 85static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 86{ 87 struct rtl_priv *rtlpriv = rtl_priv(hw); 88 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 89 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 90 struct rtl_tcb_desc tcb_desc; 91 memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); 92 93 if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON)) 94 goto err_free; 95 96 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) 97 goto err_free; 98 99 if (!rtlpriv->intf_ops->waitq_insert(hw, skb)) 100 rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); 101 102 return; 103 104err_free: 105 dev_kfree_skb_any(skb); 106} 107 108static int rtl_op_add_interface(struct ieee80211_hw *hw, 109 struct ieee80211_vif *vif) 110{ 111 struct rtl_priv *rtlpriv = rtl_priv(hw); 112 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 113 int err = 0; 114 115 if (mac->vif) { 116 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 117 ("vif has been set!! mac->vif = 0x%p\n", mac->vif)); 118 return -EOPNOTSUPP; 119 } 120 121 rtl_ips_nic_on(hw); 122 123 mutex_lock(&rtlpriv->locks.conf_mutex); 124 switch (vif->type) { 125 case NL80211_IFTYPE_STATION: 126 if (mac->beacon_enabled == 1) { 127 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 128 ("NL80211_IFTYPE_STATION\n")); 129 mac->beacon_enabled = 0; 130 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, 131 rtlpriv->cfg->maps 132 [RTL_IBSS_INT_MASKS]); 133 } 134 break; 135 case NL80211_IFTYPE_ADHOC: 136 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 137 ("NL80211_IFTYPE_ADHOC\n")); 138 139 mac->link_state = MAC80211_LINKED; 140 rtlpriv->cfg->ops->set_bcn_reg(hw); 141 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) 142 mac->basic_rates = 0xfff; 143 else 144 mac->basic_rates = 0xff0; 145 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, 146 (u8 *) (&mac->basic_rates)); 147 148 break; 149 case NL80211_IFTYPE_AP: 150 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 151 ("NL80211_IFTYPE_AP\n")); 152 153 mac->link_state = MAC80211_LINKED; 154 rtlpriv->cfg->ops->set_bcn_reg(hw); 155 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) 156 mac->basic_rates = 0xfff; 157 else 158 mac->basic_rates = 0xff0; 159 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, 160 (u8 *) (&mac->basic_rates)); 161 break; 162 default: 163 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 164 ("operation mode %d is not support!\n", vif->type)); 165 err = -EOPNOTSUPP; 166 goto out; 167 } 168 169 mac->vif = vif; 170 mac->opmode = vif->type; 171 rtlpriv->cfg->ops->set_network_type(hw, vif->type); 172 memcpy(mac->mac_addr, vif->addr, ETH_ALEN); 173 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); 174 175out: 176 mutex_unlock(&rtlpriv->locks.conf_mutex); 177 return err; 178} 179 180static void rtl_op_remove_interface(struct ieee80211_hw *hw, 181 struct ieee80211_vif *vif) 182{ 183 struct rtl_priv *rtlpriv = rtl_priv(hw); 184 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 185 186 mutex_lock(&rtlpriv->locks.conf_mutex); 187 188 /* Free beacon resources */ 189 if ((mac->opmode == NL80211_IFTYPE_AP) || 190 (mac->opmode == NL80211_IFTYPE_ADHOC) || 191 (mac->opmode == NL80211_IFTYPE_MESH_POINT)) { 192 if (mac->beacon_enabled == 1) { 193 mac->beacon_enabled = 0; 194 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, 195 rtlpriv->cfg->maps 196 [RTL_IBSS_INT_MASKS]); 197 } 198 } 199 200 /* 201 *Note: We assume NL80211_IFTYPE_UNSPECIFIED as 202 *NO LINK for our hardware. 203 */ 204 mac->vif = NULL; 205 mac->link_state = MAC80211_NOLINK; 206 memset(mac->bssid, 0, 6); 207 mac->vendor = PEER_UNKNOWN; 208 mac->opmode = NL80211_IFTYPE_UNSPECIFIED; 209 rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); 210 mutex_unlock(&rtlpriv->locks.conf_mutex); 211} 212 213static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) 214{ 215 struct rtl_priv *rtlpriv = rtl_priv(hw); 216 struct rtl_phy *rtlphy = &(rtlpriv->phy); 217 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 218 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 219 struct ieee80211_conf *conf = &hw->conf; 220 221 mutex_lock(&rtlpriv->locks.conf_mutex); 222 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /*BIT(2)*/ 223 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 224 ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n")); 225 } 226 227 /*For IPS */ 228 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 229 if (hw->conf.flags & IEEE80211_CONF_IDLE) 230 rtl_ips_nic_off(hw); 231 else 232 rtl_ips_nic_on(hw); 233 } else { 234 /* 235 *although rfoff may not cause by ips, but we will 236 *check the reason in set_rf_power_state function 237 */ 238 if (unlikely(ppsc->rfpwr_state == ERFOFF)) 239 rtl_ips_nic_on(hw); 240 } 241 242 /*For LPS */ 243 if (changed & IEEE80211_CONF_CHANGE_PS) { 244 cancel_delayed_work(&rtlpriv->works.ps_work); 245 cancel_delayed_work(&rtlpriv->works.ps_rfon_wq); 246 if (conf->flags & IEEE80211_CONF_PS) { 247 rtlpriv->psc.sw_ps_enabled = true; 248 /* sleep here is must, or we may recv the beacon and 249 * cause mac80211 into wrong ps state, this will cause 250 * power save nullfunc send fail, and further cause 251 * pkt loss, So sleep must quickly but not immediatly 252 * because that will cause nullfunc send by mac80211 253 * fail, and cause pkt loss, we have tested that 5mA 254 * is worked very well */ 255 if (!rtlpriv->psc.multi_buffered) 256 queue_delayed_work(rtlpriv->works.rtl_wq, 257 &rtlpriv->works.ps_work, 258 MSECS(5)); 259 } else { 260 rtl_swlps_rf_awake(hw); 261 rtlpriv->psc.sw_ps_enabled = false; 262 } 263 } 264 265 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { 266 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 267 ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", 268 hw->conf.long_frame_max_tx_count)); 269 mac->retry_long = hw->conf.long_frame_max_tx_count; 270 mac->retry_short = hw->conf.long_frame_max_tx_count; 271 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, 272 (u8 *) (&hw->conf. 273 long_frame_max_tx_count)); 274 } 275 276 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 277 struct ieee80211_channel *channel = hw->conf.channel; 278 u8 wide_chan = (u8) channel->hw_value; 279 280 /* 281 *because we should back channel to 282 *current_network.chan in in scanning, 283 *So if set_chan == current_network.chan 284 *we should set it. 285 *because mac80211 tell us wrong bw40 286 *info for cisco1253 bw20, so we modify 287 *it here based on UPPER & LOWER 288 */ 289 switch (hw->conf.channel_type) { 290 case NL80211_CHAN_HT20: 291 case NL80211_CHAN_NO_HT: 292 /* SC */ 293 mac->cur_40_prime_sc = 294 PRIME_CHNL_OFFSET_DONT_CARE; 295 rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20; 296 mac->bw_40 = false; 297 break; 298 case NL80211_CHAN_HT40MINUS: 299 /* SC */ 300 mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER; 301 rtlphy->current_chan_bw = 302 HT_CHANNEL_WIDTH_20_40; 303 mac->bw_40 = true; 304 305 /*wide channel */ 306 wide_chan -= 2; 307 308 break; 309 case NL80211_CHAN_HT40PLUS: 310 /* SC */ 311 mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER; 312 rtlphy->current_chan_bw = 313 HT_CHANNEL_WIDTH_20_40; 314 mac->bw_40 = true; 315 316 /*wide channel */ 317 wide_chan += 2; 318 319 break; 320 default: 321 mac->bw_40 = false; 322 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 323 ("switch case not processed\n")); 324 break; 325 } 326 327 if (wide_chan <= 0) 328 wide_chan = 1; 329 330 /* In scanning, before we go offchannel we may send a ps=1 null 331 * to AP, and then we may send a ps = 0 null to AP quickly, but 332 * first null may have caused AP to put lots of packet to hw tx 333 * buffer. These packets must be tx'd before we go off channel 334 * so we must delay more time to let AP flush these packets 335 * before going offchannel, or dis-association or delete BA will 336 * happen by AP 337 */ 338 if (rtlpriv->mac80211.offchan_delay) { 339 rtlpriv->mac80211.offchan_delay = false; 340 mdelay(50); 341 } 342 rtlphy->current_channel = wide_chan; 343 344 rtlpriv->cfg->ops->switch_channel(hw); 345 rtlpriv->cfg->ops->set_channel_access(hw); 346 rtlpriv->cfg->ops->set_bw_mode(hw, 347 hw->conf.channel_type); 348 } 349 350 mutex_unlock(&rtlpriv->locks.conf_mutex); 351 352 return 0; 353} 354 355static void rtl_op_configure_filter(struct ieee80211_hw *hw, 356 unsigned int changed_flags, 357 unsigned int *new_flags, u64 multicast) 358{ 359 struct rtl_priv *rtlpriv = rtl_priv(hw); 360 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 361 362 *new_flags &= RTL_SUPPORTED_FILTERS; 363 if (!changed_flags) 364 return; 365 366 /*TODO: we disable broadcase now, so enable here */ 367 if (changed_flags & FIF_ALLMULTI) { 368 if (*new_flags & FIF_ALLMULTI) { 369 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] | 370 rtlpriv->cfg->maps[MAC_RCR_AB]; 371 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 372 ("Enable receive multicast frame.\n")); 373 } else { 374 mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] | 375 rtlpriv->cfg->maps[MAC_RCR_AB]); 376 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 377 ("Disable receive multicast frame.\n")); 378 } 379 } 380 381 if (changed_flags & FIF_FCSFAIL) { 382 if (*new_flags & FIF_FCSFAIL) { 383 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32]; 384 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 385 ("Enable receive FCS error frame.\n")); 386 } else { 387 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32]; 388 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 389 ("Disable receive FCS error frame.\n")); 390 } 391 } 392 393 /* if ssid not set to hw don't check bssid 394 * here just used for linked scanning, & linked 395 * and nolink check bssid is set in set network_type */ 396 if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) && 397 (mac->link_state >= MAC80211_LINKED)) { 398 if (mac->opmode != NL80211_IFTYPE_AP) { 399 if (*new_flags & FIF_BCN_PRBRESP_PROMISC) { 400 rtlpriv->cfg->ops->set_chk_bssid(hw, false); 401 } else { 402 rtlpriv->cfg->ops->set_chk_bssid(hw, true); 403 } 404 } 405 } 406 407 if (changed_flags & FIF_CONTROL) { 408 if (*new_flags & FIF_CONTROL) { 409 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; 410 411 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 412 ("Enable receive control frame.\n")); 413 } else { 414 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; 415 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 416 ("Disable receive control frame.\n")); 417 } 418 } 419 420 if (changed_flags & FIF_OTHER_BSS) { 421 if (*new_flags & FIF_OTHER_BSS) { 422 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP]; 423 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 424 ("Enable receive other BSS's frame.\n")); 425 } else { 426 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP]; 427 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 428 ("Disable receive other BSS's frame.\n")); 429 } 430 } 431} 432static int rtl_op_sta_add(struct ieee80211_hw *hw, 433 struct ieee80211_vif *vif, 434 struct ieee80211_sta *sta) 435{ 436 struct rtl_priv *rtlpriv = rtl_priv(hw); 437 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 438 struct rtl_sta_info *sta_entry; 439 440 if (sta) { 441 sta_entry = (struct rtl_sta_info *) sta->drv_priv; 442 if (rtlhal->current_bandtype == BAND_ON_2_4G) { 443 sta_entry->wireless_mode = WIRELESS_MODE_G; 444 if (sta->supp_rates[0] <= 0xf) 445 sta_entry->wireless_mode = WIRELESS_MODE_B; 446 if (sta->ht_cap.ht_supported) 447 sta_entry->wireless_mode = WIRELESS_MODE_N_24G; 448 } else if (rtlhal->current_bandtype == BAND_ON_5G) { 449 sta_entry->wireless_mode = WIRELESS_MODE_A; 450 if (sta->ht_cap.ht_supported) 451 sta_entry->wireless_mode = WIRELESS_MODE_N_24G; 452 } 453 454 /* I found some times mac80211 give wrong supp_rates for adhoc*/ 455 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) 456 sta_entry->wireless_mode = WIRELESS_MODE_G; 457 458 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, 459 ("Add sta addr is %pM\n", sta->addr)); 460 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); 461 } 462 return 0; 463} 464static int rtl_op_sta_remove(struct ieee80211_hw *hw, 465 struct ieee80211_vif *vif, 466 struct ieee80211_sta *sta) 467{ 468 struct rtl_priv *rtlpriv = rtl_priv(hw); 469 struct rtl_sta_info *sta_entry; 470 if (sta) { 471 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, 472 ("Remove sta addr is %pM\n", sta->addr)); 473 sta_entry = (struct rtl_sta_info *) sta->drv_priv; 474 sta_entry->wireless_mode = 0; 475 sta_entry->ratr_index = 0; 476 } 477 return 0; 478} 479static int _rtl_get_hal_qnum(u16 queue) 480{ 481 int qnum; 482 483 switch (queue) { 484 case 0: 485 qnum = AC3_VO; 486 break; 487 case 1: 488 qnum = AC2_VI; 489 break; 490 case 2: 491 qnum = AC0_BE; 492 break; 493 case 3: 494 qnum = AC1_BK; 495 break; 496 default: 497 qnum = AC0_BE; 498 break; 499 } 500 return qnum; 501} 502 503/* 504 *for mac80211 VO=0, VI=1, BE=2, BK=3 505 *for rtl819x BE=0, BK=1, VI=2, VO=3 506 */ 507static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue, 508 const struct ieee80211_tx_queue_params *param) 509{ 510 struct rtl_priv *rtlpriv = rtl_priv(hw); 511 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 512 int aci; 513 514 if (queue >= AC_MAX) { 515 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 516 ("queue number %d is incorrect!\n", queue)); 517 return -EINVAL; 518 } 519 520 aci = _rtl_get_hal_qnum(queue); 521 mac->ac[aci].aifs = param->aifs; 522 mac->ac[aci].cw_min = cpu_to_le16(param->cw_min); 523 mac->ac[aci].cw_max = cpu_to_le16(param->cw_max); 524 mac->ac[aci].tx_op = cpu_to_le16(param->txop); 525 memcpy(&mac->edca_param[aci], param, sizeof(*param)); 526 rtlpriv->cfg->ops->set_qos(hw, aci); 527 return 0; 528} 529 530static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, 531 struct ieee80211_vif *vif, 532 struct ieee80211_bss_conf *bss_conf, u32 changed) 533{ 534 struct rtl_priv *rtlpriv = rtl_priv(hw); 535 struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 536 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 537 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 538 struct ieee80211_sta *sta = NULL; 539 540 mutex_lock(&rtlpriv->locks.conf_mutex); 541 if ((vif->type == NL80211_IFTYPE_ADHOC) || 542 (vif->type == NL80211_IFTYPE_AP) || 543 (vif->type == NL80211_IFTYPE_MESH_POINT)) { 544 if ((changed & BSS_CHANGED_BEACON) || 545 (changed & BSS_CHANGED_BEACON_ENABLED && 546 bss_conf->enable_beacon)) { 547 if (mac->beacon_enabled == 0) { 548 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, 549 ("BSS_CHANGED_BEACON_ENABLED\n")); 550 551 /*start hw beacon interrupt. */ 552 /*rtlpriv->cfg->ops->set_bcn_reg(hw); */ 553 mac->beacon_enabled = 1; 554 rtlpriv->cfg->ops->update_interrupt_mask(hw, 555 rtlpriv->cfg->maps 556 [RTL_IBSS_INT_MASKS], 557 0); 558 559 if (rtlpriv->cfg->ops->linked_set_reg) 560 rtlpriv->cfg->ops->linked_set_reg(hw); 561 } 562 } 563 if ((changed & BSS_CHANGED_BEACON_ENABLED && 564 !bss_conf->enable_beacon)) { 565 if (mac->beacon_enabled == 1) { 566 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, 567 ("ADHOC DISABLE BEACON\n")); 568 569 mac->beacon_enabled = 0; 570 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, 571 rtlpriv->cfg->maps 572 [RTL_IBSS_INT_MASKS]); 573 } 574 } 575 if (changed & BSS_CHANGED_BEACON_INT) { 576 RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE, 577 ("BSS_CHANGED_BEACON_INT\n")); 578 mac->beacon_interval = bss_conf->beacon_int; 579 rtlpriv->cfg->ops->set_bcn_intv(hw); 580 } 581 } 582 583 /*TODO: reference to enum ieee80211_bss_change */ 584 if (changed & BSS_CHANGED_ASSOC) { 585 if (bss_conf->assoc) { 586 /* we should reset all sec info & cam 587 * before set cam after linked, we should not 588 * reset in disassoc, that will cause tkip->wep 589 * fail because some flag will be wrong */ 590 /* reset sec info */ 591 rtl_cam_reset_sec_info(hw); 592 /* reset cam to fix wep fail issue 593 * when change from wpa to wep */ 594 rtl_cam_reset_all_entry(hw); 595 596 mac->link_state = MAC80211_LINKED; 597 mac->cnt_after_linked = 0; 598 mac->assoc_id = bss_conf->aid; 599 memcpy(mac->bssid, bss_conf->bssid, 6); 600 601 if (rtlpriv->cfg->ops->linked_set_reg) 602 rtlpriv->cfg->ops->linked_set_reg(hw); 603 if (mac->opmode == NL80211_IFTYPE_STATION && sta) 604 rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); 605 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, 606 ("BSS_CHANGED_ASSOC\n")); 607 } else { 608 if (mac->link_state == MAC80211_LINKED) 609 rtl_lps_leave(hw); 610 611 mac->link_state = MAC80211_NOLINK; 612 memset(mac->bssid, 0, 6); 613 614 /* reset sec info */ 615 rtl_cam_reset_sec_info(hw); 616 617 rtl_cam_reset_all_entry(hw); 618 mac->vendor = PEER_UNKNOWN; 619 620 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, 621 ("BSS_CHANGED_UN_ASSOC\n")); 622 } 623 } 624 625 if (changed & BSS_CHANGED_ERP_CTS_PROT) { 626 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, 627 ("BSS_CHANGED_ERP_CTS_PROT\n")); 628 mac->use_cts_protect = bss_conf->use_cts_prot; 629 } 630 631 if (changed & BSS_CHANGED_ERP_PREAMBLE) { 632 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 633 ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", 634 bss_conf->use_short_preamble)); 635 636 mac->short_preamble = bss_conf->use_short_preamble; 637 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE, 638 (u8 *) (&mac->short_preamble)); 639 } 640 641 if (changed & BSS_CHANGED_ERP_SLOT) { 642 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, 643 ("BSS_CHANGED_ERP_SLOT\n")); 644 645 if (bss_conf->use_short_slot) 646 mac->slot_time = RTL_SLOT_TIME_9; 647 else 648 mac->slot_time = RTL_SLOT_TIME_20; 649 650 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, 651 (u8 *) (&mac->slot_time)); 652 } 653 654 if (changed & BSS_CHANGED_HT) { 655 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, 656 ("BSS_CHANGED_HT\n")); 657 rcu_read_lock(); 658 sta = get_sta(hw, vif, bss_conf->bssid); 659 if (sta) { 660 if (sta->ht_cap.ampdu_density > 661 mac->current_ampdu_density) 662 mac->current_ampdu_density = 663 sta->ht_cap.ampdu_density; 664 if (sta->ht_cap.ampdu_factor < 665 mac->current_ampdu_factor) 666 mac->current_ampdu_factor = 667 sta->ht_cap.ampdu_factor; 668 } 669 rcu_read_unlock(); 670 671 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY, 672 (u8 *) (&mac->max_mss_density)); 673 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR, 674 &mac->current_ampdu_factor); 675 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE, 676 &mac->current_ampdu_density); 677 } 678 679 if (changed & BSS_CHANGED_BSSID) { 680 u32 basic_rates; 681 682 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, 683 (u8 *) bss_conf->bssid); 684 685 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, 686 ("%pM\n", bss_conf->bssid)); 687 688 mac->vendor = PEER_UNKNOWN; 689 memcpy(mac->bssid, bss_conf->bssid, 6); 690 rtlpriv->cfg->ops->set_network_type(hw, vif->type); 691 692 rcu_read_lock(); 693 sta = get_sta(hw, vif, bss_conf->bssid); 694 if (!sta) { 695 rcu_read_unlock(); 696 goto out; 697 } 698 699 if (rtlhal->current_bandtype == BAND_ON_5G) { 700 mac->mode = WIRELESS_MODE_A; 701 } else { 702 if (sta->supp_rates[0] <= 0xf) 703 mac->mode = WIRELESS_MODE_B; 704 else 705 mac->mode = WIRELESS_MODE_G; 706 } 707 708 if (sta->ht_cap.ht_supported) { 709 if (rtlhal->current_bandtype == BAND_ON_2_4G) 710 mac->mode = WIRELESS_MODE_N_24G; 711 else 712 mac->mode = WIRELESS_MODE_N_5G; 713 } 714 715 /* just station need it, because ibss & ap mode will 716 * set in sta_add, and will be NULL here */ 717 if (mac->opmode == NL80211_IFTYPE_STATION) { 718 struct rtl_sta_info *sta_entry; 719 sta_entry = (struct rtl_sta_info *) sta->drv_priv; 720 sta_entry->wireless_mode = mac->mode; 721 } 722 723 if (sta->ht_cap.ht_supported) { 724 mac->ht_enable = true; 725 726 /* 727 * for cisco 1252 bw20 it's wrong 728 * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { 729 * mac->bw_40 = true; 730 * } 731 * */ 732 } 733 734 if (changed & BSS_CHANGED_BASIC_RATES) { 735 /* for 5G must << RATE_6M_INDEX=4, 736 * because 5G have no cck rate*/ 737 if (rtlhal->current_bandtype == BAND_ON_5G) 738 basic_rates = sta->supp_rates[1] << 4; 739 else 740 basic_rates = sta->supp_rates[0]; 741 742 mac->basic_rates = basic_rates; 743 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, 744 (u8 *) (&basic_rates)); 745 } 746 rcu_read_unlock(); 747 } 748 749 /* 750 * For FW LPS: 751 * To tell firmware we have connected 752 * to an AP. For 92SE/CE power save v2. 753 */ 754 if (changed & BSS_CHANGED_ASSOC) { 755 if (bss_conf->assoc) { 756 if (ppsc->fwctrl_lps) { 757 u8 mstatus = RT_MEDIA_CONNECT; 758 rtlpriv->cfg->ops->set_hw_reg(hw, 759 HW_VAR_H2C_FW_JOINBSSRPT, 760 (u8 *) (&mstatus)); 761 ppsc->report_linked = true; 762 } 763 } else { 764 if (ppsc->fwctrl_lps) { 765 u8 mstatus = RT_MEDIA_DISCONNECT; 766 rtlpriv->cfg->ops->set_hw_reg(hw, 767 HW_VAR_H2C_FW_JOINBSSRPT, 768 (u8 *)(&mstatus)); 769 ppsc->report_linked = false; 770 } 771 } 772 } 773 774out: 775 mutex_unlock(&rtlpriv->locks.conf_mutex); 776} 777 778static u64 rtl_op_get_tsf(struct ieee80211_hw *hw) 779{ 780 struct rtl_priv *rtlpriv = rtl_priv(hw); 781 u64 tsf; 782 783 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&tsf)); 784 return tsf; 785} 786 787static void rtl_op_set_tsf(struct ieee80211_hw *hw, u64 tsf) 788{ 789 struct rtl_priv *rtlpriv = rtl_priv(hw); 790 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 791 u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; 792 793 mac->tsf = tsf; 794 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&bibss)); 795} 796 797static void rtl_op_reset_tsf(struct ieee80211_hw *hw) 798{ 799 struct rtl_priv *rtlpriv = rtl_priv(hw); 800 u8 tmp = 0; 801 802 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *) (&tmp)); 803} 804 805static void rtl_op_sta_notify(struct ieee80211_hw *hw, 806 struct ieee80211_vif *vif, 807 enum sta_notify_cmd cmd, 808 struct ieee80211_sta *sta) 809{ 810 switch (cmd) { 811 case STA_NOTIFY_SLEEP: 812 break; 813 case STA_NOTIFY_AWAKE: 814 break; 815 default: 816 break; 817 } 818} 819 820static int rtl_op_ampdu_action(struct ieee80211_hw *hw, 821 struct ieee80211_vif *vif, 822 enum ieee80211_ampdu_mlme_action action, 823 struct ieee80211_sta *sta, u16 tid, u16 *ssn, 824 u8 buf_size) 825{ 826 struct rtl_priv *rtlpriv = rtl_priv(hw); 827 828 switch (action) { 829 case IEEE80211_AMPDU_TX_START: 830 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, 831 ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid)); 832 return rtl_tx_agg_start(hw, sta, tid, ssn); 833 break; 834 case IEEE80211_AMPDU_TX_STOP: 835 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, 836 ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid)); 837 return rtl_tx_agg_stop(hw, sta, tid); 838 break; 839 case IEEE80211_AMPDU_TX_OPERATIONAL: 840 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, 841 ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid)); 842 rtl_tx_agg_oper(hw, sta, tid); 843 break; 844 case IEEE80211_AMPDU_RX_START: 845 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, 846 ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid)); 847 break; 848 case IEEE80211_AMPDU_RX_STOP: 849 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, 850 ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid)); 851 break; 852 default: 853 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 854 ("IEEE80211_AMPDU_ERR!!!!:\n")); 855 return -EOPNOTSUPP; 856 } 857 return 0; 858} 859 860static void rtl_op_sw_scan_start(struct ieee80211_hw *hw) 861{ 862 struct rtl_priv *rtlpriv = rtl_priv(hw); 863 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 864 865 mac->act_scanning = true; 866 867 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); 868 869 if (mac->link_state == MAC80211_LINKED) { 870 rtl_lps_leave(hw); 871 mac->link_state = MAC80211_LINKED_SCANNING; 872 } else { 873 rtl_ips_nic_on(hw); 874 } 875 876 /* Dual mac */ 877 rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; 878 879 rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY); 880 rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP); 881} 882 883static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw) 884{ 885 struct rtl_priv *rtlpriv = rtl_priv(hw); 886 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 887 888 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); 889 mac->act_scanning = false; 890 /* Dual mac */ 891 rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; 892 893 if (mac->link_state == MAC80211_LINKED_SCANNING) { 894 mac->link_state = MAC80211_LINKED; 895 if (mac->opmode == NL80211_IFTYPE_STATION) { 896 /* fix fwlps issue */ 897 rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); 898 } 899 } 900 901 rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE); 902} 903 904static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 905 struct ieee80211_vif *vif, struct ieee80211_sta *sta, 906 struct ieee80211_key_conf *key) 907{ 908 struct rtl_priv *rtlpriv = rtl_priv(hw); 909 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 910 u8 key_type = NO_ENCRYPTION; 911 u8 key_idx; 912 bool group_key = false; 913 bool wep_only = false; 914 int err = 0; 915 u8 mac_addr[ETH_ALEN]; 916 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 917 u8 zero_addr[ETH_ALEN] = { 0 }; 918 919 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { 920 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 921 ("not open hw encryption\n")); 922 return -ENOSPC; /*User disabled HW-crypto */ 923 } 924 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 925 ("%s hardware based encryption for keyidx: %d, mac: %pM\n", 926 cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, 927 sta ? sta->addr : bcast_addr)); 928 rtlpriv->sec.being_setkey = true; 929 rtl_ips_nic_on(hw); 930 mutex_lock(&rtlpriv->locks.conf_mutex); 931 /* <1> get encryption alg */ 932 933 switch (key->cipher) { 934 case WLAN_CIPHER_SUITE_WEP40: 935 key_type = WEP40_ENCRYPTION; 936 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n")); 937 break; 938 case WLAN_CIPHER_SUITE_WEP104: 939 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 940 ("alg:WEP104\n")); 941 key_type = WEP104_ENCRYPTION; 942 break; 943 case WLAN_CIPHER_SUITE_TKIP: 944 key_type = TKIP_ENCRYPTION; 945 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n")); 946 break; 947 case WLAN_CIPHER_SUITE_CCMP: 948 key_type = AESCCMP_ENCRYPTION; 949 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n")); 950 break; 951 default: 952 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 953 ("alg_err:%x!!!!:\n", key->cipher)); 954 goto out_unlock; 955 } 956 if (key_type == WEP40_ENCRYPTION || 957 key_type == WEP104_ENCRYPTION || 958 mac->opmode == NL80211_IFTYPE_ADHOC) 959 rtlpriv->sec.use_defaultkey = true; 960 961 /* <2> get key_idx */ 962 key_idx = (u8) (key->keyidx); 963 if (key_idx > 3) 964 goto out_unlock; 965 /* <3> if pairwise key enable_hw_sec */ 966 group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE); 967 968 /* wep always be group key, but there are two conditions: 969 * 1) wep only: is just for wep enc, in this condition 970 * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION 971 * will be true & enable_hw_sec will be set when wep 972 * ke setting. 973 * 2) wep(group) + AES(pairwise): some AP like cisco 974 * may use it, in this condition enable_hw_sec will not 975 * be set when wep key setting */ 976 /* we must reset sec_info after lingked before set key, 977 * or some flag will be wrong*/ 978 if (mac->opmode == NL80211_IFTYPE_AP) { 979 if (!group_key || key_type == WEP40_ENCRYPTION || 980 key_type == WEP104_ENCRYPTION) { 981 if (group_key) 982 wep_only = true; 983 rtlpriv->cfg->ops->enable_hw_sec(hw); 984 } 985 } else { 986 if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) || 987 rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) { 988 if (rtlpriv->sec.pairwise_enc_algorithm == 989 NO_ENCRYPTION && 990 (key_type == WEP40_ENCRYPTION || 991 key_type == WEP104_ENCRYPTION)) 992 wep_only = true; 993 rtlpriv->sec.pairwise_enc_algorithm = key_type; 994 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 995 ("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1" 996 " TKIP:2 AES:4 WEP104:5)\n", key_type)); 997 rtlpriv->cfg->ops->enable_hw_sec(hw); 998 } 999 } 1000 /* <4> set key based on cmd */ 1001 switch (cmd) { 1002 case SET_KEY: 1003 if (wep_only) { 1004 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 1005 ("set WEP(group/pairwise) key\n")); 1006 /* Pairwise key with an assigned MAC address. */ 1007 rtlpriv->sec.pairwise_enc_algorithm = key_type; 1008 rtlpriv->sec.group_enc_algorithm = key_type; 1009 /*set local buf about wep key. */ 1010 memcpy(rtlpriv->sec.key_buf[key_idx], 1011 key->key, key->keylen); 1012 rtlpriv->sec.key_len[key_idx] = key->keylen; 1013 memcpy(mac_addr, zero_addr, ETH_ALEN); 1014 } else if (group_key) { /* group key */ 1015 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 1016 ("set group key\n")); 1017 /* group key */ 1018 rtlpriv->sec.group_enc_algorithm = key_type; 1019 /*set local buf about group key. */ 1020 memcpy(rtlpriv->sec.key_buf[key_idx], 1021 key->key, key->keylen); 1022 rtlpriv->sec.key_len[key_idx] = key->keylen; 1023 memcpy(mac_addr, bcast_addr, ETH_ALEN); 1024 } else { /* pairwise key */ 1025 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 1026 ("set pairwise key\n")); 1027 if (!sta) { 1028 RT_ASSERT(false, ("pairwise key withnot" 1029 "mac_addr\n")); 1030 1031 err = -EOPNOTSUPP; 1032 goto out_unlock; 1033 } 1034 /* Pairwise key with an assigned MAC address. */ 1035 rtlpriv->sec.pairwise_enc_algorithm = key_type; 1036 /*set local buf about pairwise key. */ 1037 memcpy(rtlpriv->sec.key_buf[PAIRWISE_KEYIDX], 1038 key->key, key->keylen); 1039 rtlpriv->sec.key_len[PAIRWISE_KEYIDX] = key->keylen; 1040 rtlpriv->sec.pairwise_key = 1041 rtlpriv->sec.key_buf[PAIRWISE_KEYIDX]; 1042 memcpy(mac_addr, sta->addr, ETH_ALEN); 1043 } 1044 rtlpriv->cfg->ops->set_key(hw, key_idx, mac_addr, 1045 group_key, key_type, wep_only, 1046 false); 1047 /* <5> tell mac80211 do something: */ 1048 /*must use sw generate IV, or can not work !!!!. */ 1049 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 1050 key->hw_key_idx = key_idx; 1051 if (key_type == TKIP_ENCRYPTION) 1052 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; 1053 break; 1054 case DISABLE_KEY: 1055 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, 1056 ("disable key delete one entry\n")); 1057 /*set local buf about wep key. */ 1058 if (mac->opmode == NL80211_IFTYPE_AP) { 1059 if (sta) 1060 rtl_cam_del_entry(hw, sta->addr); 1061 } 1062 memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen); 1063 rtlpriv->sec.key_len[key_idx] = 0; 1064 memcpy(mac_addr, zero_addr, ETH_ALEN); 1065 /* 1066 *mac80211 will delete entrys one by one, 1067 *so don't use rtl_cam_reset_all_entry 1068 *or clear all entry here. 1069 */ 1070 rtl_cam_delete_one_entry(hw, mac_addr, key_idx); 1071 1072 rtl_cam_reset_sec_info(hw); 1073 1074 break; 1075 default: 1076 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1077 ("cmd_err:%x!!!!:\n", cmd)); 1078 } 1079out_unlock: 1080 mutex_unlock(&rtlpriv->locks.conf_mutex); 1081 rtlpriv->sec.being_setkey = false; 1082 return err; 1083} 1084 1085static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) 1086{ 1087 struct rtl_priv *rtlpriv = rtl_priv(hw); 1088 1089 bool radio_state; 1090 bool blocked; 1091 u8 valid = 0; 1092 1093 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) 1094 return; 1095 1096 mutex_lock(&rtlpriv->locks.conf_mutex); 1097 1098 /*if Radio On return true here */ 1099 radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); 1100 1101 if (valid) { 1102 if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) { 1103 rtlpriv->rfkill.rfkill_state = radio_state; 1104 1105 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, 1106 (KERN_INFO "wireless radio switch turned %s\n", 1107 radio_state ? "on" : "off")); 1108 1109 blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; 1110 wiphy_rfkill_set_hw_state(hw->wiphy, blocked); 1111 } 1112 } 1113 1114 mutex_unlock(&rtlpriv->locks.conf_mutex); 1115} 1116 1117/* this function is called by mac80211 to flush tx buffer 1118 * before switch channle or power save, or tx buffer packet 1119 * maybe send after offchannel or rf sleep, this may cause 1120 * dis-association by AP */ 1121static void rtl_op_flush(struct ieee80211_hw *hw, bool drop) 1122{ 1123 struct rtl_priv *rtlpriv = rtl_priv(hw); 1124 1125 if (rtlpriv->intf_ops->flush) 1126 rtlpriv->intf_ops->flush(hw, drop); 1127} 1128 1129const struct ieee80211_ops rtl_ops = { 1130 .start = rtl_op_start, 1131 .stop = rtl_op_stop, 1132 .tx = rtl_op_tx, 1133 .add_interface = rtl_op_add_interface, 1134 .remove_interface = rtl_op_remove_interface, 1135 .config = rtl_op_config, 1136 .configure_filter = rtl_op_configure_filter, 1137 .sta_add = rtl_op_sta_add, 1138 .sta_remove = rtl_op_sta_remove, 1139 .set_key = rtl_op_set_key, 1140 .conf_tx = rtl_op_conf_tx, 1141 .bss_info_changed = rtl_op_bss_info_changed, 1142 .get_tsf = rtl_op_get_tsf, 1143 .set_tsf = rtl_op_set_tsf, 1144 .reset_tsf = rtl_op_reset_tsf, 1145 .sta_notify = rtl_op_sta_notify, 1146 .ampdu_action = rtl_op_ampdu_action, 1147 .sw_scan_start = rtl_op_sw_scan_start, 1148 .sw_scan_complete = rtl_op_sw_scan_complete, 1149 .rfkill_poll = rtl_op_rfkill_poll, 1150 .flush = rtl_op_flush, 1151};