svn commit: r230924 - in stable/8/sys: conf dev/ixgbe modules/ixgbe

Jack F Vogel jfv at FreeBSD.org
Fri Feb 3 01:36:03 UTC 2012


Author: jfv
Date: Fri Feb  3 01:36:02 2012
New Revision: 230924
URL: http://svn.freebsd.org/changeset/base/230924

Log:
  MFC of the latest ixgbe driver.
  
  Revisions included:
  209602,209603,209607,209609,209622,215911,
  215913,215914,215924,217129,217556,222588,
  222592,225405,229767,230329,230775,230790

Modified:
  stable/8/sys/conf/files
  stable/8/sys/dev/ixgbe/LICENSE
  stable/8/sys/dev/ixgbe/README
  stable/8/sys/dev/ixgbe/ixgbe.c
  stable/8/sys/dev/ixgbe/ixgbe.h
  stable/8/sys/dev/ixgbe/ixgbe_82598.c
  stable/8/sys/dev/ixgbe/ixgbe_82599.c
  stable/8/sys/dev/ixgbe/ixgbe_api.c
  stable/8/sys/dev/ixgbe/ixgbe_api.h
  stable/8/sys/dev/ixgbe/ixgbe_common.c
  stable/8/sys/dev/ixgbe/ixgbe_common.h
  stable/8/sys/dev/ixgbe/ixgbe_mbx.c
  stable/8/sys/dev/ixgbe/ixgbe_mbx.h
  stable/8/sys/dev/ixgbe/ixgbe_osdep.h
  stable/8/sys/dev/ixgbe/ixgbe_phy.c
  stable/8/sys/dev/ixgbe/ixgbe_phy.h
  stable/8/sys/dev/ixgbe/ixgbe_type.h
  stable/8/sys/dev/ixgbe/ixgbe_vf.c
  stable/8/sys/dev/ixgbe/ixgbe_vf.h
  stable/8/sys/dev/ixgbe/ixv.c
  stable/8/sys/dev/ixgbe/ixv.h
  stable/8/sys/modules/ixgbe/Makefile
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)

Modified: stable/8/sys/conf/files
==============================================================================
--- stable/8/sys/conf/files	Thu Feb  2 21:04:24 2012	(r230923)
+++ stable/8/sys/conf/files	Fri Feb  3 01:36:02 2012	(r230924)
@@ -1263,7 +1263,9 @@ dev/ixgbe/ixgbe_82598.c		optional ixgbe 
 	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
 dev/ixgbe/ixgbe_82599.c		optional ixgbe inet \
 	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
-dev/jme/if_jme.c		optional jme pci inet
+dev/ixgbe/ixgbe_x540.c		optional ixgbe inet \
+	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
+dev/jme/if_jme.c		optional jme pci
 dev/joy/joy.c			optional joy
 dev/joy/joy_isa.c		optional joy isa
 dev/joy/joy_pccard.c		optional joy pccard

Modified: stable/8/sys/dev/ixgbe/LICENSE
==============================================================================
--- stable/8/sys/dev/ixgbe/LICENSE	Thu Feb  2 21:04:24 2012	(r230923)
+++ stable/8/sys/dev/ixgbe/LICENSE	Fri Feb  3 01:36:02 2012	(r230924)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2010, Intel Corporation 
+  Copyright (c) 2001-2011, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 

Modified: stable/8/sys/dev/ixgbe/README
==============================================================================
--- stable/8/sys/dev/ixgbe/README	Thu Feb  2 21:04:24 2012	(r230923)
+++ stable/8/sys/dev/ixgbe/README	Fri Feb  3 01:36:02 2012	(r230924)
@@ -1,8 +1,8 @@
-FreeBSD Driver for 10 Gigabit PCI Express Server Adapters
-=============================================
+FreeBSD Driver for Intel(R) Ethernet 10 Gigabit PCI Express Server Adapters
+============================================================================
 /*$FreeBSD$*/
 
-May 14, 2008
+November 12, 2010
 
 
 Contents
@@ -11,15 +11,15 @@ Contents
 - Overview
 - Supported Adapters
 - Building and Installation
-- Additional Configurations
+- Additional Configurations and Tuning
 - Known Limitations
 
 
 Overview
 ========
 
-This file describes the FreeBSD* driver for the 10 Gigabit PCIE Family of 
-Adapters.  Drivers has been developed for use with FreeBSD 7 or later.
+This file describes the FreeBSD* driver for the Intel(R) Ethernet 10 Gigabit 
+Family of Adapters.  Driver has been developed for use with FreeBSD 7.2 or later.
 
 For questions related to hardware requirements, refer to the documentation
 supplied with your Intel 10GbE adapter.  All hardware requirements listed
@@ -29,100 +29,98 @@ apply to use with FreeBSD.
 Supported Adapters
 ==================
 
-The following Intel network adapters are compatible with the drivers in this 
-release:
-
-Controller  Adapter Name                      Physical Layer
-----------  ------------                      --------------
-82598EB     Intel(R) 10 Gigabit XF SR/AF      10G Base -LR (850 nm optical fiber) 
-            Dual Port Server Adapter          10G Base -SR (1310 nm optical fiber) 
-82598EB     Intel(R) 10 Gigabit XF SR/LR 
-            Server Adapter
-            Intel(R) 82598EB 10 Gigabit AF 
-            Network Connection
-            Intel(R) 82598EB 10 Gigabit AT 
-            CX4 Network Connection
+The driver in this release is compatible with 82598 and 82599-based Intel 
+Network Connections.
               
