diff options
author | Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com> | 2012-02-29 15:15:46 +0100 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:06:51 +0200 |
commit | 78762a0d0df46d2014248887936378e126fc184c (patch) | |
tree | 740b48345a7874bfcf2e548712678c660ab5c2ed | |
parent | 5b83acdbc846ce58aca54ff4b490eb0be076c5df (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.c | 29 | ||||
-rw-r--r-- | drivers/staging/cw1200/wsm.c | 1 | ||||
-rw-r--r-- | drivers/staging/cw1200/wsm.h | 2 |
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], + ×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 */ |