b43: Add simple firmware watchdog
authorMichael Buesch <mb@bu3sch.de>
Fri, 20 Jun 2008 15:44:02 +0000 (17:44 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 27 Jun 2008 13:09:16 +0000 (09:09 -0400)
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>
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/main.c

index 532365f5ecefeb3f858bf9d0412650ac1769dd1f..edcdfa366452b7ce34b4acb6e622c3402c7fdb23 100644 (file)
@@ -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).
index 69272b9bdb69e827c171e5470ac0cb81e54e2972..c14d522d69e3a5976284d1ba7714a5964b7a5a6a 100644 (file)
@@ -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