+SFP+ Devices with Pluggable Optics
+----------------------------------
 
-Building and Installation
-=========================
-
-NOTE: You must have kernel sources installed in order to compile the driver
-      module.
-
-      In the instructions below, x.x.x is the driver version as indicated in
-      the name of the driver tar. 
-
-1. Move the base driver tar file to the directory of your choice. For 
-   example, use /home/username/ixgbe or /usr/local/src/ixgbe.
-
-2. Untar/unzip the archive:
-     tar xfz ixgbe-x.x.x.tar.gz
-
-3. To install man page:
-     cd ixgbe-x.x.x
-     gzip -c ixgbe.4 > /usr/share/man/man4/ixgbee.4.gz
-
-4. To load the driver onto a running system:
-     cd ixgbe-x.x.x/src
-     make load
-
-5. To assign an IP address to the interface, enter the following:
-     ifconfig ix<interface_num> <IP_address>
-
-6. Verify that the interface works. Enter the following, where <IP_address>
-   is the IP address for another machine on the same subnet as the interface
-   that is being tested:
-     ping <IP_address>
-
-7. If you want the driver to load automatically when the system is booted:
-
-     cd ixgbe-x.x.x/src
-     make
-     make install
-        
-    Edit /boot/loader.conf, and add the following line:
-     ixgbe_load="YES"
-
-     OR
-
-     compile the driver into the kernel (see item 8).
-
-
-   Edit /etc/rc.conf, and create the appropriate ifconfig_ixgbe<interface_num> 
-   entry:
-
-     ifconfig_ix<interface_num>="<ifconfig_settings>"
-
-     Example usage:
-
-     ifconfig_ix0="inet 192.168.10.1 netmask 255.255.255.0"
-
-     NOTE: For assistance, see the ifconfig man page.
-
-8. If you want to compile the driver into the kernel, enter:
+82599-BASED ADAPTERS  
 
-     FreeBSD 7 or later:
+NOTE: If your 82599-based Intel(R) Ethernet Network Adapter came with Intel 
+optics, or is an Intel(R) Ethernet Server Adapter X520-2, then it only supports
+Intel optics and/or the direct attach cables listed below.
 
-     cd ixgbe-x.x.x/src
-
-     cp *.[ch] /usr/src/sys/dev/ixgbe
-   
-     cp Makefile.kernel /usr/src/sys/modules/ixgbe/Makefile
-
-     Edit the kernel configuration file (i.e., GENERIC or MYKERNEL) in 
-     /usr/src/sys/i386/conf (replace "i386" with the appropriate system 
-     architecture if necessary), and ensure the following line is present:
-
-    device ixgbe
-
-   Compile and install the kernel.  The system must be reboot for the kernel 
-   updates to take affect.  For additional information on compiling the kernel, 
-   consult the FreeBSD operating system documentation.
+When 82599-based SFP+ devices are connected back to back, they should be set to
+the same Speed setting via Ethtool. Results may vary if you mix speed settings. 
+ 
+Supplier    Type                                             Part Numbers
 
