ath5k should take the retry limit (short and long) configuration from mac80211
instead of relyinng on some dubious initial values.

More importantly, the register definition for retry configuration AR5212 was
wrong, and simply copied over from AR5210. Update the register definitions from
the documentation and clean up the code.

Signed-off-by: Bruno Randolf <b...@einfach.org>

---

Notes:

This does not fix the problems, Jonathan Guerin reported, but cleans up the
ath5k part which is involved.

Anyone knows what's the matter with retry limits vs. STA retry limits? What's
the difference?
---
 drivers/net/wireless/ath/ath5k/ath5k.h  |   17 +++++--------
 drivers/net/wireless/ath/ath5k/attach.c |    4 +--
 drivers/net/wireless/ath/ath5k/base.c   |   10 +++++++
 drivers/net/wireless/ath/ath5k/qcu.c    |   42 ++++++++++---------------------
 drivers/net/wireless/ath/ath5k/reg.h    |   15 +++++------
 5 files changed, 39 insertions(+), 49 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h 
b/drivers/net/wireless/ath/ath5k/ath5k.h
index d6e7440..7b63c99 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -214,14 +214,9 @@
 /* Initial values */
 #define        AR5K_INIT_CYCRSSI_THR1                  2
 
-/* Tx retry limits */
-#define AR5K_INIT_SH_RETRY                     10
-#define AR5K_INIT_LG_RETRY                     AR5K_INIT_SH_RETRY
-/* For station mode */
-#define AR5K_INIT_SSH_RETRY                    32
-#define AR5K_INIT_SLG_RETRY                    AR5K_INIT_SSH_RETRY
-#define AR5K_INIT_TX_RETRY                     10
-
+/* default retry limits from standard */
+#define AR5K_INIT_RETRY_SHORT                  7
+#define AR5K_INIT_RETRY_LONG                   4
 
 /* Slot time */
 #define AR5K_INIT_SLOT_TIME_TURBO              6
@@ -1061,7 +1056,8 @@ struct ath5k_hw {
 #define ah_modes               ah_capabilities.cap_mode
 #define ah_ee_version          ah_capabilities.cap_eeprom.ee_version
 
-       u32                     ah_limit_tx_retries;
+       u8                      ah_retry_long;
+       u8                      ah_retry_short;
        u8                      ah_coverage_class;
        bool                    ah_ack_bitrate_high;
        u8                      ah_bwmode;
@@ -1071,7 +1067,6 @@ struct ath5k_hw {
        u8                      ah_ant_mode;
        u8                      ah_tx_ant;
        u8                      ah_def_ant;
-       bool                    ah_software_retry;
 
        struct ath5k_capabilities ah_capabilities;
 
@@ -1252,6 +1247,8 @@ int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int 
queue,
 int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
                            enum ath5k_tx_queue queue_type,
                            struct ath5k_txq_info *queue_info);
+void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,
+                                 unsigned int queue);
 u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
 void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
 int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c 
b/drivers/net/wireless/ath/ath5k/attach.c
index 9dbc1fa..3563b7c 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -118,8 +118,8 @@ int ath5k_hw_init(struct ath5k_softc *sc)
        ah->ah_bwmode = AR5K_BWMODE_DEFAULT;
        ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
        ah->ah_imr = 0;
-       ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
-       ah->ah_software_retry = false;
+       ah->ah_retry_short = AR5K_INIT_RETRY_SHORT;
+       ah->ah_retry_long = AR5K_INIT_RETRY_LONG;
        ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT;
        ah->ah_noise_floor = -95;       /* until first NF calibration is run */
        sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO;
diff --git a/drivers/net/wireless/ath/ath5k/base.c 
b/drivers/net/wireless/ath/ath5k/base.c
index 3c4ba37..25153f7 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -3078,7 +3078,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
        struct ath5k_softc *sc = hw->priv;
        struct ath5k_hw *ah = sc->ah;
        struct ieee80211_conf *conf = &hw->conf;
-       int ret = 0;
+       int ret = 0, i;
 
        mutex_lock(&sc->lock);
 
@@ -3096,6 +3096,14 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
                ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
        }
 
+       if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+               ah->ah_retry_long = conf->long_frame_max_tx_count;
+               ah->ah_retry_short = conf->short_frame_max_tx_count;
+
+               for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++)
+                       ath5k_hw_set_tx_retry_limits(ah, i);
+       }
+
        /* TODO:
         * 1) Move this on config_interface and handle each case
         * separately eg. when we have only one STA vif, use
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c 
b/drivers/net/wireless/ath/ath5k/qcu.c
index 2c9c9e7..4e51ec5 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -228,24 +228,9 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum 
ath5k_tx_queue queue_type,
 /*
  * Set tx retry limits on DCU
  */
