]> git.ipfire.org Git - people/ms/linux.git/commitdiff
ath5k: fix setup for CAB queue
authorBob Copeland <me@bobcopeland.com>
Thu, 21 Jan 2010 04:51:04 +0000 (23:51 -0500)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 1 Apr 2010 23:01:14 +0000 (16:01 -0700)
commit a951ae2176b982574ffa197455db6c89359fd5eb upstream.

The beacon sent gating doesn't seem to work with any combination
of flags.  Thus, buffered frames tend to stay buffered forever,
using up tx descriptors.

Instead, use the DBA gating and hold transmission of the buffered
frames until 80% of the beacon interval has elapsed using the ready
time.  This fixes the following error in AP mode:

   ath5k phy0: no further txbuf available, dropping packet

Add a comment to acknowledge that this isn't the best solution.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
Acked-by: Nick Kossifidis <mickflemm@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/net/wireless/ath/ath5k/ath5k.h
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/qcu.c

index bbd2f310b9ce681ea278eefbdc01c1350c160d38..8b43089bdafd8b16a8236b38c41b855d4a1c90d7 100644 (file)
@@ -535,7 +535,7 @@ struct ath5k_txq_info {
        u32     tqi_cbr_period; /* Constant bit rate period */
        u32     tqi_cbr_overflow_limit;
        u32     tqi_burst_time;
-       u32     tqi_ready_time; /* Not used */
+       u32     tqi_ready_time; /* Time queue waits after an event */
 };
 
 /*
index d6ee8acf134866c023f3a961ce63de47202c4c4d..ced648b152e08cbd01581471a75ef042b891d7c9 100644 (file)
@@ -1537,7 +1537,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
 
        ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
        if (ret)
-               return ret;
+               goto err;
+
        if (sc->opmode == NL80211_IFTYPE_AP ||
                sc->opmode == NL80211_IFTYPE_MESH_POINT) {
                /*
@@ -1564,10 +1565,25 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
        if (ret) {
                ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
                        "hardware queue!\n", __func__);
-               return ret;
+               goto err;
        }
+       ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */
+       if (ret)
+               goto err;
 
-       return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */;
+       /* reconfigure cabq with ready time to 80% of beacon_interval */
+       ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
+       if (ret)
+               goto err;
+
+       qi.tqi_ready_time = (sc->bintval * 80) / 100;
+       ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
+       if (ret)
+               goto err;
+
+       ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB);
+err:
+       return ret;
 }
 
 static void
index eeebb9aef2060eb90bb10f487c875f2d0982057a..b7c57259f1340b138c31342c68ddccd9f7ca5fee 100644 (file)
@@ -408,12 +408,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
                        break;
 
                case AR5K_TX_QUEUE_CAB:
+                       /* XXX: use BCN_SENT_GT, if we can figure out how */
                        AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-                               AR5K_QCU_MISC_FRSHED_BCN_SENT_GT |
+                               AR5K_QCU_MISC_FRSHED_DBA_GT |
                                AR5K_QCU_MISC_CBREXP_DIS |
                                AR5K_QCU_MISC_CBREXP_BCN_DIS);
 
-                       ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
+                       ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
                                (AR5K_TUNE_SW_BEACON_RESP -
                                AR5K_TUNE_DMA_BEACON_RESP) -
                                AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |