[PATCH 03/20] sfc: SFT9001: Enable robust link training

Previous thread: [PATCH] fix memory leak in drivers/net/netxen_nic_init.c by Daniel on Thursday, January 29, 2009 - 11:55 am. (1 message)

Next thread: [BUG BISECTED] boot hangs while bringing up gianfar ethernet by Ira Snyder on Thursday, January 29, 2009 - 12:41 pm. (12 messages)
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:12 pm

Please take the following changes for 2.6.29.

The changes are made up of:
- Bug fixes based on internal QA for version 2.3
- Addition of one new PHY and board
- A small feature addition for the SFT9001 (which is itself new for .29)

Ben.

Ben Hutchings (14):
  sfc: SFT9001: Include non-breaking cable diagnostics in online
    self-tests
  sfc: Fix test for MDIO read failure
  sfc: SFT9001/SFN4111T: Check PHY boot status during board
    initialisation
  sfc: SFN4111T: Fix GPIO sharing between I2C and FLASH_CFG_1
  sfc: Update board info for hardware monitor on SFN4111T-R5 and later
  sfc: SFT9001: Always enable XNP exchange on SFT9001 rev B
  sfc: SFX7101/SFT9001: Fix AN advertisements
  sfc: Remove "XFP" from log messages that are not specific to XFP
  sfc: Fix reporting of PHY id
  sfc: Add support for QT2025C PHY
  sfc: Delete unused efx_blinker::led_num field
  sfc: Clean up LED control
  sfc: Add support for SFN4112F SFP+ reference design
  sfc: Replace stats_enabled flag with a disable count

Steve Hodgson (6):
  sfc: SFT9001: Enable robust link training
  sfc: SFX7101: Remove workaround for bad link training
  sfc: SFT9001: Fix speed reporting in 1G PHY loopback
  sfc: Fix post-reset MAC selection
  sfc: Reinitialise the PHY completely in case of a PHY or NIC reset
  sfc: Test for PHYXS faults whenever we cannot test link state bits
	
-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:15 pm

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/tenxpress.c |   45 ++++++++++++++++++++++--------------------
 1 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 9ecb77d..9f5c8b8 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -708,12 +708,10 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
 {
 	struct ethtool_cmd ecmd;
 	int phy_id = efx->mii.phy_id;
-	int rc = 0, rc2, i, res_reg;
+	int rc = 0, rc2, i, ctrl_reg, res_reg;
 
-	if (!(flags & ETH_TEST_FL_OFFLINE))
-		return 0;
-
-	efx->phy_op->get_settings(efx, &ecmd);
+	if (flags & ETH_TEST_FL_OFFLINE)
+		efx->phy_op->get_settings(efx, &ecmd);
 
 	/* Initialise cable diagnostic results to unknown failure */
 	for (i = 1; i < 9; ++i)
@@ -721,18 +719,22 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
 
 	/* Run cable diagnostics; wait up to 5 seconds for them to complete.
 	 * A cable fault is not a self-test failure, but a timeout is. */
+	ctrl_reg = ((1 << CDIAG_CTRL_IMMED_LBN) |
+		    (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
+	if (flags & ETH_TEST_FL_OFFLINE) {
+		/* Break the link in order to run full diagnostics.  We
+		 * must reset the PHY to resume normal service. */
+		ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN);
+	}
 	mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-			    PMA_PMD_CDIAG_CTRL_REG,
-			    (1 << CDIAG_CTRL_IMMED_LBN) |
-			    (1 << CDIAG_CTRL_BRK_LINK_LBN) |
-			    (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
+			    PMA_PMD_CDIAG_CTRL_REG, ctrl_reg);
 	i = 0;
 	while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
 				  PMA_PMD_CDIAG_CTRL_REG) &
 	       (1 << CDIAG_CTRL_IN_PROG_LBN)) {
 		if (++i == 50) {
 			rc = -ETIMEDOUT;
-			goto reset;
+			goto out;
 		}
 		msleep(100);
 	}
@@ -757,17 +759,18 @@ static int sft9001_run_tests(struct efx_nic *efx, int ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:16 pm

Commit 27dd2caca4eabe7c13a052b7456495ba75535e6a changed
mdio_clause45_check_mmds() to read both DEVS0 and DEVS1 registers and
to combine their values into an unsigned 32-bit mask.  This made the
following test for a negative (failure) value useless.  Fix it to
check whether either read failed.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/mdio_10g.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index f6a1642..4d54010 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -124,24 +124,25 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
 int mdio_clause45_check_mmds(struct efx_nic *efx,
 			     unsigned int mmd_mask, unsigned int fatal_mask)
 {
+	int mmd = 0, probe_mmd, devs0, devs1;
 	u32 devices;
-	int mmd = 0, probe_mmd;
 
 	/* Historically we have probed the PHYXS to find out what devices are
 	 * present,but that doesn't work so well if the PHYXS isn't expected
 	 * to exist, if so just find the first item in the list supplied. */
 	probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
 	    __ffs(mmd_mask);
-	devices = (mdio_clause45_read(efx, efx->mii.phy_id,
-				      probe_mmd, MDIO_MMDREG_DEVS0) |
-		   mdio_clause45_read(efx, efx->mii.phy_id,
-				      probe_mmd, MDIO_MMDREG_DEVS1) << 16);
 
 	/* Check all the expected MMDs are present */
-	if (devices < 0) {
+	devs0 = mdio_clause45_read(efx, efx->mii.phy_id,
+				   probe_mmd, MDIO_MMDREG_DEVS0);
+	devs1 = mdio_clause45_read(efx, efx->mii.phy_id,
+				   probe_mmd, MDIO_MMDREG_DEVS1);
+	if (devs0 < 0 || devs1 < 0) {
 		EFX_ERR(efx, "failed to read devices present\n");
 		return -EIO;
 	}
+	devices = devs0 | (devs1 << 16);
 	if ((devices & mmd_mask) != mmd_mask) {
 		EFX_ERR(efx, "required MMDs not present: got %x, "
 			"wanted %x\n", devices, mmd_mask);

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:17 pm

Enable a firmware option that appears to be necessary for reliable
operation.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/tenxpress.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 9f5c8b8..0744404 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -67,6 +67,8 @@
 #define PMA_PMD_EXT_CLK312_WIDTH 1
 #define PMA_PMD_EXT_LPOWER_LBN  12
 #define PMA_PMD_EXT_LPOWER_WIDTH 1
+#define PMA_PMD_EXT_ROBUST_LBN	14
+#define PMA_PMD_EXT_ROBUST_WIDTH 1
 #define PMA_PMD_EXT_SSR_LBN	15
 #define PMA_PMD_EXT_SSR_WIDTH	1
 
@@ -284,7 +286,9 @@ static int tenxpress_init(struct efx_nic *efx)
 					 PMA_PMD_XCONTROL_REG);
 		reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) |
 			(1 << PMA_PMD_EXT_CLK_OUT_LBN) |
-			(1 << PMA_PMD_EXT_CLK312_LBN));
+			(1 << PMA_PMD_EXT_CLK312_LBN) |
+			(1 << PMA_PMD_EXT_ROBUST_LBN));
+
 		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
 				    PMA_PMD_XCONTROL_REG, reg);
 		mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:23 pm

