summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/if_iwm.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c
index 2a276915cfe..51ceb40d6f6 100644
--- a/sys/dev/pci/if_iwm.c
+++ b/sys/dev/pci/if_iwm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwm.c,v 1.295 2020/02/12 16:02:51 stsp Exp $ */
+/* $OpenBSD: if_iwm.c,v 1.296 2020/02/26 14:29:52 tobhe Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -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;