ath9k: use ieee80211_free_txskb
[deliverable/linux.git] / drivers / net / wireless / ath / ath9k / xmit.c
index 0d4155aec48d72196d5c64eee5c2517766760632..378bd70256b2c7b8ad6358b2488919198dc42950 100644 (file)
@@ -66,8 +66,7 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
 static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
                                           struct ath_txq *txq,
                                           struct ath_atx_tid *tid,
-                                          struct sk_buff *skb,
-                                          bool dequeue);
+                                          struct sk_buff *skb);
 
 enum {
        MCS_HT20,
@@ -176,7 +175,15 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
                fi = get_frame_info(skb);
                bf = fi->bf;
 
-               if (bf && fi->retries) {
+               if (!bf) {
+                       bf = ath_tx_setup_buffer(sc, txq, tid, skb);
+                       if (!bf) {
+                               ieee80211_free_txskb(sc->hw, skb);
+                               continue;
+                       }
+               }
+
+               if (fi->retries) {
                        list_add_tail(&bf->list, &bf_head);
                        ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
                        ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
@@ -568,7 +575,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                if (!an->sleeping) {
                        ath_tx_queue_tid(txq, tid);
 
-                       if (ts->ts_status & ATH9K_TXERR_FILT)
+                       if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
                                tid->ac->clear_ps_filter = true;
                }
        }
@@ -785,10 +792,13 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
                fi = get_frame_info(skb);
                bf = fi->bf;
                if (!fi->bf)
-                       bf = ath_tx_setup_buffer(sc, txq, tid, skb, true);
+                       bf = ath_tx_setup_buffer(sc, txq, tid, skb);
 
-               if (!bf)
+               if (!bf) {
+                       __skb_unlink(skb, &tid->buf_q);
+                       ieee80211_free_txskb(sc->hw, skb);
                        continue;
+               }
 
                bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
                seqno = bf->bf_state.seqno;
@@ -1731,9 +1741,11 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
                return;
        }
 
-       bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
-       if (!bf)
+       bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
+       if (!bf) {
+               ieee80211_free_txskb(sc->hw, skb);
                return;
+       }
 
        bf->bf_state.bf_type = BUF_AMPDU;
        INIT_LIST_HEAD(&bf_head);
@@ -1757,11 +1769,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
        struct ath_buf *bf;
 
        bf = fi->bf;
-       if (!bf)
-               bf = ath_tx_setup_buffer(sc, txq, tid, skb, false);
-
-       if (!bf)
-               return;
 
        INIT_LIST_HEAD(&bf_head);
        list_add_tail(&bf->list, &bf_head);
@@ -1773,11 +1780,12 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
        TX_STAT_INC(txq->axq_qnum, queued);
 }
 
-static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
+static void setup_frame_info(struct ieee80211_hw *hw,
+                            struct ieee80211_sta *sta,
+                            struct sk_buff *skb,
                             int framelen)
 {
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_sta *sta = tx_info->control.sta;
        struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        const struct ieee80211_rate *rate;
@@ -1819,10 +1827,14 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
 {
        struct ath_hw *ah = sc->sc_ah;
        struct ath9k_channel *curchan = ah->curchan;
+
        if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) &&
            (curchan->channelFlags & CHANNEL_5GHZ) &&
            (chainmask == 0x7) && (rate < 0x90))
                return 0x3;
+       else if (AR_SREV_9462(ah) && ath9k_hw_btcoex_is_enabled(ah) &&
+                IS_CCK_RATE(rate))
+               return 0x2;
        else
                return chainmask;
 }
@@ -1834,8 +1846,7 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
 static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
                                           struct ath_txq *txq,
                                           struct ath_atx_tid *tid,
-                                          struct sk_buff *skb,
-                                          bool dequeue)
+                                          struct sk_buff *skb)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ath_frame_info *fi = get_frame_info(skb);
@@ -1847,7 +1858,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
        bf = ath_tx_get_buffer(sc);
        if (!bf) {
                ath_dbg(common, XMIT, "TX buffers are full\n");
-               goto error;
+               return NULL;
        }
 
        ATH_TXBUF_RESET(bf);
@@ -1876,18 +1887,12 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
                ath_err(ath9k_hw_common(sc->sc_ah),
                        "dma_mapping_error() on TX\n");
                ath_tx_return_buffer(sc, bf);
-               goto error;
+               return NULL;
        }
 
        fi->bf = bf;
 
        return bf;
-
-error:
-       if (dequeue)
-               __skb_unlink(skb, &tid->buf_q);
-       dev_kfree_skb_any(skb);
-       return NULL;
 }
 
 /* FIXME: tx power */
@@ -1916,9 +1921,14 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
                 */
                ath_tx_send_ampdu(sc, tid, skb, txctl);
        } else {
-               bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
-               if (!bf)
+               bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
+               if (!bf) {
+                       if (txctl->paprd)
+                               dev_kfree_skb_any(skb);
+                       else
+                               ieee80211_free_txskb(sc->hw, skb);
                        return;
+               }
 
                bf->bf_state.bfs_paprd = txctl->paprd;
 
@@ -1935,7 +1945,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_sta *sta = info->control.sta;
+       struct ieee80211_sta *sta = txctl->sta;
        struct ieee80211_vif *vif = info->control.vif;
        struct ath_softc *sc = hw->priv;
        struct ath_txq *txq = txctl->txq;
@@ -1979,7 +1989,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
            !ieee80211_is_data(hdr->frame_control))
                info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
 
-       setup_frame_info(hw, skb, frmlen);
+       setup_frame_info(hw, sta, skb, frmlen);
 
        /*
         * At this point, the vif, hw_key and sta pointers in the tx control
This page took 0.02812 seconds and 5 git commands to generate.