diff options
-rw-r--r-- | drivers/net/wireless/b43/b43.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 39 |
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 | ||
1665 | static 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 | |||
1665 | static void handle_irq_ucode_debug(struct b43_wldev *dev) | 1689 | static 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 | } |
1723 | out: | 1744 | out: |
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 */ |