From 78762a0d0df46d2014248887936378e126fc184c Mon Sep 17 00:00:00 2001 From: Dmitry Tarnyagin Date: Wed, 29 Feb 2012 15:15:46 +0100 Subject: 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 --- drivers/staging/cw1200/bh.c | 29 +++++++++++++++++++++++++++++ drivers/staging/cw1200/wsm.c | 1 - drivers/staging/cw1200/wsm.h | 2 ++ 3 files changed, 31 insertions(+), 1 deletion(-) 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], + ×tamp); + + /* 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 */ -- cgit v1.2.3