Hi, here are some small improvements for iwm's interrupt handler.
- Hardware errors (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0) should be checked in both cases (ict and non-ict). - r1 and r2 should be uint32, they are read with bus_space_read_4() - (Slightly) better explanation for hardware bug mitigation ok? diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c index 34877135003..518595c601e 100644 --- a/sys/dev/pci/if_iwm.c +++ b/sys/dev/pci/if_iwm.c @@ -8589,8 +8589,9 @@ iwm_intr(void *arg) { struct iwm_softc *sc = arg; int handled = 0; - int r1, r2, rv = 0; + int rv = 0; int isperiodic = 0; + uint32_t r1, r2; IWM_WRITE(sc, IWM_CSR_INT_MASK, 0); @@ -8617,19 +8618,24 @@ iwm_intr(void *arg) if (r1 == 0xffffffff) r1 = 0; - /* i am not expected to understand this */ + /* + * Workaround for hardware bug where bits are falsely cleared + * when using interrupt coalescing. Bit 15 should be set if + * bits 18 and 19 are set. + */ if (r1 & 0xc0000) r1 |= 0x8000; + r1 = (0xff & r1) | ((0xff00 & r1) << 16); } else { r1 = IWM_READ(sc, IWM_CSR_INT); - if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0) - goto out; r2 = IWM_READ(sc, IWM_CSR_FH_INT_STATUS); } if (r1 == 0 && r2 == 0) { goto out_ena; } + if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0) + goto out; IWM_WRITE(sc, IWM_CSR_INT, r1 | ~sc->sc_intmask);