ath5k: implement ieee80211_ops->{get,set}_ringparam
authorJohn W. Linville <linville@tuxdriver.com>
Mon, 7 Mar 2011 21:32:59 +0000 (16:32 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 11 Mar 2011 20:34:18 +0000 (15:34 -0500)
set_ringparam only allows changes to tx ring at this time.

Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/base.h
drivers/net/wireless/ath/ath5k/mac80211-ops.c

index e6ff62e60a79000d5e99f3ea80a65d2012205085..4d7f21ee111cf28b3aa2120d38c4b08282c8cb8e 100644 (file)
@@ -943,6 +943,7 @@ ath5k_txq_setup(struct ath5k_softc *sc,
                spin_lock_init(&txq->lock);
                txq->setup = true;
                txq->txq_len = 0;
+               txq->txq_max = ATH5K_TXQ_LEN_MAX;
                txq->txq_poll_mark = false;
                txq->txq_stuck = 0;
        }
@@ -1534,7 +1535,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
                goto drop_packet;
        }
 
-       if (txq->txq_len >= ATH5K_TXQ_LEN_MAX)
+       if (txq->txq_len >= txq->txq_max)
                ieee80211_stop_queue(hw, txq->qnum);
 
        spin_lock_irqsave(&sc->txbuflock, flags);
index 8d1df1fa23511498e963efe783002cf3c7fc5559..978f1f4ac2f33b89c92dd40652faca4fc75ecb8d 100644 (file)
@@ -86,6 +86,7 @@ struct ath5k_txq {
        spinlock_t              lock;   /* lock on q and link */
        bool                    setup;
        int                     txq_len; /* number of queued buffers */
+       int                     txq_max; /* max allowed num of queued buffers */
        bool                    txq_poll_mark;
        unsigned int            txq_stuck;      /* informational counter */
 };
index c9b0b676adda2d19c61118dd7628f0c7df782650..9be29b728b1cffe2fdc5d9bf0977fe14e77fc562 100644 (file)
@@ -740,6 +740,47 @@ ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
 }
 
 
+static void ath5k_get_ringparam(struct ieee80211_hw *hw,
+                               u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       *tx = sc->txqs[AR5K_TX_QUEUE_ID_DATA_MIN].txq_max;
+
+       *tx_max = ATH5K_TXQ_LEN_MAX;
+       *rx = *rx_max = ATH_RXBUF;
+}
+
+
+static int ath5k_set_ringparam(struct ieee80211_hw *hw, u32 tx, u32 rx)
+{
+       struct ath5k_softc *sc = hw->priv;
+       u16 qnum;
+
+       /* only support setting tx ring size for now */
+       if (rx != ATH_RXBUF)
+               return -EINVAL;
+
+       /* restrict tx ring size min/max */
+       if (!tx || tx > ATH5K_TXQ_LEN_MAX)
+               return -EINVAL;
+
+       for (qnum = 0; qnum < ARRAY_SIZE(sc->txqs); qnum++) {
+               if (!sc->txqs[qnum].setup)
+                       continue;
+               if (sc->txqs[qnum].qnum < AR5K_TX_QUEUE_ID_DATA_MIN ||
+                   sc->txqs[qnum].qnum > AR5K_TX_QUEUE_ID_DATA_MAX)
+                       continue;
+
+               sc->txqs[qnum].txq_max = tx;
+               if (sc->txqs[qnum].txq_len >= sc->txqs[qnum].txq_max)
+                       ieee80211_stop_queue(hw, sc->txqs[qnum].qnum);
+       }
+
+       return 0;
+}
+
+
 const struct ieee80211_ops ath5k_hw_ops = {
        .tx                     = ath5k_tx,
        .start                  = ath5k_start,
@@ -778,4 +819,6 @@ const struct ieee80211_ops ath5k_hw_ops = {
        /* .napi_poll           = not implemented */
        .set_antenna            = ath5k_set_antenna,
        .get_antenna            = ath5k_get_antenna,
+       .set_ringparam          = ath5k_set_ringparam,
+       .get_ringparam          = ath5k_get_ringparam,
 };