Should actually be attributed as:
From: Steve Hodgson <shodgson@solarflare.com>

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:17 pm

Early versions of the SFX7101 firmware could complete link training in
a state where it would not adequately cancel noise (Solarflare bug
10750).  We previously worked around this by resetting the PHY after
seeing many Ethernet CRC errors.  This workaround is unsafe since it
takes no account of the interval between errors; it also appears to
be unnecessary with production firmware.  Therefore remove it.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/falcon.c      |    4 ----
 drivers/net/sfc/phy.h         |    1 -
 drivers/net/sfc/tenxpress.c   |   20 --------------------
 drivers/net/sfc/workarounds.h |    3 ---
 4 files changed, 0 insertions(+), 28 deletions(-)

diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 5b9f2d9..ae7b0b4 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -824,10 +824,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
 			    rx_ev_pause_frm ? " [PAUSE]" : "");
 	}
 #endif
-
-	if (unlikely(rx_ev_eth_crc_err && EFX_WORKAROUND_10750(efx) &&
-		     efx->phy_type == PHY_TYPE_SFX7101))
-		tenxpress_crc_err(efx);
 }
 
 /* Handle receive events that are not in-order. */
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index 58c493e..07e855c 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -17,7 +17,6 @@ extern struct efx_phy_operations falcon_sfx7101_phy_ops;
 extern struct efx_phy_operations falcon_sft9001_phy_ops;
 
 extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
-extern void tenxpress_crc_err(struct efx_nic *efx);
 
 /****************************************************************************
  * Exported functions from the driver for XFP optical PHYs
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 0744404..e6fa5c8 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -189,25 +189,12 @@
  * rails */
 #define LNPGA_PDOWN_WAIT	(HZ / 5)
 
-static int ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:23 pm

Should actually be attributed as:
From: Steve Hodgson <shodgson@solarflare.com>

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:17 pm

During SFN4111T initialisation, check whether the PHY boot status
indicates a bad firmware checksum.  If so, prepare to reflash rather
than continuing with normal initialisation.

Remove redundant PHY boot status check from tenxpress_phy_init().

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/phy.h       |    4 ++
 drivers/net/sfc/sfe4001.c   |   14 +++++--
 drivers/net/sfc/tenxpress.c |   90 ++++++++++++++++++++++++++-----------------
 3 files changed, 69 insertions(+), 39 deletions(-)

diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index 07e855c..f6e4722 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -18,6 +18,10 @@ extern struct efx_phy_operations falcon_sft9001_phy_ops;
 
 extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
 
+/* Wait for the PHY to boot. Return 0 on success, -EINVAL if the PHY failed
+ * to boot due to corrupt flash, or some other negative error code. */
+extern int sft9001_wait_boot(struct efx_nic *efx);
+
 /****************************************************************************
  * Exported functions from the driver for XFP optical PHYs
  */
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 16b80ac..2e9b4b4 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -379,6 +379,7 @@ static struct i2c_board_info sfn4111t_hwmon_info = {
 
 int sfn4111t_init(struct efx_nic *efx)
 {
+	int i = 0;
 	int rc;
 
 	efx->board_info.hwmon_client =
@@ -394,11 +395,16 @@ int sfn4111t_init(struct efx_nic *efx)
 	if (rc)
 		goto fail_hwmon;
 
-	if (efx->phy_mode & PHY_MODE_SPECIAL)
-		sfn4111t_reset(efx);
-
-	return 0;
+	do {
+		if (efx->phy_mode & PHY_MODE_SPECIAL)
+			sfn4111t_reset(efx);
+		rc = sft9001_wait_boot(efx);
+		if (rc == 0)
+			return 0;
+		efx->phy_mode = PHY_MODE_SPECIAL;
+	} while (rc == -EINVAL && ++i < 2);
 
+	device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
 fail_hwmon:
 ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:17 pm

Instead of disabling AN in loopback, just prevent restarting AN and
override the speed in sft9001_get_settings().

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/mdio_10g.c    |    4 ++++
 drivers/net/sfc/tenxpress.c   |   27 +++++++++------------------
 drivers/net/sfc/workarounds.h |    5 +++++
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 4d54010..3303628 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -15,6 +15,7 @@
 #include "net_driver.h"
 #include "mdio_10g.h"
 #include "boards.h"
+#include "workarounds.h"
 
 int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
 			    int spins, int spintime)
@@ -518,6 +519,9 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
 			reg |= BMCR_ANENABLE | BMCR_ANRESTART;
 		else
 			reg &= ~BMCR_ANENABLE;
+		if (EFX_WORKAROUND_15195(efx)
+		    && LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
+			reg &= ~BMCR_ANRESTART;
 		if (xnp)
 			reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
 		else
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 9e0b755..ec3e38b 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -531,7 +531,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
 {
 	struct tenxpress_phy_data *phy_data = efx->phy_data;
 	struct ethtool_cmd ecmd;
-	bool phy_mode_change, loop_reset, loop_toggle, loopback;
+	bool phy_mode_change, loop_reset;
 
 	if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
 		phy_data->phy_mode = efx->phy_mode;
@@ -542,12 +542,10 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
 
 	phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
 			   phy_data->phy_mode != PHY_MODE_NORMAL);
-	loopback = LOOPBACK_MASK(efx) & efx->phy_op->loopbacks;
-	loop_toggle = LOOPBACK_CHANGED(phy_data, efx, efx->phy_op->loopbacks);
 	loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:18 pm

Change sfn4111t_reset() to change only GPIO output enables so that it
doesn't break subsequent I2C operations.

Update comments to explain exactly what we're doing.

Add a short sleep to make sure the FLASH_CFG_1 value is latched before
any subsequent I2C operations.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/sfe4001.c |   15 +++++++++------
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 2e9b4b4..95bb935 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -186,19 +186,22 @@ static int sfn4111t_reset(struct efx_nic *efx)
 {
 	efx_oword_t reg;
 
-	/* GPIO pins are also used for I2C, so block that temporarily */
+	/* GPIO 3 and the GPIO register are shared with I2C, so block that */
 	mutex_lock(&efx->i2c_adap.bus_lock);
 
+	/* Pull RST_N (GPIO 2) low then let it up again, setting the
+	 * FLASH_CFG_1 strap (GPIO 3) appropriately.  Only change the
+	 * output enables; the output levels should always be 0 (low)
+	 * and we rely on external pull-ups. */
 	falcon_read(efx, &reg, GPIO_CTL_REG_KER);
 	EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true);
-	EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, false);
 	falcon_write(efx, &reg, GPIO_CTL_REG_KER);
 	msleep(1000);
-	EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, true);
-	EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, true);
-	EFX_SET_OWORD_FIELD(reg, GPIO3_OUT,
-			    !(efx->phy_mode & PHY_MODE_SPECIAL));
+	EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, false);
+	EFX_SET_OWORD_FIELD(reg, GPIO3_OEN,
+			    !!(efx->phy_mode & PHY_MODE_SPECIAL));
 	falcon_write(efx, &reg, GPIO_CTL_REG_KER);
