Tue Mar 3 09:10:45 2015 UTC ()
workaround for interrupt coalescing bug not needed on 7265.
From OpenBSD if_iwm.c rev.1.25, if_iwmvar.h rev.1.7.


(nonaka)
diff -r1.16 -r1.17 src/sys/dev/pci/if_iwm.c
diff -r1.4 -r1.5 src/sys/dev/pci/if_iwmvar.h

cvs diff -r1.16 -r1.17 src/sys/dev/pci/if_iwm.c (expand / switch to context diff)
--- src/sys/dev/pci/if_iwm.c 2015/03/02 12:07:27 1.16
+++ src/sys/dev/pci/if_iwm.c 2015/03/03 09:10:45 1.17
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_iwm.c,v 1.16 2015/03/02 12:07:27 nonaka Exp $	*/
+/*	$NetBSD: if_iwm.c,v 1.17 2015/03/03 09:10:45 nonaka Exp $	*/
 /*	OpenBSD: if_iwm.c,v 1.18 2015/02/11 01:12:42 brad Exp	*/
 
 /*
@@ -105,7 +105,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.16 2015/03/02 12:07:27 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.17 2015/03/03 09:10:45 nonaka Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -1489,25 +1489,27 @@
 		goto out;
 	}
 
-	/*
-	 * This is a bit of an abuse - This is needed for 7260 / 3160
-	 * only check host_interrupt_operation_mode even if this is
-	 * not related to host_interrupt_operation_mode.
-	 *
-	 * Enable the oscillator to count wake up time for L1 exit. This
-	 * consumes slightly more power (100uA) - but allows to be sure
-	 * that we wake up from L1 on time.
-	 *
-	 * This looks weird: read twice the same register, discard the
-	 * value, set a bit, and yet again, read that same register
-	 * just to discard the value. But that's the way the hardware
-	 * seems to like it.
-	 */
-	iwm_read_prph(sc, IWM_OSC_CLK);
-	iwm_read_prph(sc, IWM_OSC_CLK);
-	iwm_set_bits_prph(sc, IWM_OSC_CLK, IWM_OSC_CLK_FORCE_CONTROL);
-	iwm_read_prph(sc, IWM_OSC_CLK);
-	iwm_read_prph(sc, IWM_OSC_CLK);
+	if (sc->host_interrupt_operation_mode) {
+		/*
+		 * This is a bit of an abuse - This is needed for 7260 / 3160
+		 * only check host_interrupt_operation_mode even if this is
+		 * not related to host_interrupt_operation_mode.
+		 *
+		 * Enable the oscillator to count wake up time for L1 exit. This
+		 * consumes slightly more power (100uA) - but allows to be sure
+		 * that we wake up from L1 on time.
+		 *
+		 * This looks weird: read twice the same register, discard the
+		 * value, set a bit, and yet again, read that same register
+		 * just to discard the value. But that's the way the hardware
+		 * seems to like it.
+		 */
+		iwm_read_prph(sc, IWM_OSC_CLK);
+		iwm_read_prph(sc, IWM_OSC_CLK);
+		iwm_set_bits_prph(sc, IWM_OSC_CLK, IWM_OSC_CLK_FORCE_CONTROL);
+		iwm_read_prph(sc, IWM_OSC_CLK);
+		iwm_read_prph(sc, IWM_OSC_CLK);
+	}
 
 	/*
 	 * Enable DMA clock and wait for it to stabilize.
@@ -1732,8 +1734,11 @@
 	    IWM_RX_QUEUE_SIZE_LOG << IWM_FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS);
 
 	IWM_WRITE_1(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_TIMEOUT_DEF);
-	IWM_SETBITS(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_OPER_MODE);
 
+	/* W/A for interrupt coalescing bug in 7260 and 3160 */
+	if (sc->host_interrupt_operation_mode)
+		IWM_SETBITS(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_OPER_MODE);
+
 	/*
 	 * Thus sayeth el jefe (iwlwifi) via a comment:
 	 *
@@ -6690,14 +6695,17 @@
 	case PCI_PRODUCT_INTEL_WIFI_LINK_7260_1:
 	case PCI_PRODUCT_INTEL_WIFI_LINK_7260_2:
 		sc->sc_fwname = "iwlwifi-7260-9.ucode";
+		sc->host_interrupt_operation_mode = 1;
 		break;
 	case PCI_PRODUCT_INTEL_WIFI_LINK_3160_1:
 	case PCI_PRODUCT_INTEL_WIFI_LINK_3160_2:
 		sc->sc_fwname = "iwlwifi-3160-9.ucode";
+		sc->host_interrupt_operation_mode = 1;
 		break;
 	case PCI_PRODUCT_INTEL_WIFI_LINK_7265_1:
 	case PCI_PRODUCT_INTEL_WIFI_LINK_7265_2:
 		sc->sc_fwname = "iwlwifi-7265-9.ucode";
+		sc->host_interrupt_operation_mode = 0;
 		break;
 	default:
 		aprint_error_dev(self, "unknown product %#x",

cvs diff -r1.4 -r1.5 src/sys/dev/pci/if_iwmvar.h (expand / switch to context diff)
--- src/sys/dev/pci/if_iwmvar.h 2015/02/16 13:22:19 1.4
+++ src/sys/dev/pci/if_iwmvar.h 2015/03/03 09:10:45 1.5
@@ -1,5 +1,5 @@
-/*	$NetBSD: if_iwmvar.h,v 1.4 2015/02/16 13:22:19 nonaka Exp $	*/
-/*	OpenBSD: if_iwmvar.h,v 1.3 2015/02/07 07:10:44 phessler Exp 	*/
+/*	$NetBSD: if_iwmvar.h,v 1.5 2015/03/03 09:10:45 nonaka Exp $	*/
+/*	OpenBSD: if_iwmvar.h,v 1.7 2015/03/02 13:51:10 jsg Exp 	*/
 
 /*
  * Copyright (c) 2014 genua mbh <info@genua.de>
@@ -472,6 +472,8 @@
 
 	struct iwm_notif_statistics sc_stats;
 	int sc_noise;
+
+	int host_interrupt_operation_mode;
 
 	struct bpf_if *		sc_drvbpf;