Module Name:    src
Committed By:   knakahara
Date:           Tue Feb 28 09:55:47 UTC 2017

Modified Files:
        src/sys/dev/pci: if_wm.c if_wmreg.h

Log Message:
fix EITR setting.

    + 82574
      - add EITR setting, that is MSI-X mode interrupt interval
    + 82575
      - fix EITR value. 82575's EITR usage is the same as legacy (not NEWQUEUE)
        controllers
      - apply workaround which 82575's EITR does not have CNT_INGR bit
    + other NEWQUEUE controllers
      - fix interrupt interval field. NEWQUEUE (include 82575) controllers'
        interrupt interval field is 2:14
      - use CNT_INGR bit which avoid to overwrite counter

tested 82574, 82575 and I354.
ok by msaitoh@n.o.


To generate a diff of this commit:
cvs rdiff -u -r1.488 -r1.489 src/sys/dev/pci/if_wm.c
cvs rdiff -u -r1.97 -r1.98 src/sys/dev/pci/if_wmreg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_wm.c
diff -u src/sys/dev/pci/if_wm.c:1.488 src/sys/dev/pci/if_wm.c:1.489
--- src/sys/dev/pci/if_wm.c:1.488	Mon Feb 27 09:27:27 2017
+++ src/sys/dev/pci/if_wm.c	Tue Feb 28 09:55:47 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wm.c,v 1.488 2017/02/27 09:27:27 knakahara Exp $	*/
+/*	$NetBSD: if_wm.c,v 1.489 2017/02/28 09:55:47 knakahara Exp $	*/
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -84,7 +84,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.488 2017/02/27 09:27:27 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.489 2017/02/28 09:55:47 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -4874,8 +4874,19 @@ wm_init_locked(struct ifnet *ifp)
 		wm_gmii_reset(sc);
 
 	/* Calculate (E)ITR value */
-	if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) {
-		sc->sc_itr = 450;	/* For EITR */
+	if ((sc->sc_flags & WM_F_NEWQUEUE) != 0 && sc->sc_type != WM_T_82575) {
+		/*
+		 * For NEWQUEUE's EITR (except for 82575).
+		 * 82575's EITR should be set same throttling value as other
+		 * old controllers' ITR because the interrupt/sec calculation
+		 * is the same, that is, 1,000,000,000 / (N * 256).
+		 *
+		 * 82574's EITR should be set same throttling value as ITR.
+		 *
+		 * For N interrupts/sec, set this value to:
+		 * 1,000,000 / N in contrast to ITR throttoling value.
+		 */
+		sc->sc_itr = 450;
 	} else if (sc->sc_type >= WM_T_82543) {
 		/*
 		 * Set up the interrupt throttling register (units of 256ns)
@@ -4891,11 +4902,10 @@ wm_init_locked(struct ifnet *ifp)
 
 		/*
 		 * For N interrupts/sec, set this value to:
-		 * 1000000000 / (N * 256).  Note that we set the
+		 * 1,000,000,000 / (N * 256).  Note that we set the
 		 * absolute and packet timer values to this value
 		 * divided by 4 to get "simple timer" behavior.
 		 */
-
 		sc->sc_itr = 1500;		/* 2604 ints/sec */
 	}
 
@@ -5192,16 +5202,26 @@ wm_init_locked(struct ifnet *ifp)
 	CSR_WRITE(sc, WMREG_TIPG, sc->sc_tipg);
 
 	if (sc->sc_type >= WM_T_82543) {
-		/*
-		 * XXX 82574 has both ITR and EITR. SET EITR when we use
-		 * the multi queue function with MSI-X.
-		 */
 		if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) {
 			int qidx;
 			for (qidx = 0; qidx < sc->sc_nqueues; qidx++) {
 				struct wm_queue *wmq = &sc->sc_queue[qidx];
+				uint32_t eitr = __SHIFTIN(sc->sc_itr,
+				    EITR_ITR_INT_MASK);
+
+				/*
+				 * 82575 doesn't have CNT_INGR field.
+				 * So, overwrite counter field by software.
+				 */
+				if (sc->sc_type == WM_T_82575) {
+					eitr |= __SHIFTIN(sc->sc_itr,
+					    EITR_COUNTER_MASK_82575);
+				} else {
+					eitr |= EITR_CNT_INGR;
+				}
+
 				CSR_WRITE(sc, WMREG_EITR(wmq->wmq_intr_idx),
-				    sc->sc_itr);
+				    eitr);
 			}
 			/*
 			 * Link interrupts occur much less than TX
@@ -5209,6 +5229,17 @@ wm_init_locked(struct ifnet *ifp)
 			 * tune EINTR(WM_MSIX_LINKINTR_IDX) value like
 			 * FreeBSD's if_igb.
 			 */
+		} else if (sc->sc_type == WM_T_82574 && sc->sc_nintrs > 1) {
+			/*
+			 * 82574 has both ITR and EITR. SET EITR when we use
+			 * the multi queue function with MSI-X.
+			 */
+			for (int qidx = 0; qidx < sc->sc_nqueues; qidx++) {
+				struct wm_queue *wmq = &sc->sc_queue[qidx];
+				CSR_WRITE(sc,
+				    WMREG_EITR_82574(wmq->wmq_intr_idx),
+				    sc->sc_itr & EITR_ITR_INT_MASK_82574);
+			}
 		} else
 			CSR_WRITE(sc, WMREG_ITR, sc->sc_itr);
 	}

Index: src/sys/dev/pci/if_wmreg.h
diff -u src/sys/dev/pci/if_wmreg.h:1.97 src/sys/dev/pci/if_wmreg.h:1.98
--- src/sys/dev/pci/if_wmreg.h:1.97	Thu Feb  2 05:38:59 2017
+++ src/sys/dev/pci/if_wmreg.h	Tue Feb 28 09:55:47 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wmreg.h,v 1.97 2017/02/02 05:38:59 msaitoh Exp $	*/
+/*	$NetBSD: if_wmreg.h,v 1.98 2017/02/28 09:55:47 knakahara Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -1051,7 +1051,12 @@ struct livengood_tcpip_ctxdesc {
 #define EITR_OTHER	0x80000000 /* Interrupt Cause Active */
 
 #define WMREG_EITR(x)	(0x01680 + (0x4 * (x)))
-#define EITR_ITR_INT_MASK	0x0000ffff
+#define EITR_ITR_INT_MASK	__BITS(14,2)
+#define EITR_COUNTER_MASK_82575	__BITS(31,16)
+#define EITR_CNT_INGR		__BIT(31) /* does not overwrite counter */
+
+#define WMREG_EITR_82574(x)	(0x000E8 + (0x4 * (x)))
+#define EITR_ITR_INT_MASK_82574	__BITS(15, 0)
 
 #define	WMREG_RXPBS	0x2404	/* Rx Packet Buffer Size  */
 #define RXPBS_SIZE_MASK_82576	0x0000007F

Reply via email to