+	msleep(1);
 
 	mutex_unlock(&efx->i2c_adap.bus_lock);
 

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:19 pm

From: Steve Hodgson <shodgson@solarflare.com>

Modify falcon_switch_mac() to always set NIC_STAT_REG, even if the the
MAC is the same as it was before.  This ensures that the value is
correct after an online reset.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/falcon.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index ae7b0b4..d9412f8 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -2283,16 +2283,12 @@ int falcon_switch_mac(struct efx_nic *efx)
 		efx->link_fd = true;
 	}
 
+	WARN_ON(!mutex_is_locked(&efx->mac_lock));
 	efx->mac_op = (EFX_IS10G(efx) ?
 		       &falcon_xmac_operations : &falcon_gmac_operations);
-	if (old_mac_op == efx->mac_op)
-		return 0;
-
-	WARN_ON(!mutex_is_locked(&efx->mac_lock));
-
-	/* Not all macs support a mac-level link state */
-	efx->mac_up = true;
 
+	/* Always push the NIC_STAT_REG setting even if the mac hasn't
+	 * changed, because this function is run post online reset */
 	falcon_read(efx, &nic_stat, NIC_STAT_REG);
 	strap_val = EFX_IS10G(efx) ? 5 : 3;
 	if (falcon_rev(efx) >= FALCON_REV_B0) {
@@ -2305,8 +2301,13 @@ int falcon_switch_mac(struct efx_nic *efx)
 		BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val);
 	}
 
+	if (old_mac_op == efx->mac_op)
+		return 0;
 
 	EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G');
+	/* Not all macs support a mac-level link state */
+	efx->mac_up = true;
+
 	return falcon_reset_macs(efx);
 }
 

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:19 pm

From: Steve Hodgson <shodgson@solarflare.com>

In particular, set pause advertising bits properly.

A PHY reset is not necessary to recover from the register self-test,
so use a "invisible" reset there instead.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/efx.c       |   26 +++++++++++++++++++-------
 drivers/net/sfc/efx.h       |    7 ++++---
 drivers/net/sfc/selftest.c  |    7 ++++---
 drivers/net/sfc/tenxpress.c |    1 +
 4 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 7673fd9..b0e5308 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -676,9 +676,8 @@ static int efx_init_port(struct efx_nic *efx)
 	rc = efx->phy_op->init(efx);
 	if (rc)
 		return rc;
-	efx->phy_op->reconfigure(efx);
-
 	mutex_lock(&efx->mac_lock);
+	efx->phy_op->reconfigure(efx);
 	rc = falcon_switch_mac(efx);
 	mutex_unlock(&efx->mac_lock);
 	if (rc)
@@ -1622,7 +1621,8 @@ static void efx_unregister_netdev(struct efx_nic *efx)
 
 /* Tears down the entire software state and most of the hardware state
  * before reset.  */
-void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+void efx_reset_down(struct efx_nic *efx, enum reset_type method,
+		    struct ethtool_cmd *ecmd)
 {
 	EFX_ASSERT_RESET_SERIALISED(efx);
 
@@ -1639,6 +1639,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 	efx->phy_op->get_settings(efx, ecmd);
 
 	efx_fini_channels(efx);
+	if (efx->port_initialized && method != RESET_TYPE_INVISIBLE)
+		efx->phy_op->fini(efx);
 }
 
 /* This function will always ensure that the locks acquired in
@@ -1646,7 +1648,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
  * that we were unable to reinitialise the hardware, and the
  * driver should be disabled. If ok is false, then the rx and tx
  * engines are not restarted, pending a RESET_DISABLE. */
-int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:19 pm

From: Steve Hodgson <shodgson@solarflare.com>

Depending on the loopback mode, there may be no pertinent link state
bits.  In this case we test the PHYXS RX fault bit instead.  Make
sure to do this in all cases where there are no link state bits.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/mdio_10g.c |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 3303628..c1a6b26 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -181,17 +181,12 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
 		return false;
 	else if (efx_phy_mode_disabled(efx->phy_mode))
 		return false;
-	else if (efx->loopback_mode == LOOPBACK_PHYXS) {
+	else if (efx->loopback_mode == LOOPBACK_PHYXS)
 		mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS |
 			      MDIO_MMDREG_DEVS_PCS |
 			      MDIO_MMDREG_DEVS_PMAPMD |
 			      MDIO_MMDREG_DEVS_AN);
-		if (!mmd_mask) {
-			reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
-						 MDIO_PHYXS_STATUS2);
-			return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
-		}
-	} else if (efx->loopback_mode == LOOPBACK_PCS)
+	else if (efx->loopback_mode == LOOPBACK_PCS)
 		mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
 			      MDIO_MMDREG_DEVS_PMAPMD |
 			      MDIO_MMDREG_DEVS_AN);
@@ -199,6 +194,13 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
 		mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD |
 			      MDIO_MMDREG_DEVS_AN);
 
