Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 2288

kernel-2.6.18-194.11.1.el5.src.rpm

From: Andy Gospodarek <gospo@redhat.com>
Date: Fri, 12 Jun 2009 15:43:18 -0400
Subject: [net] ixgbe: backport fixups and bugfixes for 82599
Message-id: 20090612194317.GV8052@gospo.rdu.redhat.com
O-Subject: [RHEL5.4 PATCH] ixgbe: backport fixups and bugfixes for 82599
Bugzilla: 505653
RH-Acked-by: David Miller <davem@redhat.com>
RH-Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
RH-Acked-by: Neil Horman <nhorman@redhat.com>

There were a couple of issues that were noticed while testing the ixgbe
driver on 5.4 that needed to be fixed.  In order to make sure I get
everything, I have combined these fixes into one patch.  Here is the
breakdown of the issues and which upstream fixes were included:

One of the main reasons for the update for 5.4 was 82599 support.  The
code in RHEL5.4 didn't set the registers correctly because I had
purposefully skipped some patches that were initially not relevant for
RHEL5.  Turns out the initial patch morphed into some important code, so
the following patches were applied to fix that:

        commit cc41ac7c0011703460dd4d4674bb7cbf73bb883d
        Author: Jesse Brandeburg <jesse.brandeburg@intel.com>
        Date:   Tue Aug 26 04:27:27 2008 -0700

            ixgbe: fix dca hints going to wrong processor

        commit 3be1adfb912867e244729c3826b457ee76b8f737
        Author: Alexander Duyck <alexander.h.duyck@intel.com>
        Date:   Sat Aug 30 00:29:10 2008 -0700

            ixgbe: change config srrctl to only program one register per VMDq/RSS id

        commit 32344a394029baeca5bcc9fa839694b23a82cc64
        Author: Jesse Brandeburg <jesse.brandeburg@intel.com>
        Date:   Tue Feb 24 16:37:31 2009 -0800

            ixbge: fix bug when using large pages and jumbo frames

        commit 40dcd79a7bd2e0d6bf4680db4bc0268c9f149a1d
        Author: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com>
        Date:   Fri Mar 13 22:13:08 2009 +0000

            ixgbe: Disable DROP_EN for Rx queues

        commit afafd5b020a60b72d064e89244cb44a975eb2407
        Author: Alexander Duyck <alexander.h.duyck@intel.com>
        Date:   Thu May 7 10:38:56 2009 +0000

            ixgbe: always set header length in SRRCTL

        commit 163de42e240623694562656542adedbca369beaf
        Author: Alexander Duyck <alexander.h.duyck@intel.com>
        Date:   Thu May 7 10:39:16 2009 +0000

            ixgbe: set queue0 for srrctl configuration correctly for DCB

After getting the 82599 going, we discovered there were some lingering
PHY issues that needed to be resolved, so these patches were added:

        commit cd7664f69fe1f3f75b664503ae3e11a2971a4865
        Author: Don Skidmore <donald.c.skidmore@intel.com>
        Date:   Tue Mar 31 21:33:44 2009 +0000

            ixgbe: feature - driver to default with FC on.

        commit aa5aec888585fedcda7cfffc20f75240ad1cb42d
        Author: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
        Date:   Tue May 19 09:18:34 2009 +0000

            ixgbe: Add semaphore access for PHY initialization for 82599

        commit 1479ad4fbfbc801898dce1ac2d4d44f0c774ecc5
        Author: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
        Date:   Thu Jun 4 11:10:17 2009 +0000

            ixgbe: Change the 82599 PHY DSP restart logic

In addition to those, there were some small backport issues that needed
to be fixed -- one NAPI issue from RHBZ 504365 and some bits that were
added incorrectly during the backport process.

I have done verification of these patches, Chris Wright has been kind
enough to test them, and Intel has signed off on them.  I expect more
testing to be done on them in the next few days and will report back if
these tests produce any failures or unexpected results.

This will resolve RHBZ 505653 and 504365.

diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 51f51e1..a3792bf 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -108,16 +108,27 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
 		if (ret_val != 0)
 			goto setup_sfp_out;
 
+		/* PHY config will finish before releasing the semaphore */
+		ret_val = ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+		if (ret_val != 0) {
+			ret_val = IXGBE_ERR_SWFW_SYNC;
+			goto setup_sfp_out;
+		}
+
 		hw->eeprom.ops.read(hw, ++data_offset, &data_value);
 		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);
 		}
