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