+	if (!mmd_mask) {
+		/* Use presence of XGMII faults in leui of link state */
+		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
+					 MDIO_PHYXS_STATUS2);
+		return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
+	}
+
 	while (mmd_mask) {
 		if (mmd_mask & 1) {
 			/* Double reads because link state is latched, and a

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:19 pm

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/sfe4001.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 95bb935..25037c7 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -375,18 +375,26 @@ static void sfn4111t_fini(struct efx_nic *efx)
 	i2c_unregister_device(efx->board_info.hwmon_client);
 }
 
-static struct i2c_board_info sfn4111t_hwmon_info = {
+static struct i2c_board_info sfn4111t_a0_hwmon_info = {
 	I2C_BOARD_INFO("max6647", 0x4e),
 	.irq		= -1,
 };
 
+static struct i2c_board_info sfn4111t_r5_hwmon_info = {
+	I2C_BOARD_INFO("max6646", 0x4d),
+	.irq		= -1,
+};
+
 int sfn4111t_init(struct efx_nic *efx)
 {
 	int i = 0;
 	int rc;
 
 	efx->board_info.hwmon_client =
-		i2c_new_device(&efx->i2c_adap, &sfn4111t_hwmon_info);
+		i2c_new_device(&efx->i2c_adap,
+			       (efx->board_info.minor < 5) ?
+			       &sfn4111t_a0_hwmon_info :
+			       &sfn4111t_r5_hwmon_info);
 	if (!efx->board_info.hwmon_client)
 		return -EIO;
 

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:20 pm

This workaround is not specific to rev A.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/workarounds.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 420fe15..b810dcd 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -54,7 +54,7 @@
 #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A
 
 /* Need to send XNP pages for 100BaseT */
-#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001A
+#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001
 /* Need to keep AN enabled */
 #define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A
 

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:20 pm

All 10Xpress PHYs require autonegotiation all the time; enforce this
in the set_settings() method and do not treat it as a workaround.

Remove claimed support for 100M HD mode since it is not supported by
current firmware.

Do not set speed override bits when AN is enabled, and do not use
register 1.49192 for AN configuration as it can override what we set
elsewhere.

Always set the AN selector bits to 1 (802.3).

Fix confusion between Next Page and Extended Next Page.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/ethtool.c     |    3 -
 drivers/net/sfc/mdio_10g.c    |  177 ++++++++++++++++++-----------------------
 drivers/net/sfc/mdio_10g.h    |    3 +-
 drivers/net/sfc/net_driver.h  |    4 +-
 drivers/net/sfc/tenxpress.c   |  151 +++++++++++++---------------------
 drivers/net/sfc/workarounds.h |    4 -
 6 files changed, 141 insertions(+), 201 deletions(-)

diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 53d259e..7b5924c 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -219,9 +219,6 @@ int efx_ethtool_set_settings(struct net_device *net_dev,
 	struct efx_nic *efx = netdev_priv(net_dev);
 	int rc;
 
-	if (EFX_WORKAROUND_13963(efx) && !ecmd->autoneg)
-		return -EINVAL;
-
 	/* Falcon GMAC does not support 1000Mbps HD */
 	if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) {
 		EFX_LOG(efx, "rejecting unsupported 1000Mbps HD"
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index c1a6b26..4462fb5 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -267,7 +267,7 @@ void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
 	}
 }
 
-static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp)
+static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr)
 {
 	int phy_id = efx->mii.phy_id;
 	u32 result = 0;
@@ -282,9 +282,6 @@ static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp)
 		result |= ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:20 pm

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/xfp_phy.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index 2d50b6e..5d1c7f8 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -73,7 +73,7 @@ static int xfp_reset_phy(struct efx_nic *efx)
 	return rc;
 
  fail:
-	EFX_ERR(efx, "XFP: reset timed out!\n");
+	EFX_ERR(efx, "PHY reset timed out\n");
 	return rc;
 }
 
@@ -88,15 +88,15 @@ static int xfp_phy_init(struct efx_nic *efx)
 		return -ENOMEM;
 	efx->phy_data = phy_data;
 
-	EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision"
-		 " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid),
+	EFX_INFO(efx, "PHY ID reg %x (OUI %x model %x revision %x)\n",
+		 devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid),
 		 MDIO_ID_REV(devid));
 
 	phy_data->phy_mode = efx->phy_mode;
 
 	rc = xfp_reset_phy(efx);
 
-	EFX_INFO(efx, "XFP: PHY init %s.\n",
+	EFX_INFO(efx, "PHY init %s.\n",
 		 rc ? "failed" : "successful");
 	if (rc < 0)
 		goto fail;

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:20 pm

Shuffle bits of the OUI into the conventional written order.

Replace PHY id component macros with functions.

Zero-pad PHY id components in log messages.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/mdio_10g.c |   15 +++++++++++++++
 drivers/net/sfc/mdio_10g.h |    8 ++++----
 drivers/net/sfc/xfp_phy.c  |    6 +++---
 3 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 4462fb5..9f5ec3e 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -17,6 +17,21 @@
 #include "boards.h"
 #include "workarounds.h"
 
+unsigned mdio_id_oui(u32 id)
+{
+	unsigned oui = 0;
+	int i;
+
+	/* The bits of the OUI are designated a..x, with a=0 and b variable.
+	 * In the id register c is the MSB but the OUI is conventionally
+	 * written as bytes h..a, p..i, x..q.  Reorder the bits accordingly. */
+	for (i = 0; i < 22; ++i)
+		if (id & (1 << (i + 10)))
+			oui |= 1 << (i ^ 7);
+
+	return oui;
+}
+
 int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
 			    int spins, int spintime)
 {
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 8ba4977..7014d22 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -70,10 +70,10 @@
 #define MDIO_MMDREG_STAT1_LPABLE_LBN	(1)
 #define MDIO_MMDREG_STAT1_LPABLE_WIDTH	(1)
 
-/* Bits in ID reg */
-#define MDIO_ID_REV(_id32)	(_id32 & 0xf)
-#define MDIO_ID_MODEL(_id32)	((_id32 >> 4) & 0x3f)
-#define MDIO_ID_OUI(_id32)	(_id32 >> 10)
+/* Bits in combined ID regs */
+static inline unsigned mdio_id_rev(u32 id) { return id & 0xf; }
+static inline unsigned mdio_id_model(u32 id) { return (id >> 4) & 0x3f; }
+extern unsigned mdio_id_oui(u32 id);
 
 /* Bits in MMDREG_DEVS0/1. Someone thoughtfully layed things out
  * so the 'bit present' bit number of an MMD is the number of
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index 5d1c7f8..2df467d ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:21 pm

This is a new PHY supporting SFP+ modules, used in the SFN4112F
reference design.  It is similar to the QT2022C2 and shares much of
its support code.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/falcon.c     |    1 +
 drivers/net/sfc/net_driver.h |    1 +
 drivers/net/sfc/phy.h        |    4 +-
 drivers/net/sfc/xfp_phy.c    |   95 ++++++++++++++++++++++++++++++++++++++----
 4 files changed, 91 insertions(+), 10 deletions(-)

diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index d9412f8..7ad5daa 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -2249,6 +2249,7 @@ static int falcon_probe_phy(struct efx_nic *efx)
 		efx->phy_op = &falcon_sft9001_phy_ops;
 		break;
 	case PHY_TYPE_QT2022C2:
+	case PHY_TYPE_QT2025C:
 		efx->phy_op = &falcon_xfp_phy_ops;
 		break;
 	default:
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 8eb411a..39f1ff8 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -459,6 +459,7 @@ enum phy_type {
 	PHY_TYPE_QT2022C2 = 4,
 	PHY_TYPE_PM8358 = 6,
 	PHY_TYPE_SFT9001A = 8,
+	PHY_TYPE_QT2025C = 9,
 	PHY_TYPE_SFT9001B = 10,
 	PHY_TYPE_MAX	/* Insert any new items before this */
 };
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index f6e4722..c1cff9c 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -23,11 +23,11 @@ extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
 extern int sft9001_wait_boot(struct efx_nic *efx);
 
 /****************************************************************************
- * Exported functions from the driver for XFP optical PHYs
+ * AMCC/Quake QT20xx PHYs
  */
 extern struct efx_phy_operations falcon_xfp_phy_ops;
 
