svn commit: r252898 - in stable/9/sys: conf dev/ixgbe modules/ixgbe

Jack F Vogel jfv at FreeBSD.org
Sat Jul 6 21:38:56 UTC 2013


Author: jfv
Date: Sat Jul  6 21:38:55 2013
New Revision: 252898
URL: http://svnweb.freebsd.org/changeset/base/252898

Log:
  MFC ixgbe driver revisions 248901, 250108, and 251964

Added:
  stable/9/sys/dev/ixgbe/ixgbe_dcb.c
     - copied unchanged from r251964, head/sys/dev/ixgbe/ixgbe_dcb.c
  stable/9/sys/dev/ixgbe/ixgbe_dcb.h
     - copied unchanged from r251964, head/sys/dev/ixgbe/ixgbe_dcb.h
  stable/9/sys/dev/ixgbe/ixgbe_dcb_82598.c
     - copied unchanged from r251964, head/sys/dev/ixgbe/ixgbe_dcb_82598.c
  stable/9/sys/dev/ixgbe/ixgbe_dcb_82598.h
     - copied unchanged from r251964, head/sys/dev/ixgbe/ixgbe_dcb_82598.h
  stable/9/sys/dev/ixgbe/ixgbe_dcb_82599.c
     - copied unchanged from r251964, head/sys/dev/ixgbe/ixgbe_dcb_82599.c
  stable/9/sys/dev/ixgbe/ixgbe_dcb_82599.h
     - copied unchanged from r251964, head/sys/dev/ixgbe/ixgbe_dcb_82599.h
Modified:
  stable/9/sys/conf/files
  stable/9/sys/dev/ixgbe/README
  stable/9/sys/dev/ixgbe/ixgbe.c
  stable/9/sys/dev/ixgbe/ixgbe.h
  stable/9/sys/dev/ixgbe/ixgbe_82598.c
  stable/9/sys/dev/ixgbe/ixgbe_82599.c
  stable/9/sys/dev/ixgbe/ixgbe_api.c
  stable/9/sys/dev/ixgbe/ixgbe_api.h
  stable/9/sys/dev/ixgbe/ixgbe_common.c
  stable/9/sys/dev/ixgbe/ixgbe_common.h
  stable/9/sys/dev/ixgbe/ixgbe_osdep.h
  stable/9/sys/dev/ixgbe/ixgbe_phy.c
  stable/9/sys/dev/ixgbe/ixgbe_phy.h
  stable/9/sys/dev/ixgbe/ixgbe_type.h
  stable/9/sys/dev/ixgbe/ixgbe_vf.c
  stable/9/sys/dev/ixgbe/ixgbe_x540.c
  stable/9/sys/dev/ixgbe/ixgbe_x540.h
  stable/9/sys/modules/ixgbe/Makefile
Directory Properties:
  stable/9/sys/conf/   (props changed)
  stable/9/sys/dev/ixgbe/   (props changed)
  stable/9/sys/modules/ixgbe/   (props changed)

Modified: stable/9/sys/conf/files
==============================================================================
--- stable/9/sys/conf/files	Sat Jul  6 20:39:44 2013	(r252897)
+++ stable/9/sys/conf/files	Sat Jul  6 21:38:55 2013	(r252898)
@@ -1463,6 +1463,12 @@ dev/ixgbe/ixgbe_82599.c		optional ixgbe 
 	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
 dev/ixgbe/ixgbe_x540.c		optional ixgbe inet \
 	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
+dev/ixgbe/ixgbe_dcb.c		optional ixgbe inet \
+	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
+dev/ixgbe/ixgbe_dcb_82598.c	optional ixgbe inet \
+	compile-with "${NORMAL_C} -I$S/dev/ixgbe"
+dev/ixgbe/ixgbe_dcb_82599.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

Modified: stable/9/sys/dev/ixgbe/README
==============================================================================
--- stable/9/sys/dev/ixgbe/README	Sat Jul  6 20:39:44 2013	(r252897)
+++ stable/9/sys/dev/ixgbe/README	Sat Jul  6 21:38:55 2013	(r252898)
@@ -2,7 +2,7 @@ FreeBSD Driver for Intel(R) Ethernet 10 
 ============================================================================
 /*$FreeBSD$*/
 
-November 12, 2010
+Jun 18, 2013
 
 
 Contents
@@ -18,8 +18,8 @@ Contents
 Overview
 ========
 
-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.
+This file describes the FreeBSD* driver for the
+Intel(R) Ethernet 10 Gigabit Family of Adapters.
 
 For questions related to hardware requirements, refer to the documentation
 supplied with your Intel 10GbE adapter.  All hardware requirements listed
@@ -42,7 +42,7 @@ optics, or is an Intel(R) Ethernet Serve
 Intel optics and/or the direct attach cables listed below.
 
 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. 
+the same Speed setting. Results may vary if you mix speed settings. 
  
 Supplier    Type                                             Part Numbers
 
