2007-12-14 09:49:06

by Bruno Randolf

[permalink] [raw]
Subject: [PATCH 1/1] ath5k: avoid zero rates

setting up tx descriptors with a rate of zero will put the HW into a mode where
it continously sends noise on the channel, thus blocking the whole channel.
since it is important to avoid this situation, add a WARN_ON in these cases,
even if we hope to never get bad rates from the rate control module.

Changes-licensed-under: ISC
Signed-off-by: Bruno Randolf <[email protected]>
---
drivers/net/wireless/ath5k/hw.c | 40 +++++++++++++++++++++++++++++++++++++-
1 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 83fd241..6181066 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -3476,9 +3476,20 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,

/*
* Validate input
+ * - Zero retries don't make sense.
+ * - A zero rate will put the HW into a mode where it continously sends
+ * noise on the channel, so it is important to avoid this.
*/
- if (tx_tries0 == 0)
+ if (unlikely(tx_tries0 == 0)) {
+ ATH5K_ERR(ah->ah_sc, "zero retries\n");
+ WARN_ON(1);
return -EINVAL;
+ }
+ if (unlikely(tx_rate0 == 0)) {
+ ATH5K_ERR(ah->ah_sc, "zero rate\n");
+ WARN_ON(1);
+ return -EINVAL;
+ }

/* Clear status descriptor */
memset(desc->ds_hw, 0, sizeof(struct ath5k_hw_tx_status));
@@ -3595,9 +3606,20 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,

/*
* Validate input
+ * - Zero retries don't make sense.
+ * - A zero rate will put the HW into a mode where it continously sends
+ * noise on the channel, so it is important to avoid this.
*/
- if (tx_tries0 == 0)
+ if (unlikely(tx_tries0 == 0)) {
+ ATH5K_ERR(ah->ah_sc, "zero retries\n");
+ WARN_ON(1);
return -EINVAL;
+ }
+ if (unlikely(tx_rate0 == 0)) {
+ ATH5K_ERR(ah->ah_sc, "zero rate\n");
+ WARN_ON(1);
+ return -EINVAL;
+ }

/* Clear status descriptor */
memset(tx_status, 0, sizeof(struct ath5k_hw_tx_status));
@@ -3686,6 +3708,20 @@ ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
{
struct ath5k_hw_4w_tx_desc *tx_desc;

+ /*
+ * Rates can be 0 as long as the retry count is 0 too.
+ * A zero rate and nonzero retry count will put the HW into a mode where
+ * it continously sends noise on the channel, so it is important to
+ * avoid this.
+ */
+ if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
+ (tx_rate2 == 0 && tx_tries2 != 0) ||
+ (tx_rate3 == 0 && tx_tries3 != 0))) {
+ ATH5K_ERR(ah->ah_sc, "zero rate\n");
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
if (ah->ah_version == AR5K_AR5212) {
tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0;

--
1.5.3.4