-/* The QUAKE XFP PHY provides various H/W control states for LEDs */
+/* These PHYs provide various H/W control states for LEDs */
 #define QUAKE_LED_LINK_INVAL	(0)
 #define QUAKE_LED_LINK_STAT	(1)
 #define QUAKE_LED_LINK_ACT	(2)
diff ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:21 pm

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/boards.c     |    1 -
 drivers/net/sfc/net_driver.h |    2 --
 2 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c
index 6490349..1260875 100644
--- a/drivers/net/sfc/boards.c
+++ b/drivers/net/sfc/boards.c
@@ -194,7 +194,6 @@ static int sfe4002_init_leds(struct efx_nic *efx)
 	xfp_set_led(efx, SFE4002_RX_LED,
 		    QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACTSTAT);
 	xfp_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF);
-	efx->board_info.blinker.led_num = SFE4002_FAULT_LED;
 	return 0;
 }
 
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 39f1ff8..1f0dc8f 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -394,13 +394,11 @@ struct efx_channel {
 
 /**
  * struct efx_blinker - S/W LED blinking context
- * @led_num: LED ID (board-specific meaning)
  * @state: Current state - on or off
  * @resubmit: Timer resubmission flag
  * @timer: Control timer for blinking
  */
 struct efx_blinker {
-	int led_num;
 	bool state;
 	bool resubmit;
 	struct timer_list timer;

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:21 pm

Reinitialise LEDs after overriding them for identification.

Rename set_fault_led method to set_id_led since we always use it for
NIC identification and not faults.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/boards.c     |   11 +++++------
 drivers/net/sfc/efx.c        |    4 ++--
 drivers/net/sfc/net_driver.h |    8 ++++----
 3 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c
index 1260875..b709878 100644
--- a/drivers/net/sfc/boards.c
+++ b/drivers/net/sfc/boards.c
@@ -26,7 +26,7 @@ static void blink_led_timer(unsigned long context)
 {
 	struct efx_nic *efx = (struct efx_nic *)context;
 	struct efx_blinker *bl = &efx->board_info.blinker;
-	efx->board_info.set_fault_led(efx, bl->state);
+	efx->board_info.set_id_led(efx, bl->state);
 	bl->state = !bl->state;
 	if (bl->resubmit)
 		mod_timer(&bl->timer, jiffies + BLINK_INTERVAL);
@@ -48,7 +48,7 @@ static void board_blink(struct efx_nic *efx, bool blink)
 		blinker->resubmit = false;
 		if (blinker->timer.function)
 			del_timer_sync(&blinker->timer);
-		efx->board_info.set_fault_led(efx, false);
+		efx->board_info.init_leds(efx);
 	}
 }
 
@@ -185,7 +185,7 @@ static struct i2c_board_info sfe4002_hwmon_info = {
 #define SFE4002_RX_LED    (0)	/* Green */
 #define SFE4002_TX_LED    (1)	/* Amber */
 
-static int sfe4002_init_leds(struct efx_nic *efx)
+static void sfe4002_init_leds(struct efx_nic *efx)
 {
 	/* Set the TX and RX LEDs to reflect status and activity, and the
 	 * fault LED off */
@@ -194,10 +194,9 @@ static int sfe4002_init_leds(struct efx_nic *efx)
 	xfp_set_led(efx, SFE4002_RX_LED,
 		    QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACTSTAT);
 	xfp_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF);
-	return 0;
 }
 
-static void sfe4002_fault_led(struct efx_nic *efx, bool state)
+static void sfe4002_set_id_led(struct efx_nic *efx, bool state)
 {
 	xfp_set_led(efx, SFE4002_FAULT_LED, state ? QUAKE_LED_ON :
 ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:21 pm

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/boards.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/sfc/boards.h |    1 +
 2 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c
index b709878..5182ac5 100644
--- a/drivers/net/sfc/boards.c
+++ b/drivers/net/sfc/boards.c
@@ -226,6 +226,66 @@ static int sfe4002_init(struct efx_nic *efx)
 	return 0;
 }
 
+/*****************************************************************************
+ * Support for the SFN4112F
+ *
+ */
+static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */
+
+static const u8 sfn4112f_lm87_regs[] = {
+	LM87_IN_LIMITS(0, 0x83, 0x91),		/* 2.5V:  1.8V +/- 5% */
+	LM87_IN_LIMITS(1, 0x51, 0x5a),		/* Vccp1: 1.2V +/- 5% */
+	LM87_IN_LIMITS(2, 0xb6, 0xca),		/* 3.3V:  3.3V +/- 5% */
+	LM87_IN_LIMITS(4, 0xb0, 0xe0),		/* 12V:   11-14V */
+	LM87_IN_LIMITS(5, 0x44, 0x4b),		/* Vccp2: 1.0V +/- 5% */
+	LM87_AIN_LIMITS(1, 0x91, 0xa1),		/* AIN2:  1.5V +/- 5% */
+	LM87_TEMP_INT_LIMITS(10, 60),		/* board */
+	LM87_TEMP_EXT1_LIMITS(10, 70),		/* Falcon */
+	0
+};
+
+static struct i2c_board_info sfn4112f_hwmon_info = {
+	I2C_BOARD_INFO("lm87", 0x2e),
+	.platform_data	= &sfn4112f_lm87_channel,
+	.irq		= -1,
+};
+
+#define SFN4112F_ACT_LED	0
+#define SFN4112F_LINK_LED	1
+
+static void sfn4112f_init_leds(struct efx_nic *efx)
+{
+	xfp_set_led(efx, SFN4112F_ACT_LED,
+		    QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACT);
+	xfp_set_led(efx, SFN4112F_LINK_LED,
+		    QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT);
+}
+
+static void sfn4112f_set_id_led(struct efx_nic *efx, bool state)
+{
+	xfp_set_led(efx, SFN4112F_LINK_LED,
+		    state ? QUAKE_LED_ON : QUAKE_LED_OFF);
+}
+
+static int sfn4112f_check_hw(struct efx_nic *efx)
+{
+	/* Mask out unused sensors */
+	return efx_check_lm87(efx, ~0x48);
+}
+
+static int sfn4112f_init(struct efx_nic *efx)
+{
+	int rc = efx_init_lm87(efx, &sfn4112f_hwmon_info, ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 12:22 pm

Currently we use a spin-lock to serialise statistics fetches and also
to inhibit them for short periods of time, plus a flag to
enable/disable statistics fetches for longer periods of time, during
online reset.  This was apparently insufficient to deal with the several
reasons for stats being disabled.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/efx.c        |   33 ++++++++++++++++++++++-----------
 drivers/net/sfc/efx.h        |    2 ++
 drivers/net/sfc/falcon.c     |   15 +++++++++++----
 drivers/net/sfc/net_driver.h |    5 ++---
 drivers/net/sfc/sfe4001.c    |   17 ++++++++++++++++-
 drivers/net/sfc/tenxpress.c  |   12 ++++++------
 6 files changed, 59 insertions(+), 25 deletions(-)

diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 7fcdd04..ec856ac 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -685,7 +685,7 @@ static int efx_init_port(struct efx_nic *efx)
 	efx->mac_op->reconfigure(efx);
 
 	efx->port_initialized = true;
-	efx->stats_enabled = true;
+	efx_stats_enable(efx);
 	return 0;
 
 fail:
@@ -734,6 +734,7 @@ static void efx_fini_port(struct efx_nic *efx)
 	if (!efx->port_initialized)
 		return;
 
+	efx_stats_disable(efx);
 	efx->phy_op->fini(efx);
 	efx->port_initialized = false;
 
@@ -1360,6 +1361,20 @@ static int efx_net_stop(struct net_device *net_dev)
 	return 0;
 }
 
+void efx_stats_disable(struct efx_nic *efx)
+{
+	spin_lock(&efx->stats_lock);
+	++efx->stats_disable_count;
+	spin_unlock(&efx->stats_lock);
+}
+
+void efx_stats_enable(struct efx_nic *efx)
+{
+	spin_lock(&efx->stats_lock);
+	--efx->stats_disable_count;
+	spin_unlock(&efx->stats_lock);
+}
+
 /* Context: process, dev_base_lock or RTNL held, non-blocking. */
 static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
 {
@@ -1368,12 +1383,12 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
 	struct net_device_stats *stats = &net_dev->stats;
 
 	/* Update stats if ...
From: David Miller
Date: Thursday, January 29, 2009 - 4:26 pm

I'm not taking a blob of 20 patches to a driver outside of the merge
window, no freakin' way.
--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 6:05 pm

Sorry about that; I should have separated them out more clearly.

1. Patches 3, 6-13 and 20 fix bugs introduced or exposed by the
   changes already accepted for .29.  I regret that I couldn't send
   these earlier but I simply didn't have near-production hardware or
   firmware to test against until the last couple of weeks.
2. Patches 16 and 19 add new hardware support without affecting the
   behaviour on old hardware.
3. Patches 14, 15, 17 and 18 are fairly trivial fixes supporting those.
4. Patches 2 and 4 fix longstanding bugs.
5. Patches 1 and 5 add features.

Please take at least the patches in group 1.  I will re-send if you
wish.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
--

From: David Miller
Date: Thursday, January 29, 2009 - 6:08 pm

From: Ben Hutchings <bhutchings@solarflare.com>

Please resend the pure bug fixes.  Thank you.
--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 8:48 pm

From: Steve Hodgson <shodgson@solarflare.com>

Enable a firmware option that appears to be necessary for reliable
operation.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/tenxpress.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 9ecb77d..19cfc31 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -67,6 +67,8 @@
 #define PMA_PMD_EXT_CLK312_WIDTH 1
 #define PMA_PMD_EXT_LPOWER_LBN  12
 #define PMA_PMD_EXT_LPOWER_WIDTH 1
+#define PMA_PMD_EXT_ROBUST_LBN	14
+#define PMA_PMD_EXT_ROBUST_WIDTH 1
 #define PMA_PMD_EXT_SSR_LBN	15
 #define PMA_PMD_EXT_SSR_WIDTH	1
 
@@ -284,7 +286,9 @@ static int tenxpress_init(struct efx_nic *efx)
 					 PMA_PMD_XCONTROL_REG);
 		reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) |
 			(1 << PMA_PMD_EXT_CLK_OUT_LBN) |
-			(1 << PMA_PMD_EXT_CLK312_LBN));
+			(1 << PMA_PMD_EXT_CLK312_LBN) |
+			(1 << PMA_PMD_EXT_ROBUST_LBN));
+
 		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
 				    PMA_PMD_XCONTROL_REG, reg);
 		mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
--

From: David Miller
Date: Friday, January 30, 2009 - 3:09 pm

From: Ben Hutchings <bhutchings@solarflare.com>

I applied all of these patches but:

1) When you get changes written by other people, such as
   Steve Hodgson here and in the next few patches, you need
   to get Signed-off-by lines from them too.

2) Outside of the merge window I do not want to see totally
   irrelevant stuff like PHY loopback fixes.

   Those kinds of fixes are totally inappropriate at this time.

You have been warned :-)
--

From: Ben Hutchings
Date: Friday, January 30, 2009 - 5:04 pm

I have been attributing changes to my colleagues for some time and never
heard this.  In any case the copyright lies with my employer and I am
authorised to release these changes; isn't that what my initial sign-


Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


--

From: David Miller
Date: Friday, January 30, 2009 - 5:02 pm

From: Ben Hutchings <bhutchings@solarflare.com>

Sure, but it is even more meaningful if the person who actually

Normal users will not run the self-test giblet, and it has
not been reported as a 2.6.29 regression on lkml.
--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 8:48 pm

From: Steve Hodgson <shodgson@solarflare.com>

Early versions of the SFX7101 firmware could complete link training in
a state where it would not adequately cancel noise (Solarflare bug
10750).  We previously worked around this by resetting the PHY after
seeing many Ethernet CRC errors.  This workaround is unsafe since it
takes no account of the interval between errors; it also appears to
be unnecessary with production firmware.  Therefore remove it.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/falcon.c      |    4 ----
 drivers/net/sfc/phy.h         |    1 -
 drivers/net/sfc/tenxpress.c   |   20 --------------------
 drivers/net/sfc/workarounds.h |    3 ---
 4 files changed, 0 insertions(+), 28 deletions(-)

diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 5b9f2d9..ae7b0b4 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -824,10 +824,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
 			    rx_ev_pause_frm ? " [PAUSE]" : "");
 	}
 #endif
-
-	if (unlikely(rx_ev_eth_crc_err && EFX_WORKAROUND_10750(efx) &&
-		     efx->phy_type == PHY_TYPE_SFX7101))
-		tenxpress_crc_err(efx);
 }
 
 /* Handle receive events that are not in-order. */
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index 58c493e..07e855c 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -17,7 +17,6 @@ extern struct efx_phy_operations falcon_sfx7101_phy_ops;
 extern struct efx_phy_operations falcon_sft9001_phy_ops;
 
 extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
-extern void tenxpress_crc_err(struct efx_nic *efx);
 
 /****************************************************************************
  * Exported functions from the driver for XFP optical PHYs
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 19cfc31..80c8d6e 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -189,25 +189,12 @@
  * rails */
 ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 8:49 pm

From: Steve Hodgson <shodgson@solarflare.com>

Instead of disabling AN in loopback, just prevent restarting AN and
override the speed in sft9001_get_settings().

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/mdio_10g.c    |    4 ++++
 drivers/net/sfc/tenxpress.c   |   27 +++++++++------------------
 drivers/net/sfc/workarounds.h |    5 +++++
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index f6a1642..7f09ab5 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -15,6 +15,7 @@
 #include "net_driver.h"
 #include "mdio_10g.h"
 #include "boards.h"
+#include "workarounds.h"
 
 int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
 			    int spins, int spintime)
@@ -517,6 +518,9 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
 			reg |= BMCR_ANENABLE | BMCR_ANRESTART;
 		else
 			reg &= ~BMCR_ANENABLE;
+		if (EFX_WORKAROUND_15195(efx)
+		    && LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
+			reg &= ~BMCR_ANRESTART;
 		if (xnp)
 			reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
 		else
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 80c8d6e..bc2833f 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -511,7 +511,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
 {
 	struct tenxpress_phy_data *phy_data = efx->phy_data;
 	struct ethtool_cmd ecmd;
-	bool phy_mode_change, loop_reset, loop_toggle, loopback;
+	bool phy_mode_change, loop_reset;
 
 	if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
 		phy_data->phy_mode = efx->phy_mode;
@@ -522,12 +522,10 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
 
 	phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
 			   phy_data->phy_mode != PHY_MODE_NORMAL);
-	loopback = LOOPBACK_MASK(efx) & efx->phy_op->loopbacks;
-	loop_toggle = LOOPBACK_CHANGED(phy_data, efx, efx->phy_op->loopbacks);
 	loop_reset = ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 8:49 pm

Change sfn4111t_reset() to change only GPIO output enables so that it
doesn't break subsequent I2C operations.

Update comments to explain exactly what we're doing.

Add a short sleep to make sure the FLASH_CFG_1 value is latched before
any subsequent I2C operations.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/sfe4001.c |   15 +++++++++------
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 16b80ac..c7c95db 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -186,19 +186,22 @@ static int sfn4111t_reset(struct efx_nic *efx)
 {
 	efx_oword_t reg;
 
-	/* GPIO pins are also used for I2C, so block that temporarily */
+	/* GPIO 3 and the GPIO register are shared with I2C, so block that */
 	mutex_lock(&efx->i2c_adap.bus_lock);
 
+	/* Pull RST_N (GPIO 2) low then let it up again, setting the
+	 * FLASH_CFG_1 strap (GPIO 3) appropriately.  Only change the
+	 * output enables; the output levels should always be 0 (low)
+	 * and we rely on external pull-ups. */
 	falcon_read(efx, &reg, GPIO_CTL_REG_KER);
 	EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true);
-	EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, false);
 	falcon_write(efx, &reg, GPIO_CTL_REG_KER);
 	msleep(1000);
-	EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, true);
-	EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, true);
-	EFX_SET_OWORD_FIELD(reg, GPIO3_OUT,
-			    !(efx->phy_mode & PHY_MODE_SPECIAL));
+	EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, false);
+	EFX_SET_OWORD_FIELD(reg, GPIO3_OEN,
+			    !!(efx->phy_mode & PHY_MODE_SPECIAL));
 	falcon_write(efx, &reg, GPIO_CTL_REG_KER);