-		/* Now restart DSP */
-		IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000102);
-		IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000b1d);
-		IXGBE_WRITE_FLUSH(hw);
+		/* Now restart DSP by setting Restart_AN */
+		IXGBE_WRITE_REG(hw, IXGBE_AUTOC,
+		    (IXGBE_READ_REG(hw, IXGBE_AUTOC) | IXGBE_AUTOC_AN_RESTART));
+
+		/* Release the semaphore */
+		ixgbe_release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+		/* Delay obtaining semaphore again to allow FW access */
+		msleep(hw->eeprom.semaphore_delay);
 	}
 
 setup_sfp_out:
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index cf0d60b..b073887 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -48,7 +48,7 @@ char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
                               "Intel(R) 10 Gigabit PCI Express Network Driver";
 
-#define DRV_VERSION "2.0.8-k2"
+#define DRV_VERSION "2.0.8-k3"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
 
@@ -1087,16 +1087,14 @@ static int ixgbe_clean_rxonly_many(struct net_device *netdev, int *budget)
 	/* attempt to distribute budget to each queue fairly, but don't allow
 	 * the budget to go below 1 because we'll exit polling */
 	work_to_do /= (q_vector->rxr_count ?: 1);
-	work_to_do = max(*budget, 1);
+	work_to_do = max(work_to_do, 1);
 	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
 
-	/* Keep link state information with original netdev */
-	if (!netif_carrier_ok(adapter->netdev))
-		goto quit_polling;
-
 	for (i = 0; i < q_vector->rxr_count; i++) {
 		rx_ring = &(adapter->rx_ring[r_idx]);
-		ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, work_to_do);
+		/* only clean ring if netdev is linked up */
+		if (netif_carrier_ok(adapter->netdev))
+			ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, work_to_do);
 		enable_mask |= rx_ring->v_idx;
 		r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
 		                      r_idx + 1);
@@ -1109,7 +1107,6 @@ static int ixgbe_clean_rxonly_many(struct net_device *netdev, int *budget)
 	rx_ring = &(adapter->rx_ring[r_idx]);
 	/* If all Rx work done, exit the polling mode */
 	if ((work_done < work_to_do) || !netif_running(adapter->netdev)) {
-quit_polling:
 		netif_rx_complete(netdev);
 		if (adapter->itr_setting & 1)
 			ixgbe_set_itr_msix(q_vector);
@@ -1566,7 +1563,62 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
 	}
 }
 
-#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
+#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT	2
+
+static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
+{
+	struct ixgbe_ring *rx_ring;
+	u32 srrctl;
+	int queue0 = 0;
+	unsigned long mask;
+
+	if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+		if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+			int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
+			if (dcb_i == 8)
+				queue0 = index >> 4;
+			else if (dcb_i == 4)
+				queue0 = index >> 5;
+			else
+				dev_err(&adapter->pdev->dev, "Invalid DCB "
+				        "configuration\n");
+		} else {
+			queue0 = index;
+		}
+	} else {
+		mask = (unsigned long) adapter->ring_feature[RING_F_RSS].mask;
+		queue0 = index & mask;
+		index = index & mask;
+	}
+
+	rx_ring = &adapter->rx_ring[queue0];
+
+	srrctl = IXGBE_READ_REG(&adapter->hw, IXGBE_SRRCTL(index));
+
+	srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
+	srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
+
+	srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
+		  IXGBE_SRRCTL_BSIZEHDR_MASK;
+
+	if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+#if (PAGE_SIZE / 2) > IXGBE_MAX_RXBUFFER
+		srrctl |= IXGBE_MAX_RXBUFFER >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#else
+		srrctl |= (PAGE_SIZE / 2) >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#endif
+		srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
+	} else {
+		srrctl |= ALIGN(rx_ring->rx_buf_len, 1024) >>
+			  IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+		srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
+	}
+
+	IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
+}
+
+#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
+			(((S) & (PAGE_SIZE - 1)) ? 1 : 0))
 
 /**
  * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
@@ -1586,7 +1638,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
 	                  0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE,
 	                  0x6A3E67EA, 0x14364D17, 0x3BED200D};
 	u32 fctrl, hlreg0;
-	u32 reta = 0, mrqc = 0, srrctl = 0;
+	u32 reta = 0, mrqc = 0;
 	u32 rdrxctl;
 	int rx_buf_len;
 
@@ -1624,34 +1676,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
 		hlreg0 |= IXGBE_HLREG0_JUMBOEN;
 	IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
 
-	srrctl = IXGBE_READ_REG(&adapter->hw, IXGBE_SRRCTL(0));
-	srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
-	srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
-
-	if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
-		u16 bufsz = IXGBE_RXBUFFER_2048;
-		/* grow the amount we can receive on large page machines */
-		if (bufsz < (PAGE_SIZE / 2))
-			bufsz = (PAGE_SIZE / 2);
-		/* cap the bufsz at our largest descriptor size */
-		bufsz = min((u16)IXGBE_MAX_RXBUFFER, bufsz);
-		srrctl |= bufsz >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
-		srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
-		srrctl |= ((IXGBE_RX_HDR_SIZE <<
-			    IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
-			   IXGBE_SRRCTL_BSIZEHDR_MASK);
-	} else {
-		srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
-
-		if (rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE)
-			srrctl |=
-			     IXGBE_RXBUFFER_2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
-		else
-			srrctl |= rx_buf_len >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
-	}
-
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(0), srrctl);
-
 	rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc);
 	/* disable receives while setting up the descriptors */
 	rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
