On Wed, Feb 26, 2020 at 01:33:54PM +0100, Tobias Heider wrote:
> I tested with a 7260 and a 8260, patrick@ tested the diff on his 9260.
That's good enough coverage. ok stsp@
> diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c
> index 2a276915cfe..66e6ad25ba2 100644
> --- a/sys/dev/pci/if_iwm.c
> +++ b/sys/dev/pci/if_iwm.c
> @@ -8615,7 +8615,6 @@ iwm_intr(void *arg)
> struct iwm_softc *sc = arg;
> int handled = 0;
> int rv = 0;
> - int isperiodic = 0;
> uint32_t r1, r2;
>
> IWM_WRITE(sc, IWM_CSR_INT_MASK, 0);
> @@ -8722,27 +8721,32 @@ iwm_intr(void *arg)
> wakeup(&sc->sc_fw);
> }
>
> - if (r1 & IWM_CSR_INT_BIT_RX_PERIODIC) {
> - handled |= IWM_CSR_INT_BIT_RX_PERIODIC;
> - IWM_WRITE(sc, IWM_CSR_INT, IWM_CSR_INT_BIT_RX_PERIODIC);
> - if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) == 0)
> - IWM_WRITE_1(sc,
> - IWM_CSR_INT_PERIODIC_REG, IWM_CSR_INT_PERIODIC_DIS);
> - isperiodic = 1;
> - }
> -
> - if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) ||
> - isperiodic) {
> - handled |= (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX);
> - IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_RX_MASK);
> + if (r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX |
> + IWM_CSR_INT_BIT_RX_PERIODIC)) {
> + if (r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) {
> + handled |= (IWM_CSR_INT_BIT_FH_RX |
> IWM_CSR_INT_BIT_SW_RX);
> + IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS,
> IWM_CSR_FH_INT_RX_MASK);
> + }
> + if (r1 & IWM_CSR_INT_BIT_RX_PERIODIC) {
> + handled |= IWM_CSR_INT_BIT_RX_PERIODIC;
> + IWM_WRITE(sc, IWM_CSR_INT, IWM_CSR_INT_BIT_RX_PERIODIC);
> + }
>
> - iwm_notif_intr(sc);
> + /* Disable periodic interrupt; we use it as just a one-shot. */
> + IWM_WRITE_1(sc, IWM_CSR_INT_PERIODIC_REG,
> IWM_CSR_INT_PERIODIC_DIS);
>
> - /* enable periodic interrupt, see above */
> - if (r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX) &&
> - !isperiodic)
> + /*
> + * Enable periodic interrupt in 8 msec only if we received
> + * real RX interrupt (instead of just periodic int), to catch
> + * any dangling Rx interrupt. If it was just the periodic
> + * interrupt, there was no dangling Rx activity, and no need
> + * to extend the periodic interrupt; one-shot is enough.
> + */
> + if (r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX))
> IWM_WRITE_1(sc, IWM_CSR_INT_PERIODIC_REG,
> IWM_CSR_INT_PERIODIC_ENA);
> +
> + iwm_notif_intr(sc);
> }
>
> rv = 1;
>