+	msleep(1);
 
 	mutex_unlock(&efx->i2c_adap.bus_lock);
 

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 8:49 pm

From: Steve Hodgson <shodgson@solarflare.com>

Modify falcon_switch_mac() to always set NIC_STAT_REG, even if the the
MAC is the same as it was before.  This ensures that the value is
correct after an online reset.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/falcon.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index ae7b0b4..d9412f8 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -2283,16 +2283,12 @@ int falcon_switch_mac(struct efx_nic *efx)
 		efx->link_fd = true;
 	}
 
+	WARN_ON(!mutex_is_locked(&efx->mac_lock));
 	efx->mac_op = (EFX_IS10G(efx) ?
 		       &falcon_xmac_operations : &falcon_gmac_operations);
-	if (old_mac_op == efx->mac_op)
-		return 0;
-
-	WARN_ON(!mutex_is_locked(&efx->mac_lock));
-
-	/* Not all macs support a mac-level link state */
-	efx->mac_up = true;
 
+	/* Always push the NIC_STAT_REG setting even if the mac hasn't
+	 * changed, because this function is run post online reset */
 	falcon_read(efx, &nic_stat, NIC_STAT_REG);
 	strap_val = EFX_IS10G(efx) ? 5 : 3;
 	if (falcon_rev(efx) >= FALCON_REV_B0) {
@@ -2305,8 +2301,13 @@ int falcon_switch_mac(struct efx_nic *efx)
 		BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val);
 	}
 