@@ -1670,6 +1694,27 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
 		adapter->rx_ring[i].head = IXGBE_RDH(j);
 		adapter->rx_ring[i].tail = IXGBE_RDT(j);
 		adapter->rx_ring[i].rx_buf_len = rx_buf_len;
+
+		ixgbe_configure_srrctl(adapter, j);
+	}
+
+	if (hw->mac.type == ixgbe_mac_82598EB) {
+		/*
+		 * For VMDq support of different descriptor types or
+		 * buffer sizes through the use of multiple SRRCTL
+		 * registers, RDRXCTL.MVMEN must be set to 1
+		 *
+		 * also, the manual doesn't mention it clearly but DCA hints
+		 * will only use queue 0's tags unless this bit is set.  Side
+		 * effects of setting this bit are only that SRRCTL must be
+		 * fully programmed [0..15]
+		 */
+		if (adapter->flags &
+		    (IXGBE_FLAG_RSS_ENABLED | IXGBE_FLAG_VMDQ_ENABLED)) {
+			rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+			rdrxctl |= IXGBE_RDRXCTL_MVMEN;
+			IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
+		}
 	}
 
 	/* Program MRQC for the distribution of queues */
@@ -2848,7 +2893,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
 		adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599;
 
 	/* default flow control settings */
-	hw->fc.requested_mode = ixgbe_fc_none;
+	hw->fc.requested_mode = ixgbe_fc_full;
 	hw->fc.high_water = IXGBE_DEFAULT_FCRTH;
 	hw->fc.low_water = IXGBE_DEFAULT_FCRTL;
 	hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
@@ -3098,8 +3143,8 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 
-	if ((max_frame < (ETH_ZLEN + ETH_FCS_LEN)) ||
-	    (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE))
+	/* MTU < 68 is an error and causes problems on some kernels */
+	if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE))
 		return -EINVAL;
 
 	DPRINTK(PROBE, INFO, "changing MTU from %d to %d\n",
@@ -3247,10 +3292,10 @@ void ixgbe_napi_del_all(struct ixgbe_adapter *adapter)
 
 	for (q_idx = 0; q_idx < q_vectors; q_idx++) {
 		struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
-#if 0 /* gospo: consider this */
+
 		if (!q_vector->rxr_count)
 			continue;
-#endif
+
 		free_netdev(q_vector->dummy_netdev);
 		q_vector->dummy_netdev = NULL;
 	}
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 50a9bdc..8041fc9 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -728,13 +728,11 @@
 #define IXGBE_BARCTRL_FLSIZE    0x0700
 #define IXGBE_BARCTRL_CSRSIZE   0x2000
 
-/* RSCCTL Bit Masks */
-#define IXGBE_RSCCTL_RSCEN          0x01
-#define IXGBE_RSCCTL_MAXDESC_1      0x00
+/* RDRXCTL Bit Masks */
+#define IXGBE_RDRXCTL_RDMTS_1_2     0x00000000 /* Rx Desc Min Threshold Size */
 #define IXGBE_RDRXCTL_CRCSTRIP      0x00000002 /* CRC Strip */
-#define IXGBE_RSCCTL_MAXDESC_4      0x04
-#define IXGBE_RSCCTL_MAXDESC_8      0x08
-#define IXGBE_RSCCTL_MAXDESC_16     0x0C
+#define IXGBE_RDRXCTL_DMAIDONE      0x00000008 /* DMA init cycle done */
+#define IXGBE_RDRXCTL_MVMEN         0x00000020
 #define IXGBE_RDRXCTL_AGGDIS        0x00010000 /* Aggregation disable */
 
 /* RQTC Bit Masks and Shifts */
@@ -1943,9 +1941,6 @@ enum ixgbe_fc_mode {
 	ixgbe_fc_rx_pause,
 	ixgbe_fc_tx_pause,
 	ixgbe_fc_full,
-#ifdef CONFIG_DCB
-	ixgbe_fc_pfc,
-#endif
 	ixgbe_fc_default
 };