aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-06-20 17:44:02 +0200
committerJohn W. Linville <linville@tuxdriver.com>2008-06-27 09:09:16 -0400
commit9b839a7453dc7a25dbd367486017648182df541f (patch)
treef2b12183594aba5f0e278210239fc41071f05ba8
parent9ae705cfd390f9077eec856ea4dff374d166de33 (diff)
b43: Add simple firmware watchdog
This adds a simple firmware watchdog for the opensource firmware. This will check every 15 seconds, if the firmware zeroed out the watchdog register. The firmware will do this in its eventloop. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/b43/b43.h2
-rw-r--r--drivers/net/wireless/b43/main.c15
2 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 532365f5ece..edcdfa36645 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -441,6 +441,8 @@ enum {
#define B43_FWPANIC_DIE 0 /* Firmware died. Don't auto-restart it. */
#define B43_FWPANIC_RESTART 1 /* Firmware died. Schedule a controller reset. */
+/* The firmware register that contains the watchdog counter. */
+#define B43_WATCHDOG_REG 1
/* Device specific rate values.
* The actual values defined here are (rate_in_mbps * 2).
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 69272b9bdb6..c14d522d69e 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2807,6 +2807,21 @@ static void b43_periodic_every30sec(struct b43_wldev *dev)
static void b43_periodic_every15sec(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
+ u16 wdr;
+
+ if (dev->fw.opensource) {
+ /* Check if the firmware is still alive.
+ * It will reset the watchdog counter to 0 in its idle loop. */
+ wdr = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_WATCHDOG_REG);
+ if (unlikely(wdr)) {
+ b43err(dev->wl, "Firmware watchdog: The firmware died!\n");
+ b43_controller_restart(dev, "Firmware watchdog");
+ return;
+ } else {
+ b43_shm_write16(dev, B43_SHM_SCRATCH,
+ B43_WATCHDOG_REG, 1);
+ }
+ }
if (phy->type == B43_PHYTYPE_G) {
//TODO: update_aci_moving_average