ath9k: Ensure a fair beacon distribution in IBSS mode.
authorVivek Natarajan <vnatarajan@atheros.com>
Wed, 25 Nov 2009 06:31:54 +0000 (12:01 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Sat, 28 Nov 2009 20:04:52 +0000 (15:04 -0500)
Update the beacon queue parameters with best effort queue parameters for
IBSS mode. This reduces the number of beacons generated by ath9k and
ensures a fair beacon distribution when there are multiple IBSS stations.
Also CWmin is quadrupled to achieve the expected percentage of
distribution.

Signed-off-by: Vivek Natarajan <vnatarajan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/main.c

index 3eb9677..42f79ca 100644 (file)
@@ -329,6 +329,7 @@ void ath_beacon_tasklet(unsigned long data);
 void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
 int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif);
 void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
+int ath_beaconq_config(struct ath_softc *sc);
 
 /*******/
 /* ANI */
index cb774cc..1660ef1 100644 (file)
  *  the operating mode of the station (AP or AdHoc).  Parameters are AIFS
  *  settings and channel width min/max
 */
-static int ath_beaconq_config(struct ath_softc *sc)
+int ath_beaconq_config(struct ath_softc *sc)
 {
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ath9k_tx_queue_info qi;
+       struct ath9k_tx_queue_info qi, qi_be;
+       int qnum;
 
        ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
        if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
@@ -37,9 +38,12 @@ static int ath_beaconq_config(struct ath_softc *sc)
                qi.tqi_cwmax = 0;
        } else {
                /* Adhoc mode; important thing is to use 2x cwmin. */
-               qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs;
-               qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin;
-               qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax;
+               qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA,
+                                      ATH9K_WME_AC_BE);
+               ath9k_hw_get_txq_props(ah, qnum, &qi_be);
+               qi.tqi_aifs = qi_be.tqi_aifs;
+               qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
+               qi.tqi_cwmax = qi_be.tqi_cwmax;
        }
 
        if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
index cfe710b..b959814 100644 (file)
@@ -2882,6 +2882,10 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
        if (ret)
                ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
 
+       if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
+               if ((qnum == sc->tx.hwq_map[ATH9K_WME_AC_BE]) && !ret)
+                       ath_beaconq_config(sc);
+
        mutex_unlock(&sc->mutex);
 
        return ret;