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                int pos = curchan->hw_value;
1207
1208                ath_dbg(common, CONFIG, "Set channel: %d MHz\n",
1209                        curchan->center_freq);
1210
1211                ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
1212                                          &hw->conf.chandef);
1213
1214                if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1215                        ath_err(common, "Unable to set channel\n");
1216                        ret = -EINVAL;
1217                        goto out;
1218                }
1219
1220        }
1221
1222        if (changed & IEEE80211_CONF_CHANGE_PS) {
1223                if (conf->flags & IEEE80211_CONF_PS) {
1224                        ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
1225                        priv->ps_enabled = true;
1226                } else {
1227                        priv->ps_enabled = false;
1228                        cancel_work_sync(&priv->ps_work);
1229                        ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1230                }
1231        }
1232
1233        if (changed & IEEE80211_CONF_CHANGE_POWER) {
1234                priv->txpowlimit = 2 * conf->power_level;
1235                ath9k_cmn_update_txpow(priv->ah, priv->curtxpow,
1236                                       priv->txpowlimit, &priv->curtxpow);
1237        }
1238
1239out:
1240        ath9k_htc_ps_restore(priv);
1241        mutex_unlock(&priv->mutex);
1242        return ret;
1243}
1244
1245#define SUPPORTED_FILTERS                       \
1246        (FIF_PROMISC_IN_BSS |                   \
1247        FIF_ALLMULTI |                          \
1248        FIF_CONTROL |                           \
1249        FIF_PSPOLL |                            \
1250        FIF_OTHER_BSS |                         \
1251        FIF_BCN_PRBRESP_PROMISC |               \
1252        FIF_PROBE_REQ |                         \
1253        FIF_FCSFAIL)
1254
1255static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1256                                       unsigned int changed_flags,
1257                                       unsigned int *total_flags,
1258                                       u64 multicast)
1259{
1260        struct ath9k_htc_priv *priv = hw->priv;
1261        u32 rfilt;
1262
1263        mutex_lock(&priv->mutex);
1264        changed_flags &= SUPPORTED_FILTERS;
1265        *total_flags &= SUPPORTED_FILTERS;
1266
1267        if (test_bit(OP_INVALID, &priv->op_flags)) {
1268                ath_dbg(ath9k_hw_common(priv->ah), ANY,
1269                        "Unable to configure filter on invalid state\n");
1270                mutex_unlock(&priv->mutex);
1271                return;
1272        }
1273        ath9k_htc_ps_wakeup(priv);
1274
1275        priv->rxfilter = *total_flags;
1276        rfilt = ath9k_htc_calcrxfilter(priv);
1277        ath9k_hw_setrxfilter(priv->ah, rfilt);
1278
1279        ath_dbg(ath9k_hw_common(priv->ah), CONFIG, "Set HW RX filter: 0x%x\n",
1280                rfilt);
1281
1282        ath9k_htc_ps_restore(priv);
1283        mutex_unlock(&priv->mutex);
1284}
1285
1286static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
1287                             struct ieee80211_vif *vif,
1288                             struct ieee80211_sta *sta)
1289{
1290        struct ath9k_htc_priv *priv = hw->priv;
1291        int ret;
1292
1293        mutex_lock(&priv->mutex);
1294        ath9k_htc_ps_wakeup(priv);
1295        ret = ath9k_htc_add_station(priv, vif, sta);
1296        if (!ret)
1297                ath9k_htc_init_rate(priv, sta);
1298        ath9k_htc_ps_restore(priv);
1299        mutex_unlock(&priv->mutex);
1300
1301        return ret;
1302}
1303
1304static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
1305                                struct ieee80211_vif *vif,
1306                                struct ieee80211_sta *sta)
1307{
1308        struct ath9k_htc_priv *priv = hw->priv;
1309        struct ath9k_htc_sta *ista;
1310        int ret;
1311
1312        mutex_lock(&priv->mutex);
1313        ath9k_htc_ps_wakeup(priv);
1314        ista = (struct ath9k_htc_sta *) sta->drv_priv;
1315        htc_sta_drain(priv->htc, ista->index);
1316        ret = ath9k_htc_remove_station(priv, vif, sta);
1317        ath9k_htc_ps_restore(priv);
1318        mutex_unlock(&priv->mutex);
1319
1320        return ret;
1321}
1322
1323static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
1324                                    struct ieee80211_vif *vif,
1325                                    struct ieee80211_sta *sta, u32 changed)
1326{
1327        struct ath9k_htc_priv *priv = hw->priv;
1328        struct ath_common *common = ath9k_hw_common(priv->ah);
1329        struct ath9k_htc_target_rate trate;
1330
1331        mutex_lock(&priv->mutex);
1332        ath9k_htc_ps_wakeup(priv);
1333
1334        if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
1335                memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
1336                ath9k_htc_setup_rate(priv, sta, &trate);
1337                if (!ath9k_htc_send_rate_cmd(priv, &trate))
1338                        ath_dbg(common, CONFIG,
1339                                "Supported rates for sta: %pM updated, rate caps: 0x%X\n",
1340                                sta->addr, be32_to_cpu(trate.capflags));
1341                else
1342                        ath_dbg(common, CONFIG,
1343                                "Unable to update supported rates for sta: %pM\n",
1344                                sta->addr);
1345        }
1346
1347        ath9k_htc_ps_restore(priv);
1348        mutex_unlock(&priv->mutex);
1349}
1350
1351static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
1352                             struct ieee80211_vif *vif, u16 queue,
1353                             const struct ieee80211_tx_queue_params *params)
1354{
1355        struct ath9k_htc_priv *priv = hw->priv;
1356        struct ath_common *common = ath9k_hw_common(priv->ah);
1357        struct ath9k_tx_queue_info qi;
1358        int ret = 0, qnum;
1359
1360        if (queue >= IEEE80211_NUM_ACS)
1361                return 0;
1362
1363        mutex_lock(&priv->mutex);
1364        ath9k_htc_ps_wakeup(priv);
1365
1366        memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1367
1368        qi.tqi_aifs = params->aifs;
1369        qi.tqi_cwmin = params->cw_min;
1370        qi.tqi_cwmax = params->cw_max;
1371        qi.tqi_burstTime = params->txop * 32;
1372
1373        qnum = get_hw_qnum(queue, priv->hwq_map);
1374
1375        ath_dbg(common, CONFIG,
1376                "Configure tx [queue/hwq] [%d/%d],  aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1377                queue, qnum, params->aifs, params->cw_min,
1378                params->cw_max, params->txop);
1379
1380        ret = ath_htc_txq_update(priv, qnum, &qi);
1381        if (ret) {
1382                ath_err(common, "TXQ Update failed\n");
1383                goto out;
1384        }
1385
1386        if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
1387            (qnum == priv->hwq_map[IEEE80211_AC_BE]))
1388                    ath9k_htc_beaconq_config(priv);
1389out:
1390        ath9k_htc_ps_restore(priv);
1391        mutex_unlock(&priv->mutex);
1392
1393        return ret;
1394}
1395
1396static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1397                             enum set_key_cmd cmd,
1398                             struct ieee80211_vif *vif,
1399                             struct ieee80211_sta *sta,
1400                             struct ieee80211_key_conf *key)
1401{
1402        struct ath9k_htc_priv *priv = hw->priv;
1403        struct ath_common *common = ath9k_hw_common(priv->ah);
1404        int ret = 0;
1405
1406        if (htc_modparam_nohwcrypt)
1407                return -ENOSPC;
1408
1409        if ((vif->type == NL80211_IFTYPE_ADHOC ||
1410             vif->type == NL80211_IFTYPE_MESH_POINT) &&
1411            (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
1412             key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
1413            !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
1414                /*
1415                 * For now, disable hw crypto for the RSN IBSS group keys. This
1416                 * could be optimized in the future to use a modified key cache
1417                 * design to support per-STA RX GTK, but until that gets
1418                 * implemented, use of software crypto for group addressed
1419                 * frames is a acceptable to allow RSN IBSS to be used.
1420                 */
1421                return -EOPNOTSUPP;
1422        }
1423
1424        mutex_lock(&priv->mutex);
1425        ath_dbg(common, CONFIG, "Set HW Key\n");
1426        ath9k_htc_ps_wakeup(priv);
1427
1428        switch (cmd) {
1429        case SET_KEY:
1430                ret = ath_key_config(common, vif, sta, key);
1431                if (ret >= 0) {
1432                        key->hw_key_idx = ret;
1433                        /* push IV and Michael MIC generation to stack */
1434                        key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1435                        if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1436                                key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1437                        if (priv->ah->sw_mgmt_crypto &&
1438                            key->cipher == WLAN_CIPHER_SUITE_CCMP)
1439                                key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
1440                        ret = 0;
1441                }
1442                break;
1443        case DISABLE_KEY:
1444                ath_key_delete(common, key);
1445                break;
1446        default:
1447                ret = -EINVAL;
1448        }
1449
1450        ath9k_htc_ps_restore(priv);
1451        mutex_unlock(&priv->mutex);
1452
1453        return ret;
1454}
1455
1456static void ath9k_htc_set_bssid(struct ath9k_htc_priv *priv)
1457{
1458        struct ath_common *common = ath9k_hw_common(priv->ah);
1459
1460        ath9k_hw_write_associd(priv->ah);
1461        ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n",
1462                common->curbssid, common->curaid);
1463}
1464
1465static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1466{
1467        struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
1468        struct ath_common *common = ath9k_hw_common(priv->ah);
1469        struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1470
1471        if ((vif->type == NL80211_IFTYPE_STATION) && bss_conf->assoc) {
1472                common->curaid = bss_conf->aid;
1473                memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1474        }
1475}
1476
1477static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv)
1478{
1479        if (priv->num_sta_assoc_vif == 1) {
1480                ieee80211_iterate_active_interfaces_atomic(
1481                        priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1482                        ath9k_htc_bss_iter, priv);
1483                ath9k_htc_set_bssid(priv);
1484        }
1485}
1486
1487static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1488                                       struct ieee80211_vif *vif,
1489                                       struct ieee80211_bss_conf *bss_conf,
1490                                       u32 changed)
1491{
1492        struct ath9k_htc_priv *priv = hw->priv;
1493        struct ath_hw *ah = priv->ah;
1494        struct ath_common *common = ath9k_hw_common(ah);
1495
1496        mutex_lock(&priv->mutex);
1497        ath9k_htc_ps_wakeup(priv);
1498
1499        if (changed & BSS_CHANGED_ASSOC) {
1500                ath_dbg(common, CONFIG, "BSS Changed ASSOC %d\n",
1501                        bss_conf->assoc);
1502
1503                bss_conf->assoc ?
1504                        priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--;
1505
1506                if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
1507                        ath9k_htc_choose_set_bssid(priv);
1508                        if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1))
1509                                ath9k_htc_start_ani(priv);
1510                        else if (priv->num_sta_assoc_vif == 0)
1511                                ath9k_htc_stop_ani(priv);
1512                }
1513        }
1514
1515        if (changed & BSS_CHANGED_IBSS) {
1516                if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
1517                        common->curaid = bss_conf->aid;
1518                        memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1519                        ath9k_htc_set_bssid(priv);
1520                }
1521        }
1522
1523        if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {
1524                ath_dbg(common, CONFIG, "Beacon enabled for BSS: %pM\n",
1525                        bss_conf->bssid);
1526                ath9k_htc_set_tsfadjust(priv, vif);
1527                set_bit(OP_ENABLE_BEACON, &priv->op_flags);
1528                ath9k_htc_beacon_config(priv, vif);
1529        }
1530
1531        if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) {
1532                /*
1533                 * Disable SWBA interrupt only if there are no
1534                 * concurrent AP/mesh or IBSS interfaces.
1535                 */
1536                if ((priv->num_ap_vif + priv->num_mbss_vif <= 1) ||
1537                     priv->num_ibss_vif) {
1538                        ath_dbg(common, CONFIG,
1539                                "Beacon disabled for BSS: %pM\n",
1540                                bss_conf->bssid);
1541                        clear_bit(OP_ENABLE_BEACON, &priv->op_flags);
1542                        ath9k_htc_beacon_config(priv, vif);
1543                }
1544        }
1545
1546        if (changed & BSS_CHANGED_BEACON_INT) {
1547                /*
1548                 * Reset the HW TSF for the first AP or mesh interface.
1549                 */
1550                if (priv->nvifs == 1 &&
1551                    ((priv->ah->opmode == NL80211_IFTYPE_AP &&
1552                      vif->type == NL80211_IFTYPE_AP &&
1553                      priv->num_ap_vif == 1) ||
1554                    (priv->ah->opmode == NL80211_IFTYPE_MESH_POINT &&
1555                      vif->type == NL80211_IFTYPE_MESH_POINT &&
1556                      priv->num_mbss_vif == 1))) {
1557                        set_bit(OP_TSF_RESET, &priv->op_flags);
1558                }
1559                ath_dbg(common, CONFIG,
1560                        "Beacon interval changed for BSS: %pM\n",
1561                        bss_conf->bssid);
1562                ath9k_htc_beacon_config(priv, vif);
1563        }
1564
1565        if (changed & BSS_CHANGED_ERP_SLOT) {
1566                if (bss_conf->use_short_slot)
1567                        ah->slottime = 9;
1568                else
1569                        ah->slottime = 20;
1570
1571                ath9k_hw_init_global_settings(ah);
1572        }
1573
1574        if (changed & BSS_CHANGED_HT)
1575                ath9k_htc_update_rate(priv, vif, bss_conf);
1576
1577        ath9k_htc_ps_restore(priv);
1578        mutex_unlock(&priv->mutex);
1579}
1580
1581static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw,
1582                             struct ieee80211_vif *vif)
1583{
1584        struct ath9k_htc_priv *priv = hw->priv;
1585        u64 tsf;
1586
1587        mutex_lock(&priv->mutex);
1588        ath9k_htc_ps_wakeup(priv);
1589        tsf = ath9k_hw_gettsf64(priv->ah);
1590        ath9k_htc_ps_restore(priv);
1591        mutex_unlock(&priv->mutex);
1592
1593        return tsf;
1594}
1595
1596static void ath9k_htc_set_tsf(struct ieee80211_hw *hw,
1597                              struct ieee80211_vif *vif, u64 tsf)
1598{
1599        struct ath9k_htc_priv *priv = hw->priv;
1600
1601        mutex_lock(&priv->mutex);
1602        ath9k_htc_ps_wakeup(priv);
1603        ath9k_hw_settsf64(priv->ah, tsf);
1604        ath9k_htc_ps_restore(priv);
1605        mutex_unlock(&priv->mutex);
1606}
1607
1608static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw,
1609                                struct ieee80211_vif *vif)
1610{
1611        struct ath9k_htc_priv *priv = hw->priv;
1612
1613        mutex_lock(&priv->mutex);
1614        ath9k_htc_ps_wakeup(priv);
1615        ath9k_hw_reset_tsf(priv->ah);
1616        ath9k_htc_ps_restore(priv);
1617        mutex_unlock(&priv->mutex);
1618}
1619
1620static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1621                                  struct ieee80211_vif *vif,
1622                                  enum ieee80211_ampdu_mlme_action action,
1623                                  struct ieee80211_sta *sta,
1624                                  u16 tid, u16 *ssn, u8 buf_size)
1625{
1626        struct ath9k_htc_priv *priv = hw->priv;
1627        struct ath9k_htc_sta *ista;
1628        int ret = 0;
1629
1630        mutex_lock(&priv->mutex);
1631        ath9k_htc_ps_wakeup(priv);
1632
1633        switch (action) {
1634        case IEEE80211_AMPDU_RX_START:
1635                break;
1636        case IEEE80211_AMPDU_RX_STOP:
1637                break;
1638        case IEEE80211_AMPDU_TX_START:
1639                ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1640                if (!ret)
1641                        ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1642                break;
1643        case IEEE80211_AMPDU_TX_STOP_CONT:
1644        case IEEE80211_AMPDU_TX_STOP_FLUSH:
1645        case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
1646                ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1647                ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1648                break;
1649        case IEEE80211_AMPDU_TX_OPERATIONAL:
1650                ista = (struct ath9k_htc_sta *) sta->drv_priv;
1651                spin_lock_bh(&priv->tx.tx_lock);
1652                ista->tid_state[tid] = AGGR_OPERATIONAL;
1653                spin_unlock_bh(&priv->tx.tx_lock);
1654                break;
1655        default:
1656                ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
1657        }
1658
1659        ath9k_htc_ps_restore(priv);
1660        mutex_unlock(&priv->mutex);
1661
1662        return ret;
1663}
1664
1665static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1666{
1667        struct ath9k_htc_priv *priv = hw->priv;
1668
1669        mutex_lock(&priv->mutex);
1670        spin_lock_bh(&priv->beacon_lock);
1671        set_bit(OP_SCANNING, &priv->op_flags);
1672        spin_unlock_bh(&priv->beacon_lock);
1673        cancel_work_sync(&priv->ps_work);
1674        ath9k_htc_stop_ani(priv);
1675        mutex_unlock(&priv->mutex);
1676}
1677
1678static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1679{
1680        struct ath9k_htc_priv *priv = hw->priv;
1681
1682        mutex_lock(&priv->mutex);
1683        spin_lock_bh(&priv->beacon_lock);
1684        clear_bit(OP_SCANNING, &priv->op_flags);
1685        spin_unlock_bh(&priv->beacon_lock);
1686        ath9k_htc_ps_wakeup(priv);
1687        ath9k_htc_vif_reconfig(priv);
1688        ath9k_htc_ps_restore(priv);
1689        mutex_unlock(&priv->mutex);
1690}
1691
1692static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1693{
1694        return 0;
1695}
1696
1697static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1698                                         u8 coverage_class)
1699{
1700        struct ath9k_htc_priv *priv = hw->priv;
1701
1702        mutex_lock(&priv->mutex);
1703        ath9k_htc_ps_wakeup(priv);
1704        priv->ah->coverage_class = coverage_class;
1705        ath9k_hw_init_global_settings(priv->ah);
1706        ath9k_htc_ps_restore(priv);
1707        mutex_unlock(&priv->mutex);
1708}
1709
1710/*
1711 * Currently, this is used only for selecting the minimum rate
1712 * for management frames, rate selection for data frames remain
1713 * unaffected.
1714 */
1715static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw,
1716                                      struct ieee80211_vif *vif,
1717                                      const struct cfg80211_bitrate_mask *mask)
1718{
1719        struct ath9k_htc_priv *priv = hw->priv;
1720        struct ath_common *common = ath9k_hw_common(priv->ah);
1721        struct ath9k_htc_target_rate_mask tmask;
1722        struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1723        int ret = 0;
1724        u8 cmd_rsp;
1725
1726        memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask));
1727
1728        tmask.vif_index = avp->index;
1729        tmask.band = IEEE80211_BAND_2GHZ;
1730        tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy);
1731
1732        WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
1733        if (ret) {
1734                ath_err(common,
1735                        "Unable to set 2G rate mask for "
1736                        "interface at idx: %d\n", avp->index);
1737                goto out;
1738        }
1739
1740        tmask.band = IEEE80211_BAND_5GHZ;
1741        tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy);
1742
1743        WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
1744        if (ret) {
1745                ath_err(common,
1746                        "Unable to set 5G rate mask for "
1747                        "interface at idx: %d\n", avp->index);
1748                goto out;
1749        }
1750
1751        ath_dbg(common, CONFIG, "Set bitrate masks: 0x%x, 0x%x\n",
1752                mask->control[IEEE80211_BAND_2GHZ].legacy,
1753                mask->control[IEEE80211_BAND_5GHZ].legacy);
1754out:
1755        return ret;
1756}
1757
1758
1759static int ath9k_htc_get_stats(struct ieee80211_hw *hw,
1760                               struct ieee80211_low_level_stats *stats)
1761{
1762        struct ath9k_htc_priv *priv = hw->priv;
1763        struct ath_hw *ah = priv->ah;
1764        struct ath9k_mib_stats *mib_stats = &ah->ah_mibStats;
1765
1766        stats->dot11ACKFailureCount = mib_stats->ackrcv_bad;
1767        stats->dot11RTSFailureCount = mib_stats->rts_bad;
1768        stats->dot11FCSErrorCount = mib_stats->fcs_bad;
1769        stats->dot11RTSSuccessCount = mib_stats->rts_good;
1770
1771        return 0;
1772}
1773
1774struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv)
1775{
1776        struct base_eep_header *pBase = NULL;
1777        /*
1778         * This can be done since all the 3 EEPROM families have the
1779         * same base header upto a certain point, and we are interested in
1780         * the data only upto that point.
1781         */
1782
1783        if (AR_SREV_9271(priv->ah))
1784                pBase = (struct base_eep_header *)
1785                        &priv->ah->eeprom.map4k.baseEepHeader;
1786        else if (priv->ah->hw_version.usbdev == AR9280_USB)
1787                pBase = (struct base_eep_header *)
1788                        &priv->ah->eeprom.def.baseEepHeader;
1789        else if (priv->ah->hw_version.usbdev == AR9287_USB)
1790                pBase = (struct base_eep_header *)
1791                        &priv->ah->eeprom.map9287.baseEepHeader;
1792        return pBase;
1793}
1794
1795
1796static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
1797                                 u32 *rx_ant)
1798{
1799        struct ath9k_htc_priv *priv = hw->priv;
1800        struct base_eep_header *pBase = ath9k_htc_get_eeprom_base(priv);
1801        if (pBase) {
1802                *tx_ant = pBase->txMask;
1803                *rx_ant = pBase->rxMask;
1804        } else {
1805                *tx_ant = 0;
1806                *rx_ant = 0;
1807        }
1808        return 0;
1809}
1810
1811struct ieee80211_ops ath9k_htc_ops = {
1812        .tx                 = ath9k_htc_tx,
1813        .start              = ath9k_htc_start,
1814        .stop               = ath9k_htc_stop,
1815        .add_interface      = ath9k_htc_add_interface,
1816        .remove_interface   = ath9k_htc_remove_interface,
1817        .config             = ath9k_htc_config,
1818        .configure_filter   = ath9k_htc_configure_filter,
1819        .sta_add            = ath9k_htc_sta_add,
1820        .sta_remove         = ath9k_htc_sta_remove,
1821        .conf_tx            = ath9k_htc_conf_tx,
1822        .sta_rc_update      = ath9k_htc_sta_rc_update,
1823        .bss_info_changed   = ath9k_htc_bss_info_changed,
1824        .set_key            = ath9k_htc_set_key,
1825        .get_tsf            = ath9k_htc_get_tsf,
1826        .set_tsf            = ath9k_htc_set_tsf,
1827        .reset_tsf          = ath9k_htc_reset_tsf,
1828        .ampdu_action       = ath9k_htc_ampdu_action,
1829        .sw_scan_start      = ath9k_htc_sw_scan_start,
1830        .sw_scan_complete   = ath9k_htc_sw_scan_complete,
1831        .set_rts_threshold  = ath9k_htc_set_rts_threshold,
1832        .rfkill_poll        = ath9k_htc_rfkill_poll_state,
1833        .set_coverage_class = ath9k_htc_set_coverage_class,
1834        .set_bitrate_mask   = ath9k_htc_set_bitrate_mask,
1835        .get_stats          = ath9k_htc_get_stats,
1836        .get_antenna        = ath9k_htc_get_antenna,
1837
1838#ifdef CONFIG_ATH9K_HTC_DEBUGFS
1839        .get_et_sset_count  = ath9k_htc_get_et_sset_count,
1840        .get_et_stats       = ath9k_htc_get_et_stats,
1841        .get_et_strings     = ath9k_htc_get_et_strings,
1842#endif
1843};
1844