linux/drivers/net/wireless/ath/ath9k/htc_drv_txrx.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/* TX */
  21/******/
  22
  23static const int subtype_txq_to_hwq[] = {
  24        [IEEE80211_AC_BE] = ATH_TXQ_AC_BE,
  25        [IEEE80211_AC_BK] = ATH_TXQ_AC_BK,
  26        [IEEE80211_AC_VI] = ATH_TXQ_AC_VI,
  27        [IEEE80211_AC_VO] = ATH_TXQ_AC_VO,
  28};
  29
  30#define ATH9K_HTC_INIT_TXQ(subtype) do {                        \
  31                qi.tqi_subtype = subtype_txq_to_hwq[subtype];   \
  32                qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;             \
  33                qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;            \
  34                qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;            \
  35                qi.tqi_physCompBuf = 0;                         \
  36                qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |      \
  37                        TXQ_FLAG_TXDESCINT_ENABLE;              \
  38        } while (0)
  39
  40int get_hw_qnum(u16 queue, int *hwq_map)
  41{
  42        switch (queue) {
  43        case 0:
  44                return hwq_map[IEEE80211_AC_VO];
  45        case 1:
  46                return hwq_map[IEEE80211_AC_VI];
  47        case 2:
  48                return hwq_map[IEEE80211_AC_BE];
  49        case 3:
  50                return hwq_map[IEEE80211_AC_BK];
  51        default:
  52                return hwq_map[IEEE80211_AC_BE];
  53        }
  54}
  55
  56void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv)
  57{
  58        spin_lock_bh(&priv->tx.tx_lock);
  59        priv->tx.queued_cnt++;
  60        if ((priv->tx.queued_cnt >= ATH9K_HTC_TX_THRESHOLD) &&
  61            !(priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) {
  62                priv->tx.flags |= ATH9K_HTC_OP_TX_QUEUES_STOP;
  63                ieee80211_stop_queues(priv->hw);
  64        }
  65        spin_unlock_bh(&priv->tx.tx_lock);
  66}
  67
  68void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv)
  69{
  70        spin_lock_bh(&priv->tx.tx_lock);
  71        if ((priv->tx.queued_cnt < ATH9K_HTC_TX_THRESHOLD) &&
  72            (priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) {
  73                priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
  74                ieee80211_wake_queues(priv->hw);
  75        }
  76        spin_unlock_bh(&priv->tx.tx_lock);
  77}
  78
  79int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv)
  80{
  81        int slot;
  82
  83        spin_lock_bh(&priv->tx.tx_lock);
  84        slot = find_first_zero_bit(priv->tx.tx_slot, MAX_TX_BUF_NUM);
  85        if (slot >= MAX_TX_BUF_NUM) {
  86                spin_unlock_bh(&priv->tx.tx_lock);
  87                return -ENOBUFS;
  88        }
  89        __set_bit(slot, priv->tx.tx_slot);
  90        spin_unlock_bh(&priv->tx.tx_lock);
  91
  92        return slot;
  93}
  94
  95void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot)
  96{
  97        spin_lock_bh(&priv->tx.tx_lock);
  98        __clear_bit(slot, priv->tx.tx_slot);
  99        spin_unlock_bh(&priv->tx.tx_lock);
 100}
 101
 102static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv,
 103                                                u16 qnum)
 104{
 105        enum htc_endpoint_id epid;
 106
 107        switch (qnum) {
 108        case 0:
 109                TX_QSTAT_INC(IEEE80211_AC_VO);
 110                epid = priv->data_vo_ep;
 111                break;
 112        case 1:
 113                TX_QSTAT_INC(IEEE80211_AC_VI);
 114                epid = priv->data_vi_ep;
 115                break;
 116        case 2:
 117                TX_QSTAT_INC(IEEE80211_AC_BE);
 118                epid = priv->data_be_ep;
 119                break;
 120        case 3:
 121        default:
 122                TX_QSTAT_INC(IEEE80211_AC_BK);
 123                epid = priv->data_bk_ep;
 124                break;
 125        }
 126
 127        return epid;
 128}
 129
 130static inline struct sk_buff_head*
 131get_htc_epid_queue(struct ath9k_htc_priv *priv, u8 epid)
 132{
 133        struct ath_common *common = ath9k_hw_common(priv->ah);
 134        struct sk_buff_head *epid_queue = NULL;
 135
 136        if (epid == priv->mgmt_ep)
 137                epid_queue = &priv->tx.mgmt_ep_queue;
 138        else if (epid == priv->cab_ep)
 139                epid_queue = &priv->tx.cab_ep_queue;
 140        else if (epid == priv->data_be_ep)
 141                epid_queue = &priv->tx.data_be_queue;
 142        else if (epid == priv->data_bk_ep)
 143                epid_queue = &priv->tx.data_bk_queue;
 144        else if (epid == priv->data_vi_ep)
 145                epid_queue = &priv->tx.data_vi_queue;
 146        else if (epid == priv->data_vo_ep)
 147                epid_queue = &priv->tx.data_vo_queue;
 148        else
 149                ath_err(common, "Invalid EPID: %d\n", epid);
 150
 151        return epid_queue;
 152}
 153
 154/*
 155 * Removes the driver header and returns the TX slot number
 156 */
 157static inline int strip_drv_header(struct ath9k_htc_priv *priv,
 158                                   struct sk_buff *skb)
 159{
 160        struct ath_common *common = ath9k_hw_common(priv->ah);
 161        struct ath9k_htc_tx_ctl *tx_ctl;
 162        int slot;
 163
 164        tx_ctl = HTC_SKB_CB(skb);
 165
 166        if (tx_ctl->epid == priv->mgmt_ep) {
 167                struct tx_mgmt_hdr *tx_mhdr =
 168                        (struct tx_mgmt_hdr *)skb->data;
 169                slot = tx_mhdr->cookie;
 170                skb_pull(skb, sizeof(struct tx_mgmt_hdr));
 171        } else if ((tx_ctl->epid == priv->data_bk_ep) ||
 172                   (tx_ctl->epid == priv->data_be_ep) ||
 173                   (tx_ctl->epid == priv->data_vi_ep) ||
 174                   (tx_ctl->epid == priv->data_vo_ep) ||
 175                   (tx_ctl->epid == priv->cab_ep)) {
 176                struct tx_frame_hdr *tx_fhdr =
 177                        (struct tx_frame_hdr *)skb->data;
 178                slot = tx_fhdr->cookie;
 179                skb_pull(skb, sizeof(struct tx_frame_hdr));
 180        } else {
 181                ath_err(common, "Unsupported EPID: %d\n", tx_ctl->epid);
 182                slot = -EINVAL;
 183        }
 184
 185        return slot;
 186}
 187
 188int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
 189                       struct ath9k_tx_queue_info *qinfo)
 190{
 191        struct ath_hw *ah = priv->ah;
 192        int error = 0;
 193        struct ath9k_tx_queue_info qi;
 194
 195        ath9k_hw_get_txq_props(ah, qnum, &qi);
 196
 197        qi.tqi_aifs = qinfo->tqi_aifs;
 198        qi.tqi_cwmin = qinfo->tqi_cwmin / 2; /* XXX */
 199        qi.tqi_cwmax = qinfo->tqi_cwmax;
 200        qi.tqi_burstTime = qinfo->tqi_burstTime;
 201        qi.tqi_readyTime = qinfo->tqi_readyTime;
 202
 203        if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
 204                ath_err(ath9k_hw_common(ah),
 205                        "Unable to update hardware queue %u!\n", qnum);
 206                error = -EIO;
 207        } else {
 208                ath9k_hw_resettxqueue(ah, qnum);
 209        }
 210
 211        return error;
 212}
 213
 214static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv,
 215                              struct ath9k_htc_vif *avp,
 216                              struct sk_buff *skb,
 217                              u8 sta_idx, u8 vif_idx, u8 slot)
 218{
 219        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 220        struct ieee80211_mgmt *mgmt;
 221        struct ieee80211_hdr *hdr;
 222        struct tx_mgmt_hdr mgmt_hdr;
 223        struct ath9k_htc_tx_ctl *tx_ctl;
 224        u8 *tx_fhdr;
 225
 226        tx_ctl = HTC_SKB_CB(skb);
 227        hdr = (struct ieee80211_hdr *) skb->data;
 228
 229        memset(tx_ctl, 0, sizeof(*tx_ctl));
 230        memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
 231
 232        /*
 233         * Set the TSF adjust value for probe response
 234         * frame also.
 235         */
 236        if (avp && unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
 237                mgmt = (struct ieee80211_mgmt *)skb->data;
 238                mgmt->u.probe_resp.timestamp = avp->tsfadjust;
 239        }
 240
 241        tx_ctl->type = ATH9K_HTC_MGMT;
 242
 243        mgmt_hdr.node_idx = sta_idx;
 244        mgmt_hdr.vif_idx = vif_idx;
 245        mgmt_hdr.tidno = 0;
 246        mgmt_hdr.flags = 0;
 247        mgmt_hdr.cookie = slot;
 248
 249        mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
 250        if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
 251                mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
 252        else
 253                mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
 254
 255        tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
 256        memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
 257        tx_ctl->epid = priv->mgmt_ep;
 258}
 259
 260static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv,
 261                              struct ieee80211_vif *vif,
 262                              struct sk_buff *skb,
 263                              u8 sta_idx, u8 vif_idx, u8 slot,
 264                              bool is_cab)
 265{
 266        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 267        struct ieee80211_hdr *hdr;
 268        struct ath9k_htc_tx_ctl *tx_ctl;
 269        struct tx_frame_hdr tx_hdr;
 270        u32 flags = 0;
 271        u8 *qc, *tx_fhdr;
 272        u16 qnum;
 273
 274        tx_ctl = HTC_SKB_CB(skb);
 275        hdr = (struct ieee80211_hdr *) skb->data;
 276
 277        memset(tx_ctl, 0, sizeof(*tx_ctl));
 278        memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
 279
 280        tx_hdr.node_idx = sta_idx;
 281        tx_hdr.vif_idx = vif_idx;
 282        tx_hdr.cookie = slot;
 283
 284        /*
 285         * This is a bit redundant but it helps to get
 286         * the per-packet index quickly when draining the
 287         * TX queue in the HIF layer. Otherwise we would
 288         * have to parse the packet contents ...
 289         */
 290        tx_ctl->sta_idx = sta_idx;
 291
 292        if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
 293                tx_ctl->type = ATH9K_HTC_AMPDU;
 294                tx_hdr.data_type = ATH9K_HTC_AMPDU;
 295        } else {
 296                tx_ctl->type = ATH9K_HTC_NORMAL;
 297                tx_hdr.data_type = ATH9K_HTC_NORMAL;
 298        }
 299
 300        if (ieee80211_is_data_qos(hdr->frame_control)) {
 301                qc = ieee80211_get_qos_ctl(hdr);
 302                tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
 303        }
 304
 305        /* Check for RTS protection */
 306        if (priv->hw->wiphy->rts_threshold != (u32) -1)
 307                if (skb->len > priv->hw->wiphy->rts_threshold)
 308                        flags |= ATH9K_HTC_TX_RTSCTS;
 309
 310        /* CTS-to-self */
 311        if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
 312            (vif && vif->bss_conf.use_cts_prot))
 313                flags |= ATH9K_HTC_TX_CTSONLY;
 314
 315        tx_hdr.flags = cpu_to_be32(flags);
 316        tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
 317        if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
 318                tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
 319        else
 320                tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
 321
 322        tx_fhdr = skb_push(skb, sizeof(tx_hdr));
 323        memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
 324
 325        if (is_cab) {
 326                CAB_STAT_INC;
 327                tx_ctl->epid = priv->cab_ep;
 328                return;
 329        }
 330
 331        qnum = skb_get_queue_mapping(skb);
 332        tx_ctl->epid = get_htc_epid(priv, qnum);
 333}
 334
 335int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
 336                       struct ieee80211_sta *sta,
 337                       struct sk_buff *skb,
 338                       u8 slot, bool is_cab)
 339{
 340        struct ieee80211_hdr *hdr;
 341        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 342        struct ieee80211_vif *vif = tx_info->control.vif;
 343        struct ath9k_htc_sta *ista;
 344        struct ath9k_htc_vif *avp = NULL;
 345        u8 sta_idx, vif_idx;
 346
 347        hdr = (struct ieee80211_hdr *) skb->data;
 348
 349        /*
 350         * Find out on which interface this packet has to be
 351         * sent out.
 352         */
 353        if (vif) {
 354                avp = (struct ath9k_htc_vif *) vif->drv_priv;
 355                vif_idx = avp->index;
 356        } else {
 357                if (!priv->ah->is_monitoring) {
 358                        ath_dbg(ath9k_hw_common(priv->ah), XMIT,
 359                                "VIF is null, but no monitor interface !\n");
 360                        return -EINVAL;
 361                }
 362
 363                vif_idx = priv->mon_vif_idx;
 364        }
 365
 366        /*
 367         * Find out which station this packet is destined for.
 368         */
 369        if (sta) {
 370                ista = (struct ath9k_htc_sta *) sta->drv_priv;
 371                sta_idx = ista->index;
 372        } else {
 373                sta_idx = priv->vif_sta_pos[vif_idx];
 374        }
 375
 376        if (ieee80211_is_data(hdr->frame_control))
 377                ath9k_htc_tx_data(priv, vif, skb,
 378                                  sta_idx, vif_idx, slot, is_cab);
 379        else
 380                ath9k_htc_tx_mgmt(priv, avp, skb,
 381                                  sta_idx, vif_idx, slot);
 382
 383
 384        return htc_send(priv->htc, skb);
 385}
 386
 387static inline bool __ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
 388                                             struct ath9k_htc_sta *ista, u8 tid)
 389{
 390        bool ret = false;
 391
 392        spin_lock_bh(&priv->tx.tx_lock);
 393        if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP))
 394                ret = true;
 395        spin_unlock_bh(&priv->tx.tx_lock);
 396
 397        return ret;
 398}
 399
 400static void ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
 401                                    struct ieee80211_vif *vif,
 402                                    struct sk_buff *skb)
 403{
 404        struct ieee80211_sta *sta;
 405        struct ieee80211_hdr *hdr;
 406        __le16 fc;
 407
 408        hdr = (struct ieee80211_hdr *) skb->data;
 409        fc = hdr->frame_control;
 410
 411        rcu_read_lock();
 412
 413        sta = ieee80211_find_sta(vif, hdr->addr1);
 414        if (!sta) {
 415                rcu_read_unlock();
 416                return;
 417        }
 418
 419        if (sta && conf_is_ht(&priv->hw->conf) &&
 420            !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
 421                if (ieee80211_is_data_qos(fc)) {
 422                        u8 *qc, tid;
 423                        struct ath9k_htc_sta *ista;
 424
 425                        qc = ieee80211_get_qos_ctl(hdr);
 426                        tid = qc[0] & 0xf;
 427                        ista = (struct ath9k_htc_sta *)sta->drv_priv;
 428                        if (__ath9k_htc_check_tx_aggr(priv, ista, tid)) {
 429                                ieee80211_start_tx_ba_session(sta, tid, 0);
 430                                spin_lock_bh(&priv->tx.tx_lock);
 431                                ista->tid_state[tid] = AGGR_PROGRESS;
 432                                spin_unlock_bh(&priv->tx.tx_lock);
 433                        }
 434                }
 435        }
 436
 437        rcu_read_unlock();
 438}
 439
 440static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
 441                                 struct sk_buff *skb,
 442                                 struct __wmi_event_txstatus *txs)
 443{
 444        struct ieee80211_vif *vif;
 445        struct ath9k_htc_tx_ctl *tx_ctl;
 446        struct ieee80211_tx_info *tx_info;
 447        struct ieee80211_tx_rate *rate;
 448        struct ieee80211_conf *cur_conf = &priv->hw->conf;
 449        bool txok;
 450        int slot;
 451        int hdrlen, padsize;
 452
 453        slot = strip_drv_header(priv, skb);
 454        if (slot < 0) {
 455                dev_kfree_skb_any(skb);
 456                return;
 457        }
 458
 459        tx_ctl = HTC_SKB_CB(skb);
 460        txok = tx_ctl->txok;
 461        tx_info = IEEE80211_SKB_CB(skb);
 462        vif = tx_info->control.vif;
 463        rate = &tx_info->status.rates[0];
 464
 465        memset(&tx_info->status, 0, sizeof(tx_info->status));
 466
 467        /*
 468         * URB submission failed for this frame, it never reached
 469         * the target.
 470         */
 471        if (!txok || !vif || !txs)
 472                goto send_mac80211;
 473
 474        if (txs->ts_flags & ATH9K_HTC_TXSTAT_ACK) {
 475                tx_info->flags |= IEEE80211_TX_STAT_ACK;
 476                if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
 477                        tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
 478        }
 479
 480        if (txs->ts_flags & ATH9K_HTC_TXSTAT_FILT)
 481                tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
 482
 483        if (txs->ts_flags & ATH9K_HTC_TXSTAT_RTC_CTS)
 484                rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
 485
 486        rate->count = 1;
 487        rate->idx = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_RATE);
 488
 489        if (txs->ts_flags & ATH9K_HTC_TXSTAT_MCS) {
 490                rate->flags |= IEEE80211_TX_RC_MCS;
 491
 492                if (txs->ts_flags & ATH9K_HTC_TXSTAT_CW40)
 493                        rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
 494                if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI)
 495                        rate->flags |= IEEE80211_TX_RC_SHORT_GI;
 496        } else {
 497                if (cur_conf->chandef.chan->band == NL80211_BAND_5GHZ)
 498                        rate->idx += 4; /* No CCK rates */
 499        }
 500
 501        ath9k_htc_check_tx_aggr(priv, vif, skb);
 502
 503send_mac80211:
 504        spin_lock_bh(&priv->tx.tx_lock);
 505        if (WARN_ON(--priv->tx.queued_cnt < 0))
 506                priv->tx.queued_cnt = 0;
 507        spin_unlock_bh(&priv->tx.tx_lock);
 508
 509        ath9k_htc_tx_clear_slot(priv, slot);
 510
 511        /* Remove padding before handing frame back to mac80211 */
 512        hdrlen = ieee80211_get_hdrlen_from_skb(skb);
 513
 514        padsize = hdrlen & 3;
 515        if (padsize && skb->len > hdrlen + padsize) {
 516                memmove(skb->data + padsize, skb->data, hdrlen);
 517                skb_pull(skb, padsize);
 518        }
 519
 520        /* Send status to mac80211 */
 521        ieee80211_tx_status(priv->hw, skb);
 522}
 523
 524static inline void ath9k_htc_tx_drainq(struct ath9k_htc_priv *priv,
 525                                       struct sk_buff_head *queue)
 526{
 527        struct sk_buff *skb;
 528
 529        while ((skb = skb_dequeue(queue)) != NULL) {
 530                ath9k_htc_tx_process(priv, skb, NULL);
 531        }
 532}
 533
 534void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv)
 535{
 536        struct ath9k_htc_tx_event *event, *tmp;
 537
 538        spin_lock_bh(&priv->tx.tx_lock);
 539        priv->tx.flags |= ATH9K_HTC_OP_TX_DRAIN;
 540        spin_unlock_bh(&priv->tx.tx_lock);
 541
 542        /*
 543         * Ensure that all pending TX frames are flushed,
 544         * and that the TX completion/failed tasklets is killed.
 545         */
 546        htc_stop(priv->htc);
 547        tasklet_kill(&priv->wmi->wmi_event_tasklet);
 548        tasklet_kill(&priv->tx_failed_tasklet);
 549
 550        ath9k_htc_tx_drainq(priv, &priv->tx.mgmt_ep_queue);
 551        ath9k_htc_tx_drainq(priv, &priv->tx.cab_ep_queue);
 552        ath9k_htc_tx_drainq(priv, &priv->tx.data_be_queue);
 553        ath9k_htc_tx_drainq(priv, &priv->tx.data_bk_queue);
 554        ath9k_htc_tx_drainq(priv, &priv->tx.data_vi_queue);
 555        ath9k_htc_tx_drainq(priv, &priv->tx.data_vo_queue);
 556        ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed);
 557
 558        /*
 559         * The TX cleanup timer has already been killed.
 560         */
 561        spin_lock_bh(&priv->wmi->event_lock);
 562        list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) {
 563                list_del(&event->list);
 564                kfree(event);
 565        }
 566        spin_unlock_bh(&priv->wmi->event_lock);
 567
 568        spin_lock_bh(&priv->tx.tx_lock);
 569        priv->tx.flags &= ~ATH9K_HTC_OP_TX_DRAIN;
 570        spin_unlock_bh(&priv->tx.tx_lock);
 571}
 572
 573void ath9k_tx_failed_tasklet(unsigned long data)
 574{
 575        struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
 576
 577        spin_lock_bh(&priv->tx.tx_lock);
 578        if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
 579                spin_unlock_bh(&priv->tx.tx_lock);
 580                return;
 581        }
 582        spin_unlock_bh(&priv->tx.tx_lock);
 583
 584        ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed);
 585}
 586
 587static inline bool check_cookie(struct ath9k_htc_priv *priv,
 588                                struct sk_buff *skb,
 589                                u8 cookie, u8 epid)
 590{
 591        u8 fcookie = 0;
 592
 593        if (epid == priv->mgmt_ep) {
 594                struct tx_mgmt_hdr *hdr;
 595                hdr = (struct tx_mgmt_hdr *) skb->data;
 596                fcookie = hdr->cookie;
 597        } else if ((epid == priv->data_bk_ep) ||
 598                   (epid == priv->data_be_ep) ||
 599                   (epid == priv->data_vi_ep) ||
 600                   (epid == priv->data_vo_ep) ||
 601                   (epid == priv->cab_ep)) {
 602                struct tx_frame_hdr *hdr;
 603                hdr = (struct tx_frame_hdr *) skb->data;
 604                fcookie = hdr->cookie;
 605        }
 606
 607        if (fcookie == cookie)
 608                return true;
 609
 610        return false;
 611}
 612
 613static struct sk_buff* ath9k_htc_tx_get_packet(struct ath9k_htc_priv *priv,
 614                                               struct __wmi_event_txstatus *txs)
 615{
 616        struct ath_common *common = ath9k_hw_common(priv->ah);
 617        struct sk_buff_head *epid_queue;
 618        struct sk_buff *skb, *tmp;
 619        unsigned long flags;
 620        u8 epid = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_EPID);
 621
 622        epid_queue = get_htc_epid_queue(priv, epid);
 623        if (!epid_queue)
 624                return NULL;
 625
 626        spin_lock_irqsave(&epid_queue->lock, flags);
 627        skb_queue_walk_safe(epid_queue, skb, tmp) {
 628                if (check_cookie(priv, skb, txs->cookie, epid)) {
 629                        __skb_unlink(skb, epid_queue);
 630                        spin_unlock_irqrestore(&epid_queue->lock, flags);
 631                        return skb;
 632                }
 633        }
 634        spin_unlock_irqrestore(&epid_queue->lock, flags);
 635
 636        ath_dbg(common, XMIT, "No matching packet for cookie: %d, epid: %d\n",
 637                txs->cookie, epid);
 638
 639        return NULL;
 640}
 641
 642void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event)
 643{
 644        struct wmi_event_txstatus *txs = wmi_event;
 645        struct __wmi_event_txstatus *__txs;
 646        struct sk_buff *skb;
 647        struct ath9k_htc_tx_event *tx_pend;
 648        int i;
 649
 650        for (i = 0; i < txs->cnt; i++) {
 651                WARN_ON(txs->cnt > HTC_MAX_TX_STATUS);
 652
 653                __txs = &txs->txstatus[i];
 654
 655                skb = ath9k_htc_tx_get_packet(priv, __txs);
 656                if (!skb) {
 657                        /*
 658                         * Store this event, so that the TX cleanup
 659                         * routine can check later for the needed packet.
 660                         */
 661                        tx_pend = kzalloc(sizeof(struct ath9k_htc_tx_event),
 662                                          GFP_ATOMIC);
 663                        if (!tx_pend)
 664                                continue;
 665
 666                        memcpy(&tx_pend->txs, __txs,
 667                               sizeof(struct __wmi_event_txstatus));
 668
 669                        spin_lock(&priv->wmi->event_lock);
 670                        list_add_tail(&tx_pend->list,
 671                                      &priv->wmi->pending_tx_events);
 672                        spin_unlock(&priv->wmi->event_lock);
 673
 674                        continue;
 675                }
 676
 677                ath9k_htc_tx_process(priv, skb, __txs);
 678        }
 679
 680        /* Wake TX queues if needed */
 681        ath9k_htc_check_wake_queues(priv);
 682}
 683
 684void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb,
 685                    enum htc_endpoint_id ep_id, bool txok)
 686{
 687        struct ath9k_htc_priv *priv = drv_priv;
 688        struct ath9k_htc_tx_ctl *tx_ctl;
 689        struct sk_buff_head *epid_queue;
 690
 691        tx_ctl = HTC_SKB_CB(skb);
 692        tx_ctl->txok = txok;
 693        tx_ctl->timestamp = jiffies;
 694
 695        if (!txok) {
 696                skb_queue_tail(&priv->tx.tx_failed, skb);
 697                tasklet_schedule(&priv->tx_failed_tasklet);
 698                return;
 699        }
 700
 701        epid_queue = get_htc_epid_queue(priv, ep_id);
 702        if (!epid_queue) {
 703                dev_kfree_skb_any(skb);
 704                return;
 705        }
 706
 707        skb_queue_tail(epid_queue, skb);
 708}
 709
 710static inline bool check_packet(struct ath9k_htc_priv *priv, struct sk_buff *skb)
 711{
 712        struct ath_common *common = ath9k_hw_common(priv->ah);
 713        struct ath9k_htc_tx_ctl *tx_ctl;
 714
 715        tx_ctl = HTC_SKB_CB(skb);
 716
 717        if (time_after(jiffies,
 718                       tx_ctl->timestamp +
 719                       msecs_to_jiffies(ATH9K_HTC_TX_TIMEOUT_INTERVAL))) {
 720                ath_dbg(common, XMIT, "Dropping a packet due to TX timeout\n");
 721                return true;
 722        }
 723
 724        return false;
 725}
 726
 727static void ath9k_htc_tx_cleanup_queue(struct ath9k_htc_priv *priv,
 728                                       struct sk_buff_head *epid_queue)
 729{
 730        bool process = false;
 731        unsigned long flags;
 732        struct sk_buff *skb, *tmp;
 733        struct sk_buff_head queue;
 734
 735        skb_queue_head_init(&queue);
 736
 737        spin_lock_irqsave(&epid_queue->lock, flags);
 738        skb_queue_walk_safe(epid_queue, skb, tmp) {
 739                if (check_packet(priv, skb)) {
 740                        __skb_unlink(skb, epid_queue);
 741                        __skb_queue_tail(&queue, skb);
 742                        process = true;
 743                }
 744        }
 745        spin_unlock_irqrestore(&epid_queue->lock, flags);
 746
 747        if (process) {
 748                skb_queue_walk_safe(&queue, skb, tmp) {
 749                        __skb_unlink(skb, &queue);
 750                        ath9k_htc_tx_process(priv, skb, NULL);
 751                }
 752        }
 753}
 754
 755void ath9k_htc_tx_cleanup_timer(struct timer_list *t)
 756{
 757        struct ath9k_htc_priv *priv = from_timer(priv, t, tx.cleanup_timer);
 758        struct ath_common *common = ath9k_hw_common(priv->ah);
 759        struct ath9k_htc_tx_event *event, *tmp;
 760        struct sk_buff *skb;
 761
 762        spin_lock(&priv->wmi->event_lock);
 763        list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) {
 764
 765                skb = ath9k_htc_tx_get_packet(priv, &event->txs);
 766                if (skb) {
 767                        ath_dbg(common, XMIT,
 768                                "Found packet for cookie: %d, epid: %d\n",
 769                                event->txs.cookie,
 770                                MS(event->txs.ts_rate, ATH9K_HTC_TXSTAT_EPID));
 771
 772                        ath9k_htc_tx_process(priv, skb, &event->txs);
 773                        list_del(&event->list);
 774                        kfree(event);
 775                        continue;
 776                }
 777
 778                if (++event->count >= ATH9K_HTC_TX_TIMEOUT_COUNT) {
 779                        list_del(&event->list);
 780                        kfree(event);
 781                }
 782        }
 783        spin_unlock(&priv->wmi->event_lock);
 784
 785        /*
 786         * Check if status-pending packets have to be cleaned up.
 787         */
 788        ath9k_htc_tx_cleanup_queue(priv, &priv->tx.mgmt_ep_queue);
 789        ath9k_htc_tx_cleanup_queue(priv, &priv->tx.cab_ep_queue);
 790        ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_be_queue);
 791        ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_bk_queue);
 792        ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vi_queue);
 793        ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vo_queue);
 794
 795        /* Wake TX queues if needed */
 796        ath9k_htc_check_wake_queues(priv);
 797
 798        mod_timer(&priv->tx.cleanup_timer,
 799                  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
 800}
 801
 802int ath9k_tx_init(struct ath9k_htc_priv *priv)
 803{
 804        skb_queue_head_init(&priv->tx.mgmt_ep_queue);
 805        skb_queue_head_init(&priv->tx.cab_ep_queue);
 806        skb_queue_head_init(&priv->tx.data_be_queue);
 807        skb_queue_head_init(&priv->tx.data_bk_queue);
 808        skb_queue_head_init(&priv->tx.data_vi_queue);
 809        skb_queue_head_init(&priv->tx.data_vo_queue);
 810        skb_queue_head_init(&priv->tx.tx_failed);
 811        return 0;
 812}
 813
 814void ath9k_tx_cleanup(struct ath9k_htc_priv *priv)
 815{
 816
 817}
 818
 819bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype)
 820{
 821        struct ath_hw *ah = priv->ah;
 822        struct ath_common *common = ath9k_hw_common(ah);
 823        struct ath9k_tx_queue_info qi;
 824        int qnum;
 825
 826        memset(&qi, 0, sizeof(qi));
 827        ATH9K_HTC_INIT_TXQ(subtype);
 828
 829        qnum = ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_DATA, &qi);
 830        if (qnum == -1)
 831                return false;
 832
 833        if (qnum >= ARRAY_SIZE(priv->hwq_map)) {
 834                ath_err(common, "qnum %u out of range, max %zu!\n",
 835                        qnum, ARRAY_SIZE(priv->hwq_map));
 836                ath9k_hw_releasetxqueue(ah, qnum);
 837                return false;
 838        }
 839
 840        priv->hwq_map[subtype] = qnum;
 841        return true;
 842}
 843
 844int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv)
 845{
 846        struct ath9k_tx_queue_info qi;
 847
 848        memset(&qi, 0, sizeof(qi));
 849        ATH9K_HTC_INIT_TXQ(0);
 850
 851        return ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_CAB, &qi);
 852}
 853
 854/******/
 855/* RX */
 856/******/
 857
 858/*
 859 * Calculate the RX filter to be set in the HW.
 860 */
 861u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
 862{
 863#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
 864
 865        struct ath_hw *ah = priv->ah;
 866        u32 rfilt;
 867
 868        rfilt = (ath9k_hw_getrxfilter(ah) & RX_FILTER_PRESERVE)
 869                | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
 870                | ATH9K_RX_FILTER_MCAST;
 871
 872        if (priv->rxfilter & FIF_PROBE_REQ)
 873                rfilt |= ATH9K_RX_FILTER_PROBEREQ;
 874
 875        if (ah->is_monitoring)
 876                rfilt |= ATH9K_RX_FILTER_PROM;
 877
 878        if (priv->rxfilter & FIF_CONTROL)
 879                rfilt |= ATH9K_RX_FILTER_CONTROL;
 880
 881        if ((ah->opmode == NL80211_IFTYPE_STATION) &&
 882            (priv->nvifs <= 1) &&
 883            !(priv->rxfilter & FIF_BCN_PRBRESP_PROMISC))
 884                rfilt |= ATH9K_RX_FILTER_MYBEACON;
 885        else
 886                rfilt |= ATH9K_RX_FILTER_BEACON;
 887
 888        if (conf_is_ht(&priv->hw->conf)) {
 889                rfilt |= ATH9K_RX_FILTER_COMP_BAR;
 890                rfilt |= ATH9K_RX_FILTER_UNCOMP_BA_BAR;
 891        }
 892
 893        if (priv->rxfilter & FIF_PSPOLL)
 894                rfilt |= ATH9K_RX_FILTER_PSPOLL;
 895
 896        if (priv->nvifs > 1 || priv->rxfilter & FIF_OTHER_BSS)
 897                rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
 898
 899        return rfilt;
 900
 901#undef RX_FILTER_PRESERVE
 902}
 903
 904/*
 905 * Recv initialization for opmode change.
 906 */
 907static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv)
 908{
 909        struct ath_hw *ah = priv->ah;
 910        u32 rfilt, mfilt[2];
 911
 912        /* configure rx filter */
 913        rfilt = ath9k_htc_calcrxfilter(priv);
 914        ath9k_hw_setrxfilter(ah, rfilt);
 915
 916        /* calculate and install multicast filter */
 917        mfilt[0] = mfilt[1] = ~0;
 918        ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
 919}
 920
 921void ath9k_host_rx_init(struct ath9k_htc_priv *priv)
 922{
 923        struct ath_common *common = ath9k_hw_common(priv->ah);
 924        ath9k_hw_rxena(priv->ah);
 925        ath9k_htc_opmode_init(priv);
 926        ath9k_hw_startpcureceive(priv->ah, test_bit(ATH_OP_SCANNING, &common->op_flags));
 927}
 928
 929static inline void convert_htc_flag(struct ath_rx_status *rx_stats,
 930                                   struct ath_htc_rx_status *rxstatus)
 931{
 932        rx_stats->enc_flags = 0;
 933        rx_stats->bw = RATE_INFO_BW_20;
 934        if (rxstatus->rs_flags & ATH9K_RX_2040)
 935                rx_stats->bw = RATE_INFO_BW_40;
 936        if (rxstatus->rs_flags & ATH9K_RX_GI)
 937                rx_stats->enc_flags |= RX_ENC_FLAG_SHORT_GI;
 938}
 939
 940static void rx_status_htc_to_ath(struct ath_rx_status *rx_stats,
 941                                 struct ath_htc_rx_status *rxstatus)
 942{
 943        rx_stats->rs_datalen    = be16_to_cpu(rxstatus->rs_datalen);
 944        rx_stats->rs_status     = rxstatus->rs_status;
 945        rx_stats->rs_phyerr     = rxstatus->rs_phyerr;
 946        rx_stats->rs_rssi       = rxstatus->rs_rssi;
 947        rx_stats->rs_keyix      = rxstatus->rs_keyix;
 948        rx_stats->rs_rate       = rxstatus->rs_rate;
 949        rx_stats->rs_antenna    = rxstatus->rs_antenna;
 950        rx_stats->rs_more       = rxstatus->rs_more;
 951
 952        memcpy(rx_stats->rs_rssi_ctl, rxstatus->rs_rssi_ctl,
 953                sizeof(rx_stats->rs_rssi_ctl));
 954        memcpy(rx_stats->rs_rssi_ext, rxstatus->rs_rssi_ext,
 955                sizeof(rx_stats->rs_rssi_ext));
 956
 957        rx_stats->rs_isaggr     = rxstatus->rs_isaggr;
 958        rx_stats->rs_moreaggr   = rxstatus->rs_moreaggr;
 959        rx_stats->rs_num_delims = rxstatus->rs_num_delims;
 960        convert_htc_flag(rx_stats, rxstatus);
 961}
 962
 963static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
 964                             struct ath9k_htc_rxbuf *rxbuf,
 965                             struct ieee80211_rx_status *rx_status)
 966
 967{
 968        struct ieee80211_hdr *hdr;
 969        struct ieee80211_hw *hw = priv->hw;
 970        struct sk_buff *skb = rxbuf->skb;
 971        struct ath_common *common = ath9k_hw_common(priv->ah);
 972        struct ath_hw *ah = common->ah;
 973        struct ath_htc_rx_status *rxstatus;
 974        struct ath_rx_status rx_stats;
 975        bool decrypt_error = false;
 976
 977        if (skb->len < HTC_RX_FRAME_HEADER_SIZE) {
 978                ath_err(common, "Corrupted RX frame, dropping (len: %d)\n",
 979                        skb->len);
 980                goto rx_next;
 981        }
 982
 983        rxstatus = (struct ath_htc_rx_status *)skb->data;
 984
 985        if (be16_to_cpu(rxstatus->rs_datalen) -
 986            (skb->len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
 987                ath_err(common,
 988                        "Corrupted RX data len, dropping (dlen: %d, skblen: %d)\n",
 989                        rxstatus->rs_datalen, skb->len);
 990                goto rx_next;
 991        }
 992
 993        /* Get the RX status information */
 994
 995        memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
 996
 997        /* Copy everything from ath_htc_rx_status (HTC_RX_FRAME_HEADER).
 998         * After this, we can drop this part of skb. */
 999        rx_status_htc_to_ath(&rx_stats, rxstatus);
1000        ath9k_htc_err_stat_rx(priv, &rx_stats);
1001        rx_status->mactime = be64_to_cpu(rxstatus->rs_tstamp);
1002        skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE);
1003
1004        /*
1005         * everything but the rate is checked here, the rate check is done
1006         * separately to avoid doing two lookups for a rate for each frame.
1007         */
1008        hdr = (struct ieee80211_hdr *)skb->data;
1009
1010        /*
1011         * Process PHY errors and return so that the packet
1012         * can be dropped.
1013         */
1014        if (rx_stats.rs_status & ATH9K_RXERR_PHY) {
1015                /* TODO: Not using DFS processing now. */
1016                if (ath_cmn_process_fft(&priv->spec_priv, hdr,
1017                                    &rx_stats, rx_status->mactime)) {
1018                        /* TODO: Code to collect spectral scan statistics */
1019                }
1020                goto rx_next;
1021        }
1022
1023        if (!ath9k_cmn_rx_accept(common, hdr, rx_status, &rx_stats,
1024                        &decrypt_error, priv->rxfilter))
1025                goto rx_next;
1026
1027        ath9k_cmn_rx_skb_postprocess(common, skb, &rx_stats,
1028                                     rx_status, decrypt_error);
1029
1030        if (ath9k_cmn_process_rate(common, hw, &rx_stats, rx_status))
1031                goto rx_next;
1032
1033        rx_stats.is_mybeacon = ath_is_mybeacon(common, hdr);
1034        ath9k_cmn_process_rssi(common, hw, &rx_stats, rx_status);
1035
1036        rx_status->band = ah->curchan->chan->band;
1037        rx_status->freq = ah->curchan->chan->center_freq;
1038        rx_status->antenna = rx_stats.rs_antenna;
1039        rx_status->flag |= RX_FLAG_MACTIME_END;
1040
1041        return true;
1042rx_next:
1043        return false;
1044}
1045
1046/*
1047 * FIXME: Handle FLUSH later on.
1048 */
1049void ath9k_rx_tasklet(unsigned long data)
1050{
1051        struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
1052        struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
1053        struct ieee80211_rx_status rx_status;
1054        struct sk_buff *skb;
1055        unsigned long flags;
1056        struct ieee80211_hdr *hdr;
1057
1058        do {
1059                spin_lock_irqsave(&priv->rx.rxbuflock, flags);
1060                list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
1061                        if (tmp_buf->in_process) {
1062                                rxbuf = tmp_buf;
1063                                break;
1064                        }
1065                }
1066
1067                if (rxbuf == NULL) {
1068                        spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
1069                        break;
1070                }
1071
1072                if (!rxbuf->skb)
1073                        goto requeue;
1074
1075                if (!ath9k_rx_prepare(priv, rxbuf, &rx_status)) {
1076                        dev_kfree_skb_any(rxbuf->skb);
1077                        goto requeue;
1078                }
1079
1080                memcpy(IEEE80211_SKB_RXCB(rxbuf->skb), &rx_status,
1081                       sizeof(struct ieee80211_rx_status));
1082                skb = rxbuf->skb;
1083                hdr = (struct ieee80211_hdr *) skb->data;
1084
1085                if (ieee80211_is_beacon(hdr->frame_control) && priv->ps_enabled)
1086                                ieee80211_queue_work(priv->hw, &priv->ps_work);
1087
1088                spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
1089
1090                ieee80211_rx(priv->hw, skb);
1091
1092                spin_lock_irqsave(&priv->rx.rxbuflock, flags);
1093requeue:
1094                rxbuf->in_process = false;
1095                rxbuf->skb = NULL;
1096                list_move_tail(&rxbuf->list, &priv->rx.rxbuf);
1097                rxbuf = NULL;
1098                spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
1099        } while (1);
1100
1101}
1102
1103void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
1104                    enum htc_endpoint_id ep_id)
1105{
1106        struct ath9k_htc_priv *priv = drv_priv;
1107        struct ath_hw *ah = priv->ah;
1108        struct ath_common *common = ath9k_hw_common(ah);
1109        struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
1110        unsigned long flags;
1111
1112        spin_lock_irqsave(&priv->rx.rxbuflock, flags);
1113        list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
1114                if (!tmp_buf->in_process) {
1115                        rxbuf = tmp_buf;
1116                        break;
1117                }
1118        }
1119        spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
1120
1121        if (rxbuf == NULL) {
1122                ath_dbg(common, ANY, "No free RX buffer\n");
1123                goto err;
1124        }
1125
1126        spin_lock_irqsave(&priv->rx.rxbuflock, flags);
1127        rxbuf->skb = skb;
1128        rxbuf->in_process = true;
1129        spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
1130
1131        tasklet_schedule(&priv->rx_tasklet);
1132        return;
1133err:
1134        dev_kfree_skb_any(skb);
1135}
1136
1137/* FIXME: Locking for cleanup/init */
1138
1139void ath9k_rx_cleanup(struct ath9k_htc_priv *priv)
1140{
1141        struct ath9k_htc_rxbuf *rxbuf, *tbuf;
1142
1143        list_for_each_entry_safe(rxbuf, tbuf, &priv->rx.rxbuf, list) {
1144                list_del(&rxbuf->list);
1145                if (rxbuf->skb)
1146                        dev_kfree_skb_any(rxbuf->skb);
1147                kfree(rxbuf);
1148        }
1149}
1150
1151int ath9k_rx_init(struct ath9k_htc_priv *priv)
1152{
1153        int i = 0;
1154
1155        INIT_LIST_HEAD(&priv->rx.rxbuf);
1156        spin_lock_init(&priv->rx.rxbuflock);
1157
1158        for (i = 0; i < ATH9K_HTC_RXBUF; i++) {
1159                struct ath9k_htc_rxbuf *rxbuf =
1160                        kzalloc(sizeof(struct ath9k_htc_rxbuf), GFP_KERNEL);
1161                if (rxbuf == NULL)
1162                        goto err;
1163
1164                list_add_tail(&rxbuf->list, &priv->rx.rxbuf);
1165        }
1166
1167        return 0;
1168
1169err:
1170        ath9k_rx_cleanup(priv);
1171        return -ENOMEM;
1172}
1173