summaryrefslogtreecommitdiff
path: root/drivers/staging/cw1200/bh.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/cw1200/bh.c')
-rw-r--r--drivers/staging/cw1200/bh.c29
1 files changed, 29 insertions, 0 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 */