]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/mwl8k.c
mwl8k: changing mwl8k_destroy_ba prototype
[karo-tx-linux.git] / drivers / net / wireless / mwl8k.c
index f221b95b90b3c2935c67e9c272d5f1c2a89000d4..76b2f9133159079fbc638df64c6d5a9910af8a04 100644 (file)
@@ -101,6 +101,18 @@ MODULE_PARM_DESC(ap_mode_default,
 #define MWL8K_MAX_TX_QUEUES    (MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES)
 #define mwl8k_tx_queues(priv)  (MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues)
 
+/* txpriorities are mapped with hw queues.
+ * Each hw queue has a txpriority.
+ */
+#define TOTAL_HW_TX_QUEUES     8
+
+/* Each HW queue can have one AMPDU stream.
+ * But, because one of the hw queue is reserved,
+ * maximum AMPDU queues that can be created are
+ * one short of total tx queues.
+ */
+#define MWL8K_NUM_AMPDU_STREAMS        (TOTAL_HW_TX_QUEUES - 1)
+
 struct rxd_ops {
        int rxd_size;
        void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
@@ -160,7 +172,6 @@ struct mwl8k_ampdu_stream {
        u8 tid;
        u8 state;
        u8 idx;
-       u8 txq_idx; /* index of this stream in priv->txq */
 };
 
 struct mwl8k_priv {
@@ -1734,14 +1745,13 @@ mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid)
        struct mwl8k_priv *priv = hw->priv;
        int i;
 
-       for (i = 0; i < priv->num_ampdu_queues; i++) {
+       for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) {
                stream = &priv->ampdu[i];
                if (stream->state == AMPDU_NO_STREAM) {
                        stream->sta = sta;
                        stream->state = AMPDU_STREAM_NEW;
                        stream->tid = tid;
                        stream->idx = i;
-                       stream->txq_idx = MWL8K_TX_WMM_QUEUES + i;
                        wiphy_debug(hw->wiphy, "Added a new stream for %pM %d",
                                    sta->addr, tid);
                        return stream;
@@ -1782,7 +1792,7 @@ mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid)
        struct mwl8k_priv *priv = hw->priv;
        int i;
 
-       for (i = 0 ; i < priv->num_ampdu_queues; i++) {
+       for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) {
                struct mwl8k_ampdu_stream *stream;
                stream = &priv->ampdu[i];
                if (stream->state == AMPDU_NO_STREAM)
@@ -1829,6 +1839,13 @@ static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid)
                tx_stats->pkts++;
 }
 
+/* The hardware ampdu queues start from 5.
+ * txpriorities for ampdu queues are
+ * 5 6 7 0 1 2 3 4 ie., queue 5 is highest
+ * and queue 3 is lowest (queue 4 is reserved)
+ */
+#define BA_QUEUE               5
+
 static void
 mwl8k_txq_xmit(struct ieee80211_hw *hw,
               int index,
@@ -1928,8 +1945,13 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
                stream = mwl8k_lookup_stream(hw, sta->addr, tid);
                if (stream != NULL) {
                        if (stream->state == AMPDU_STREAM_ACTIVE) {
-                               txpriority = stream->txq_idx;
-                               index = stream->txq_idx;
+                               WARN_ON(!(qos & MWL8K_QOS_ACK_POLICY_BLOCKACK));
+                               txpriority = (BA_QUEUE + stream->idx) %
+                                            TOTAL_HW_TX_QUEUES;
+                               if (stream->idx <= 1)
+                                       index = stream->idx +
+                                               MWL8K_TX_WMM_QUEUES;
+
                        } else if (stream->state == AMPDU_STREAM_NEW) {
                                /* We get here if the driver sends us packets
                                 * after we've initiated a stream, but before
@@ -1971,6 +1993,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
                        }
                }
                spin_unlock(&priv->stream_lock);
+       } else {
+               qos &= ~MWL8K_QOS_ACK_POLICY_MASK;
+               qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
        }
 
        dma = pci_map_single(priv->pdev, skb->data,
@@ -3763,7 +3788,7 @@ mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream,
 }
 
 static void mwl8k_destroy_ba(struct ieee80211_hw *hw,
-                            struct mwl8k_ampdu_stream *stream)
+                            u8 idx)
 {
        struct mwl8k_cmd_bastream *cmd;
 
@@ -3775,10 +3800,10 @@ static void mwl8k_destroy_ba(struct ieee80211_hw *hw,
        cmd->header.length = cpu_to_le16(sizeof(*cmd));
        cmd->action = cpu_to_le32(MWL8K_BA_DESTROY);
 
-       cmd->destroy_params.ba_context = cpu_to_le32(stream->idx);
+       cmd->destroy_params.ba_context = cpu_to_le32(idx);
        mwl8k_post_cmd(hw, &cmd->header);
 
-       wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", stream->idx);
+       wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", idx);
 
        kfree(cmd);
 }
@@ -5092,7 +5117,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        int i, rc = 0;
        struct mwl8k_priv *priv = hw->priv;
        struct mwl8k_ampdu_stream *stream;
-       u8 *addr = sta->addr;
+       u8 *addr = sta->addr, idx;
        struct mwl8k_sta *sta_info = MWL8K_STA(sta);
 
        if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
@@ -5170,11 +5195,14 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                }
                ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid);
                break;
-       case IEEE80211_AMPDU_TX_STOP:
+       case IEEE80211_AMPDU_TX_STOP_CONT:
+       case IEEE80211_AMPDU_TX_STOP_FLUSH:
+       case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
                if (stream) {
                        if (stream->state == AMPDU_STREAM_ACTIVE) {
+                               idx = stream->idx;
                                spin_unlock(&priv->stream_lock);
-                               mwl8k_destroy_ba(hw, stream);
+                               mwl8k_destroy_ba(hw, idx);
                                spin_lock(&priv->stream_lock);
                        }
                        mwl8k_remove_stream(hw, stream);
@@ -5190,8 +5218,9 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                if (!rc)
                        stream->state = AMPDU_STREAM_ACTIVE;
                else {
+                       idx = stream->idx;
                        spin_unlock(&priv->stream_lock);
-                       mwl8k_destroy_ba(hw, stream);
+                       mwl8k_destroy_ba(hw, idx);
                        spin_lock(&priv->stream_lock);
                        wiphy_debug(hw->wiphy,
                                "Failed adding stream for sta %pM tid %d\n",