svn commit: r221041 - head/sys/dev/ixgbe

Jack F Vogel jfv at FreeBSD.org
Mon Apr 25 23:34:22 UTC 2011


Author: jfv
Date: Mon Apr 25 23:34:21 2011
New Revision: 221041
URL: http://svn.freebsd.org/changeset/base/221041

Log:
  - Add the RX refresh changes from igb to ixgbe
  - Also a couple minor tweaks to the TX code from the same source.
  - Add the INET ioctl code which has been missing from this driver,
    and which caused IP aliases to reset the interface.
  - Last, some minor logic changes that just reflect upcoming
    hardware support, but have no other functional effect now.
  
  MFC after a week

Modified:
  head/sys/dev/ixgbe/ixgbe.c
  head/sys/dev/ixgbe/ixgbe.h

Modified: head/sys/dev/ixgbe/ixgbe.c
==============================================================================
--- head/sys/dev/ixgbe/ixgbe.c	Mon Apr 25 23:12:18 2011	(r221040)
+++ head/sys/dev/ixgbe/ixgbe.c	Mon Apr 25 23:34:21 2011	(r221041)
@@ -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 
@@ -33,7 +33,7 @@
 /*$FreeBSD$*/
 
 #ifdef HAVE_KERNEL_OPTION_HEADERS
-#include "opt_device_polling.h"
+#include "opt_inet.h"
 #endif
 
 #include "ixgbe.h"
@@ -46,7 +46,7 @@ int             ixgbe_display_debug_stat
 /*********************************************************************
  *  Driver version
  *********************************************************************/
-char ixgbe_driver_version[] = "2.3.8";
+char ixgbe_driver_version[] = "2.3.10";
 
 /*********************************************************************
  *  PCI Device ID Table
@@ -270,8 +270,8 @@ TUNABLE_INT("hw.ixgbe.hdr_split", &ixgbe
 /*
  * Number of Queues, can be set to 0,
  * it then autoconfigures based on the
- * number of cpus. Each queue is a pair
- * of RX and TX rings with a msix vector
+ * number of cpus with a max of 8. This
+ * can be overriden manually here.
  */
 static int ixgbe_num_queues = 0;
 TUNABLE_INT("hw.ixgbe.num_queues", &ixgbe_num_queues);
@@ -787,10 +787,6 @@ ixgbe_mq_start_locked(struct ifnet *ifp,
 		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);
@@ -814,7 +810,9 @@ ixgbe_mq_start_locked(struct ifnet *ifp,
 		ETHER_BPF_MTAP(ifp, next);
 		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
 			break;
-		if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD) {
+		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;
 			break;
 		}