+SR Modules			
+Intel 	    DUAL RATE 1G/10G SFP+ SR (bailed)                FTLX8571D3BCV-IT	
+Intel	    DUAL RATE 1G/10G SFP+ SR (bailed)                AFBR-703SDZ-IN2
+Intel      DUAL RATE 1G/10G SFP+ SR (bailed)                 AFBR-703SDDZ-IN1	
+LR Modules			
+Intel 	    DUAL RATE 1G/10G SFP+ LR (bailed)                FTLX1471D3BCV-IT	
+Intel	    DUAL RATE 1G/10G SFP+ LR (bailed)                AFCT-701SDZ-IN2	
+Intel       DUAL RATE 1G/10G SFP+ LR (bailed)                AFCT-701SDDZ-IN1
+
+The following is a list of 3rd party SFP+ modules and direct attach cables that
+have received some testing. Not all modules are applicable to all devices.
+
+Supplier   Type                                              Part Numbers
+
+Finisar    SFP+ SR bailed, 10g single rate                   FTLX8571D3BCL
+Avago      SFP+ SR bailed, 10g single rate                   AFBR-700SDZ
+Finisar    SFP+ LR bailed, 10g single rate                   FTLX8571D3BCV-IT
+		
+Finisar    DUAL RATE 1G/10G SFP+ SR (No Bail)	             FTLX8571D3QCV-IT
+Avago	   DUAL RATE 1G/10G SFP+ SR (No Bail)	             AFBR-703SDZ-IN1	
+Finisar	   DUAL RATE 1G/10G SFP+ LR (No Bail)	             FTLX1471D3QCV-IT
+Avago	   DUAL RATE 1G/10G SFP+ LR (No Bail)	             AFCT-701SDZ-IN1
+Finistar   1000BASE-T SFP                                    FCLF8522P2BTL
+Avago      1000BASE-T SFP                                    ABCU-5710RZ
+		
+82599-based adapters support all passive and active limiting direct attach 
+cables that comply with SFF-8431 v4.1 and SFF-8472 v10.4 specifications.
+
+Laser turns off for SFP+ when ifconfig down
+--------------------------------------------------------
+"ifconfig down" turns off the laser for 82599-based SFP+ fiber adapters.
+"ifconfig up" turns on the later.
+
+82598-BASED ADAPTERS
+
+NOTES for 82598-Based Adapters: 
+- Intel(R) Ethernet Network Adapters that support removable optical modules 
+  only support their original module type (i.e., the Intel(R) 10 Gigabit SR 
+  Dual Port Express Module only supports SR optical modules). If you plug 
+  in a different type of module, the driver will not load.
+- Hot Swapping/hot plugging optical modules is not supported.  
+- Only single speed, 10 gigabit modules are supported.  
+- LAN on Motherboard (LOMs) may support DA, SR, or LR modules. Other module 
+  types are not supported. Please see your system documentation for details.  
+
+The following is a list of 3rd party SFP+ modules and direct attach cables that have 
+received some testing. Not all modules are applicable to all devices.
+
+Supplier   Type                                              Part Numbers
+
+Finisar    SFP+ SR bailed, 10g single rate                   FTLX8571D3BCL
+Avago      SFP+ SR bailed, 10g single rate                   AFBR-700SDZ
+Finisar    SFP+ LR bailed, 10g single rate                   FTLX1471D3BCL
+	
+82598-based adapters support all passive direct attach cables that comply 
+with SFF-8431 v4.1 and SFF-8472 v10.4 specifications. Active direct attach 
+cables are not supported.
+
+Third party optic modules and cables referred to above are listed only for the 
+purpose of highlighting third party specifications and potential compatibility, 
+and are not recommendations or endorsements or sponsorship of any third party's
+product by Intel. Intel is not endorsing or promoting products made by any 
+third party and the third party reference is provided only to share information
+regarding certain optic modules and cables with the above specifications. There
+may be other manufacturers or suppliers, producing or supplying optic modules 
+and cables with similar or matching descriptions. Customers must use their own 
+discretion and diligence to purchase optic modules and cables from any third 
+party of their choice. Customer are solely responsible for assessing the 
+suitability of the product and/or devices and for the selection of the vendor 
+for purchasing any product. INTEL ASSUMES NO LIABILITY WHATSOEVER, AND INTEL
+DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY, RELATING TO SALE AND/OR USE OF 
+SUCH THIRD PARTY PRODUCTS OR SELECTION OF VENDOR BY CUSTOMERS.
 
 Configuration and Tuning
-=========================
+========================
 
 The driver supports Transmit/Receive Checksum Offload and Jumbo Frames on
 all 10 Gigabit adapters. 
@@ -143,7 +141,7 @@ all 10 Gigabit adapters. 
   The Jumbo Frames MTU range for Intel Adapters is 1500 to 16114. The default
   MTU range is 1500. To modify the setting, enter the following:
 
-        ifconfig ix <interface_num> <hostname or IP address> mtu 9000
+        ifconfig ix<interface_num> <hostname or IP address> mtu 9000
 
   To confirm an interface's MTU value, use the ifconfig command. To confirm
   the MTU used between two specific devices, use:
@@ -200,6 +198,8 @@ all 10 Gigabit adapters. 
   TSO
   ---
 
+  TSO is enabled by default.
+
   To disable:
 
          ifconfig <interface_num> -tso 
@@ -209,23 +209,21 @@ all 10 Gigabit adapters. 
          ifconfig <interface_num> tso
 
   LRO
-  ___
+  ---
   
-   Large Receive Offload is available in version 1.4.4, it is on
-   by default. It can be toggled off and on by using:
-	sysctl dev.ix.X.enable_lro=[0,1]
-
-   NOTE: when changing this feature you MUST be sure the interface
-   is reinitialized, it is easy to do this with ifconfig down/up.
-   The LRO code will ultimately move into the kernel stack code,
-   but for this first release it was included with the driver.
+  Large Receive Offload is available in the driver; it is on by default. 
+  It can be disabled by using:
+         ifconfig <interface_num> -lro
+  To enable:
+         ifconfig <interface_num> lro
+
 
   Important system configuration changes:
   ---------------------------------------
 
-  When there is a choice run on a 64bit OS rather than 32, it makes
-  a significant difference in improvement.
-
+  When there is a choice run on a 64bit OS rather than 32, it makes a 
+  significant difference in improvement.
+  
   The default scheduler SCHED_4BSD is not smart about SMP locality issues. 
   Significant improvement can be achieved by switching to the ULE scheduler.
 
@@ -233,34 +231,79 @@ all 10 Gigabit adapters. 
   SCHED_ULE. Note that this is only advisable on FreeBSD 7, on 6.X there have
   been stability problems with ULE.
 
-  Change the file /etc/sysctl.conf, add the line:  
+  The interface can generate high number of interrupts. To avoid running 
+  into the limit set by the kernel, adjust hw.intr_storm_threshold 
+  setting using sysctl:
  
-         hw.intr_storm_threshold: 8000 (the default is 1000)
+       sysctl hw.intr_storm_threshold=9000 (the default is 1000)
+
+  For this change to take effect on boot, edit /etc/sysctl.conf and add the 
+  line:  
+       hw.intr_storm_threshold=9000
+
+  If you still see Interrupt Storm detected messages, increase the limit to a
+  higher number.
 
   Best throughput results are seen with a large MTU; use 9000 if possible. 
 
-  The default number of descriptors is 256, increasing this to 1024 or even 
-  2048 may improve performance.
+  The default number of descriptors is 1024, increasing this to 2K or even 
+  4K may improve performance in some workloads, but change carefully.
 
 
 Known Limitations
 =================