-static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,
-                                       unsigned int queue)
+void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,
+                                 unsigned int queue)
 {
-       u32 retry_lg, retry_sh;
-
-       /*
-        * Calculate and set retry limits
-        */
-       if (ah->ah_software_retry) {
-               /* XXX Need to test this */
-               retry_lg = ah->ah_limit_tx_retries;
-               retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
-                       AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
-       } else {
-               retry_lg = AR5K_INIT_LG_RETRY;
-               retry_sh = AR5K_INIT_SH_RETRY;
-       }
-
        /* Single data queue on AR5210 */
        if (ah->ah_version == AR5K_AR5210) {
                struct ath5k_txq_info *tq = &ah->ah_txq[queue];
@@ -255,25 +240,26 @@ static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw 
*ah,
 
                ath5k_hw_reg_write(ah,
                        (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
-                       | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
+                       | AR5K_REG_SM(ah->ah_retry_long,
                                AR5K_NODCU_RETRY_LMT_SLG_RETRY)
-                       | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
+                       | AR5K_REG_SM(ah->ah_retry_short,
                                AR5K_NODCU_RETRY_LMT_SSH_RETRY)
-                       | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
-                       | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
+                       | AR5K_REG_SM(ah->ah_retry_long,
+                               AR5K_NODCU_RETRY_LMT_LG_RETRY)
+                       | AR5K_REG_SM(ah->ah_retry_short,
+                               AR5K_NODCU_RETRY_LMT_SH_RETRY),
                        AR5K_NODCU_RETRY_LMT);
        /* DCU on AR5211+ */
        } else {
                ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
-                               AR5K_DCU_RETRY_LMT_SLG_RETRY) |
-                       AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
-                               AR5K_DCU_RETRY_LMT_SSH_RETRY) |
-                       AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
-                       AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
+                       AR5K_REG_SM(ah->ah_retry_long,
+                               AR5K_DCU_RETRY_LMT_RTS) |
+                       AR5K_REG_SM(ah->ah_retry_long,
+                               AR5K_DCU_RETRY_LMT_STA_RTS) |
+                       AR5K_REG_SM(max(ah->ah_retry_long, ah->ah_retry_short),
+                               AR5K_DCU_RETRY_LMT_STA_DATA),
                        AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
        }
-       return;
 }
 
 /**
diff --git a/drivers/net/wireless/ath/ath5k/reg.h 
b/drivers/net/wireless/ath/ath5k/reg.h
index 7ad05d4..ca6392b 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -686,16 +686,15 @@
 
 /*
  * DCU retry limit registers
+ * all these fields don't allow zero values
  */
 #define AR5K_DCU_RETRY_LMT_BASE                0x1080                  /* 
Register Address -Queue0 DCU_RETRY_LMT */
-#define AR5K_DCU_RETRY_LMT_SH_RETRY    0x0000000f      /* Short retry limit 
mask */
-#define AR5K_DCU_RETRY_LMT_SH_RETRY_S  0
-#define AR5K_DCU_RETRY_LMT_LG_RETRY    0x000000f0      /* Long retry limit 
mask */
-#define AR5K_DCU_RETRY_LMT_LG_RETRY_S  4
-#define AR5K_DCU_RETRY_LMT_SSH_RETRY   0x00003f00      /* Station short retry 
limit mask (?) */
-#define AR5K_DCU_RETRY_LMT_SSH_RETRY_S 8
-#define AR5K_DCU_RETRY_LMT_SLG_RETRY   0x000fc000      /* Station long retry 
limit mask (?) */
-#define AR5K_DCU_RETRY_LMT_SLG_RETRY_S 14
+#define AR5K_DCU_RETRY_LMT_RTS         0x0000000f      /* RTS failure limit. 
Transmission fails if no CTS is received for this number of times */
+#define AR5K_DCU_RETRY_LMT_RTS_S       0
+#define AR5K_DCU_RETRY_LMT_STA_RTS     0x00003f00      /* STA RTS failure 
limit. If exceeded CW reset */
+#define AR5K_DCU_RETRY_LMT_STA_RTS_S   8
+#define AR5K_DCU_RETRY_LMT_STA_DATA    0x000fc000      /* STA data failure 
limit. If exceeded CW reset. */
+#define AR5K_DCU_RETRY_LMT_STA_DATA_S  14
 #define        AR5K_QUEUE_DFS_RETRY_LIMIT(_q)  
AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q)
 
 /*

_______________________________________________
ath5k-devel mailing list
ath5k-devel@lists.ath5k.org
https://lists.ath5k.org/mailman/listinfo/ath5k-devel

Reply via email to