Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit afa83e23 authored by Michael Buesch's avatar Michael Buesch Committed by John W. Linville
Browse files

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: default avatarMichael Buesch <mb@bu3sch.de>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 68217832
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -422,12 +422,21 @@ enum {
					 B43_IRQ_RFKILL | \
					 B43_IRQ_TX_OK)

/* The firmware register to fetch the debug-IRQ reason from. */
#define B43_DEBUGIRQ_REASON_REG		63
/* Debug-IRQ reasons. */
#define B43_DEBUGIRQ_PANIC		0	/* The firmware panic'ed */
#define B43_DEBUGIRQ_DUMP_SHM		1	/* Dump shared SHM */
#define B43_DEBUGIRQ_DUMP_REGS		2	/* Dump the microcode registers */
#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.
 * The actual values defined here are (rate_in_mbps * 2).
 * Some code depends on this. Don't change it. */
+31 −8
Original line number Diff line number Diff line
@@ -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);
}

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)
{
	unsigned int i, cnt;
@@ -1672,15 +1696,12 @@ static void handle_irq_ucode_debug(struct b43_wldev *dev)
	if (!dev->fw.opensource)
		return;

	/* Microcode register 63 contains the debug-IRQ reason. */
	reason = b43_shm_read16(dev, B43_SHM_SCRATCH, 63);
	/* Read the register that contains the reason code for this IRQ. */
	reason = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_DEBUGIRQ_REASON_REG);

	switch (reason) {
	case B43_DEBUGIRQ_PANIC:
		/* The reason for the panic is in register 3. */
		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");
		b43_handle_firmware_panic(dev);
		break;
	case B43_DEBUGIRQ_DUMP_SHM:
		if (!B43_DEBUG)
@@ -1721,7 +1742,9 @@ static void handle_irq_ucode_debug(struct b43_wldev *dev)
		       reason);
	}
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 */