aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/main.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-05-19 17:51:37 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:48:16 -0400
commitafa83e239af58a93eddd10a7a43ac5618884db15 (patch)
tree1ce44c6bddeca3b49ef7f66eab783e8501d6ea83 /drivers/net/wireless/b43/main.c
parent6821783271aaf541504ff8a138184fcc83fa282b (diff)
b43: Add panic reason code that doesn't trigger restart
Add a firmware panic reason code that doesn't trigger a restart. This is useful for firmware debugging and avoiding endless restart loops. We can use FWPANIC_DIE to halt the firmware at a well defined point. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r--drivers/net/wireless/b43/main.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 6011747bb3b9..e1dfb4074676 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1662,6 +1662,30 @@ static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
1662 b43dbg(dev->wl, "Set beacon interval to %u\n", beacon_int); 1662 b43dbg(dev->wl, "Set beacon interval to %u\n", beacon_int);
1663} 1663}
1664 1664
1665static void b43_handle_firmware_panic(struct b43_wldev *dev)
1666{
1667 u16 reason;
1668
1669 /* Read the register that contains the reason code for the panic. */
1670 reason = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_FWPANIC_REASON_REG);
1671 b43err(dev->wl, "Whoopsy, firmware panic! Reason: %u\n", reason);
1672
1673 switch (reason) {
1674 default:
1675 b43dbg(dev->wl, "The panic reason is unknown.\n");
1676 /* fallthrough */
1677 case B43_FWPANIC_DIE:
1678 /* Do not restart the controller or firmware.
1679 * The device is nonfunctional from now on.
1680 * Restarting would result in this panic to trigger again,
1681 * so we avoid that recursion. */
1682 break;
1683 case B43_FWPANIC_RESTART:
1684 b43_controller_restart(dev, "Microcode panic");
1685 break;
1686 }
1687}
1688
1665static void handle_irq_ucode_debug(struct b43_wldev *dev) 1689static void handle_irq_ucode_debug(struct b43_wldev *dev)
1666{ 1690{
1667 unsigned int i, cnt; 1691 unsigned int i, cnt;
@@ -1672,15 +1696,12 @@ static void handle_irq_ucode_debug(struct b43_wldev *dev)
1672 if (!dev->fw.opensource) 1696 if (!dev->fw.opensource)
1673 return; 1697 return;
1674 1698
1675 /* Microcode register 63 contains the debug-IRQ reason. */ 1699 /* Read the register that contains the reason code for this IRQ. */
1676 reason = b43_shm_read16(dev, B43_SHM_SCRATCH, 63); 1700 reason = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_DEBUGIRQ_REASON_REG);
1701
1677 switch (reason) { 1702 switch (reason) {
1678 case B43_DEBUGIRQ_PANIC: 1703 case B43_DEBUGIRQ_PANIC:
1679 /* The reason for the panic is in register 3. */ 1704 b43_handle_firmware_panic(dev);
1680 reason = b43_shm_read16(dev, B43_SHM_SCRATCH, 3);
1681 b43err(dev->wl, "Whoopsy, the microcode panic'ed! Reason: %u\n",
1682 reason);
1683 b43_controller_restart(dev, "Microcode panic");
1684 break; 1705 break;
1685 case B43_DEBUGIRQ_DUMP_SHM: 1706 case B43_DEBUGIRQ_DUMP_SHM:
1686 if (!B43_DEBUG) 1707 if (!B43_DEBUG)
@@ -1721,7 +1742,9 @@ static void handle_irq_ucode_debug(struct b43_wldev *dev)
1721 reason); 1742 reason);
1722 } 1743 }
1723out: 1744out:
1724 b43_shm_write16(dev, B43_SHM_SCRATCH, 63, B43_DEBUGIRQ_ACK); 1745 /* Acknowledge the debug-IRQ, so the firmware can continue. */
1746 b43_shm_write16(dev, B43_SHM_SCRATCH,
1747 B43_DEBUGIRQ_REASON_REG, B43_DEBUGIRQ_ACK);
1725} 1748}
1726 1749
1727/* Interrupt handler bottom-half */ 1750/* Interrupt handler bottom-half */