@@ -864,10 +862,35 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
 {
 	struct adapter	*adapter = ifp->if_softc;
 	struct ifreq	*ifr = (struct ifreq *) data;
+#ifdef INET
+	struct ifaddr *ifa = (struct ifaddr *)data;
+#endif
 	int             error = 0;
 
 	switch (command) {
 
+        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.
+			 */
+			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_flags & IFF_NOARP))
+				arp_ifinit(ifp, ifa);
+		} else
+#endif
+			error = ether_ioctl(ifp, command, data);
+		break;
+
 	case SIOCSIFMTU:
 		IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
 		if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - ETHER_HDR_LEN) {
@@ -989,7 +1012,7 @@ ixgbe_init_locked(struct adapter *adapte
 	if (ifp->if_capenable & IFCAP_TXCSUM) {
 		ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
 #if __FreeBSD_version >= 800000
-		if (hw->mac.type == ixgbe_mac_82599EB)
+		if (hw->mac.type != ixgbe_mac_82598EB)
 			ifp->if_hwassist |= CSUM_SCTP;
 #endif
 	}
@@ -1032,14 +1055,12 @@ ixgbe_init_locked(struct adapter *adapte
 
 	gpie = IXGBE_READ_REG(&adapter->hw, IXGBE_GPIE);
 
-	if (hw->mac.type == ixgbe_mac_82599EB) {
-		gpie |= IXGBE_SDP1_GPIEN;
-		gpie |= IXGBE_SDP2_GPIEN;
-	}
-
 	/* Enable Fan Failure Interrupt */
-	if (hw->device_id == IXGBE_DEV_ID_82598AT)
-		gpie |= IXGBE_SDP1_GPIEN;
+	gpie |= IXGBE_SDP1_GPIEN;
+
+	/* Add for Thermal detection */
+	if (hw->mac.type == ixgbe_mac_82599EB)
+		gpie |= IXGBE_SDP2_GPIEN;
 
 	if (adapter->msix > 1) {
 		/* Enable Enhanced MSIX mode */
@@ -1121,7 +1142,7 @@ ixgbe_init_locked(struct adapter *adapte
 
 #ifdef IXGBE_FDIR
 	/* Init Flow director */
-	if (hw->mac.type == ixgbe_mac_82599EB)
+	if (hw->mac.type != ixgbe_mac_82598EB)
 		ixgbe_init_fdir_signature_82599(&adapter->hw, fdir_pballoc);
 #endif
 
@@ -1338,8 +1359,6 @@ ixgbe_msix_que(void *arg)
 	more_tx = ixgbe_txeof(txr);
 	IXGBE_TX_UNLOCK(txr);
 
-	more_rx = ixgbe_rxeof(que, adapter->rx_process_limit);
-
 	/* Do AIM now? */
 
 	if (ixgbe_enable_aim == FALSE)
@@ -1417,7 +1436,7 @@ ixgbe_msix_link(void *arg)
 	if (reg_eicr & IXGBE_EICR_LSC)
 		taskqueue_enqueue(adapter->tq, &adapter->link_task);
 
-	if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+	if (adapter->hw.mac.type != ixgbe_mac_82598EB) {
 #ifdef IXGBE_FDIR
 		if (reg_eicr & IXGBE_EICR_FLOW_DIR) {
 			/* This is probably overkill :) */
@@ -2792,7 +2811,7 @@ ixgbe_setup_transmit_ring(struct tx_ring
 
 #ifdef IXGBE_FDIR
 	/* Set the rate at which we sample packets */
-	if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+	if (adapter->hw.mac.type != ixgbe_mac_82598EB)
 		txr->atr_sample = atr_sample_rate;
 #endif
 
@@ -2874,7 +2893,7 @@ ixgbe_initialize_transmit_units(struct a
 
 	}
 
-	if (hw->mac.type == ixgbe_mac_82599EB) {
+	if (hw->mac.type != ixgbe_mac_82598EB) {
 		u32 dmatxctl, rttdcs;
 		dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
 		dmatxctl |= IXGBE_DMATXCTL_TE;
@@ -3386,11 +3405,15 @@ ixgbe_refresh_mbufs(struct rx_ring *rxr,
 	bus_dma_segment_t	pseg[1];
 	struct ixgbe_rx_buf	*rxbuf;
 	struct mbuf		*mh, *mp;
-	int			i, nsegs, error, cleaned;
+	int			i, j, nsegs, error;
+	bool			refreshed = FALSE;
 
-	i = rxr->next_to_refresh;
-	cleaned = -1; /* Signify no completions */
-	while (i != limit) {
+	i = j = rxr->next_to_refresh;
+	/* Control the loop with one beyond */
+	if (++j == adapter->num_rx_desc)
+		j = 0;
+
+	while (j != limit) {
 		rxbuf = &rxr->rx_buffers[i];
 		if (rxr->hdr_split == FALSE)
 			goto no_split;
@@ -3418,7 +3441,8 @@ ixgbe_refresh_mbufs(struct rx_ring *rxr,
 		rxbuf->m_head = mh;
 		bus_dmamap_sync(rxr->htag, rxbuf->hmap,
 		    BUS_DMASYNC_PREREAD);
-		rxr->rx_base[i].read.hdr_addr = htole64(hseg[0].ds_addr);
+		rxr->rx_base[i].read.hdr_addr =
+		    htole64(hseg[0].ds_addr);
 
 no_split:
 		if (rxbuf->m_pack == NULL) {
@@ -3446,17 +3470,17 @@ no_split:
 		rxr->rx_base[i].read.pkt_addr =
 		    htole64(pseg[0].ds_addr);
 
-		cleaned = i;
-		/* Calculate next index */
-		if (++i == adapter->num_rx_desc)
-			i = 0;
-		/* This is the work marker for refresh */
+		refreshed = TRUE;
+		/* Next is precalculated */
+		i = j;
 		rxr->next_to_refresh = i;
+		if (++j == adapter->num_rx_desc)
+			j = 0;
 	}
 update:
-	if (cleaned != -1) /* If we refreshed some, bump tail */
+	if (refreshed) /* Update hardware tail index */
 		IXGBE_WRITE_REG(&adapter->hw,
-		    IXGBE_RDT(rxr->me), cleaned);
+		    IXGBE_RDT(rxr->me), rxr->next_to_refresh);
 	return;
 }
 
@@ -3727,6 +3751,7 @@ skip_head:
 	rxr->lro_enabled = FALSE;
 	rxr->rx_split_packets = 0;
 	rxr->rx_bytes = 0;
+	rxr->discard = FALSE;
 
 	bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@@ -3736,7 +3761,7 @@ skip_head:
 	** 82598 uses software LRO, the
 	** 82599 uses a hardware assist.
 	*/
-	if ((adapter->hw.mac.type == ixgbe_mac_82599EB) &&
+	if ((adapter->hw.mac.type != ixgbe_mac_82598EB) &&
 	    (ifp->if_capenable & IFCAP_RXCSUM) &&
 	    (ifp->if_capenable & IFCAP_LRO))
 		ixgbe_setup_hw_rsc(rxr);
@@ -3862,8 +3887,7 @@ ixgbe_initialize_receive_units(struct ad
 		IXGBE_WRITE_REG(hw, IXGBE_RDT(i), 0);
 	}
 
-	if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
-		/* PSRTYPE must be initialized in 82599 */
+	if (adapter->hw.mac.type != ixgbe_mac_82598EB) {
 		u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
 			      IXGBE_PSRTYPE_UDPHDR |
 			      IXGBE_PSRTYPE_IPV4HDR |
@@ -4307,10 +4331,8 @@ next_desc:
 	}
 
 	/* Refresh any remaining buf structs */
-	if (processed != 0) {
+	if (ixgbe_rx_unrefreshed(rxr))
 		ixgbe_refresh_mbufs(rxr, i);
-		processed = 0;
-	}
 
 	rxr->next_to_check = i;
 
@@ -4472,7 +4494,7 @@ ixgbe_setup_vlan_hw_support(struct adapt
 	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, ctrl);
 
 	/* On 82599 the VLAN enable is per/queue in RXDCTL */
-	if (hw->mac.type == ixgbe_mac_82599EB)
+	if (hw->mac.type != ixgbe_mac_82598EB)
 		for (int i = 0; i < adapter->num_queues; i++) {
 			ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
 				ctrl |= IXGBE_RXDCTL_VME;
@@ -4491,9 +4513,7 @@ ixgbe_enable_intr(struct adapter *adapte
 	/* Enable Fan Failure detection */
 	if (hw->device_id == IXGBE_DEV_ID_82598AT)
 		    mask |= IXGBE_EIMS_GPI_SDP1;
-
-	/* 82599 specific interrupts */
-	if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+	else {
 		    mask |= IXGBE_EIMS_ECC;
 		    mask |= IXGBE_EIMS_GPI_SDP1;
 		    mask |= IXGBE_EIMS_GPI_SDP2;
@@ -4810,7 +4830,7 @@ ixgbe_update_stats_counters(struct adapt
 	adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
 	adapter->stats.gprc -= missed_rx;
 
-	if (hw->mac.type == ixgbe_mac_82599EB) {
+	if (hw->mac.type != ixgbe_mac_82598EB) {
 		adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL) +
 		    ((u64)IXGBE_READ_REG(hw, IXGBE_GORCH) << 32);
 		adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL) +
@@ -4878,7 +4898,7 @@ ixgbe_update_stats_counters(struct adapt
 	adapter->stats.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC);
 	adapter->stats.fclast += IXGBE_READ_REG(hw, IXGBE_FCLAST);
 	/* Only read FCOE on 82599 */
-	if (hw->mac.type == ixgbe_mac_82599EB) {
+	if (hw->mac.type != ixgbe_mac_82598EB) {
 		adapter->stats.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC);
 		adapter->stats.fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC);
 		adapter->stats.fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC);

Modified: head/sys/dev/ixgbe/ixgbe.h
==============================================================================
--- head/sys/dev/ixgbe/ixgbe.h	Mon Apr 25 23:12:18 2011	(r221040)
+++ head/sys/dev/ixgbe/ixgbe.h	Mon Apr 25 23:34:21 2011	(r221041)
@@ -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 
@@ -497,4 +497,19 @@ drbr_needs_enqueue(struct ifnet *ifp, st
 }
 #endif
 
+/*
+** Find the number of unrefreshed RX descriptors
+*/
+static inline u16
+ixgbe_rx_unrefreshed(struct rx_ring *rxr)
+{       
+	struct adapter  *adapter = rxr->adapter;
+        
+	if (rxr->next_to_check > rxr->next_to_refresh)
+		return (rxr->next_to_check - rxr->next_to_refresh - 1);
+	else
+		return ((adapter->num_rx_desc + rxr->next_to_check) -
+		    rxr->next_to_refresh - 1);
+}       
+
 #endif /* _IXGBE_H_ */


More information about the svn-src-head mailing list