+	if (old_mac_op == efx->mac_op)
+		return 0;
 
 	EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G');
+	/* Not all macs support a mac-level link state */
+	efx->mac_up = true;
+
 	return falcon_reset_macs(efx);
 }
 

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 8:51 pm

From: Steve Hodgson <shodgson@solarflare.com>

Depending on the loopback mode, there may be no pertinent link state
bits.  In this case we test the PHYXS RX fault bit instead.  Make
sure to do this in all cases where there are no link state bits.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/mdio_10g.c |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 7f09ab5..16bc585 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -180,17 +180,12 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
 		return false;
 	else if (efx_phy_mode_disabled(efx->phy_mode))
 		return false;
-	else if (efx->loopback_mode == LOOPBACK_PHYXS) {
+	else if (efx->loopback_mode == LOOPBACK_PHYXS)
 		mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS |
 			      MDIO_MMDREG_DEVS_PCS |
 			      MDIO_MMDREG_DEVS_PMAPMD |
 			      MDIO_MMDREG_DEVS_AN);
-		if (!mmd_mask) {
-			reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
-						 MDIO_PHYXS_STATUS2);
-			return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
-		}
-	} else if (efx->loopback_mode == LOOPBACK_PCS)
+	else if (efx->loopback_mode == LOOPBACK_PCS)
 		mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
 			      MDIO_MMDREG_DEVS_PMAPMD |
 			      MDIO_MMDREG_DEVS_AN);
@@ -198,6 +193,13 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
 		mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD |
 			      MDIO_MMDREG_DEVS_AN);
 
