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