summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>2012-02-29 15:15:46 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:06:51 +0200
commit78762a0d0df46d2014248887936378e126fc184c (patch)
tree740b48345a7874bfcf2e548712678c660ab5c2ed
parent5b83acdbc846ce58aca54ff4b490eb0be076c5df (diff)
cw1200: Detect "stuck" TX frames at early stage.
The patch implements early detection of frames, not acknowledged by firmware. ST-Ericsson ID: 418642 Change-Id: I7af4e2b0aa87a31dd38a3820cb66f5ebc3141978 Signed-off-by: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
-rw-r--r--drivers/staging/cw1200/bh.c29
-rw-r--r--drivers/staging/cw1200/wsm.c1
-rw-r--r--drivers/staging/cw1200/wsm.h2
3 files changed, 31 insertions, 1 deletions
diff --git a/drivers/staging/cw1200/bh.c b/drivers/staging/cw1200/bh.c
index 22b43a5f1cd..427f3e2ba52 100644
--- a/drivers/staging/cw1200/bh.c
+++ b/drivers/staging/cw1200/bh.c
@@ -265,7 +265,9 @@ static int cw1200_bh(void *arg)
int tx_burst;
int rx_burst = 0;
long status;
+#if defined(CONFIG_CW1200_WSM_DUMPS)
size_t wsm_dump_max = -1;
+#endif
u32 dummy;
for (;;) {
@@ -301,8 +303,35 @@ static int cw1200_bh(void *arg)
break;
if (!status && priv->hw_bufs_used) {
+ unsigned long timestamp = jiffies;
+ long timeout;
+ bool pending = false;
+ int i;
+
wiphy_warn(priv->hw->wiphy, "Missed interrupt?\n");
rx = 1;
+
+ /* Get a timestamp of "oldest" frame */
+ for (i = 0; i < 4; ++i)
+ pending |= cw1200_queue_get_xmit_timestamp(
+ &priv->tx_queue[i],
+ &timestamp);
+
+ /* Check if frame transmission is timed out.
+ * Add an extra second with respect to possible
+ * interrupt loss. */
+ timeout = timestamp +
+ WSM_CMD_LAST_CHANCE_TIMEOUT +
+ 1 * HZ -
+ jiffies;
+
+ /* And terminate BH tread if the frame is "stuck" */
+ if (pending && timeout < 0) {
+ wiphy_warn(priv->hw->wiphy,
+ "Timeout waiting for TX confirm.\n");
+ break;
+ }
+
#if defined(CONFIG_CW1200_DUMP_ON_ERROR)
BUG_ON(1);
#endif /* CONFIG_CW1200_DUMP_ON_ERROR */
diff --git a/drivers/staging/cw1200/wsm.c b/drivers/staging/cw1200/wsm.c
index d1ea95c28e4..3cf53704f07 100644
--- a/drivers/staging/cw1200/wsm.c
+++ b/drivers/staging/cw1200/wsm.c
@@ -33,7 +33,6 @@
#define WSM_CMD_JOIN_TIMEOUT (7 * HZ) /* Join timeout is 5 sec. in FW */
#define WSM_CMD_START_TIMEOUT (7 * HZ)
#define WSM_CMD_RESET_TIMEOUT (3 * HZ) /* 2 sec. timeout was observed. */
-#define WSM_CMD_LAST_CHANCE_TIMEOUT (HZ * 3 / 2)
#define WSM_SKIP(buf, size) \
do { \
diff --git a/drivers/staging/cw1200/wsm.h b/drivers/staging/cw1200/wsm.h
index fb15ef53294..c3bd002d432 100644
--- a/drivers/staging/cw1200/wsm.h
+++ b/drivers/staging/cw1200/wsm.h
@@ -598,6 +598,8 @@ struct wsm_hdr {
#define MAX_BEACON_SKIP_TIME_MS 1000
+#define WSM_CMD_LAST_CHANCE_TIMEOUT (HZ * 3 / 2)
+
/* ******************************************************************** */
/* WSM capcbility */