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>
This commit is contained in:
committed by
John W. Linville
parent
6821783271
commit
afa83e239a
@@ -422,12 +422,21 @@ enum {
|
|||||||
B43_IRQ_RFKILL | \
|
B43_IRQ_RFKILL | \
|
||||||
B43_IRQ_TX_OK)
|
B43_IRQ_TX_OK)
|
||||||
|
|
||||||
|
/* The firmware register to fetch the debug-IRQ reason from. */
|
||||||
|
#define B43_DEBUGIRQ_REASON_REG 63
|
||||||
/* Debug-IRQ reasons. */
|
/* Debug-IRQ reasons. */
|
||||||
#define B43_DEBUGIRQ_PANIC 0 /* The firmware panic'ed */
|
#define B43_DEBUGIRQ_PANIC 0 /* The firmware panic'ed */
|
||||||
#define B43_DEBUGIRQ_DUMP_SHM 1 /* Dump shared SHM */
|
#define B43_DEBUGIRQ_DUMP_SHM 1 /* Dump shared SHM */
|
||||||
#define B43_DEBUGIRQ_DUMP_REGS 2 /* Dump the microcode registers */
|
#define B43_DEBUGIRQ_DUMP_REGS 2 /* Dump the microcode registers */
|
||||||
#define B43_DEBUGIRQ_ACK 0xFFFF /* The host writes that to ACK the IRQ */
|
#define B43_DEBUGIRQ_ACK 0xFFFF /* The host writes that to ACK the IRQ */
|
||||||
|
|
||||||
|
/* The firmware register to fetch the panic reason from. */
|
||||||
|
#define B43_FWPANIC_REASON_REG 3
|
||||||
|
/* Firmware panic reason codes */
|
||||||
|
#define B43_FWPANIC_DIE 0 /* Firmware died. Don't auto-restart it. */
|
||||||
|
#define B43_FWPANIC_RESTART 1 /* Firmware died. Schedule a controller reset. */
|
||||||
|
|
||||||
|
|
||||||
/* Device specific rate values.
|
/* Device specific rate values.
|
||||||
* The actual values defined here are (rate_in_mbps * 2).
|
* The actual values defined here are (rate_in_mbps * 2).
|
||||||
* Some code depends on this. Don't change it. */
|
* Some code depends on this. Don't change it. */
|
||||||
|
@@ -1662,6 +1662,30 @@ static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
|
|||||||
b43dbg(dev->wl, "Set beacon interval to %u\n", beacon_int);
|
b43dbg(dev->wl, "Set beacon interval to %u\n", beacon_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void b43_handle_firmware_panic(struct b43_wldev *dev)
|
||||||
|
{
|
||||||
|
u16 reason;
|
||||||
|
|
||||||
|
/* Read the register that contains the reason code for the panic. */
|
||||||
|
reason = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_FWPANIC_REASON_REG);
|
||||||
|
b43err(dev->wl, "Whoopsy, firmware panic! Reason: %u\n", reason);
|
||||||
|
|
||||||
|
switch (reason) {
|
||||||
|
default:
|
||||||
|
b43dbg(dev->wl, "The panic reason is unknown.\n");
|
||||||
|
/* fallthrough */
|
||||||
|
case B43_FWPANIC_DIE:
|
||||||
|
/* Do not restart the controller or firmware.
|
||||||
|
* The device is nonfunctional from now on.
|
||||||
|
* Restarting would result in this panic to trigger again,
|
||||||
|
* so we avoid that recursion. */
|
||||||
|
break;
|
||||||
|
case B43_FWPANIC_RESTART:
|
||||||
|
b43_controller_restart(dev, "Microcode panic");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_irq_ucode_debug(struct b43_wldev *dev)
|
static void handle_irq_ucode_debug(struct b43_wldev *dev)
|
||||||
{
|
{
|
||||||
unsigned int i, cnt;
|
unsigned int i, cnt;
|
||||||
@@ -1672,15 +1696,12 @@ static void handle_irq_ucode_debug(struct b43_wldev *dev)
|
|||||||
if (!dev->fw.opensource)
|
if (!dev->fw.opensource)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Microcode register 63 contains the debug-IRQ reason. */
|
/* Read the register that contains the reason code for this IRQ. */
|
||||||
reason = b43_shm_read16(dev, B43_SHM_SCRATCH, 63);
|
reason = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_DEBUGIRQ_REASON_REG);
|
||||||
|
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case B43_DEBUGIRQ_PANIC:
|
case B43_DEBUGIRQ_PANIC:
|
||||||
/* The reason for the panic is in register 3. */
|
b43_handle_firmware_panic(dev);
|
||||||
reason = b43_shm_read16(dev, B43_SHM_SCRATCH, 3);
|
|
||||||
b43err(dev->wl, "Whoopsy, the microcode panic'ed! Reason: %u\n",
|
|
||||||
reason);
|
|
||||||
b43_controller_restart(dev, "Microcode panic");
|
|
||||||
break;
|
break;
|
||||||
case B43_DEBUGIRQ_DUMP_SHM:
|
case B43_DEBUGIRQ_DUMP_SHM:
|
||||||
if (!B43_DEBUG)
|
if (!B43_DEBUG)
|
||||||
@@ -1721,7 +1742,9 @@ static void handle_irq_ucode_debug(struct b43_wldev *dev)
|
|||||||
reason);
|
reason);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
b43_shm_write16(dev, B43_SHM_SCRATCH, 63, B43_DEBUGIRQ_ACK);
|
/* Acknowledge the debug-IRQ, so the firmware can continue. */
|
||||||
|
b43_shm_write16(dev, B43_SHM_SCRATCH,
|
||||||
|
B43_DEBUGIRQ_REASON_REG, B43_DEBUGIRQ_ACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interrupt handler bottom-half */
|
/* Interrupt handler bottom-half */
|
||||||
|
Reference in New Issue
Block a user