+	if (!mmd_mask) {
+		/* Use presence of XGMII faults in leui of link state */
+		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
+					 MDIO_PHYXS_STATUS2);
+		return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
+	}
+
 	while (mmd_mask) {
 		if (mmd_mask & 1) {
 			/* Double reads because link state is latched, and a

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 8:50 pm

From: Steve Hodgson <shodgson@solarflare.com>

In particular, set pause advertising bits properly.

A PHY reset is not necessary to recover from the register self-test,
so use a "invisible" reset there instead.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/efx.c       |   26 +++++++++++++++++++-------
 drivers/net/sfc/efx.h       |    7 ++++---
 drivers/net/sfc/selftest.c  |    7 ++++---
 drivers/net/sfc/tenxpress.c |    1 +
 4 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 7673fd9..b0e5308 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -676,9 +676,8 @@ static int efx_init_port(struct efx_nic *efx)
 	rc = efx->phy_op->init(efx);
 	if (rc)
 		return rc;
-	efx->phy_op->reconfigure(efx);
-
 	mutex_lock(&efx->mac_lock);
+	efx->phy_op->reconfigure(efx);
 	rc = falcon_switch_mac(efx);
 	mutex_unlock(&efx->mac_lock);
 	if (rc)
@@ -1622,7 +1621,8 @@ static void efx_unregister_netdev(struct efx_nic *efx)
 
 /* Tears down the entire software state and most of the hardware state
  * before reset.  */
-void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+void efx_reset_down(struct efx_nic *efx, enum reset_type method,
+		    struct ethtool_cmd *ecmd)
 {
 	EFX_ASSERT_RESET_SERIALISED(efx);
 
@@ -1639,6 +1639,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 	efx->phy_op->get_settings(efx, ecmd);
 
 	efx_fini_channels(efx);
+	if (efx->port_initialized && method != RESET_TYPE_INVISIBLE)
+		efx->phy_op->fini(efx);
 }
 
 /* This function will always ensure that the locks acquired in
@@ -1646,7 +1648,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
  * that we were unable to reinitialise the hardware, and the
  * driver should be disabled. If ok is false, then the rx and tx
  * engines are not restarted, pending a RESET_DISABLE. */
-int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 8:51 pm

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/sfe4001.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index c7c95db..853057e 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -375,17 +375,25 @@ static void sfn4111t_fini(struct efx_nic *efx)
 	i2c_unregister_device(efx->board_info.hwmon_client);
 }
 
-static struct i2c_board_info sfn4111t_hwmon_info = {
+static struct i2c_board_info sfn4111t_a0_hwmon_info = {
 	I2C_BOARD_INFO("max6647", 0x4e),
 	.irq		= -1,
 };
 
+static struct i2c_board_info sfn4111t_r5_hwmon_info = {
+	I2C_BOARD_INFO("max6646", 0x4d),
+	.irq		= -1,
+};
+
 int sfn4111t_init(struct efx_nic *efx)
 {
 	int rc;
 
 	efx->board_info.hwmon_client =
-		i2c_new_device(&efx->i2c_adap, &sfn4111t_hwmon_info);
+		i2c_new_device(&efx->i2c_adap,
+			       (efx->board_info.minor < 5) ?
+			       &sfn4111t_a0_hwmon_info :
+			       &sfn4111t_r5_hwmon_info);
 	if (!efx->board_info.hwmon_client)
 		return -EIO;
 

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 8:52 pm

This workaround is not specific to rev A.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/workarounds.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 420fe15..b810dcd 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -54,7 +54,7 @@
 #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A
 
 /* Need to send XNP pages for 100BaseT */
-#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001A
+#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001
 /* Need to keep AN enabled */
 #define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A
 

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
--

From: Ben Hutchings
Date: Thursday, January 29, 2009 - 8:59 pm

All 10Xpress PHYs require autonegotiation all the time; enforce this
in the set_settings() method and do not treat it as a workaround.

Remove claimed support for 100M HD mode since it is not supported by
current firmware.

Do not set speed override bits when AN is enabled, and do not use
register 1.49192 for AN configuration as it can override what we set
elsewhere.

Always set the AN selector bits to 1 (802.3).

Fix confusion between Next Page and Extended Next Page.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
Sorry this is so large, but my original auto-negotiation support
code was fairly wrong-headed and does require all these changes to
work correctly.

Ben.

 drivers/net/sfc/ethtool.c     |    3 -
 drivers/net/sfc/mdio_10g.c    |  177 ++++++++++++++++++-----------------------
 drivers/net/sfc/mdio_10g.h    |    3 +-
 drivers/net/sfc/net_driver.h  |    4 +-
 drivers/net/sfc/tenxpress.c   |  151 +++++++++++++---------------------
 drivers/net/sfc/workarounds.h |    4 -
 6 files changed, 141 insertions(+), 201 deletions(-)

diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 53d259e..7b5924c 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -219,9 +219,6 @@ int efx_ethtool_set_settings(struct net_device *net_dev,
 	struct efx_nic *efx = netdev_priv(net_dev);
 	int rc;
 
-	if (EFX_WORKAROUND_13963(efx) && !ecmd->autoneg)
-		return -EINVAL;
-
 	/* Falcon GMAC does not support 1000Mbps HD */
 	if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) {
 		EFX_LOG(efx, "rejecting unsupported 1000Mbps HD"
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 16bc585..f9e2f95 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -266,7 +266,7 @@ void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
 	}
 }
 
-static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp)
+static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr)
 {
 ...
From: Ben Hutchings
Date: Thursday, January 29, 2009 - 9:00 pm

Currently we use a spin-lock to serialise statistics fetches and also
to inhibit them for short periods of time, plus a flag to
enable/disable statistics fetches for longer periods of time, during
online reset.  This was apparently insufficient to deal with the several
reasons for stats being disabled.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/efx.c        |   33 ++++++++++++++++++++++-----------
 drivers/net/sfc/efx.h        |    2 ++
 drivers/net/sfc/falcon.c     |   15 +++++++++++----
 drivers/net/sfc/net_driver.h |    5 ++---
 drivers/net/sfc/sfe4001.c    |   15 ++++++++++++++-
 drivers/net/sfc/tenxpress.c  |   12 ++++++------
 6 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index b0e5308..ab0e09b 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -685,7 +685,7 @@ static int efx_init_port(struct efx_nic *efx)
 	efx->mac_op->reconfigure(efx);
 
 	efx->port_initialized = true;
-	efx->stats_enabled = true;
+	efx_stats_enable(efx);
 	return 0;
 
 fail:
@@ -734,6 +734,7 @@ static void efx_fini_port(struct efx_nic *efx)
 	if (!efx->port_initialized)
 		return;
 
+	efx_stats_disable(efx);
 	efx->phy_op->fini(efx);
 	efx->port_initialized = false;
 
@@ -1360,6 +1361,20 @@ static int efx_net_stop(struct net_device *net_dev)
 	return 0;
 }
 
+void efx_stats_disable(struct efx_nic *efx)
+{
+	spin_lock(&efx->stats_lock);
+	++efx->stats_disable_count;
+	spin_unlock(&efx->stats_lock);
+}
+
+void efx_stats_enable(struct efx_nic *efx)
+{
+	spin_lock(&efx->stats_lock);
+	--efx->stats_disable_count;
+	spin_unlock(&efx->stats_lock);
+}
+
 /* Context: process, dev_base_lock or RTNL held, non-blocking. */
 static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
 {
@@ -1368,12 +1383,12 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
 	struct net_device_stats *stats = &net_dev->stats;
 
 	/* Update stats if ...
Previous thread: [PATCH] fix memory leak in drivers/net/netxen_nic_init.c by Daniel on Thursday, January 29, 2009 - 11:55 am. (1 message)

Next thread: [BUG BISECTED] boot hangs while bringing up gianfar ethernet by Ira Snyder on Thursday, January 29, 2009 - 12:41 pm. (12 messages)