linux/drivers/net/wireless/ath/ath9k/htc_drv_main.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2010-2011 Atheros Communications Inc.
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17#include "htc.h"
  18
  19/*************/
  20/* Utilities */
  21/*************/
  22
  23/* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */
  24static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
  25                                              struct ath9k_channel *ichan)
  26{
  27        enum htc_phymode mode;
  28
  29        mode = -EINVAL;
  30
  31        switch (ichan->chanmode) {
  32        case CHANNEL_G:
  33        case CHANNEL_G_HT20:
  34        case CHANNEL_G_HT40PLUS:
  35        case CHANNEL_G_HT40MINUS:
  36                mode = HTC_MODE_11NG;
  37                break;
  38        case CHANNEL_A:
  39        case CHANNEL_A_HT20:
  40        case CHANNEL_A_HT40PLUS:
  41        case CHANNEL_A_HT40MINUS:
  42                mode = HTC_MODE_11NA;
  43                break;
  44        default:
  45                break;
  46        }
  47
  48        WARN_ON(mode < 0);
  49
  50        return mode;
  51}
  52
  53bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
  54                        enum ath9k_power_mode mode)
  55{
  56        bool ret;
  57
  58        mutex_lock(&priv->htc_pm_lock);
  59        ret = ath9k_hw_setpower(priv->ah, mode);
  60        mutex_unlock(&priv->htc_pm_lock);
  61
  62        return ret;
  63}
  64
  65void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv)
  66{
  67        mutex_lock(&priv->htc_pm_lock);
  68        if (++priv->ps_usecount != 1)
  69                goto unlock;
  70        ath9k_hw_setpower(priv->ah, ATH9K_PM_AWAKE);
  71
  72unlock:
  73        mutex_unlock(&priv->htc_pm_lock);
  74}
  75
  76void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv)
  77{
  78        bool reset;
  79
  80        mutex_lock(&priv->htc_pm_lock);
  81        if (--priv->ps_usecount != 0)
  82                goto unlock;
  83
  84        if (priv->ps_idle) {
  85                ath9k_hw_setrxabort(priv->ah, true);
  86                ath9k_hw_stopdmarecv(priv->ah, &reset);
  87                ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP);
  88        } else if (priv->ps_enabled) {
  89                ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP);
  90        }
  91
  92unlock:
  93        mutex_unlock(&priv->htc_pm_lock);
  94}
  95
  96void ath9k_ps_work(struct work_struct *work)
  97{
  98        struct ath9k_htc_priv *priv =
  99                container_of(work, struct ath9k_htc_priv,
 100                             ps_work);
 101        ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
 102
 103        /* The chip wakes up after receiving the first beacon
 104           while network sleep is enabled. For the driver to
 105           be in sync with the hw, set the chip to awake and
 106           only then set it to sleep.
 107         */
 108        ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
 109}
 110
 111static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
 112{
 113        struct ath9k_htc_priv *priv = data;
 114        struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
 115
 116        if ((vif->type == NL80211_IFTYPE_AP ||
 117             vif->type == NL80211_IFTYPE_MESH_POINT) &&
 118            bss_conf->enable_beacon)
 119                priv->reconfig_beacon = true;
 120
 121        if (bss_conf->assoc) {
 122                priv->rearm_ani = true;
 123                priv->reconfig_beacon = true;
 124        }
 125}
 126
 127static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv)
 128{
 129        priv->rearm_ani = false;
 130        priv->reconfig_beacon = false;
 131
 132        ieee80211_iterate_active_interfaces_atomic(
 133                priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
 134                ath9k_htc_vif_iter, priv);
 135        if (priv->rearm_ani)
 136                ath9k_htc_start_ani(priv);
 137
 138        if (priv->reconfig_beacon) {
 139                ath9k_htc_ps_wakeup(priv);
 140                ath9k_htc_beacon_reconfig(priv);
 141                ath9k_htc_ps_restore(priv);
 142        }
 143}
 144
 145static void ath9k_htc_bssid_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
 146{
 147        struct ath9k_vif_iter_data *iter_data = data;
 148        int i;
 149
 150        for (i = 0; i < ETH_ALEN; i++)
 151                iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);
 152}
 153
 154static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
 155                                     struct ieee80211_vif *vif)
 156{
 157        struct ath_common *common = ath9k_hw_common(priv->ah);
 158        struct ath9k_vif_iter_data iter_data;
 159
 160        /*
 161         * Use the hardware MAC address as reference, the hardware uses it
 162         * together with the BSSID mask when matching addresses.
 163         */
 164        iter_data.hw_macaddr = common->macaddr;
 165        memset(&iter_data.mask, 0xff, ETH_ALEN);
 166
 167        if (vif)
 168                ath9k_htc_bssid_iter(&iter_data, vif->addr, vif);
 169
 170        /* Get list of all active MAC addresses */
 171        ieee80211_iterate_active_interfaces_atomic(
 172                priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
 173                ath9k_htc_bssid_iter, &iter_data);
 174
 175        memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
 176        ath_hw_setbssidmask(common);
 177}
 178
 179static void ath9k_htc_set_opmode(struct ath9k_htc_priv *priv)
 180{
 181        if (priv->num_ibss_vif)
 182                priv->ah->opmode = NL80211_IFTYPE_ADHOC;
 183        else if (priv->num_ap_vif)
 184                priv->ah->opmode = NL80211_IFTYPE_AP;
 185        else if (priv->num_mbss_vif)
 186                priv->ah->opmode = NL80211_IFTYPE_MESH_POINT;
 187        else
 188                priv->ah->opmode = NL80211_IFTYPE_STATION;
 189
 190        ath9k_hw_setopmode(priv->ah);
 191}
 192
 193void ath9k_htc_reset(struct ath9k_htc_priv *priv)
 194{
 195        struct ath_hw *ah = priv->ah;
 196        struct ath_common *common = ath9k_hw_common(ah);
 197        struct ieee80211_channel *channel = priv->hw->conf.chandef.chan;
 198        struct ath9k_hw_cal_data *caldata = NULL;
 199        enum htc_phymode mode;
 200        __be16 htc_mode;
 201        u8 cmd_rsp;
 202        int ret;
 203
 204        mutex_lock(&priv->mutex);
 205        ath9k_htc_ps_wakeup(priv);
 206
 207        ath9k_htc_stop_ani(priv);
 208        ieee80211_stop_queues(priv->hw);
 209
 210        del_timer_sync(&priv->tx.cleanup_timer);
 211        ath9k_htc_tx_drain(priv);
 212
 213        WMI_CMD(WMI_DISABLE_INTR_CMDID);
 214        WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
 215        WMI_CMD(WMI_STOP_RECV_CMDID);
 216
 217        ath9k_wmi_event_drain(priv);
 218
 219        caldata = &priv->caldata;
 220        ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);
 221        if (ret) {
 222                ath_err(common,
 223                        "Unable to reset device (%u Mhz) reset status %d\n",
 224                        channel->center_freq, ret);
 225        }
 226
 227        ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
 228                               &priv->curtxpow);
 229
 230        WMI_CMD(WMI_START_RECV_CMDID);
 231        ath9k_host_rx_init(priv);
 232
 233        mode = ath9k_htc_get_curmode(priv, ah->curchan);
 234        htc_mode = cpu_to_be16(mode);
 235        WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
 236
 237        WMI_CMD(WMI_ENABLE_INTR_CMDID);
 238        htc_start(priv->htc);
 239        ath9k_htc_vif_reconfig(priv);
 240        ieee80211_wake_queues(priv->hw);
 241
 242        mod_timer(&priv->tx.cleanup_timer,
 243                  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
 244
 245        ath9k_htc_ps_restore(priv);
 246        mutex_unlock(&priv->mutex);
 247}
 248
 249static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
 250                                 struct ieee80211_hw *hw,
 251                                 struct ath9k_channel *hchan)
 252{
 253        struct ath_hw *ah = priv->ah;
 254        struct ath_common *common = ath9k_hw_common(ah);
 255        struct ieee80211_conf *conf = &common->hw->conf;
 256        bool fastcc;
 257        struct ieee80211_channel *channel = hw->conf.chandef.chan;
 258        struct ath9k_hw_cal_data *caldata = NULL;
 259        enum htc_phymode mode;
 260        __be16 htc_mode;
 261        u8 cmd_rsp;
 262        int ret;
 263
 264        if (test_bit(OP_INVALID, &priv->op_flags))
 265                return -EIO;
 266
 267        fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
 268
 269        ath9k_htc_ps_wakeup(priv);
 270
 271        del_timer_sync(&priv->tx.cleanup_timer);
 272        ath9k_htc_tx_drain(priv);
 273
 274        WMI_CMD(WMI_DISABLE_INTR_CMDID);
 275        WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
 276        WMI_CMD(WMI_STOP_RECV_CMDID);
 277
 278        ath9k_wmi_event_drain(priv);
 279
 280        ath_dbg(common, CONFIG,
 281                "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
 282                priv->ah->curchan->channel,
 283                channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
 284                fastcc);
 285
 286        if (!fastcc)
 287                caldata = &priv->caldata;
 288
 289        ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
 290        if (ret) {
 291                ath_err(common,
 292                        "Unable to reset channel (%u Mhz) reset status %d\n",
 293                        channel->center_freq, ret);
 294                goto err;
 295        }
 296
 297        ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
 298                               &priv->curtxpow);
 299
 300        WMI_CMD(WMI_START_RECV_CMDID);
 301        if (ret)
 302                goto err;
 303
 304        ath9k_host_rx_init(priv);
 305
 306        mode = ath9k_htc_get_curmode(priv, hchan);
 307        htc_mode = cpu_to_be16(mode);
 308        WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
 309        if (ret)
 310                goto err;
 311
 312        WMI_CMD(WMI_ENABLE_INTR_CMDID);
 313        if (ret)
 314                goto err;
 315
 316        htc_start(priv->htc);
 317
 318        if (!test_bit(OP_SCANNING, &priv->op_flags) &&
 319            !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
 320                ath9k_htc_vif_reconfig(priv);
 321
 322        mod_timer(&priv->tx.cleanup_timer,
 323                  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
 324
 325err:
 326        ath9k_htc_ps_restore(priv);
 327        return ret;
 328}
 329
 330/*
 331 * Monitor mode handling is a tad complicated because the firmware requires
 332 * an interface to be created exclusively, while mac80211 doesn't associate
 333 * an interface with the mode.
 334 *
 335 * So, for now, only one monitor interface can be configured.
 336 */
 337static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
 338{
 339        struct ath_common *common = ath9k_hw_common(priv->ah);
 340        struct ath9k_htc_target_vif hvif;
 341        int ret = 0;
 342        u8 cmd_rsp;
 343
 344        memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
 345        memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
 346        hvif.index = priv->mon_vif_idx;
 347        WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
 348        if (ret) {
 349                ath_err(common, "Unable to remove monitor interface at idx: %d\n",
 350                        priv->mon_vif_idx);
 351        }
 352
 353        priv->nvifs--;
 354        priv->vif_slot &= ~(1 << priv->mon_vif_idx);
 355}
 356
 357static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
 358{
 359        struct ath_common *common = ath9k_hw_common(priv->ah);
 360        struct ath9k_htc_target_vif hvif;
 361        struct ath9k_htc_target_sta tsta;
 362        int ret = 0, sta_idx;
 363        u8 cmd_rsp;
 364
 365        if ((priv->nvifs >= ATH9K_HTC_MAX_VIF) ||
 366            (priv->nstations >= ATH9K_HTC_MAX_STA)) {
 367                ret = -ENOBUFS;
 368                goto err_vif;
 369        }
 370
 371        sta_idx = ffz(priv->sta_slot);
 372        if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA)) {
 373                ret = -ENOBUFS;
 374                goto err_vif;
 375        }
 376
 377        /*
 378         * Add an interface.
 379         */
 380        memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
 381        memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
 382
 383        hvif.opmode = HTC_M_MONITOR;
 384        hvif.index = ffz(priv->vif_slot);
 385
 386        WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
 387        if (ret)
 388                goto err_vif;
 389
 390        /*
 391         * Assign the monitor interface index as a special case here.
 392         * This is needed when the interface is brought down.
 393         */
 394        priv->mon_vif_idx = hvif.index;
 395        priv->vif_slot |= (1 << hvif.index);
 396
 397        /*
 398         * Set the hardware mode to monitor only if there are no
 399         * other interfaces.
 400         */
 401        if (!priv->nvifs)
 402                priv->ah->opmode = NL80211_IFTYPE_MONITOR;
 403
 404        priv->nvifs++;
 405
 406        /*
 407         * Associate a station with the interface for packet injection.
 408         */
 409        memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
 410
 411        memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN);
 412
 413        tsta.is_vif_sta = 1;
 414        tsta.sta_index = sta_idx;
 415        tsta.vif_index = hvif.index;
 416        tsta.maxampdu = cpu_to_be16(0xffff);
 417
 418        WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
 419        if (ret) {
 420                ath_err(common, "Unable to add station entry for monitor mode\n");
 421                goto err_sta;
 422        }
 423
 424        priv->sta_slot |= (1 << sta_idx);
 425        priv->nstations++;
 426        priv->vif_sta_pos[priv->mon_vif_idx] = sta_idx;
 427        priv->ah->is_monitoring = true;
 428
 429        ath_dbg(common, CONFIG,
 430                "Attached a monitor interface at idx: %d, sta idx: %d\n",
 431                priv->mon_vif_idx, sta_idx);
 432
 433        return 0;
 434
 435err_sta:
 436        /*
 437         * Remove the interface from the target.
 438         */
 439        __ath9k_htc_remove_monitor_interface(priv);
 440err_vif:
 441        ath_dbg(common, FATAL, "Unable to attach a monitor interface\n");
 442
 443        return ret;
 444}
 445
 446static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
 447{
 448        struct ath_common *common = ath9k_hw_common(priv->ah);
 449        int ret = 0;
 450        u8 cmd_rsp, sta_idx;
 451
 452        __ath9k_htc_remove_monitor_interface(priv);
 453
 454        sta_idx = priv->vif_sta_pos[priv->mon_vif_idx];
 455
 456        WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
 457        if (ret) {
 458                ath_err(common, "Unable to remove station entry for monitor mode\n");
 459                return ret;
 460        }
 461
 462        priv->sta_slot &= ~(1 << sta_idx);
 463        priv->nstations--;
 464        priv->ah->is_monitoring = false;
 465
 466        ath_dbg(common, CONFIG,
 467                "Removed a monitor interface at idx: %d, sta idx: %d\n",
 468                priv->mon_vif_idx, sta_idx);
 469
 470        return 0;
 471}
 472
 473static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
 474                                 struct ieee80211_vif *vif,
 475                                 struct ieee80211_sta *sta)
 476{
 477        struct ath_common *common = ath9k_hw_common(priv->ah);
 478        struct ath9k_htc_target_sta tsta;
 479        struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
 480        struct ath9k_htc_sta *ista;
 481        int ret, sta_idx;
 482        u8 cmd_rsp;
 483        u16 maxampdu;
 484
 485        if (priv->nstations >= ATH9K_HTC_MAX_STA)
 486                return -ENOBUFS;
 487
 488        sta_idx = ffz(priv->sta_slot);
 489        if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA))
 490                return -ENOBUFS;
 491
 492        memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
 493
 494        if (sta) {
 495                ista = (struct ath9k_htc_sta *) sta->drv_priv;
 496                memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
 497                memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
 498                ista->index = sta_idx;
 499                tsta.is_vif_sta = 0;
 500                maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
 501                                 sta->ht_cap.ampdu_factor);
 502                tsta.maxampdu = cpu_to_be16(maxampdu);
 503        } else {
 504                memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
 505                tsta.is_vif_sta = 1;
 506                tsta.maxampdu = cpu_to_be16(0xffff);
 507        }
 508
 509        tsta.sta_index = sta_idx;
 510        tsta.vif_index = avp->index;
 511
 512        WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
 513        if (ret) {
 514                if (sta)
 515                        ath_err(common,
 516                                "Unable to add station entry for: %pM\n",
 517                                sta->addr);
 518                return ret;
 519        }
 520
 521        if (sta) {
 522                ath_dbg(common, CONFIG,
 523                        "Added a station entry for: %pM (idx: %d)\n",
 524                        sta->addr, tsta.sta_index);
 525        } else {
 526                ath_dbg(common, CONFIG,
 527                        "Added a station entry for VIF %d (idx: %d)\n",
 528                        avp->index, tsta.sta_index);
 529        }
 530
 531        priv->sta_slot |= (1 << sta_idx);
 532        priv->nstations++;
 533        if (!sta)
 534                priv->vif_sta_pos[avp->index] = sta_idx;
 535
 536        return 0;
 537}
 538
 539static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
 540                                    struct ieee80211_vif *vif,
 541                                    struct ieee80211_sta *sta)
 542{
 543        struct ath_common *common = ath9k_hw_common(priv->ah);
 544        struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
 545        struct ath9k_htc_sta *ista;
 546        int ret;
 547        u8 cmd_rsp, sta_idx;
 548
 549        if (sta) {
 550                ista = (struct ath9k_htc_sta *) sta->drv_priv;
 551                sta_idx = ista->index;
 552        } else {
 553                sta_idx = priv->vif_sta_pos[avp->index];
 554        }
 555
 556        WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
 557        if (ret) {
 558                if (sta)
 559                        ath_err(common,
 560                                "Unable to remove station entry for: %pM\n",
 561                                sta->addr);
 562                return ret;
 563        }
 564
 565        if (sta) {
 566                ath_dbg(common, CONFIG,
 567                        "Removed a station entry for: %pM (idx: %d)\n",
 568                        sta->addr, sta_idx);
 569        } else {
 570                ath_dbg(common, CONFIG,
 571                        "Removed a station entry for VIF %d (idx: %d)\n",
 572                        avp->index, sta_idx);
 573        }
 574
 575        priv->sta_slot &= ~(1 << sta_idx);
 576        priv->nstations--;
 577
 578        return 0;
 579}
 580
 581int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
 582                                u8 enable_coex)
 583{
 584        struct ath9k_htc_cap_target tcap;
 585        int ret;
 586        u8 cmd_rsp;
 587
 588        memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
 589
 590        tcap.ampdu_limit = cpu_to_be32(0xffff);
 591        tcap.ampdu_subframes = 0xff;
 592        tcap.enable_coex = enable_coex;
 593        tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
 594
 595        WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
 596
 597        return ret;
 598}
 599
 600static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
 601                                 struct ieee80211_sta *sta,
 602                                 struct ath9k_htc_target_rate *trate)
 603{
 604        struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
 605        struct ieee80211_supported_band *sband;
 606        u32 caps = 0;
 607        int i, j;
 608
 609        sband = priv->hw->wiphy->bands[priv->hw->conf.chandef.chan->band];
 610
 611        for (i = 0, j = 0; i < sband->n_bitrates; i++) {
 612                if (sta->supp_rates[sband->band] & BIT(i)) {
 613                        trate->rates.legacy_rates.rs_rates[j]
 614                                = (sband->bitrates[i].bitrate * 2) / 10;
 615                        j++;
 616                }
 617        }
 618        trate->rates.legacy_rates.rs_nrates = j;
 619
 620        if (sta->ht_cap.ht_supported) {
 621                for (i = 0, j = 0; i < 77; i++) {
 622                        if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
 623                                trate->rates.ht_rates.rs_rates[j++] = i;
 624                        if (j == ATH_HTC_RATE_MAX)
 625                                break;
 626                }
 627                trate->rates.ht_rates.rs_nrates = j;
 628
 629                caps = WLAN_RC_HT_FLAG;
 630                if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
 631                        caps |= ATH_RC_TX_STBC_FLAG;
 632                if (sta->ht_cap.mcs.rx_mask[1])
 633                        caps |= WLAN_RC_DS_FLAG;
 634                if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
 635                     (conf_is_ht40(&priv->hw->conf)))
 636                        caps |= WLAN_RC_40_FLAG;
 637                if (conf_is_ht40(&priv->hw->conf) &&
 638                    (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
 639                        caps |= WLAN_RC_SGI_FLAG;
 640                else if (conf_is_ht20(&priv->hw->conf) &&
 641                         (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20))
 642                        caps |= WLAN_RC_SGI_FLAG;
 643        }
 644
 645        trate->sta_index = ista->index;
 646        trate->isnew = 1;
 647        trate->capflags = cpu_to_be32(caps);
 648}
 649
 650static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv,
 651                                    struct ath9k_htc_target_rate *trate)
 652{
 653        struct ath_common *common = ath9k_hw_common(priv->ah);
 654        int ret;
 655        u8 cmd_rsp;
 656
 657        WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate);
 658        if (ret) {
 659                ath_err(common,
 660                        "Unable to initialize Rate information on target\n");
 661        }
 662
 663        return ret;
 664}
 665
 666static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
 667                                struct ieee80211_sta *sta)
 668{
 669        struct ath_common *common = ath9k_hw_common(priv->ah);
 670        struct ath9k_htc_target_rate trate;
 671        int ret;
 672
 673        memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
 674        ath9k_htc_setup_rate(priv, sta, &trate);
 675        ret = ath9k_htc_send_rate_cmd(priv, &trate);
 676        if (!ret)
 677                ath_dbg(common, CONFIG,
 678                        "Updated target sta: %pM, rate caps: 0x%X\n",
 679                        sta->addr, be32_to_cpu(trate.capflags));
 680}
 681
 682static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
 683                                  struct ieee80211_vif *vif,
 684                                  struct ieee80211_bss_conf *bss_conf)
 685{
 686        struct ath_common *common = ath9k_hw_common(priv->ah);
 687        struct ath9k_htc_target_rate trate;
 688        struct ieee80211_sta *sta;
 689        int ret;
 690
 691        memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
 692
 693        rcu_read_lock();
 694        sta = ieee80211_find_sta(vif, bss_conf->bssid);
 695        if (!sta) {
 696                rcu_read_unlock();
 697                return;
 698        }
 699        ath9k_htc_setup_rate(priv, sta, &trate);
 700        rcu_read_unlock();
 701
 702        ret = ath9k_htc_send_rate_cmd(priv, &trate);
 703        if (!ret)
 704                ath_dbg(common, CONFIG,
 705                        "Updated target sta: %pM, rate caps: 0x%X\n",
 706                        bss_conf->bssid, be32_to_cpu(trate.capflags));
 707}
 708
 709static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
 710                                  struct ieee80211_vif *vif,
 711                                  struct ieee80211_sta *sta,
 712                                  enum ieee80211_ampdu_mlme_action action,
 713                                  u16 tid)
 714{
 715        struct ath_common *common = ath9k_hw_common(priv->ah);
 716        struct ath9k_htc_target_aggr aggr;
 717        struct ath9k_htc_sta *ista;
 718        int ret = 0;
 719        u8 cmd_rsp;
 720
 721        if (tid >= ATH9K_HTC_MAX_TID)
 722                return -EINVAL;
 723
 724        memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
 725        ista = (struct ath9k_htc_sta *) sta->drv_priv;
 726
 727        aggr.sta_index = ista->index;
 728        aggr.tidno = tid & 0xf;
 729        aggr.aggr_enable = (action == IEEE80211_AMPDU_TX_START) ? true : false;
 730
 731        WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
 732        if (ret)
 733                ath_dbg(common, CONFIG,
 734                        "Unable to %s TX aggregation for (%pM, %d)\n",
 735                        (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
 736        else
 737                ath_dbg(common, CONFIG,
 738                        "%s TX aggregation for (%pM, %d)\n",
 739                        (aggr.aggr_enable) ? "Starting" : "Stopping",
 740                        sta->addr, tid);
 741
 742        spin_lock_bh(&priv->tx.tx_lock);
 743        ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
 744        spin_unlock_bh(&priv->tx.tx_lock);
 745
 746        return ret;
 747}
 748
 749/*******/
 750/* ANI */
 751/*******/
 752
 753void ath9k_htc_start_ani(struct ath9k_htc_priv *priv)
 754{
 755        struct ath_common *common = ath9k_hw_common(priv->ah);
 756        unsigned long timestamp = jiffies_to_msecs(jiffies);
 757
 758        common->ani.longcal_timer = timestamp;
 759        common->ani.shortcal_timer = timestamp;
 760        common->ani.checkani_timer = timestamp;
 761
 762        set_bit(OP_ANI_RUNNING, &priv->op_flags);
 763
 764        ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
 765                                     msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
 766}
 767
 768void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv)
 769{
 770        cancel_delayed_work_sync(&priv->ani_work);
 771        clear_bit(OP_ANI_RUNNING, &priv->op_flags);
 772}
 773
 774void ath9k_htc_ani_work(struct work_struct *work)
 775{
 776        struct ath9k_htc_priv *priv =
 777                container_of(work, struct ath9k_htc_priv, ani_work.work);
 778        struct ath_hw *ah = priv->ah;
 779        struct ath_common *common = ath9k_hw_common(ah);
 780        bool longcal = false;
 781        bool shortcal = false;
 782        bool aniflag = false;
 783        unsigned int timestamp = jiffies_to_msecs(jiffies);
 784        u32 cal_interval, short_cal_interval;
 785
 786        short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
 787                ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
 788
 789        /* Only calibrate if awake */
 790        if (ah->power_mode != ATH9K_PM_AWAKE)
 791                goto set_timer;
 792
 793        /* Long calibration runs independently of short calibration. */
 794        if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
 795                longcal = true;
 796                ath_dbg(common, ANI, "longcal @%lu\n", jiffies);
 797                common->ani.longcal_timer = timestamp;
 798        }
 799
 800        /* Short calibration applies only while caldone is false */
 801        if (!common->ani.caldone) {
 802                if ((timestamp - common->ani.shortcal_timer) >=
 803                    short_cal_interval) {
 804                        shortcal = true;
 805                        ath_dbg(common, ANI, "shortcal @%lu\n", jiffies);
 806                        common->ani.shortcal_timer = timestamp;
 807                        common->ani.resetcal_timer = timestamp;
 808                }
 809        } else {
 810                if ((timestamp - common->ani.resetcal_timer) >=
 811                    ATH_RESTART_CALINTERVAL) {
 812                        common->ani.caldone = ath9k_hw_reset_calvalid(ah);
 813                        if (common->ani.caldone)
 814                                common->ani.resetcal_timer = timestamp;
 815                }
 816        }
 817
 818        /* Verify whether we must check ANI */
 819        if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
 820                aniflag = true;
 821                common->ani.checkani_timer = timestamp;
 822        }
 823
 824        /* Skip all processing if there's nothing to do. */
 825        if (longcal || shortcal || aniflag) {
 826
 827                ath9k_htc_ps_wakeup(priv);
 828
 829                /* Call ANI routine if necessary */
 830                if (aniflag)
 831                        ath9k_hw_ani_monitor(ah, ah->curchan);
 832
 833                /* Perform calibration if necessary */
 834                if (longcal || shortcal)
 835                        common->ani.caldone =
 836                                ath9k_hw_calibrate(ah, ah->curchan,
 837                                                   ah->rxchainmask, longcal);
 838
 839                ath9k_htc_ps_restore(priv);
 840        }
 841
 842set_timer:
 843        /*
 844        * Set timer interval based on previous results.
 845        * The interval must be the shortest necessary to satisfy ANI,
 846        * short calibration and long calibration.
 847        */
 848        cal_interval = ATH_LONG_CALINTERVAL;
 849        cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
 850        if (!common->ani.caldone)
 851                cal_interval = min(cal_interval, (u32)short_cal_interval);
 852
 853        ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
 854                                     msecs_to_jiffies(cal_interval));
 855}
 856
 857/**********************/
 858/* mac80211 Callbacks */
 859/**********************/
 860
 861static void ath9k_htc_tx(struct ieee80211_hw *hw,
 862                         struct ieee80211_tx_control *control,
 863                         struct sk_buff *skb)
 864{
 865        struct ieee80211_hdr *hdr;
 866        struct ath9k_htc_priv *priv = hw->priv;
 867        struct ath_common *common = ath9k_hw_common(priv->ah);
 868        int padpos, padsize, ret, slot;
 869
 870        hdr = (struct ieee80211_hdr *) skb->data;
 871
 872        /* Add the padding after the header if this is not already done */
 873        padpos = ieee80211_hdrlen(hdr->frame_control);
 874        padsize = padpos & 3;
 875        if (padsize && skb->len > padpos) {
 876                if (skb_headroom(skb) < padsize) {
 877                        ath_dbg(common, XMIT, "No room for padding\n");
 878                        goto fail_tx;
 879                }
 880                skb_push(skb, padsize);
 881                memmove(skb->data, skb->data + padsize, padpos);
 882        }
 883
 884        slot = ath9k_htc_tx_get_slot(priv);
 885        if (slot < 0) {
 886                ath_dbg(common, XMIT, "No free TX slot\n");
 887                goto fail_tx;
 888        }
 889
 890        ret = ath9k_htc_tx_start(priv, control->sta, skb, slot, false);
 891        if (ret != 0) {
 892                ath_dbg(common, XMIT, "Tx failed\n");
 893                goto clear_slot;
 894        }
 895
 896        ath9k_htc_check_stop_queues(priv);
 897
 898        return;
 899
 900clear_slot:
 901        ath9k_htc_tx_clear_slot(priv, slot);
 902fail_tx:
 903        dev_kfree_skb_any(skb);
 904}
 905
 906static int ath9k_htc_start(struct ieee80211_hw *hw)
 907{
 908        struct ath9k_htc_priv *priv = hw->priv;
 909        struct ath_hw *ah = priv->ah;
 910        struct ath_common *common = ath9k_hw_common(ah);
 911        struct ieee80211_channel *curchan = hw->conf.chandef.chan;
 912        struct ath9k_channel *init_channel;
 913        int ret = 0;
 914        enum htc_phymode mode;
 915        __be16 htc_mode;
 916        u8 cmd_rsp;
 917
 918        mutex_lock(&priv->mutex);
 919
 920        ath_dbg(common, CONFIG,
 921                "Starting driver with initial channel: %d MHz\n",
 922                curchan->center_freq);
 923
 924        /* Ensure that HW is awake before flushing RX */
 925        ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
 926        WMI_CMD(WMI_FLUSH_RECV_CMDID);
 927
 928        /* setup initial channel */
 929        init_channel = ath9k_cmn_get_curchannel(hw, ah);
 930
 931        ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
 932        if (ret) {
 933                ath_err(common,
 934                        "Unable to reset hardware; reset status %d (freq %u MHz)\n",
 935                        ret, curchan->center_freq);
 936                mutex_unlock(&priv->mutex);
 937                return ret;
 938        }
 939
 940        ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
 941                               &priv->curtxpow);
 942
 943        mode = ath9k_htc_get_curmode(priv, init_channel);
 944        htc_mode = cpu_to_be16(mode);
 945        WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
 946        WMI_CMD(WMI_ATH_INIT_CMDID);
 947        WMI_CMD(WMI_START_RECV_CMDID);
 948
 949        ath9k_host_rx_init(priv);
 950
 951        ret = ath9k_htc_update_cap_target(priv, 0);
 952        if (ret)
 953                ath_dbg(common, CONFIG,
 954                        "Failed to update capability in target\n");
 955
 956        clear_bit(OP_INVALID, &priv->op_flags);
 957        htc_start(priv->htc);
 958
 959        spin_lock_bh(&priv->tx.tx_lock);
 960        priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
 961        spin_unlock_bh(&priv->tx.tx_lock);
 962
 963        ieee80211_wake_queues(hw);
 964
 965        mod_timer(&priv->tx.cleanup_timer,
 966                  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
 967
 968        ath9k_htc_start_btcoex(priv);
 969
 970        mutex_unlock(&priv->mutex);
 971
 972        return ret;
 973}
 974
 975static void ath9k_htc_stop(struct ieee80211_hw *hw)
 976{
 977        struct ath9k_htc_priv *priv = hw->priv;
 978        struct ath_hw *ah = priv->ah;
 979        struct ath_common *common = ath9k_hw_common(ah);
 980        int ret __attribute__ ((unused));
 981        u8 cmd_rsp;
 982
 983        mutex_lock(&priv->mutex);
 984
 985        if (test_bit(OP_INVALID, &priv->op_flags)) {
 986                ath_dbg(common, ANY, "Device not present\n");
 987                mutex_unlock(&priv->mutex);
 988                return;
 989        }
 990
 991        ath9k_htc_ps_wakeup(priv);
 992
 993        WMI_CMD(WMI_DISABLE_INTR_CMDID);
 994        WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
 995        WMI_CMD(WMI_STOP_RECV_CMDID);
 996
 997        tasklet_kill(&priv->rx_tasklet);
 998
 999        del_timer_sync(&priv->tx.cleanup_timer);
1000        ath9k_htc_tx_drain(priv);
1001        ath9k_wmi_event_drain(priv);
1002
1003        mutex_unlock(&priv->mutex);
1004
1005        /* Cancel all the running timers/work .. */
1006        cancel_work_sync(&priv->fatal_work);
1007        cancel_work_sync(&priv->ps_work);
1008
1009#ifdef CONFIG_MAC80211_LEDS
1010        cancel_work_sync(&priv->led_work);
1011#endif
1012        ath9k_htc_stop_ani(priv);
1013
1014        mutex_lock(&priv->mutex);
1015
1016        ath9k_htc_stop_btcoex(priv);
1017
1018        /* Remove a monitor interface if it's present. */
1019        if (priv->ah->is_monitoring)
1020                ath9k_htc_remove_monitor_interface(priv);
1021
1022        ath9k_hw_phy_disable(ah);
1023        ath9k_hw_disable(ah);
1024        ath9k_htc_ps_restore(priv);
1025        ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1026
1027        set_bit(OP_INVALID, &priv->op_flags);
1028
1029        ath_dbg(common, CONFIG, "Driver halt\n");
1030        mutex_unlock(&priv->mutex);
1031}
1032
1033static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1034                                   struct ieee80211_vif *vif)
1035{
1036        struct ath9k_htc_priv *priv = hw->priv;
1037        struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1038        struct ath_common *common = ath9k_hw_common(priv->ah);
1039        struct ath9k_htc_target_vif hvif;
1040        int ret = 0;
1041        u8 cmd_rsp;
1042
1043        mutex_lock(&priv->mutex);
1044
1045        ath9k_htc_ps_wakeup(priv);
1046        memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1047        memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1048
1049        switch (vif->type) {
1050        case NL80211_IFTYPE_STATION:
1051                hvif.opmode = HTC_M_STA;
1052                break;
1053        case NL80211_IFTYPE_ADHOC:
1054                hvif.opmode = HTC_M_IBSS;
1055                break;
1056        case NL80211_IFTYPE_AP:
1057                hvif.opmode = HTC_M_HOSTAP;
1058                break;
1059        case NL80211_IFTYPE_MESH_POINT:
1060                hvif.opmode = HTC_M_WDS;        /* close enough */
1061                break;
1062        default:
1063                ath_err(common,
1064                        "Interface type %d not yet supported\n", vif->type);
1065                ret = -EOPNOTSUPP;
1066                goto out;
1067        }
1068
1069        /* Index starts from zero on the target */
1070        avp->index = hvif.index = ffz(priv->vif_slot);
1071        hvif.rtsthreshold = cpu_to_be16(2304);
1072        WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1073        if (ret)
1074                goto out;
1075
1076        /*
1077         * We need a node in target to tx mgmt frames
1078         * before association.
1079         */
1080        ret = ath9k_htc_add_station(priv, vif, NULL);
1081        if (ret) {
1082                WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1083                goto out;
1084        }
1085
1086        ath9k_htc_set_bssid_mask(priv, vif);
1087
1088        priv->vif_slot |= (1 << avp->index);
1089        priv->nvifs++;
1090
1091        INC_VIF(priv, vif->type);
1092
1093        if ((vif->type == NL80211_IFTYPE_AP) ||
1094            (vif->type == NL80211_IFTYPE_MESH_POINT) ||
1095            (vif->type == NL80211_IFTYPE_ADHOC))
1096                ath9k_htc_assign_bslot(priv, vif);
1097
1098        ath9k_htc_set_opmode(priv);
1099
1100        if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
1101            !test_bit(OP_ANI_RUNNING, &priv->op_flags)) {
1102                ath9k_hw_set_tsfadjust(priv->ah, true);
1103                ath9k_htc_start_ani(priv);
1104        }
1105
1106        ath_dbg(common, CONFIG, "Attach a VIF of type: %d at idx: %d\n",
1107                vif->type, avp->index);
1108
1109out:
1110        ath9k_htc_ps_restore(priv);
1111        mutex_unlock(&priv->mutex);
1112
1113        return ret;
1114}
1115
1116static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1117                                       struct ieee80211_vif *vif)
1118{
1119        struct ath9k_htc_priv *priv = hw->priv;
1120        struct ath_common *common = ath9k_hw_common(priv->ah);
1121        struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1122        struct ath9k_htc_target_vif hvif;
1123        int ret = 0;
1124        u8 cmd_rsp;
1125
1126        mutex_lock(&priv->mutex);
1127        ath9k_htc_ps_wakeup(priv);
1128
1129        memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1130        memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1131        hvif.index = avp->index;
1132        WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1133        if (ret) {
1134                ath_err(common, "Unable to remove interface at idx: %d\n",
1135                        avp->index);
1136        }
1137        priv->nvifs--;
1138        priv->vif_slot &= ~(1 << avp->index);
1139
1140        ath9k_htc_remove_station(priv, vif, NULL);
1141
1142        DEC_VIF(priv, vif->type);
1143
1144        if ((vif->type == NL80211_IFTYPE_AP) ||
1145             vif->type == NL80211_IFTYPE_MESH_POINT ||
1146            (vif->type == NL80211_IFTYPE_ADHOC))
1147                ath9k_htc_remove_bslot(priv, vif);
1148
1149        ath9k_htc_set_opmode(priv);
1150
1151        ath9k_htc_set_bssid_mask(priv, vif);
1152
1153        /*
1154         * Stop ANI only if there are no associated station interfaces.
1155         */
1156        if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) {
1157                priv->rearm_ani = false;
1158                ieee80211_iterate_active_interfaces_atomic(
1159                        priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1160                        ath9k_htc_vif_iter, priv);
1161                if (!priv->rearm_ani)
1162                        ath9k_htc_stop_ani(priv);
1163        }
1164
1165        ath_dbg(common, CONFIG, "Detach Interface at idx: %d\n", avp->index);
1166
1167        ath9k_htc_ps_restore(priv);
1168        mutex_unlock(&priv->mutex);
1169}
1170
1171static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1172{
1173        struct ath9k_htc_priv *priv = hw->priv;
1174        struct ath_common *common = ath9k_hw_common(priv->ah);
1175        struct ieee80211_conf *conf = &hw->conf;
1176        bool chip_reset = false;
1177        int ret = 0;
1178
1179        mutex_lock(&priv->mutex);
1180        ath9k_htc_ps_wakeup(priv);
1181
1182        if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1183                mutex_lock(&priv->htc_pm_lock);
1184
1185                priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1186                if (!priv->ps_idle)
1187                        chip_reset = true;
1188
1189                mutex_unlock(&priv->htc_pm_lock);
1190        }
1191
1192        /*
1193         * Monitor interface should be added before
1194         * IEEE80211_CONF_CHANGE_CHANNEL is handled.
1195         */
1196        if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1197                if ((conf->flags & IEEE80211_CONF_MONITOR) &&
1198                    !priv->ah->is_monitoring)
1199                        ath9k_htc_add_monitor_interface(priv);
1200                else if (priv->ah->is_monitoring)
1201                        ath9k_htc_remove_monitor_interface(priv);
1202        }
1203
1204        if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || chip_reset) {
1205                struct ieee80211_channel *curchan = hw->conf.chandef.chan;
1206                enum nl80211_channel_type channel_type =
1207                        cfg80211_get_chandef_type(&hw->conf.chandef);
1208                int pos = curchan->hw_value;
1209
1210                ath_dbg(common, CONFIG, "Set channel: %d MHz\n",
1211                        curchan->center_freq);
1212
1213                ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
1214                                          hw->conf.chandef.chan,
1215                                          channel_type);
1216
1217                if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1218                        ath_err(common, "Unable to set channel\n");
1219                        ret = -EINVAL;
1220                        goto out;
1221                }
1222
1223        }
1224
1225        if (changed & IEEE80211_CONF_CHANGE_PS) {
1226                if (conf->flags & IEEE80211_CONF_PS) {
1227                        ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
1228                        priv->ps_enabled = true;
1229                } else {
1230                        priv->ps_enabled = false;
1231                        cancel_work_sync(&priv->ps_work);
1232                        ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1233                }
1234        }
1235
1236        if (changed & IEEE80211_CONF_CHANGE_POWER) {
1237                priv->txpowlimit = 2 * conf->power_level;
1238                ath9k_cmn_update_txpow(priv->ah, priv->curtxpow,
1239                                       priv->txpowlimit, &priv->curtxpow);
1240        }
1241
1242out:
1243        ath9k_htc_ps_restore(priv);
1244        mutex_unlock(&priv->mutex);
1245        return ret;
1246}
1247
1248#define SUPPORTED_FILTERS                       \
1249        (FIF_PROMISC_IN_BSS |                   \
1250        FIF_ALLMULTI |                          \
1251        FIF_CONTROL |                           \
1252        FIF_PSPOLL |                            \
1253        FIF_OTHER_BSS |                         \
1254        FIF_BCN_PRBRESP_PROMISC |               \
1255        FIF_PROBE_REQ |                         \
1256        FIF_FCSFAIL)
1257
1258static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1259                                       unsigned int changed_flags,
1260                                       unsigned int *total_flags,
1261                                       u64 multicast)
1262{
1263        struct ath9k_htc_priv *priv = hw->priv;
1264        u32 rfilt;
1265
1266        mutex_lock(&priv->mutex);
1267        changed_flags &= SUPPORTED_FILTERS;
1268        *total_flags &= SUPPORTED_FILTERS;
1269
1270        if (test_bit(OP_INVALID, &priv->op_flags)) {
1271                ath_dbg(ath9k_hw_common(priv->ah), ANY,
1272                        "Unable to configure filter on invalid state\n");
1273                mutex_unlock(&priv->mutex);
1274                return;
1275        }
1276        ath9k_htc_ps_wakeup(priv);
1277
1278        priv->rxfilter = *total_flags;
1279        rfilt = ath9k_htc_calcrxfilter(priv);
1280        ath9k_hw_setrxfilter(priv->ah, rfilt);
1281
1282        ath_dbg(ath9k_hw_common(priv->ah), CONFIG, "Set HW RX filter: 0x%x\n",
1283                rfilt);
1284
1285        ath9k_htc_ps_restore(priv);
1286        mutex_unlock(&priv->mutex);
1287}
1288
1289static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
1290                             struct ieee80211_vif *vif,
1291                             struct ieee80211_sta *sta)
1292{
1293        struct ath9k_htc_priv *priv = hw->priv;
1294        int ret;
1295
1296        mutex_lock(&priv->mutex);
1297        ath9k_htc_ps_wakeup(priv);
1298        ret = ath9k_htc_add_station(priv, vif, sta);
1299        if (!ret)
1300                ath9k_htc_init_rate(priv, sta);
1301        ath9k_htc_ps_restore(priv);
1302        mutex_unlock(&priv->mutex);
1303
1304        return ret;
1305}
1306
1307static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
1308                                struct ieee80211_vif *vif,
1309                                struct ieee80211_sta *sta)
1310{
1311        struct ath9k_htc_priv *priv = hw->priv;
1312        struct ath9k_htc_sta *ista;
1313        int ret;
1314
1315        mutex_lock(&priv->mutex);
1316        ath9k_htc_ps_wakeup(priv);
1317        ista = (struct ath9k_htc_sta *) sta->drv_priv;
1318        htc_sta_drain(priv->htc, ista->index);
1319        ret = ath9k_htc_remove_station(priv, vif, sta);
1320        ath9k_htc_ps_restore(priv);
1321        mutex_unlock(&priv->mutex);
1322
1323        return ret;
1324}
1325
1326static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
1327                                    struct ieee80211_vif *vif,
1328                                    struct ieee80211_sta *sta, u32 changed)
1329{
1330        struct ath9k_htc_priv *priv = hw->priv;
1331        struct ath_common *common = ath9k_hw_common(priv->ah);
1332        struct ath9k_htc_target_rate trate;
1333
1334        mutex_lock(&priv->mutex);
1335        ath9k_htc_ps_wakeup(priv);
1336
1337        if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
1338                memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
1339                ath9k_htc_setup_rate(priv, sta, &trate);
1340                if (!ath9k_htc_send_rate_cmd(priv, &trate))
1341                        ath_dbg(common, CONFIG,
1342                                "Supported rates for sta: %pM updated, rate caps: 0x%X\n",
1343                                sta->addr, be32_to_cpu(trate.capflags));
1344                else
1345                        ath_dbg(common, CONFIG,
1346                                "Unable to update supported rates for sta: %pM\n",
1347                                sta->addr);
1348        }
1349
1350        ath9k_htc_ps_restore(priv);
1351        mutex_unlock(&priv->mutex);
1352}
1353
1354static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
1355                             struct ieee80211_vif *vif, u16 queue,
1356                             const struct ieee80211_tx_queue_params *params)
1357{
1358        struct ath9k_htc_priv *priv = hw->priv;
1359        struct ath_common *common = ath9k_hw_common(priv->ah);
1360        struct ath9k_tx_queue_info qi;
1361        int ret = 0, qnum;
1362
1363        if (queue >= IEEE80211_NUM_ACS)
1364                return 0;
1365
1366        mutex_lock(&priv->mutex);
1367        ath9k_htc_ps_wakeup(priv);
1368
1369        memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1370
1371        qi.tqi_aifs = params->aifs;
1372        qi.tqi_cwmin = params->cw_min;
1373        qi.tqi_cwmax = params->cw_max;
1374        qi.tqi_burstTime = params->txop * 32;
1375
1376        qnum = get_hw_qnum(queue, priv->hwq_map);
1377
1378        ath_dbg(common, CONFIG,
1379                "Configure tx [queue/hwq] [%d/%d],  aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1380                queue, qnum, params->aifs, params->cw_min,
1381                params->cw_max, params->txop);
1382
1383        ret = ath_htc_txq_update(priv, qnum, &qi);
1384        if (ret) {
1385                ath_err(common, "TXQ Update failed\n");
1386                goto out;
1387        }
1388
1389        if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
1390            (qnum == priv->hwq_map[IEEE80211_AC_BE]))
1391                    ath9k_htc_beaconq_config(priv);
1392out:
1393        ath9k_htc_ps_restore(priv);
1394        mutex_unlock(&priv->mutex);
1395
1396        return ret;
1397}
1398
1399static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1400                             enum set_key_cmd cmd,
1401                             struct ieee80211_vif *vif,
1402                             struct ieee80211_sta *sta,
1403                             struct ieee80211_key_conf *key)
1404{
1405        struct ath9k_htc_priv *priv = hw->priv;
1406        struct ath_common *common = ath9k_hw_common(priv->ah);
1407        int ret = 0;
1408
1409        if (htc_modparam_nohwcrypt)
1410                return -ENOSPC;
1411
1412        if ((vif->type == NL80211_IFTYPE_ADHOC ||
1413             vif->type == NL80211_IFTYPE_MESH_POINT) &&
1414            (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
1415             key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
1416            !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
1417                /*
1418                 * For now, disable hw crypto for the RSN IBSS group keys. This
1419                 * could be optimized in the future to use a modified key cache
1420                 * design to support per-STA RX GTK, but until that gets
1421                 * implemented, use of software crypto for group addressed
1422                 * frames is a acceptable to allow RSN IBSS to be used.
1423                 */
1424                return -EOPNOTSUPP;
1425        }
1426
1427        mutex_lock(&priv->mutex);
1428        ath_dbg(common, CONFIG, "Set HW Key\n");
1429        ath9k_htc_ps_wakeup(priv);
1430
1431        switch (cmd) {
1432        case SET_KEY:
1433                ret = ath_key_config(common, vif, sta, key);
1434                if (ret >= 0) {
1435                        key->hw_key_idx = ret;
1436                        /* push IV and Michael MIC generation to stack */
1437                        key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1438                        if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1439                                key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1440                        if (priv->ah->sw_mgmt_crypto &&
1441                            key->cipher == WLAN_CIPHER_SUITE_CCMP)
1442                                key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
1443                        ret = 0;
1444                }
1445                break;
1446        case DISABLE_KEY:
1447                ath_key_delete(common, key);
1448                break;
1449        default:
1450                ret = -EINVAL;
1451        }
1452
1453        ath9k_htc_ps_restore(priv);
1454        mutex_unlock(&priv->mutex);
1455
1456        return ret;
1457}
1458
1459static void ath9k_htc_set_bssid(struct ath9k_htc_priv *priv)
1460{
1461        struct ath_common *common = ath9k_hw_common(priv->ah);
1462
1463        ath9k_hw_write_associd(priv->ah);
1464        ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n",
1465                common->curbssid, common->curaid);
1466}
1467
1468static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1469{
1470        struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
1471        struct ath_common *common = ath9k_hw_common(priv->ah);
1472        struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1473
1474        if ((vif->type == NL80211_IFTYPE_STATION) && bss_conf->assoc) {
1475                common->curaid = bss_conf->aid;
1476                memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1477        }
1478}
1479
1480static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv)
1481{
1482        if (priv->num_sta_assoc_vif == 1) {
1483                ieee80211_iterate_active_interfaces_atomic(
1484                        priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1485                        ath9k_htc_bss_iter, priv);
1486                ath9k_htc_set_bssid(priv);
1487        }
1488}
1489
1490static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1491                                       struct ieee80211_vif *vif,
1492                                       struct ieee80211_bss_conf *bss_conf,
1493                                       u32 changed)
1494{
1495        struct ath9k_htc_priv *priv = hw->priv;
1496        struct ath_hw *ah = priv->ah;
1497        struct ath_common *common = ath9k_hw_common(ah);
1498
1499        mutex_lock(&priv->mutex);
1500        ath9k_htc_ps_wakeup(priv);
1501
1502        if (changed & BSS_CHANGED_ASSOC) {
1503                ath_dbg(common, CONFIG, "BSS Changed ASSOC %d\n",
1504                        bss_conf->assoc);
1505
1506                bss_conf->assoc ?
1507                        priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--;
1508
1509                if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
1510                        ath9k_htc_choose_set_bssid(priv);
1511                        if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1))
1512                                ath9k_htc_start_ani(priv);
1513                        else if (priv->num_sta_assoc_vif == 0)
1514                                ath9k_htc_stop_ani(priv);
1515                }
1516        }
1517
1518        if (changed & BSS_CHANGED_IBSS) {
1519                if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
1520                        common->curaid = bss_conf->aid;
1521                        memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1522                        ath9k_htc_set_bssid(priv);
1523                }
1524        }
1525
1526        if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {
1527                ath_dbg(common, CONFIG, "Beacon enabled for BSS: %pM\n",
1528                        bss_conf->bssid);
1529                ath9k_htc_set_tsfadjust(priv, vif);
1530                set_bit(OP_ENABLE_BEACON, &priv->op_flags);
1531                ath9k_htc_beacon_config(priv, vif);
1532        }
1533
1534        if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) {
1535                /*
1536                 * Disable SWBA interrupt only if there are no
1537                 * concurrent AP/mesh or IBSS interfaces.
1538                 */
1539                if ((priv->num_ap_vif + priv->num_mbss_vif <= 1) ||
1540                     priv->num_ibss_vif) {
1541                        ath_dbg(common, CONFIG,
1542                                "Beacon disabled for BSS: %pM\n",
1543                                bss_conf->bssid);
1544                        clear_bit(OP_ENABLE_BEACON, &priv->op_flags);
1545                        ath9k_htc_beacon_config(priv, vif);
1546                }
1547        }
1548
1549        if (changed & BSS_CHANGED_BEACON_INT) {
1550                /*
1551                 * Reset the HW TSF for the first AP or mesh interface.
1552                 */
1553                if (priv->nvifs == 1 &&
1554                    ((priv->ah->opmode == NL80211_IFTYPE_AP &&
1555                      vif->type == NL80211_IFTYPE_AP &&
1556                      priv->num_ap_vif == 1) ||
1557                    (priv->ah->opmode == NL80211_IFTYPE_MESH_POINT &&
1558                      vif->type == NL80211_IFTYPE_MESH_POINT &&
1559                      priv->num_mbss_vif == 1))) {
1560                        set_bit(OP_TSF_RESET, &priv->op_flags);
1561                }
1562                ath_dbg(common, CONFIG,
1563                        "Beacon interval changed for BSS: %pM\n",
1564                        bss_conf->bssid);
1565                ath9k_htc_beacon_config(priv, vif);
1566        }
1567
1568        if (changed & BSS_CHANGED_ERP_SLOT) {
1569                if (bss_conf->use_short_slot)
1570                        ah->slottime = 9;
1571                else
1572                        ah->slottime = 20;
1573
1574                ath9k_hw_init_global_settings(ah);
1575        }
1576
1577        if (changed & BSS_CHANGED_HT)
1578                ath9k_htc_update_rate(priv, vif, bss_conf);
1579
1580        ath9k_htc_ps_restore(priv);
1581        mutex_unlock(&priv->mutex);
1582}
1583
1584static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw,
1585                             struct ieee80211_vif *vif)
1586{
1587        struct ath9k_htc_priv *priv = hw->priv;
1588        u64 tsf;
1589
1590        mutex_lock(&priv->mutex);
1591        ath9k_htc_ps_wakeup(priv);
1592        tsf = ath9k_hw_gettsf64(priv->ah);
1593        ath9k_htc_ps_restore(priv);
1594        mutex_unlock(&priv->mutex);
1595
1596        return tsf;
1597}
1598
1599static void ath9k_htc_set_tsf(struct ieee80211_hw *hw,
1600                              struct ieee80211_vif *vif, u64 tsf)
1601{
1602        struct ath9k_htc_priv *priv = hw->priv;
1603
1604        mutex_lock(&priv->mutex);
1605        ath9k_htc_ps_wakeup(priv);
1606        ath9k_hw_settsf64(priv->ah, tsf);
1607        ath9k_htc_ps_restore(priv);
1608        mutex_unlock(&priv->mutex);
1609}
1610
1611static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw,
1612                                struct ieee80211_vif *vif)
1613{
1614        struct ath9k_htc_priv *priv = hw->priv;
1615
1616        mutex_lock(&priv->mutex);
1617        ath9k_htc_ps_wakeup(priv);
1618        ath9k_hw_reset_tsf(priv->ah);
1619        ath9k_htc_ps_restore(priv);
1620        mutex_unlock(&priv->mutex);
1621}
1622
1623static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1624                                  struct ieee80211_vif *vif,
1625                                  enum ieee80211_ampdu_mlme_action action,
1626                                  struct ieee80211_sta *sta,
1627                                  u16 tid, u16 *ssn, u8 buf_size)
1628{
1629        struct ath9k_htc_priv *priv = hw->priv;
1630        struct ath9k_htc_sta *ista;
1631        int ret = 0;
1632
1633        mutex_lock(&priv->mutex);
1634        ath9k_htc_ps_wakeup(priv);
1635
1636        switch (action) {
1637        case IEEE80211_AMPDU_RX_START:
1638                break;
1639        case IEEE80211_AMPDU_RX_STOP:
1640                break;
1641        case IEEE80211_AMPDU_TX_START:
1642                ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1643                if (!ret)
1644                        ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1645                break;
1646        case IEEE80211_AMPDU_TX_STOP_CONT:
1647        case IEEE80211_AMPDU_TX_STOP_FLUSH:
1648        case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
1649                ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1650                ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1651                break;
1652        case IEEE80211_AMPDU_TX_OPERATIONAL:
1653                ista = (struct ath9k_htc_sta *) sta->drv_priv;
1654                spin_lock_bh(&priv->tx.tx_lock);
1655                ista->tid_state[tid] = AGGR_OPERATIONAL;
1656                spin_unlock_bh(&priv->tx.tx_lock);
1657                break;
1658        default:
1659                ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
1660        }
1661
1662        ath9k_htc_ps_restore(priv);
1663        mutex_unlock(&priv->mutex);
1664
1665        return ret;
1666}
1667
1668static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1669{
1670        struct ath9k_htc_priv *priv = hw->priv;
1671
1672        mutex_lock(&priv->mutex);
1673        spin_lock_bh(&priv->beacon_lock);
1674        set_bit(OP_SCANNING, &priv->op_flags);
1675        spin_unlock_bh(&priv->beacon_lock);
1676        cancel_work_sync(&priv->ps_work);
1677        ath9k_htc_stop_ani(priv);
1678        mutex_unlock(&priv->mutex);
1679}
1680
1681static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1682{
1683        struct ath9k_htc_priv *priv = hw->priv;
1684
1685        mutex_lock(&priv->mutex);
1686        spin_lock_bh(&priv->beacon_lock);
1687        clear_bit(OP_SCANNING, &priv->op_flags);
1688        spin_unlock_bh(&priv->beacon_lock);
1689        ath9k_htc_ps_wakeup(priv);
1690        ath9k_htc_vif_reconfig(priv);
1691        ath9k_htc_ps_restore(priv);
1692        mutex_unlock(&priv->mutex);
1693}
1694
1695static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1696{
1697        return 0;
1698}
1699
1700static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1701                                         u8 coverage_class)
1702{
1703        struct ath9k_htc_priv *priv = hw->priv;
1704
1705        mutex_lock(&priv->mutex);
1706        ath9k_htc_ps_wakeup(priv);
1707        priv->ah->coverage_class = coverage_class;
1708        ath9k_hw_init_global_settings(priv->ah);
1709        ath9k_htc_ps_restore(priv);
1710        mutex_unlock(&priv->mutex);
1711}
1712
1713/*
1714 * Currently, this is used only for selecting the minimum rate
1715 * for management frames, rate selection for data frames remain
1716 * unaffected.
1717 */
1718static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw,
1719                                      struct ieee80211_vif *vif,
1720                                      const struct cfg80211_bitrate_mask *mask)
1721{
1722        struct ath9k_htc_priv *priv = hw->priv;
1723        struct ath_common *common = ath9k_hw_common(priv->ah);
1724        struct ath9k_htc_target_rate_mask tmask;
1725        struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1726        int ret = 0;
1727        u8 cmd_rsp;
1728
1729        memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask));
1730
1731        tmask.vif_index = avp->index;
1732        tmask.band = IEEE80211_BAND_2GHZ;
1733        tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy);
1734
1735        WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
1736        if (ret) {
1737                ath_err(common,
1738                        "Unable to set 2G rate mask for "
1739                        "interface at idx: %d\n", avp->index);
1740                goto out;
1741        }
1742
1743        tmask.band = IEEE80211_BAND_5GHZ;
1744        tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy);
1745
1746        WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
1747        if (ret) {
1748                ath_err(common,
1749                        "Unable to set 5G rate mask for "
1750                        "interface at idx: %d\n", avp->index);
1751                goto out;
1752        }
1753
1754        ath_dbg(common, CONFIG, "Set bitrate masks: 0x%x, 0x%x\n",
1755                mask->control[IEEE80211_BAND_2GHZ].legacy,
1756                mask->control[IEEE80211_BAND_5GHZ].legacy);
1757out:
1758        return ret;
1759}
1760
1761
1762static int ath9k_htc_get_stats(struct ieee80211_hw *hw,
1763                               struct ieee80211_low_level_stats *stats)
1764{
1765        struct ath9k_htc_priv *priv = hw->priv;
1766        struct ath_hw *ah = priv->ah;
1767        struct ath9k_mib_stats *mib_stats = &ah->ah_mibStats;
1768
1769        stats->dot11ACKFailureCount = mib_stats->ackrcv_bad;
1770        stats->dot11RTSFailureCount = mib_stats->rts_bad;
1771        stats->dot11FCSErrorCount = mib_stats->fcs_bad;
1772        stats->dot11RTSSuccessCount = mib_stats->rts_good;
1773
1774        return 0;
1775}
1776
1777struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv)
1778{
1779        struct base_eep_header *pBase = NULL;
1780        /*
1781         * This can be done since all the 3 EEPROM families have the
1782         * same base header upto a certain point, and we are interested in
1783         * the data only upto that point.
1784         */
1785
1786        if (AR_SREV_9271(priv->ah))
1787                pBase = (struct base_eep_header *)
1788                        &priv->ah->eeprom.map4k.baseEepHeader;
1789        else if (priv->ah->hw_version.usbdev == AR9280_USB)
1790                pBase = (struct base_eep_header *)
1791                        &priv->ah->eeprom.def.baseEepHeader;
1792        else if (priv->ah->hw_version.usbdev == AR9287_USB)
1793                pBase = (struct base_eep_header *)
1794                        &priv->ah->eeprom.map9287.baseEepHeader;
1795        return pBase;
1796}
1797
1798
1799static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
1800                                 u32 *rx_ant)
1801{
1802        struct ath9k_htc_priv *priv = hw->priv;
1803        struct base_eep_header *pBase = ath9k_htc_get_eeprom_base(priv);
1804        if (pBase) {
1805                *tx_ant = pBase->txMask;
1806                *rx_ant = pBase->rxMask;
1807        } else {
1808                *tx_ant = 0;
1809                *rx_ant = 0;
1810        }
1811        return 0;
1812}
1813
1814struct ieee80211_ops ath9k_htc_ops = {
1815        .tx                 = ath9k_htc_tx,
1816        .start              = ath9k_htc_start,
1817        .stop               = ath9k_htc_stop,
1818        .add_interface      = ath9k_htc_add_interface,
1819        .remove_interface   = ath9k_htc_remove_interface,
1820        .config             = ath9k_htc_config,
1821        .configure_filter   = ath9k_htc_configure_filter,
1822        .sta_add            = ath9k_htc_sta_add,
1823        .sta_remove         = ath9k_htc_sta_remove,
1824        .conf_tx            = ath9k_htc_conf_tx,
1825        .sta_rc_update      = ath9k_htc_sta_rc_update,
1826        .bss_info_changed   = ath9k_htc_bss_info_changed,
1827        .set_key            = ath9k_htc_set_key,
1828        .get_tsf            = ath9k_htc_get_tsf,
1829        .set_tsf            = ath9k_htc_set_tsf,
1830        .reset_tsf          = ath9k_htc_reset_tsf,
1831        .ampdu_action       = ath9k_htc_ampdu_action,
1832        .sw_scan_start      = ath9k_htc_sw_scan_start,
1833        .sw_scan_complete   = ath9k_htc_sw_scan_complete,
1834        .set_rts_threshold  = ath9k_htc_set_rts_threshold,
1835        .rfkill_poll        = ath9k_htc_rfkill_poll_state,
1836        .set_coverage_class = ath9k_htc_set_coverage_class,
1837        .set_bitrate_mask   = ath9k_htc_set_bitrate_mask,
1838        .get_stats          = ath9k_htc_get_stats,
1839        .get_antenna        = ath9k_htc_get_antenna,
1840
1841#ifdef CONFIG_ATH9K_HTC_DEBUGFS
1842        .get_et_sset_count  = ath9k_htc_get_et_sset_count,
1843        .get_et_stats       = ath9k_htc_get_et_stats,
1844        .get_et_strings     = ath9k_htc_get_et_strings,
1845#endif
1846};
1847