From: Bruno Randolf <br1@einfach.org>
To: linville@tuxdriver.com
Cc: ath5k-devel@lists.ath5k.org, linux-wireless@vger.kernel.org
Subject: [PATCH 07/11] ath5k: Add watchdog for stuck TX queues
Date: Fri, 17 Sep 2010 11:36:56 +0900 [thread overview]
Message-ID: <20100917023656.24997.24132.stgit@tt-desk> (raw)
In-Reply-To: <20100917023543.24997.48466.stgit@tt-desk>
Since we do not know any better solution to the problem that TX queues can get
stuck, this adds a timer-based watchdog, which will check for stuck queues and
reset the hardware if necessary.
Ported from ath9k commit 164ace38536849966ffa377b1b1132993a5a375d.
Signed-off-by: Bruno Randolf <br1@einfach.org>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 2 +
drivers/net/wireless/ath/ath5k/base.c | 51 ++++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath5k/base.h | 3 ++
3 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 50209ae..9475b21 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -206,6 +206,8 @@
#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */
#define ATH5K_TUNE_CALIBRATION_INTERVAL_NF 60000 /* 60 sec */
+#define ATH5K_TX_COMPLETE_POLL_INT 3000 /* 3 sec */
+
#define AR5K_INIT_CARR_SENSE_EN 1
/*Swap RX/TX Descriptor for big endian archs*/
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index eba2e74..d13df7a 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -895,6 +895,7 @@ ath5k_txq_setup(struct ath5k_softc *sc,
spin_lock_init(&txq->lock);
txq->setup = true;
txq->txq_len = 0;
+ txq->txq_poll_mark = false;
}
return &sc->txqs[qnum];
}
@@ -993,6 +994,7 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
spin_unlock_bh(&sc->txbuflock);
}
txq->link = NULL;
+ txq->txq_poll_mark = false;
spin_unlock_bh(&txq->lock);
}
@@ -1620,6 +1622,8 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
sc->txbuf_len++;
txq->txq_len--;
spin_unlock(&sc->txbuflock);
+
+ txq->txq_poll_mark = false;
}
if (likely(list_empty(&txq->q)))
txq->link = NULL;
@@ -2174,6 +2178,46 @@ ath5k_tasklet_ani(unsigned long data)
}
+static void
+ath5k_tx_complete_poll_work(struct work_struct *work)
+{
+ struct ath5k_softc *sc = container_of(work, struct ath5k_softc,
+ tx_complete_work.work);
+ struct ath5k_txq *txq;
+ int i;
+ bool needreset = false;
+
+ for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
+ if (sc->txqs[i].setup) {
+ txq = &sc->txqs[i];
+ spin_lock_bh(&txq->lock);
+ if (txq->txq_len > 0) {
+ if (txq->txq_poll_mark) {
+ ATH5K_DBG(sc, ATH5K_DEBUG_XMIT,
+ "TX queue stuck %d\n",
+ txq->qnum);
+ needreset = true;
+ spin_unlock_bh(&txq->lock);
+ break;
+ } else {
+ txq->txq_poll_mark = true;
+ }
+ }
+ spin_unlock_bh(&txq->lock);
+ }
+ }
+
+ if (needreset) {
+ ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+ "TX queues stuck, resetting\n");
+ ath5k_reset(sc, sc->curchan);
+ }
+
+ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
+ msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
+}
+
+
/*************************\
* Initialization routines *
\*************************/
@@ -2265,6 +2309,10 @@ ath5k_init(struct ath5k_softc *sc)
done:
mmiowb();
mutex_unlock(&sc->lock);
+
+ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
+ msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
+
return ret;
}
@@ -2323,6 +2371,8 @@ ath5k_stop_hw(struct ath5k_softc *sc)
stop_tasklets(sc);
+ cancel_delayed_work_sync(&sc->tx_complete_work);
+
ath5k_rfkill_hw_stop(sc->ah);
return ret;
@@ -2509,6 +2559,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc);
INIT_WORK(&sc->reset_work, ath5k_reset_work);
+ INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work);
ret = ath5k_eeprom_read_mac(ah, mac);
if (ret) {
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 5e2366d..d8e2674 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -87,6 +87,7 @@ struct ath5k_txq {
spinlock_t lock; /* lock on q and link */
bool setup;
int txq_len; /* number of queued buffers */
+ bool txq_poll_mark;
};
#define ATH5K_LED_MAX_NAME_LEN 31
@@ -233,6 +234,8 @@ struct ath5k_softc {
struct ath5k_ani_state ani_state;
struct tasklet_struct ani_tasklet; /* ANI calibration */
+
+ struct delayed_work tx_complete_work;
};
#define ath5k_hw_hasbssidmask(_ah) \
next prev parent reply other threads:[~2010-09-17 2:36 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-17 2:36 [PATCH 00/11] ath5k: Add multiple queues / QoS support + more Bruno Randolf
2010-09-17 2:36 ` [PATCH 01/11] ath/ath5k/ath9k: Fix crypto capabilities merge issue Bruno Randolf
2010-09-17 2:36 ` [PATCH 02/11] This change reorganizes the main ath5k file in order to re-group Bruno Randolf
2010-09-17 3:32 ` Bob Copeland
2010-09-17 2:36 ` [PATCH 03/11] ath5k: Use four hardware queues Bruno Randolf
2010-09-17 2:36 ` [PATCH 04/11] ath5k: Fix queue debug file Bruno Randolf
2010-09-17 2:36 ` [PATCH 05/11] ath5k: Fix TX queues stopping Bruno Randolf
2010-09-17 2:36 ` [PATCH 06/11] ath5k: Move tx frame completion into separate function Bruno Randolf
2010-09-17 2:36 ` Bruno Randolf [this message]
2010-09-17 2:37 ` [PATCH 08/11] ath5k: Count how many times a queue got stuck Bruno Randolf
2010-09-17 2:37 ` [PATCH 09/11] ath5k: Keep last descriptor in queue Bruno Randolf
2010-09-17 2:37 ` [PATCH 10/11] ath5k: Simplify cw_min/max and AIFS configuration Bruno Randolf
2010-09-17 2:37 ` [PATCH 11/11] ath5k: Add tx queue configuration function Bruno Randolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100917023656.24997.24132.stgit@tt-desk \
--to=br1@einfach.org \
--cc=ath5k-devel@lists.ath5k.org \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).