aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/b43/b43.h9
-rw-r--r--drivers/net/wireless/b43/main.c39
2 files changed, 40 insertions, 8 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index f588dfa9c1d4..f0041750355d 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -422,12 +422,21 @@ enum {
422 B43_IRQ_RFKILL | \ 422 B43_IRQ_RFKILL | \
423 B43_IRQ_TX_OK) 423 B43_IRQ_TX_OK)
424 424
425/* The firmware register to fetch the debug-IRQ reason from. */
426#define B43_DEBUGIRQ_REASON_REG 63
425/* Debug-IRQ reasons. */ 427/* Debug-IRQ reasons. */
426#define B43_DEBUGIRQ_PANIC 0 /* The firmware panic'ed */ 428#define B43_DEBUGIRQ_PANIC 0 /* The firmware panic'ed */
427#define B43_DEBUGIRQ_DUMP_SHM 1 /* Dump shared SHM */ 429#define B43_DEBUGIRQ_DUMP_SHM 1 /* Dump shared SHM */
428#define B43_DEBUGIRQ_DUMP_REGS 2 /* Dump the microcode registers */ 430#define B43_DEBUGIRQ_DUMP_REGS 2 /* Dump the microcode registers */
429#define B43_DEBUGIRQ_ACK 0xFFFF /* The host writes that to ACK the IRQ */ 431#define B43_DEBUGIRQ_ACK 0xFFFF /* The host writes that to ACK the IRQ */
430 432
433/* The firmware register to fetch the panic reason from. */
434#define B43_FWPANIC_REASON_REG 3
435/* Firmware panic reason codes */
436#define B43_FWPANIC_DIE 0 /* Firmware died. Don't auto-restart it. */
437#define B43_FWPANIC_RESTART 1 /* Firmware died. Schedule a controller reset. */
438
439
431/* Device specific rate values. 440/* Device specific rate values.
432 * The actual values defined here are (rate_in_mbps * 2). 441 * The actual values defined here are (rate_in_mbps * 2).
433 * Some code depends on this. Don't change it. */ 442 * Some code depends on this. Don't change it. */
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 */