+
+For known hardware and troubleshooting issues, refer to the following website.
+
+    http://support.intel.com/support/go/network/adapter/home.htm
+
+Either select the link for your adapter or perform a search for the adapter 
+number. The adapter's page lists many issues. For a complete list of hardware
+issues download your adapter's user guide and read the Release Notes. 
+
+  UDP stress test with 10GbE driver
+  ---------------------------------  
   Under small packets UDP stress test with 10GbE driver, the FreeBSD system 
   will drop UDP packets due to the fullness of socket buffers. You may want 
   to change the driver's Flow Control variables to the minimum value for 
   controlling packet reception.
 
+  Attempting to configure larger MTUs with a large numbers of processors may 
+  generate the error message "ix0:could not setup receive structures"
+  --------------------------------------------------------------------------
+  When using the ixgbe driver with RSS autoconfigured based on the number of 
+  cores (the default setting) and that number is larger than 4, increase the 
+  memory resources allocated for the mbuf pool as follows:
+
+  Add to the sysctl.conf file for the system:
+
+  kern.ipc.nmbclusters=262144
+  kern.ipc.nmbjumbop=262144
+
+  Lower than expected performance on dual port 10GbE devices
+  ----------------------------------------------------------
+  Some PCI-E x8 slots are actually configured as x4 slots. These slots have 
+  insufficient bandwidth for full 10Gbe line rate with dual port 10GbE devices.
+  The driver can detect this situation and will write the following message in
+  the system log: "PCI-Express bandwidth available for this card is not 
+  sufficient for optimal performance. For optimal performance a x8 PCI-Express 
+  slot is required."
+
+  If this error occurs, moving your adapter to a true x8 slot will resolve the 
+  issue.
+
+
 
 Support
 =======
 
 For general information and support, go to the Intel support website at:
 
-        http://support.intel.com
+        www.intel.com/support/
 
 If an issue is identified with the released source code on the supported
 kernel with a supported adapter, email the specific information related to 
-the issue to freebsd at intel.com.
+the issue to freebsd at intel.com
 
 
 

Modified: stable/8/sys/dev/ixgbe/ixgbe.c
==============================================================================
--- stable/8/sys/dev/ixgbe/ixgbe.c	Thu Feb  2 21:04:24 2012	(r230923)
+++ stable/8/sys/dev/ixgbe/ixgbe.c	Fri Feb  3 01:36:02 2012	(r230924)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2012, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -34,6 +34,7 @@
 
 #ifdef HAVE_KERNEL_OPTION_HEADERS
 #include "opt_inet.h"
+#include "opt_inet6.h"
 #endif
 
 #include "ixgbe.h"
@@ -46,7 +47,7 @@ int             ixgbe_display_debug_stat
 /*********************************************************************
  *  Driver version
  *********************************************************************/
-char ixgbe_driver_version[] = "2.3.10";
+char ixgbe_driver_version[] = "2.4.5";
 
 /*********************************************************************
  *  PCI Device ID Table
@@ -80,6 +81,8 @@ static ixgbe_vendor_info_t ixgbe_vendor_
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_COMBO_BACKPLANE, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_BACKPLANE_FCOE, 0, 0, 0},
 	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_FCOE, 0, 0, 0},
+	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599EN_SFP, 0, 0, 0},
+	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T, 0, 0, 0},
 	/* required last entry */
 	{0, 0, 0, 0, 0}
 };
@@ -152,6 +155,7 @@ static void	ixgbe_refresh_mbufs(struct r
 static int      ixgbe_xmit(struct tx_ring *, struct mbuf **);
 static int	ixgbe_set_flowcntl(SYSCTL_HANDLER_ARGS);
 static int	ixgbe_set_advertise(SYSCTL_HANDLER_ARGS);
+static int	ixgbe_set_thermal_test(SYSCTL_HANDLER_ARGS);
 static int	ixgbe_dma_malloc(struct adapter *, bus_size_t,
 		    struct ixgbe_dma_alloc *, int);
 static void     ixgbe_dma_free(struct adapter *, struct ixgbe_dma_alloc *);
@@ -318,7 +322,7 @@ static int fdir_pballoc = 1;
  *  ixgbe_probe determines if the driver should be loaded on
  *  adapter based on PCI vendor/device id of the adapter.
  *
- *  return 0 on success, positive on failure
+ *  return BUS_PROBE_DEFAULT on success, positive on failure
  *********************************************************************/
 
 static int
@@ -357,7 +361,7 @@ ixgbe_probe(device_t dev)
 				ixgbe_driver_version);
 			device_set_desc_copy(dev, adapter_name);
 			++ixgbe_total_ports;
-			return (0);
+			return (BUS_PROBE_DEFAULT);
 		}
 		ent++;
 	}
@@ -385,6 +389,11 @@ ixgbe_attach(device_t dev)
 
 	INIT_DEBUGOUT("ixgbe_attach: begin");
 
+	if (resource_disabled("ixgbe", device_get_unit(dev))) {
+		device_printf(dev, "Disabled by device hint\n");
+		return (ENXIO);
+	}
+
 	/* Allocate, clear, and link in our adapter structure */
 	adapter = device_get_softc(dev);
 	adapter->dev = adapter->osdep.dev = dev;
