Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Jun 2015 18:15:50 +0000 (UTC)
From:      Sean Bruno <sbruno@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r283890 - projects/em_mq/sys/dev/e1000
Message-ID:  <201506011815.t51IFo1f027612@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sbruno
Date: Mon Jun  1 18:15:50 2015
New Revision: 283890
URL: https://svnweb.freebsd.org/changeset/base/283890

Log:
  Handle Intel Errata notice 12.  Reading the ICR can lead to a case where
  the driver would process a link status or other status and ignore a
  simultaneous interrupt for an incoming packet.  In the msi link handler
  assume that we should schedule tx/rx processing by setting the ICS to
  generate a soft interrupt for tx/rx processing to ensure that this race
  doesn't cause missed packets.
  
  Handle Intel Errata notice 3.  Always set TARC bit 26.
  
  Handle Intel Errata regarding multiqueue behavavior.  Always set TARC
  bits to enable compensation mode of 1/1 for the 2 queues.  Always set
  TARC bits 23, 24 & 25 in multiqueue operation.
  
  Add new DB command for debugging to fully reset the adapter when testing.
  
  Thanks to Intel for their continuing support of FreeBSD.
  
  Submitted by:	jfv and erj

Modified:
  projects/em_mq/sys/dev/e1000/if_em.c
  projects/em_mq/sys/dev/e1000/if_em.h

Modified: projects/em_mq/sys/dev/e1000/if_em.c
==============================================================================
--- projects/em_mq/sys/dev/e1000/if_em.c	Mon Jun  1 18:15:45 2015	(r283889)
+++ projects/em_mq/sys/dev/e1000/if_em.c	Mon Jun  1 18:15:50 2015	(r283890)
@@ -1660,6 +1660,16 @@ em_msix_link(void *arg)
 	} else
 		E1000_WRITE_REG(&adapter->hw, E1000_IMS,
 		    EM_MSIX_LINK | E1000_IMS_LSC);
+	/*
+ 	** Because we must read the ICR for this interrupt
+ 	** it may clear other causes using autoclear, for
+ 	** this reason we simply create a soft interrupt
+ 	** for all these vectors.
+ 	*/
+	if (reg_icr) {
+		E1000_WRITE_REG(&adapter->hw,
+			E1000_ICS, adapter->ims);
+	}
 	return;
 }
 
@@ -2365,7 +2375,7 @@ em_update_link_status(struct adapter *ad
 		    (hw->mac.type == e1000_82572))) {
 			int tarc0;
 			tarc0 = E1000_READ_REG(hw, E1000_TARC(0));
-			tarc0 &= ~SPEED_MODE_BIT;
+			tarc0 &= ~TARC_SPEED_MODE_BIT;
 			E1000_WRITE_REG(hw, E1000_TARC(0), tarc0);
 		}
 		if (bootverbose)
@@ -2603,6 +2613,7 @@ em_allocate_msix(struct adapter *adapter
 		** NOTHING to do with the MSIX vector
 		*/
 		rxr->ims = 1 << (20 + i);
+		adapter->ims |= rxr->ims;
 		adapter->ivars |= (8 | rxr->msix) << (i * 4);
 
 		em_last_bind_cpu = CPU_NEXT(em_last_bind_cpu);
@@ -2647,6 +2658,7 @@ em_allocate_msix(struct adapter *adapter
 		** NOTHING to do with the MSIX vector
 		*/
 		txr->ims = 1 << (22 + i);
+		adapter->ims |= txr->ims;
 		adapter->ivars |= (8 | txr->msix) << (8 + (i * 4));
 
 		em_last_bind_cpu = CPU_NEXT(em_last_bind_cpu);
@@ -3538,15 +3550,25 @@ em_initialize_transmit_unit(struct adapt
 	if ((adapter->hw.mac.type == e1000_82571) ||
 	    (adapter->hw.mac.type == e1000_82572)) {
 		tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0));
-		tarc |= SPEED_MODE_BIT;
+		tarc |= TARC_SPEED_MODE_BIT;
 		E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc);
 	} else if (adapter->hw.mac.type == e1000_80003es2lan) {
+		/* errata: program both queues to unweighted RR */
 		tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0));
 		tarc |= 1;
 		E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc);
 		tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(1));
 		tarc |= 1;
 		E1000_WRITE_REG(&adapter->hw, E1000_TARC(1), tarc);
+	} else if (adapter->hw.mac.type == e1000_82574) {
+		tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0));
+		tarc |= TARC_ERRATA_BIT;
+		if ( adapter->num_queues > 1) {
+			tarc |= (TARC_COMPENSATION_MODE | TARC_MQ_FIX);
+			E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc);
+			E1000_WRITE_REG(&adapter->hw, E1000_TARC(1), tarc);
+		} else
+			E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc);
 	}
 
 	adapter->txd_cmd = E1000_TXD_CMD_IFCS;
@@ -5970,6 +5992,23 @@ em_enable_vectors_82574(struct adapter *
 #endif
 
 #ifdef DDB
+DB_COMMAND(em_reset_dev, em_ddb_reset_dev)
+{
+	devclass_t	dc;
+	int max_em;
+
+	dc = devclass_find("em");
+	max_em = devclass_get_maxunit(dc);
+
+	for (int index = 0; index < (max_em - 1); index++) {
+		device_t dev;
+		dev = devclass_get_device(dc, index);
+		if (device_get_driver(dev) == &em_driver) {
+			struct adapter *adapter = device_get_softc(dev);
+			em_init_locked(adapter);
+		}
+	}
+}
 DB_COMMAND(em_dump_queue, em_ddb_dump_queue)
 {
 	devclass_t	dc;

Modified: projects/em_mq/sys/dev/e1000/if_em.h
==============================================================================
--- projects/em_mq/sys/dev/e1000/if_em.h	Mon Jun  1 18:15:45 2015	(r283889)
+++ projects/em_mq/sys/dev/e1000/if_em.h	Mon Jun  1 18:15:50 2015	(r283890)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2015, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -215,7 +215,15 @@
  */
 #define EM_DBA_ALIGN			128
 
-#define SPEED_MODE_BIT (1<<21)		/* On PCI-E MACs only */
+/*
+ * See Intel 82574 Driver Programming Interface Manual, Section 10.2.6.9
+ */
+#define TARC_COMPENSATION_MODE	(1 << 7)	/* Compensation Mode */
+#define TARC_SPEED_MODE_BIT 	(1 << 21)	/* On PCI-E MACs only */
+#define TARC_MQ_FIX	(1 << 23) | \
+			(1 << 24) | \
+			(1 << 25)		/* Handle errata in MQ mode */
+#define TARC_ERRATA_BIT 	(1 << 26)	/* Note from errata on 82574 */
 
 /* PCI Config defines */
 #define EM_BAR_TYPE(v)		((v) & EM_BAR_TYPE_MASK)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506011815.t51IFo1f027612>