iwm: interrupt cleanup

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

iwm: interrupt cleanup

Tobias Heider-2
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);
 

Reply | Threaded
Open this post in threaded view
|

Re: iwm: interrupt cleanup

Stefan Sperling-5
On Tue, Feb 11, 2020 at 04:51:08PM +0100, Tobias Heider wrote:

> 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?

Yes, sure.

> 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);
>  
>
>