@@ -397,7 +406,7 @@ ixgbe_attach(device_t dev)
 
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
 			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-			OID_AUTO, "flow_control", CTLTYPE_INT | CTLFLAG_RW,
+			OID_AUTO, "fc", CTLTYPE_INT | CTLFLAG_RW,
 			adapter, 0, ixgbe_set_flowcntl, "I", "Flow Control");
 
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
@@ -410,6 +419,21 @@ ixgbe_attach(device_t dev)
 			OID_AUTO, "enable_aim", CTLTYPE_INT|CTLFLAG_RW,
 			&ixgbe_enable_aim, 1, "Interrupt Moderation");
 
+	/*
+	** Allow a kind of speed control by forcing the autoneg
+	** advertised speed list to only a certain value, this
+	** supports 1G on 82599 devices, and 100Mb on x540.
+	*/
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+			OID_AUTO, "advertise_speed", CTLTYPE_INT | CTLFLAG_RW,
+			adapter, 0, ixgbe_set_advertise, "I", "Link Speed");
+
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+			OID_AUTO, "ts", CTLTYPE_INT | CTLFLAG_RW, adapter,
+			0, ixgbe_set_thermal_test, "I", "Thermal Test");
+
 	/* Set up the timer callout */
 	callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0);
 
@@ -497,9 +521,10 @@ ixgbe_attach(device_t dev)
 
 	/* Get Hardware Flow Control setting */
 	hw->fc.requested_mode = ixgbe_fc_full;
+	adapter->fc = hw->fc.requested_mode;
 	hw->fc.pause_time = IXGBE_FC_PAUSE;
 	hw->fc.low_water = IXGBE_FC_LO;
-	hw->fc.high_water = IXGBE_FC_HI;
+	hw->fc.high_water[0] = IXGBE_FC_HI;
 	hw->fc.send_xon = TRUE;
 
 	error = ixgbe_init_hw(hw);