@@ -70,7 +70,12 @@ Finisar	   DUAL RATE 1G/10G SFP+ LR (No 
 Avago	   DUAL RATE 1G/10G SFP+ LR (No Bail)	             AFCT-701SDZ-IN1
 Finistar   1000BASE-T SFP                                    FCLF8522P2BTL
 Avago      1000BASE-T SFP                                    ABCU-5710RZ
-		
+
+NOTE: As of driver version 2.5.13 it is possible to allow the operation
+of unsupported modules by setting the static variable 'allow_unsupported_sfp'
+to TRUE and rebuilding the driver. If problems occur please assure that they
+can be reproduced with fully supported optics first.
+
 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.
 
@@ -224,14 +229,7 @@ all 10 Gigabit adapters. 
   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.
-
-  This is done by changing the entry in the config file from SCHED_4BSD to 
-  SCHED_ULE. Note that this is only advisable on FreeBSD 7, on 6.X there have
-  been stability problems with ULE.
-
-  The interface can generate high number of interrupts. To avoid running 
+  The interface can generate a high number of interrupts. To avoid running 
   into the limit set by the kernel, adjust hw.intr_storm_threshold 
   setting using sysctl:
  
@@ -242,12 +240,10 @@ all 10 Gigabit adapters. 
        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. 
+  higher number, or the detection can be disabled by setting it to 0.
 
-  The default number of descriptors is 1024, increasing this to 2K or even 
-  4K may improve performance in some workloads, but change carefully.
+  The default number of descriptors is 2048, increasing or descreasing
+  may improve performance in some workloads, but change carefully.
 
 
 Known Limitations
@@ -284,7 +280,7 @@ issues download your adapter's user guid
   ----------------------------------------------------------
   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 driver will 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."

Modified: stable/9/sys/dev/ixgbe/ixgbe.c
==============================================================================
--- stable/9/sys/dev/ixgbe/ixgbe.c	Sat Jul  6 20:39:44 2013	(r252897)
+++ stable/9/sys/dev/ixgbe/ixgbe.c	Sat Jul  6 21:38:55 2013	(r252898)
@@ -32,6 +32,7 @@
 ******************************************************************************/
 /*$FreeBSD$*/
 
+
 #ifdef HAVE_KERNEL_OPTION_HEADERS
 #include "opt_inet.h"
 #include "opt_inet6.h"
@@ -47,7 +48,7 @@ int             ixgbe_display_debug_stat
 /*********************************************************************
  *  Driver version
  *********************************************************************/
-char ixgbe_driver_version[] = "2.5.7 - STABLE/9";
+char ixgbe_driver_version[] = "2.5.13";
 
 /*********************************************************************
  *  PCI Device ID Table
@@ -109,8 +110,7 @@ static void     ixgbe_start(struct ifnet
 static void     ixgbe_start_locked(struct tx_ring *, struct ifnet *);
 #else /* ! IXGBE_LEGACY_TX */
 static int	ixgbe_mq_start(struct ifnet *, struct mbuf *);
-static int	ixgbe_mq_start_locked(struct ifnet *,
-                    struct tx_ring *, struct mbuf *);
+static int	ixgbe_mq_start_locked(struct ifnet *, struct tx_ring *);
 static void	ixgbe_qflush(struct ifnet *);
 static void	ixgbe_deferred_mq_start(void *, int);
 #endif /* IXGBE_LEGACY_TX */
@@ -122,6 +122,7 @@ static void     ixgbe_media_status(struc
 static int      ixgbe_media_change(struct ifnet *);
 static void     ixgbe_identify_hardware(struct adapter *);
 static int      ixgbe_allocate_pci_resources(struct adapter *);
+static void	ixgbe_get_slot_info(struct ixgbe_hw *);
 static int      ixgbe_allocate_msix(struct adapter *);
 static int      ixgbe_allocate_legacy(struct adapter *);
 static int	ixgbe_allocate_queues(struct adapter *);
@@ -149,7 +150,7 @@ static void	ixgbe_setup_hw_rsc(struct rx
 static void     ixgbe_enable_intr(struct adapter *);
 static void     ixgbe_disable_intr(struct adapter *);
 static void     ixgbe_update_stats_counters(struct adapter *);
-static bool	ixgbe_txeof(struct tx_ring *);
+static void	ixgbe_txeof(struct tx_ring *);
 static bool	ixgbe_rxeof(struct ix_queue *);
 static void	ixgbe_rx_checksum(u32, struct mbuf *, u32);
 static void     ixgbe_set_promisc(struct adapter *);
@@ -206,6 +207,9 @@ static void	ixgbe_atr(struct tx_ring *, 
 static void	ixgbe_reinit_fdir(void *, int);
 #endif
 
+/* Missing shared code prototype */
+extern void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw);
+
 /*********************************************************************
  *  FreeBSD Device Interface Entry Points
  *********************************************************************/
@@ -291,6 +295,13 @@ static int ixgbe_rxd = PERFORM_RXD;
 TUNABLE_INT("hw.ixgbe.rxd", &ixgbe_rxd);
 
 /*
+** Defining this on will allow the use
+** of unsupported SFP+ modules, note that
+** doing so you are on your own :)
+*/
+static int allow_unsupported_sfp = FALSE;
+
+/*
 ** HW RSC control: 
 **  this feature only works with
 **  IPv4, and only on 82599 and later.
@@ -507,6 +518,7 @@ ixgbe_attach(device_t dev)
 	}
 
 	/* Initialize the shared code */
+	hw->allow_unsupported_sfp = allow_unsupported_sfp;
 	error = ixgbe_init_shared_code(hw);
 	if (error == IXGBE_ERR_SFP_NOT_PRESENT) {
 		/*
@@ -576,24 +588,10 @@ ixgbe_attach(device_t dev)
 	adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
 	    ixgbe_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
 
-        /* Print PCIE bus type/speed/width info */
-	ixgbe_get_bus_info(hw);
-	device_printf(dev,"PCI Express Bus: Speed %s %s\n",
-	    ((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s":
-	    (hw->bus.speed == ixgbe_bus_speed_2500) ? "2.5Gb/s":"Unknown"),
-	    (hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" :
-	    (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" :
-	    (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" :
-	    ("Unknown"));
-
-	if ((hw->bus.width <= ixgbe_bus_width_pcie_x4) &&
-	    (hw->bus.speed == ixgbe_bus_speed_2500)) {
-		device_printf(dev, "PCI-Express bandwidth available"
-		    " for this card\n     is not sufficient for"
-		    " optimal performance.\n");
-		device_printf(dev, "For optimal performance a x8 "
-		    "PCIE, or x4 PCIE 2 slot is required.\n");
-        }
+        /*
+	** Check PCIE slot type/speed/width
+	*/
+	ixgbe_get_slot_info(hw);
 
 	/* Set an initial default flow control value */
 	adapter->fc =  ixgbe_fc_full;
@@ -797,7 +795,7 @@ ixgbe_mq_start(struct ifnet *ifp, struct
 	struct adapter	*adapter = ifp->if_softc;
 	struct ix_queue	*que;
 	struct tx_ring	*txr;
-	int 		i = 0, err = 0;
+	int 		i, err = 0;
 
 	/* Which queue to use */
 	if ((m->m_flags & M_FLOWID) != 0)
@@ -808,40 +806,37 @@ ixgbe_mq_start(struct ifnet *ifp, struct
 	txr = &adapter->tx_rings[i];
 	que = &adapter->queues[i];
 
+	err = drbr_enqueue(ifp, txr->br, m);
+	if (err)
+		return (err);
 	if (IXGBE_TX_TRYLOCK(txr)) {
-		err = ixgbe_mq_start_locked(ifp, txr, m);
+		err = ixgbe_mq_start_locked(ifp, txr);
 		IXGBE_TX_UNLOCK(txr);
-	} else {
-		err = drbr_enqueue(ifp, txr->br, m);
+	} else
 		taskqueue_enqueue(que->tq, &txr->txq_task);
-	}
 
 	return (err);
 }
 
 static int
-ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
+ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr)
 {
 	struct adapter  *adapter = txr->adapter;
         struct mbuf     *next;
-        int             enqueued, err = 0;
+        int             enqueued = 0, err = 0;
 
 	if (((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) ||
-	    adapter->link_active == 0) {
-		if (m != NULL)
-			err = drbr_enqueue(ifp, txr->br, m);
-		return (err);
-	}
-
-	enqueued = 0;
-	if (m != NULL) {
-		err = drbr_enqueue(ifp, txr->br, m);
-		if (err) {
-			return (err);
-		}
-	}
+	    adapter->link_active == 0)
+		return (ENETDOWN);
 
 	/* Process the queue */
+#if __FreeBSD_version < 901504
+	next = drbr_dequeue(ifp, txr->br);
+	while (next != NULL) {
+		if ((err = ixgbe_xmit(txr, &next)) != 0) {
+			if (next != NULL)
+				err = drbr_enqueue(ifp, txr->br, next);
+#else
 	while ((next = drbr_peek(ifp, txr->br)) != NULL) {
 		if ((err = ixgbe_xmit(txr, &next)) != 0) {
 			if (next == NULL) {
@@ -849,16 +844,20 @@ ixgbe_mq_start_locked(struct ifnet *ifp,
 			} else {
 				drbr_putback(ifp, txr->br, next);
 			}
+#endif
 			break;
 		}
+#if __FreeBSD_version >= 901504
 		drbr_advance(ifp, txr->br);
+#endif
 		enqueued++;
 		/* Send a copy of the frame to the BPF listener */
 		ETHER_BPF_MTAP(ifp, next);
 		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
 			break;
-		if (txr->tx_avail < IXGBE_TX_OP_THRESHOLD)
-			ixgbe_txeof(txr);
+#if __FreeBSD_version < 901504
+		next = drbr_dequeue(ifp, txr->br);
+#endif
 	}
 
 	if (enqueued > 0) {
@@ -885,7 +884,7 @@ ixgbe_deferred_mq_start(void *arg, int p
 
 	IXGBE_TX_LOCK(txr);
 	if (!drbr_empty(ifp, txr->br))
-		ixgbe_mq_start_locked(ifp, txr, NULL);
+		ixgbe_mq_start_locked(ifp, txr);
 	IXGBE_TX_UNLOCK(txr);
 }
 
@@ -1418,20 +1417,19 @@ ixgbe_handle_que(void *context, int pend
 		ixgbe_txeof(txr);
 #ifndef IXGBE_LEGACY_TX
 		if (!drbr_empty(ifp, txr->br))
-			ixgbe_mq_start_locked(ifp, txr, NULL);
+			ixgbe_mq_start_locked(ifp, txr);
 #else
 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 			ixgbe_start_locked(txr, ifp);
 #endif
 		IXGBE_TX_UNLOCK(txr);
-		if (more) {
-			taskqueue_enqueue(que->tq, &que->que_task);
-			return;
-		}
 	}
 
 	/* Reenable this interrupt */
-	ixgbe_enable_queue(adapter, que->msix);
+	if (que->res != NULL)
+		ixgbe_enable_queue(adapter, que->msix);
+	else
+		ixgbe_enable_intr(adapter);
 	return;
 }
 
@@ -1448,9 +1446,10 @@ ixgbe_legacy_irq(void *arg)
 	struct ix_queue *que = arg;
 	struct adapter	*adapter = que->adapter;
 	struct ixgbe_hw	*hw = &adapter->hw;
+	struct ifnet    *ifp = adapter->ifp;
 	struct 		tx_ring *txr = adapter->tx_rings;
-	bool		more_tx, more_rx;
-	u32       	reg_eicr, loop = MAX_LOOP;
+	bool		more;
+	u32       	reg_eicr;
 
 
 	reg_eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
@@ -1461,17 +1460,19 @@ ixgbe_legacy_irq(void *arg)
 		return;
 	}
 
-	more_rx = ixgbe_rxeof(que);
+	more = ixgbe_rxeof(que);
 
 	IXGBE_TX_LOCK(txr);
-	do {
-		more_tx = ixgbe_txeof(txr);
-	} while (loop-- && more_tx);
+	ixgbe_txeof(txr);
+#ifdef IXGBE_LEGACY_TX
+	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		ixgbe_start_locked(txr, ifp);
+#else
+	if (!drbr_empty(ifp, txr->br))
+		ixgbe_mq_start_locked(ifp, txr);
+#endif
 	IXGBE_TX_UNLOCK(txr);
 
-	if (more_rx || more_tx)
-		taskqueue_enqueue(que->tq, &que->que_task);
-
 	/* Check for fan failure */
 	if ((hw->phy.media_type == ixgbe_media_type_copper) &&
 	    (reg_eicr & IXGBE_EICR_GPI_SDP1)) {
@@ -1484,7 +1485,10 @@ ixgbe_legacy_irq(void *arg)
 	if (reg_eicr & IXGBE_EICR_LSC)
 		taskqueue_enqueue(adapter->tq, &adapter->link_task);
 
-	ixgbe_enable_intr(adapter);
+	if (more)
+		taskqueue_enqueue(que->tq, &que->que_task);
+	else
+		ixgbe_enable_intr(adapter);
 	return;
 }
 
@@ -1499,29 +1503,26 @@ ixgbe_msix_que(void *arg)
 {
 	struct ix_queue	*que = arg;
 	struct adapter  *adapter = que->adapter;
+	struct ifnet    *ifp = adapter->ifp;
 	struct tx_ring	*txr = que->txr;
 	struct rx_ring	*rxr = que->rxr;
-	bool		more_tx, more_rx;
+	bool		more;
 	u32		newitr = 0;
 
 	ixgbe_disable_queue(adapter, que->msix);
 	++que->irqs;
 
-	more_rx = ixgbe_rxeof(que);
+	more = ixgbe_rxeof(que);
 
 	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.
-	*/
+	ixgbe_txeof(txr);
 #ifdef IXGBE_LEGACY_TX
-	if (!IFQ_DRV_IS_EMPTY(&adapter->ifp->if_snd))
+	if (!IFQ_DRV_IS_EMPTY(ifp->if_snd))
+		ixgbe_start_locked(txr, ifp);
 #else
-	if (!drbr_empty(adapter->ifp, txr->br))
+	if (!drbr_empty(ifp, txr->br))
+		ixgbe_mq_start_locked(ifp, txr);
 #endif
-		more_tx = 1;
 	IXGBE_TX_UNLOCK(txr);
 
 	/* Do AIM now? */
@@ -1575,9 +1576,9 @@ ixgbe_msix_que(void *arg)
         rxr->packets = 0;
 
 no_calc:
-	if (more_tx || more_rx)
+	if (more)
 		taskqueue_enqueue(que->tq, &que->que_task);
-	else /* Reenable this interrupt */
+	else
 		ixgbe_enable_queue(adapter, que->msix);
 	return;
 }
@@ -1639,11 +1640,11 @@ ixgbe_msix_link(void *arg)
 
 	/* Check for over temp condition */
 	if ((hw->mac.type == ixgbe_mac_X540) &&
-	    (reg_eicr & IXGBE_EICR_GPI_SDP0)) {
+	    (reg_eicr & IXGBE_EICR_TS)) {
                 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(hw, IXGBE_EICR, IXGBE_EICR_TS);
 	}
 
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
@@ -1892,10 +1893,34 @@ ixgbe_set_promisc(struct adapter *adapte
 {
 	u_int32_t       reg_rctl;
 	struct ifnet   *ifp = adapter->ifp;
+	int		mcnt = 0;
 
 	reg_rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
 	reg_rctl &= (~IXGBE_FCTRL_UPE);
-	reg_rctl &= (~IXGBE_FCTRL_MPE);
+	if (ifp->if_flags & IFF_ALLMULTI)
+		mcnt = MAX_NUM_MULTICAST_ADDRESSES;
+	else {
+		struct	ifmultiaddr *ifma;
+#if __FreeBSD_version < 800000
+		IF_ADDR_LOCK(ifp);
+#else
+		if_maddr_rlock(ifp);
+#endif
+		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+			if (ifma->ifma_addr->sa_family != AF_LINK)
+				continue;
+			if (mcnt == MAX_NUM_MULTICAST_ADDRESSES)
+				break;
+			mcnt++;
+		}
+#if __FreeBSD_version < 800000
+		IF_ADDR_UNLOCK(ifp);
+#else
+		if_maddr_runlock(ifp);
+#endif
+	}
+	if (mcnt < MAX_NUM_MULTICAST_ADDRESSES)
+		reg_rctl &= (~IXGBE_FCTRL_MPE);
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_rctl);
 
 	if (ifp->if_flags & IFF_PROMISC) {
@@ -2038,7 +2063,7 @@ ixgbe_local_timer(void *arg)
 		    (paused == 0))
 			++hung;
 		else if (txr->queue_status == IXGBE_QUEUE_WORKING)
-			taskqueue_enqueue(que->tq, &que->que_task);
+			taskqueue_enqueue(que->tq, &txr->txq_task);
         }
 	/* Only truely watchdog if all queues show hung */
         if (hung == adapter->num_queues)
@@ -2125,9 +2150,14 @@ ixgbe_stop(void *arg)
 	ixgbe_reset_hw(hw);
 	hw->adapter_stopped = FALSE;
 	ixgbe_stop_adapter(hw);
-	/* Turn off the laser */
-	if (hw->phy.multispeed_fiber)
-		ixgbe_disable_tx_laser(hw);
+	if (hw->mac.type == ixgbe_mac_82599EB)
+		ixgbe_stop_mac_link_on_d3_82599(hw);
+	/* Turn off the laser - noop with no optics */
+	ixgbe_disable_tx_laser(hw);
+
+	/* Update the stack */
+	adapter->link_up = FALSE;
+       	ixgbe_update_link_status(adapter);
 
 	/* reprogram the RAR[0] in case user changed it. */
 	ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV);
@@ -2579,7 +2609,11 @@ ixgbe_setup_interface(device_t dev, stru
 		return (-1);
 	}
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+#if __FreeBSD_version < 1000025
 	ifp->if_baudrate = 1000000000;
+#else
+	if_initbaudrate(ifp, IF_Gbps(10));
+#endif
 	ifp->if_init = ixgbe_init;
 	ifp->if_softc = adapter;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
@@ -2590,6 +2624,8 @@ ixgbe_setup_interface(device_t dev, stru
 #else
 	ifp->if_start = ixgbe_start;
 	IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 2);
+	ifp->if_snd.ifq_drv_maxlen = adapter->num_tx_desc - 2;
+	IFQ_SET_READY(&ifp->if_snd);
 #endif
 
 	ether_ifattach(ifp, adapter->hw.mac.addr);
@@ -3533,7 +3569,7 @@ ixgbe_atr(struct tx_ring *txr, struct mb
  *  tx_buffer is put back on the free queue.
  *
  **********************************************************************/
-static bool
+static void
 ixgbe_txeof(struct tx_ring *txr)
 {
 	struct adapter		*adapter = txr->adapter;
@@ -3576,13 +3612,13 @@ ixgbe_txeof(struct tx_ring *txr)
 			netmap_tx_irq(ifp, txr->me |
 			    (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT));
 		}
-		return FALSE;
+		return;
 	}
 #endif /* DEV_NETMAP */
 
 	if (txr->tx_avail == txr->num_desc) {
 		txr->queue_status = IXGBE_QUEUE_IDLE;
-		return FALSE;
+		return;
 	}
 
 	/* Get work starting point */
@@ -3676,12 +3712,10 @@ ixgbe_txeof(struct tx_ring *txr)
 	if ((!processed) && ((ticks - txr->watchdog_time) > IXGBE_WATCHDOG))
 		txr->queue_status = IXGBE_QUEUE_HUNG;
 
-	if (txr->tx_avail == txr->num_desc) {
+	if (txr->tx_avail == txr->num_desc)
 		txr->queue_status = IXGBE_QUEUE_IDLE;
-		return (FALSE);
-	}
 
-	return TRUE;
+	return;
 }
 
 /*********************************************************************
@@ -4363,6 +4397,7 @@ ixgbe_rxeof(struct ix_queue *que)
 	if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed))
 		return (FALSE);
 #endif /* DEV_NETMAP */
+
 	for (i = rxr->next_to_check; count != 0;) {
 		struct mbuf	*sendmp, *mp;
 		u32		rsc, ptype;
@@ -4552,15 +4587,12 @@ next_desc:
 	IXGBE_RX_UNLOCK(rxr);
 
 	/*
-	** We still have cleaning to do?
-	** Schedule another interrupt if so.
+	** Still have cleaning to do?
 	*/
-	if ((staterr & IXGBE_RXD_STAT_DD) != 0) {
-		ixgbe_rearm_queues(adapter, (u64)(1 << que->msix));
+	if ((staterr & IXGBE_RXD_STAT_DD) != 0)
 		return (TRUE);
-	}
-
-	return (FALSE);
+	else
+		return (FALSE);
 }
 
 
@@ -4715,11 +4747,11 @@ ixgbe_setup_vlan_hw_support(struct adapt
 static void
 ixgbe_enable_intr(struct adapter *adapter)
 {
-	struct ixgbe_hw *hw = &adapter->hw;
-	struct ix_queue *que = adapter->queues;
-	u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
-
+	struct ixgbe_hw	*hw = &adapter->hw;
+	struct ix_queue	*que = adapter->queues;
+	u32		mask, fwsm;
 
+	mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
 	/* Enable Fan Failure detection */
 	if (hw->device_id == IXGBE_DEV_ID_82598AT)
 		    mask |= IXGBE_EIMS_GPI_SDP1;
@@ -4736,6 +4768,10 @@ ixgbe_enable_intr(struct adapter *adapte
 			break;
 		case ixgbe_mac_X540:
 			mask |= IXGBE_EIMS_ECC;
+			/* Detect if Thermal Sensor is enabled */
+			fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM);
+			if (fwsm & IXGBE_FWSM_TS_ENABLED)
+				mask |= IXGBE_EIMS_TS;
 #ifdef IXGBE_FDIR
 			mask |= IXGBE_EIMS_FLOW_DIR;
 #endif
@@ -4805,6 +4841,111 @@ ixgbe_write_pci_cfg(struct ixgbe_hw *hw,
 }
 
 /*
+** Get the width and transaction speed of
+** the slot this adapter is plugged into.
+*/
+static void
+ixgbe_get_slot_info(struct ixgbe_hw *hw)
+{
+	device_t		dev = ((struct ixgbe_osdep *)hw->back)->dev;
+	struct ixgbe_mac_info	*mac = &hw->mac;
+	u16			link;
+	u32			offset;
+
+	/* For most devices simply call the shared code routine */
+	if (hw->device_id != IXGBE_DEV_ID_82599_SFP_SF_QP) {
+		ixgbe_get_bus_info(hw);
+		goto display;
+	}
+
+	/*
+	** For the Quad port adapter we need to parse back
+	** up the PCI tree to find the speed of the expansion
+	** slot into which this adapter is plugged. A bit more work.
+	*/
+	dev = device_get_parent(device_get_parent(dev));
+#ifdef IXGBE_DEBUG
+	device_printf(dev, "parent pcib = %x,%x,%x\n",
+	    pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev));
+#endif
+	dev = device_get_parent(device_get_parent(dev));
+#ifdef IXGBE_DEBUG
+	device_printf(dev, "slot pcib = %x,%x,%x\n",
+	    pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev));
+#endif
+	/* Now get the PCI Express Capabilities offset */
+	pci_find_cap(dev, PCIY_EXPRESS, &offset);
+	/* ...and read the Link Status Register */
+	link = pci_read_config(dev, offset + PCIER_LINK_STA, 2);
+	switch (link & IXGBE_PCI_LINK_WIDTH) {
+	case IXGBE_PCI_LINK_WIDTH_1:
+		hw->bus.width = ixgbe_bus_width_pcie_x1;
+		break;
+	case IXGBE_PCI_LINK_WIDTH_2:
+		hw->bus.width = ixgbe_bus_width_pcie_x2;
+		break;
+	case IXGBE_PCI_LINK_WIDTH_4:
+		hw->bus.width = ixgbe_bus_width_pcie_x4;
+		break;
+	case IXGBE_PCI_LINK_WIDTH_8:
+		hw->bus.width = ixgbe_bus_width_pcie_x8;
+		break;
+	default:
+		hw->bus.width = ixgbe_bus_width_unknown;
+		break;
+	}
+
+	switch (link & IXGBE_PCI_LINK_SPEED) {
+	case IXGBE_PCI_LINK_SPEED_2500:
+		hw->bus.speed = ixgbe_bus_speed_2500;
+		break;
+	case IXGBE_PCI_LINK_SPEED_5000:
+		hw->bus.speed = ixgbe_bus_speed_5000;
+		break;
+	case IXGBE_PCI_LINK_SPEED_8000:
+		hw->bus.speed = ixgbe_bus_speed_8000;
+		break;
+	default:
+		hw->bus.speed = ixgbe_bus_speed_unknown;
+		break;
+	}
+
+	mac->ops.set_lan_id(hw);
+
+display:
+	device_printf(dev,"PCI Express Bus: Speed %s %s\n",
+	    ((hw->bus.speed == ixgbe_bus_speed_8000) ? "8.0GT/s":
+	    (hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0GT/s":
+	    (hw->bus.speed == ixgbe_bus_speed_2500) ? "2.5GT/s":"Unknown"),
+	    (hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" :
+	    (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" :
+	    (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" :
+	    ("Unknown"));
+
+	if ((hw->device_id != IXGBE_DEV_ID_82599_SFP_SF_QP) &&
+	    ((hw->bus.width <= ixgbe_bus_width_pcie_x4) &&
+	    (hw->bus.speed == ixgbe_bus_speed_2500))) {
+		device_printf(dev, "PCI-Express bandwidth available"
+		    " for this card\n     is not sufficient for"
+		    " optimal performance.\n");
+		device_printf(dev, "For optimal performance a x8 "
+		    "PCIE, or x4 PCIE Gen2 slot is required.\n");
+        }
+	if ((hw->device_id == IXGBE_DEV_ID_82599_SFP_SF_QP) &&
+	    ((hw->bus.width <= ixgbe_bus_width_pcie_x8) &&
+	    (hw->bus.speed < ixgbe_bus_speed_8000))) {
+		device_printf(dev, "PCI-Express bandwidth available"
+		    " for this card\n     is not sufficient for"
+		    " optimal performance.\n");
+		device_printf(dev, "For optimal performance a x8 "
+		    "PCIE Gen3 slot is required.\n");
+        }
+
+	return;
+}
+
+
+/*
 ** Setup the correct IVAR register for a particular MSIX interrupt
 **   (yes this is all very magic and confusing :)
 **  - entry is the register array entry
@@ -5605,6 +5746,7 @@ ixgbe_set_advertise(SYSCTL_HANDLER_ARGS)
 /*
 ** Thermal Shutdown Trigger
 **   - cause a Thermal Overtemp IRQ
+**   - this now requires firmware enabling
 */
 static int
 ixgbe_set_thermal_test(SYSCTL_HANDLER_ARGS)

Modified: stable/9/sys/dev/ixgbe/ixgbe.h
==============================================================================
--- stable/9/sys/dev/ixgbe/ixgbe.h	Sat Jul  6 20:39:44 2013	(r252897)
+++ stable/9/sys/dev/ixgbe/ixgbe.h	Sat Jul  6 21:38:55 2013	(r252898)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2012, Intel Corporation 
+  Copyright (c) 2001-2013, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -213,6 +213,7 @@
 #define IXGBE_BULK_LATENCY	1200
 #define IXGBE_LINK_ITR		2000
 
+
 /*
  *****************************************************************************
  * vendor_info_array
@@ -230,6 +231,7 @@ typedef struct _ixgbe_vendor_info_t {
 	unsigned int    index;
 } ixgbe_vendor_info_t;
 
+
 /* This is used to get SFP+ module data */
 struct ixgbe_i2c_req {
         u8 dev_addr;
@@ -456,6 +458,7 @@ struct adapter {
 	/* Multicast array memory */
 	u8			*mta;
 
+
 	/* Misc stats maintained by the driver */
 	unsigned long   	dropped_pkts;
 	unsigned long   	mbuf_defrag_failed;
@@ -467,6 +470,7 @@ struct adapter {
 	struct ixgbe_hw_stats 	stats;
 };
 
+
 /* Precision Time Sync (IEEE 1588) defines */
 #define ETHERTYPE_IEEE1588      0x88F7
 #define PICOSECS_PER_TICK       20833
@@ -489,6 +493,10 @@ struct adapter {
 #define IXGBE_CORE_LOCK_ASSERT(_sc)       mtx_assert(&(_sc)->core_mtx, MA_OWNED)
 #define IXGBE_TX_LOCK_ASSERT(_sc)         mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
 
+/* For backward compatibility */
+#if !defined(PCIER_LINK_STA)
+#define PCIER_LINK_STA PCIR_EXPRESS_LINK_STA
+#endif
 
 static inline bool
 ixgbe_is_sfp(struct ixgbe_hw *hw)

Modified: stable/9/sys/dev/ixgbe/ixgbe_82598.c
==============================================================================
--- stable/9/sys/dev/ixgbe/ixgbe_82598.c	Sat Jul  6 20:39:44 2013	(r252897)
+++ stable/9/sys/dev/ixgbe/ixgbe_82598.c	Sat Jul  6 21:38:55 2013	(r252898)
@@ -166,6 +166,8 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw
 	/* Manageability interface */
 	mac->ops.set_fw_drv_ver = NULL;
 
+	mac->ops.get_rtrup2tc = NULL;
+
 	return ret_val;
 }
 
@@ -1115,10 +1117,19 @@ static s32 ixgbe_read_i2c_phy_82598(stru
 	u16 sfp_addr = 0;
 	u16 sfp_data = 0;
 	u16 sfp_stat = 0;
+	u16 gssr;
 	u32 i;
 
 	DEBUGFUNC("ixgbe_read_i2c_phy_82598");
 
+	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
+		gssr = IXGBE_GSSR_PHY1_SM;
+	else
+		gssr = IXGBE_GSSR_PHY0_SM;
+
+	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != IXGBE_SUCCESS)
+		return IXGBE_ERR_SWFW_SYNC;
+
 	if (hw->phy.type == ixgbe_phy_nl) {
 		/*
 		 * NetLogic phy SDA/SCL registers are at addresses 0xC30A to
@@ -1127,17 +1138,17 @@ static s32 ixgbe_read_i2c_phy_82598(stru
 		 */
 		sfp_addr = (dev_addr << 8) + byte_offset;
 		sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
-		hw->phy.ops.write_reg(hw,
-				      IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
-				      IXGBE_MDIO_PMA_PMD_DEV_TYPE,
-				      sfp_addr);
+		hw->phy.ops.write_reg_mdi(hw,
+					  IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
+					  IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+					  sfp_addr);
 
 		/* Poll status */
 		for (i = 0; i < 100; i++) {
-			hw->phy.ops.read_reg(hw,
-					     IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
-					     IXGBE_MDIO_PMA_PMD_DEV_TYPE,
-					     &sfp_stat);
+			hw->phy.ops.read_reg_mdi(hw,
+						IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
+						IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+						&sfp_stat);
 			sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
 			if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
 				break;
@@ -1151,8 +1162,8 @@ static s32 ixgbe_read_i2c_phy_82598(stru
 		}
 
 		/* Read data */
-		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
-				     IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
+		hw->phy.ops.read_reg_mdi(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
+					IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
 
 		*eeprom_data = (u8)(sfp_data >> 8);
 	} else {
@@ -1160,6 +1171,7 @@ static s32 ixgbe_read_i2c_phy_82598(stru
 	}
 
 out:
+	hw->mac.ops.release_swfw_sync(hw, gssr);
 	return status;
 }
 

Modified: stable/9/sys/dev/ixgbe/ixgbe_82599.c
==============================================================================
--- stable/9/sys/dev/ixgbe/ixgbe_82599.c	Sat Jul  6 20:39:44 2013	(r252897)
+++ stable/9/sys/dev/ixgbe/ixgbe_82599.c	Sat Jul  6 21:38:55 2013	(r252898)
@@ -77,7 +77,7 @@ void ixgbe_init_mac_link_ops_82599(struc
 	 * and MNG not enabled
 	 */
 	if ((mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
-	    !(ixgbe_mng_enabled(hw))) {
+	    !hw->mng_fw_enabled) {
 		mac->ops.disable_tx_laser =
 				       &ixgbe_disable_tx_laser_multispeed_fiber;
 		mac->ops.enable_tx_laser =
@@ -180,11 +180,13 @@ s32 ixgbe_setup_sfp_modules_82599(struct
 			goto setup_sfp_out;
 		}
 
-		hw->eeprom.ops.read(hw, ++data_offset, &data_value);
+		if (hw->eeprom.ops.read(hw, ++data_offset, &data_value))
+			goto setup_sfp_err;
 		while (data_value != 0xffff) {
 			IXGBE_WRITE_REG(hw, IXGBE_CORECTL, data_value);
 			IXGBE_WRITE_FLUSH(hw);
-			hw->eeprom.ops.read(hw, ++data_offset, &data_value);
+			if (hw->eeprom.ops.read(hw, ++data_offset, &data_value))
+				goto setup_sfp_err;
 		}
 
 		/* Release the semaphore */
@@ -229,6 +231,15 @@ s32 ixgbe_setup_sfp_modules_82599(struct
 
 setup_sfp_out:
 	return ret_val;
+
+setup_sfp_err:
+	/* Release the semaphore */
+	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+	/* Delay obtaining semaphore again to allow FW access */
+	msec_delay(hw->eeprom.semaphore_delay);
+	ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
+		      "eeprom read at offset %d failed", data_offset);
+	return IXGBE_ERR_PHY;
 }
 
 /**
@@ -314,6 +325,11 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw
 	mac->ops.set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic;
 
 
+	mac->ops.get_rtrup2tc = &ixgbe_dcb_get_rtrup2tc_generic;
+
+	/* Cache if MNG FW is up */
+	hw->mng_fw_enabled = ixgbe_mng_enabled(hw);
+
 	return ret_val;
 }
 
@@ -479,6 +495,29 @@ out:
 }
 
 /**
+ *  ixgbe_stop_mac_link_on_d3_82599 - Disables link on D3
+ *  @hw: pointer to hardware structure
+ *
+ *  Disables link during D3 power down sequence.
+ *
+ **/
+void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw)
+{
+	u32 autoc2_reg;
+	u16 ee_ctrl_2 = 0;
+
+	DEBUGFUNC("ixgbe_stop_mac_link_on_d3_82599");
+	ixgbe_read_eeprom(hw, IXGBE_EEPROM_CTRL_2, &ee_ctrl_2);
+
+	if (!hw->mng_fw_enabled && !hw->wol_enabled &&
+		ee_ctrl_2 & IXGBE_EEPROM_CCD_BIT) {
+		autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+		autoc2_reg |= IXGBE_AUTOC2_LINK_DISABLE_ON_D3_MASK;
+		IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2_reg);
+	}
+}
+
+/**
  *  ixgbe_start_mac_link_82599 - Setup MAC link settings
  *  @hw: pointer to hardware structure
  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
@@ -1122,7 +1161,8 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw
 {
 	ixgbe_link_speed link_speed;
 	s32 status;
-	u32 ctrl, i, autoc, autoc2;
+	u32 ctrl, i, autoc2;
+	u32 curr_lms;
 	bool link_up = FALSE;
 
 	DEBUGFUNC("ixgbe_reset_hw_82599");
@@ -1156,6 +1196,13 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw
 	if (hw->phy.reset_disable == FALSE && hw->phy.ops.reset != NULL)
 		hw->phy.ops.reset(hw);
 
+	/* remember AUTOC from before we reset */
+	if (hw->mac.cached_autoc)
+		curr_lms = hw->mac.cached_autoc & IXGBE_AUTOC_LMS_MASK;
+	else
+		curr_lms = IXGBE_READ_REG(hw, IXGBE_AUTOC) &
+					  IXGBE_AUTOC_LMS_MASK;
+
 mac_reset_top:
 	/*
 	 * Issue global reset to the MAC.  Needs to be SW reset if link is up.
@@ -1204,7 +1251,7 @@ mac_reset_top:
 	 * stored off yet.  Otherwise restore the stored original
 	 * values since the reset operation sets back to defaults.
 	 */
-	autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	hw->mac.cached_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
 	autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
 
 	/* Enable link if disabled in NVM */
@@ -1215,12 +1262,24 @@ mac_reset_top:
 	}
 
 	if (hw->mac.orig_link_settings_stored == FALSE) {
-		hw->mac.orig_autoc = autoc;
+		hw->mac.orig_autoc = hw->mac.cached_autoc;

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


More information about the svn-src-all mailing list