@@ -700,16 +725,20 @@ ixgbe_start_locked(struct tx_ring *txr, 
 		return;
 
 	while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
+		if (txr->tx_avail <= IXGBE_QUEUE_MIN_FREE) {
+			txr->queue_status |= IXGBE_QUEUE_DEPLETED;
+			break;
+                }
 
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
 		if (m_head == NULL)
 			break;
 
 		if (ixgbe_xmit(txr, &m_head)) {
-			if (m_head == NULL)
-				break;
-			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-			IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
+			if (m_head != NULL)
+				IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
+			if (txr->tx_avail <= IXGBE_QUEUE_MIN_FREE)
+				txr->queue_status |= IXGBE_QUEUE_DEPLETED;
 			break;
 		}
 		/* Send a copy of the frame to the BPF listener */
@@ -758,11 +787,14 @@ ixgbe_mq_start(struct ifnet *ifp, struct
 	/* Which queue to use */
 	if ((m->m_flags & M_FLOWID) != 0)
 		i = m->m_pkthdr.flowid % adapter->num_queues;
+	else
+		i = curcpu % adapter->num_queues;
 
 	txr = &adapter->tx_rings[i];
 	que = &adapter->queues[i];
 
-	if (IXGBE_TX_TRYLOCK(txr)) {
+	if (((txr->queue_status & IXGBE_QUEUE_DEPLETED) == 0) &&
+	    IXGBE_TX_TRYLOCK(txr)) {
 		err = ixgbe_mq_start_locked(ifp, txr, m);
 		IXGBE_TX_UNLOCK(txr);
 	} else {
@@ -780,13 +812,18 @@ ixgbe_mq_start_locked(struct ifnet *ifp,
         struct mbuf     *next;
         int             enqueued, err = 0;
 
-	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
-	    IFF_DRV_RUNNING || adapter->link_active == 0) {
+	if (((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) ||
+	    (txr->queue_status == IXGBE_QUEUE_DEPLETED) ||
+	    adapter->link_active == 0) {
 		if (m != NULL)
 			err = drbr_enqueue(ifp, txr->br, m);
 		return (err);
 	}
 
+	/* Call cleanup if number of TX descriptors low */
+	if (txr->tx_avail <= IXGBE_TX_CLEANUP_THRESHOLD)
+		ixgbe_txeof(txr);
+
 	enqueued = 0;
 	if (m == NULL) {
 		next = drbr_dequeue(ifp, txr->br);
@@ -813,7 +850,7 @@ ixgbe_mq_start_locked(struct ifnet *ifp,
 		if (txr->tx_avail < IXGBE_TX_OP_THRESHOLD)
 			ixgbe_txeof(txr);
 		if (txr->tx_avail < IXGBE_TX_OP_THRESHOLD) {
-			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+			txr->queue_status |= IXGBE_QUEUE_DEPLETED;
 			break;
 		}
 		next = drbr_dequeue(ifp, txr->br);
@@ -821,10 +858,13 @@ ixgbe_mq_start_locked(struct ifnet *ifp,
 
 	if (enqueued > 0) {
 		/* Set watchdog on */
-		txr->queue_status = IXGBE_QUEUE_WORKING;
+		txr->queue_status |= IXGBE_QUEUE_WORKING;
 		txr->watchdog_time = ticks;
 	}
 
+	if (txr->tx_avail < IXGBE_TX_CLEANUP_THRESHOLD)
+		ixgbe_txeof(txr);
+
 	return (err);
 }
 
@@ -862,8 +902,9 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
 {
 	struct adapter	*adapter = ifp->if_softc;
 	struct ifreq	*ifr = (struct ifreq *) data;
-#ifdef INET
+#if defined(INET) || defined(INET6)
 	struct ifaddr *ifa = (struct ifaddr *)data;
+	bool		avoid_reset = FALSE;
 #endif
 	int             error = 0;
 
@@ -871,26 +912,28 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
 
         case SIOCSIFADDR:
 #ifdef INET
-		if (ifa->ifa_addr->sa_family == AF_INET) {
-			/*
-			 * Since resetting hardware takes a very long time
-			 * and results in link renegotiation we only
-			 * initialize the hardware only when it is absolutely
-			 * required.
-			 */
+		if (ifa->ifa_addr->sa_family == AF_INET)
+			avoid_reset = TRUE;
+#endif
+#ifdef INET6
+		if (ifa->ifa_addr->sa_family == AF_INET6)
+			avoid_reset = TRUE;
+#endif
+#if defined(INET) || defined(INET6)
+		/*
+		** Calling init results in link renegotiation,
+		** so we avoid doing it when possible.
+		*/
+		if (avoid_reset) {
 			ifp->if_flags |= IFF_UP;
-			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-				IXGBE_CORE_LOCK(adapter);
-				ixgbe_init_locked(adapter);
-				IXGBE_CORE_UNLOCK(adapter);
-			}
+			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+				ixgbe_init(adapter);
 			if (!(ifp->if_flags & IFF_NOARP))
 				arp_ifinit(ifp, ifa);
 		} else
-#endif
 			error = ether_ioctl(ifp, command, data);
+#endif
 		break;
-
 	case SIOCSIFMTU:
 		IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
 		if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - ETHER_HDR_LEN) {
@@ -951,6 +994,8 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
 			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
 		if (mask & IFCAP_VLAN_HWFILTER)
 			ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
+		if (mask & IFCAP_VLAN_HWTSO)
+			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
 		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 			IXGBE_CORE_LOCK(adapter);
 			ixgbe_init_locked(adapter);
@@ -1058,10 +1103,14 @@ ixgbe_init_locked(struct adapter *adapte
 	/* Enable Fan Failure Interrupt */
 	gpie |= IXGBE_SDP1_GPIEN;
 
-	/* Add for Thermal detection */
+	/* Add for Module detection */
 	if (hw->mac.type == ixgbe_mac_82599EB)
 		gpie |= IXGBE_SDP2_GPIEN;
 
+	/* Thermal Failure Detection */
+	if (hw->mac.type == ixgbe_mac_X540)
+		gpie |= IXGBE_SDP0_GPIEN;
+
 	if (adapter->msix > 1) {
 		/* Enable Enhanced MSIX mode */
 		gpie |= IXGBE_GPIE_MSIX_MODE;
@@ -1142,8 +1191,12 @@ ixgbe_init_locked(struct adapter *adapte
 
 #ifdef IXGBE_FDIR
 	/* Init Flow director */
-	if (hw->mac.type != ixgbe_mac_82598EB)
+	if (hw->mac.type != ixgbe_mac_82598EB) {
+		u32 hdrm = 64 << fdir_pballoc;
+
+		hw->mac.ops.setup_rxpba(hw, 0, hdrm, PBA_STRATEGY_EQUAL);
 		ixgbe_init_fdir_signature_82599(&adapter->hw, fdir_pballoc);
+	}
 #endif
 
 	/*
@@ -1271,7 +1324,7 @@ ixgbe_handle_que(void *context, int pend
 			ixgbe_start_locked(txr, ifp);
 #endif
 		IXGBE_TX_UNLOCK(txr);
-		if (more) {
+		if (more || (ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
 			taskqueue_enqueue(que->tq, &que->que_task);
 			return;
 		}
@@ -1338,7 +1391,7 @@ ixgbe_legacy_irq(void *arg)
 
 /*********************************************************************
  *
- *  MSI Queue Interrupt Service routine
+ *  MSIX Queue Interrupt Service routine
  *
  **********************************************************************/
 void
@@ -1351,12 +1404,24 @@ ixgbe_msix_que(void *arg)
 	bool		more_tx, more_rx;
 	u32		newitr = 0;
 
+	ixgbe_disable_queue(adapter, que->msix);
 	++que->irqs;
 
 	more_rx = ixgbe_rxeof(que, adapter->rx_process_limit);
 
 	IXGBE_TX_LOCK(txr);
 	more_tx = ixgbe_txeof(txr);
+	/*
+	** Make certain that if the stack 
+	** has anything queued the task gets
+	** scheduled to handle it.
+	*/
+#if __FreeBSD_version < 800000
+	if (!IFQ_DRV_IS_EMPTY(&adapter->ifp->if_snd))
+#else
+	if (!drbr_empty(adapter->ifp, txr->br))
+#endif
+		more_tx = 1;
 	IXGBE_TX_UNLOCK(txr);
 
 	/* Do AIM now? */
@@ -1474,6 +1539,15 @@ ixgbe_msix_link(void *arg)
 		IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
 	}
 
+	/* Check for over temp condition */
+	if ((hw->mac.type == ixgbe_mac_X540) &&
+	    (reg_eicr & IXGBE_EICR_GPI_SDP0)) {
+                device_printf(adapter->dev, "\nCRITICAL: OVER TEMP!! "
+		    "PHY IS SHUT DOWN!!\n");
+                device_printf(adapter->dev, "System shutdown required\n");
+		IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0);
+	}
+
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
 	return;
 }
@@ -1506,6 +1580,9 @@ ixgbe_media_status(struct ifnet * ifp, s
 	ifmr->ifm_status |= IFM_ACTIVE;
 
 	switch (adapter->link_speed) {
+		case IXGBE_LINK_SPEED_100_FULL:
+			ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
+			break;
 		case IXGBE_LINK_SPEED_1GB_FULL:
 			ifmr->ifm_active |= IFM_1000_T | IFM_FDX;
 			break;
@@ -1541,7 +1618,9 @@ ixgbe_media_change(struct ifnet * ifp)
         switch (IFM_SUBTYPE(ifm->ifm_media)) {
         case IFM_AUTO:
                 adapter->hw.phy.autoneg_advertised =
-		    IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_10GB_FULL;
+		    IXGBE_LINK_SPEED_100_FULL |
+		    IXGBE_LINK_SPEED_1GB_FULL |
+		    IXGBE_LINK_SPEED_10GB_FULL;
                 break;
         default:
                 device_printf(adapter->dev, "Only auto media type\n");
@@ -1570,7 +1649,7 @@ ixgbe_xmit(struct tx_ring *txr, struct m
 	struct mbuf	*m_head;
 	bus_dma_segment_t segs[adapter->num_segs];
 	bus_dmamap_t	map;
-	struct ixgbe_tx_buf *txbuf, *txbuf_mapped;
+	struct ixgbe_tx_buf *txbuf;
 	union ixgbe_adv_tx_desc *txd = NULL;
 
 	m_head = *m_headp;
@@ -1589,7 +1668,6 @@ ixgbe_xmit(struct tx_ring *txr, struct m
          */
         first = txr->next_avail_desc;
 	txbuf = &txr->tx_buffers[first];
-	txbuf_mapped = txbuf;
 	map = txbuf->map;
 
 	/*
@@ -1708,6 +1786,8 @@ ixgbe_xmit(struct tx_ring *txr, struct m
 	txr->next_avail_desc = i;
 
 	txbuf->m_head = m_head;
+	/* Swap the dma map between the first and last descriptor */
+	txr->tx_buffers[first].map = txbuf->map;
 	txbuf->map = map;
 	bus_dmamap_sync(txr->txtag, map, BUS_DMASYNC_PREWRITE);
 
@@ -1812,7 +1892,7 @@ ixgbe_set_multi(struct adapter *adapter)
 
 	update_ptr = mta;
 	ixgbe_update_mc_addr_list(&adapter->hw,
-	    update_ptr, mcnt, ixgbe_mc_array_itr);
+	    update_ptr, mcnt, ixgbe_mc_array_itr, TRUE);
 
 	return;
 }
@@ -1846,11 +1926,15 @@ ixgbe_mc_array_itr(struct ixgbe_hw *hw, 
 static void
 ixgbe_local_timer(void *arg)
 {
-	struct adapter *adapter = arg;
+	struct adapter	*adapter = arg;
 	device_t	dev = adapter->dev;
-	struct tx_ring *txr = adapter->tx_rings;
+	struct ifnet	*ifp = adapter->ifp;
+	struct ix_queue *que = adapter->queues;
+	struct tx_ring	*txr = adapter->tx_rings;
+	int		hung, busy, paused;
 
 	mtx_assert(&adapter->core_mtx, MA_OWNED);
+	hung = busy = paused = 0;
 
 	/* Check for pluggable optics */
 	if (adapter->sfp_probe)
@@ -1865,21 +1949,38 @@ ixgbe_local_timer(void *arg)
 	 * then don't do the watchdog check
 	 */
 	if (IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)
-		goto out;
+		paused = 1;
 
 	/*
-	** Check status on the TX queues for a hang
-	*/
-        for (int i = 0; i < adapter->num_queues; i++, txr++)
-		if (txr->queue_status == IXGBE_QUEUE_HUNG)
-			goto hung;
+	** Check the TX queues status
+	**      - central locked handling of OACTIVE
+	**      - watchdog only if all queues show hung
+	*/          
+	for (int i = 0; i < adapter->num_queues; i++, que++, txr++) {
+		if ((txr->queue_status & IXGBE_QUEUE_HUNG) &&
+		    (paused == 0))
+			++hung;
+		if (txr->queue_status & IXGBE_QUEUE_DEPLETED)
+			++busy;
+		if ((txr->queue_status & IXGBE_QUEUE_IDLE) == 0)
+			taskqueue_enqueue(que->tq, &que->que_task);
+        }
+	/* Only truely watchdog if all queues show hung */
+        if (hung == adapter->num_queues)
+                goto watchdog;
+	/* Only turn off the stack flow when ALL are depleted */
+        if (busy == adapter->num_queues)
+                ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+        else if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) &&
+            (busy < adapter->num_queues))
+                ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
 out:
 	ixgbe_rearm_queues(adapter, adapter->que_mask);
 	callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter);
 	return;
 
-hung:
+watchdog:
 	device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
 	device_printf(dev,"Queue(%d) tdh = %d, hw tdt = %d\n", txr->me,
 	    IXGBE_READ_REG(&adapter->hw, IXGBE_TDH(txr->me)),
@@ -1949,9 +2050,11 @@ ixgbe_stop(void *arg)
 
 	INIT_DEBUGOUT("ixgbe_stop: begin\n");
 	ixgbe_disable_intr(adapter);
+	callout_stop(&adapter->timer);
 
-	/* Tell the stack that the interface is no longer active */
-	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+	/* Let the stack know...*/
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 
 	ixgbe_reset_hw(hw);
 	hw->adapter_stopped = FALSE;
@@ -1959,7 +2062,6 @@ ixgbe_stop(void *arg)
 	/* Turn off the laser */
 	if (hw->phy.multispeed_fiber)
 		ixgbe_disable_tx_laser(hw);
-	callout_stop(&adapter->timer);
 
 	/* reprogram the RAR[0] in case user changed it. */
 	ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV);
@@ -2013,35 +2115,41 @@ ixgbe_setup_optics(struct adapter *adapt
 	int		layer;
 	
 	layer = ixgbe_get_supported_physical_layer(hw);
-	switch (layer) {
-		case IXGBE_PHYSICAL_LAYER_10GBASE_T:
-			adapter->optics = IFM_10G_T;
-			break;
-		case IXGBE_PHYSICAL_LAYER_1000BASE_T:
-			adapter->optics = IFM_1000_T;
-			break;
-		case IXGBE_PHYSICAL_LAYER_10GBASE_LR:
-		case IXGBE_PHYSICAL_LAYER_10GBASE_LRM:
-			adapter->optics = IFM_10G_LR;
-			break;
-		case IXGBE_PHYSICAL_LAYER_10GBASE_SR:
-			adapter->optics = IFM_10G_SR;
-			break;
-		case IXGBE_PHYSICAL_LAYER_10GBASE_KX4:
-		case IXGBE_PHYSICAL_LAYER_10GBASE_CX4:
-			adapter->optics = IFM_10G_CX4;
-			break;
-		case IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU:
-			adapter->optics = IFM_10G_TWINAX;
-			break;
-		case IXGBE_PHYSICAL_LAYER_1000BASE_KX:
-		case IXGBE_PHYSICAL_LAYER_10GBASE_KR:
-		case IXGBE_PHYSICAL_LAYER_10GBASE_XAUI:
-		case IXGBE_PHYSICAL_LAYER_UNKNOWN:
-		default:
-			adapter->optics = IFM_ETHER | IFM_AUTO;
-			break;
+
+	if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T) {
+		adapter->optics = IFM_10G_T;
+		return;
+	}
+
+	if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_T) {
+		adapter->optics = IFM_1000_T;
+		return;
+	}
+
+	if (layer & (IXGBE_PHYSICAL_LAYER_10GBASE_LR |
+	    IXGBE_PHYSICAL_LAYER_10GBASE_LRM)) {
+		adapter->optics = IFM_10G_LR;
+		return;
+	}
+
+	if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_SR) {
+		adapter->optics = IFM_10G_SR;
+		return;
+	}
+
+	if (layer & IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU) {
+		adapter->optics = IFM_10G_TWINAX;
+		return;
+	}
+
+	if (layer & (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
+	    IXGBE_PHYSICAL_LAYER_10GBASE_CX4)) {
+		adapter->optics = IFM_10G_CX4;
+		return;
 	}
+
+	/* If we get here just set the default */
+	adapter->optics = IFM_ETHER | IFM_AUTO;
 	return;
 }
 
@@ -2265,7 +2373,9 @@ ixgbe_setup_msix(struct adapter *adapter
 msi:
        	msgs = pci_msi_count(dev);
        	if (msgs == 1 && pci_alloc_msi(dev, &msgs) == 0)
-               	device_printf(adapter->dev,"Using MSI interrupt\n");
+               	device_printf(adapter->dev,"Using an MSI interrupt\n");
+	else
+               	device_printf(adapter->dev,"Using a Legacy interrupt\n");
 	return (msgs);
 }
 
@@ -2412,19 +2522,21 @@ ixgbe_setup_interface(device_t dev, stru
 	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
 
 	ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4 | IFCAP_VLAN_HWCSUM;
-	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
 	ifp->if_capabilities |= IFCAP_JUMBO_MTU;
+	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING
+			     |  IFCAP_VLAN_HWTSO
+			     |  IFCAP_VLAN_MTU;
 	ifp->if_capenable = ifp->if_capabilities;
 
 	/* Don't enable LRO by default */
 	ifp->if_capabilities |= IFCAP_LRO;
 
 	/*
-	** Dont turn this on by default, if vlans are
+	** Don't turn this on by default, if vlans are
 	** created on another pseudo device (eg. lagg)
 	** then vlan events are not passed thru, breaking
 	** operation, but with HW FILTER off it works. If
-	** using vlans directly on the em driver you can
+	** using vlans directly on the ixgbe driver you can
 	** enable this and get full hardware tag filtering.
 	*/
 	ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
@@ -2876,6 +2988,7 @@ ixgbe_initialize_transmit_units(struct a
 			txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
 			break;
 		case ixgbe_mac_82599EB:
+		case ixgbe_mac_X540:
 		default:
 			txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
 			break;
@@ -2886,6 +2999,7 @@ ixgbe_initialize_transmit_units(struct a
 			IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), txctrl);
 			break;
 		case ixgbe_mac_82599EB:
+		case ixgbe_mac_X540:
 		default:
 			IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), txctrl);
 			break;
@@ -3371,18 +3485,13 @@ ixgbe_txeof(struct tx_ring *txr)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-stable-8 mailing list