* [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29
@ 2009-01-29 19:12 Ben Hutchings
2009-01-29 19:15 ` [PATCH 01/20] sfc: SFT9001: Include non-breaking cable diagnostics in online self-tests Ben Hutchings
` (20 more replies)
0 siblings, 21 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:12 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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.
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 01/20] sfc: SFT9001: Include non-breaking cable diagnostics in online self-tests
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
@ 2009-01-29 19:15 ` Ben Hutchings
2009-01-29 19:16 ` [PATCH 02/20] sfc: Fix test for MDIO read failure Ben Hutchings
` (19 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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 *results, unsigned flags)
results[5 + i] = len_reg;
}
- /* We must reset to exit cable diagnostic mode. The BIST will
- * also run when we do this. */
-reset:
- rc2 = tenxpress_special_reset(efx);
- results[0] = rc2 ? -1 : 1;
- if (!rc)
- rc = rc2;
-
- rc2 = efx->phy_op->set_settings(efx, &ecmd);
- if (!rc)
- rc = rc2;
+out:
+ if (flags & ETH_TEST_FL_OFFLINE) {
+ /* Reset, running the BIST and then resuming normal service. */
+ rc2 = tenxpress_special_reset(efx);
+ results[0] = rc2 ? -1 : 1;
+ if (!rc)
+ rc = rc2;
+
+ rc2 = efx->phy_op->set_settings(efx, &ecmd);
+ if (!rc)
+ rc = rc2;
+ }
return rc;
}
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 02/20] sfc: Fix test for MDIO read failure
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
2009-01-29 19:15 ` [PATCH 01/20] sfc: SFT9001: Include non-breaking cable diagnostics in online self-tests Ben Hutchings
@ 2009-01-29 19:16 ` Ben Hutchings
2009-01-29 19:17 ` [PATCH 03/20] sfc: SFT9001: Enable robust link training Ben Hutchings
` (18 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:16 UTC (permalink / raw)
To: David Miller; +Cc: Roel Kluin, netdev, linux-net-drivers
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 speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 03/20] sfc: SFT9001: Enable robust link training
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
2009-01-29 19:15 ` [PATCH 01/20] sfc: SFT9001: Include non-breaking cable diagnostics in online self-tests Ben Hutchings
2009-01-29 19:16 ` [PATCH 02/20] sfc: Fix test for MDIO read failure Ben Hutchings
@ 2009-01-29 19:17 ` Ben Hutchings
2009-01-29 19:23 ` Ben Hutchings
2009-01-29 19:17 ` [PATCH 04/20] sfc: SFX7101: Remove workaround for bad " Ben Hutchings
` (17 subsequent siblings)
20 siblings, 1 reply; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:17 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 04/20] sfc: SFX7101: Remove workaround for bad link training
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (2 preceding siblings ...)
2009-01-29 19:17 ` [PATCH 03/20] sfc: SFT9001: Enable robust link training Ben Hutchings
@ 2009-01-29 19:17 ` Ben Hutchings
2009-01-29 19:23 ` Ben Hutchings
2009-01-29 19:17 ` [PATCH 05/20] sfc: SFT9001/SFN4111T: Check PHY boot status during board initialisation Ben Hutchings
` (16 subsequent siblings)
20 siblings, 1 reply; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:17 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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 crc_error_reset_threshold = 100;
-module_param(crc_error_reset_threshold, int, 0644);
-MODULE_PARM_DESC(crc_error_reset_threshold,
- "Max number of CRC errors before XAUI reset");
-
struct tenxpress_phy_data {
enum efx_loopback_mode loopback_mode;
- atomic_t bad_crc_count;
enum efx_phy_mode phy_mode;
int bad_lp_tries;
};
-void tenxpress_crc_err(struct efx_nic *efx)
-{
- struct tenxpress_phy_data *phy_data = efx->phy_data;
- if (phy_data != NULL)
- atomic_inc(&phy_data->bad_crc_count);
-}
-
static ssize_t show_phy_short_reach(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -627,13 +614,6 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
if (phy_data->phy_mode != PHY_MODE_NORMAL)
return;
-
- if (EFX_WORKAROUND_10750(efx) &&
- atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) {
- EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n");
- falcon_reset_xaui(efx);
- atomic_set(&phy_data->bad_crc_count, 0);
- }
}
static void tenxpress_phy_fini(struct efx_nic *efx)
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 82e03e1..797a0cf 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -18,7 +18,6 @@
#define EFX_WORKAROUND_ALWAYS(efx) 1
#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
-#define EFX_WORKAROUND_SFX7101(efx) ((efx)->phy_type == PHY_TYPE_SFX7101)
#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A)
/* XAUI resets if link not detected */
@@ -29,8 +28,6 @@
#define EFX_WORKAROUND_7884 EFX_WORKAROUND_10G
/* TX pkt parser problem with <= 16 byte TXes */
#define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS
-/* Low rate CRC errors require XAUI reset */
-#define EFX_WORKAROUND_10750 EFX_WORKAROUND_SFX7101
/* TX_EV_PKT_ERR can be caused by a dangling TX descriptor
* or a PCIe error (bug 11028) */
#define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 05/20] sfc: SFT9001/SFN4111T: Check PHY boot status during board initialisation
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (3 preceding siblings ...)
2009-01-29 19:17 ` [PATCH 04/20] sfc: SFX7101: Remove workaround for bad " Ben Hutchings
@ 2009-01-29 19:17 ` Ben Hutchings
2009-01-29 19:17 ` [PATCH 06/20] sfc: SFT9001: Fix speed reporting in 1G PHY loopback Ben Hutchings
` (15 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:17 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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:
i2c_unregister_device(efx->board_info.hwmon_client);
return rc;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index e6fa5c8..9e0b755 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -157,14 +157,16 @@
#define PCS_10GBASET_BLKLK_WIDTH 1
/* Boot status register */
-#define PCS_BOOT_STATUS_REG 53248
-#define PCS_BOOT_FATAL_ERR_LBN (0)
-#define PCS_BOOT_PROGRESS_LBN (1)
-#define PCS_BOOT_PROGRESS_WIDTH (2)
-#define PCS_BOOT_COMPLETE_LBN (3)
-
-#define PCS_BOOT_MAX_DELAY (100)
-#define PCS_BOOT_POLL_DELAY (10)
+#define PCS_BOOT_STATUS_REG 53248
+#define PCS_BOOT_FATAL_ERROR_LBN 0
+#define PCS_BOOT_PROGRESS_LBN 1
+#define PCS_BOOT_PROGRESS_WIDTH 2
+#define PCS_BOOT_PROGRESS_INIT 0
+#define PCS_BOOT_PROGRESS_WAIT_MDIO 1
+#define PCS_BOOT_PROGRESS_CHECKSUM 2
+#define PCS_BOOT_PROGRESS_JUMP 3
+#define PCS_BOOT_DOWNLOAD_WAIT_LBN 3
+#define PCS_BOOT_CODE_STARTED_LBN 4
/* 100M/1G PHY registers */
#define GPHY_XCONTROL_REG 49152
@@ -227,40 +229,62 @@ static ssize_t set_phy_short_reach(struct device *dev,
static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach,
set_phy_short_reach);
-/* Check that the C166 has booted successfully */
-static int tenxpress_phy_check(struct efx_nic *efx)
+int sft9001_wait_boot(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
- int count = PCS_BOOT_MAX_DELAY / PCS_BOOT_POLL_DELAY;
+ unsigned long timeout = jiffies + HZ + 1;
int boot_stat;
- /* Wait for the boot to complete (or not) */
- while (count) {
- boot_stat = mdio_clause45_read(efx, phy_id,
+ for (;;) {
+ boot_stat = mdio_clause45_read(efx, efx->mii.phy_id,
MDIO_MMD_PCS,
PCS_BOOT_STATUS_REG);
- if (boot_stat & (1 << PCS_BOOT_COMPLETE_LBN))
- break;
- count--;
- udelay(PCS_BOOT_POLL_DELAY);
- }
+ if (boot_stat >= 0) {
+ EFX_LOG(efx, "PHY boot status = %#x\n", boot_stat);
+ switch (boot_stat &
+ ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
+ (3 << PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) |
+ (1 << PCS_BOOT_CODE_STARTED_LBN))) {
+ case ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
+ (PCS_BOOT_PROGRESS_CHECKSUM <<
+ PCS_BOOT_PROGRESS_LBN)):
+ case ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
+ (PCS_BOOT_PROGRESS_INIT <<
+ PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)):
+ return -EINVAL;
+ case ((PCS_BOOT_PROGRESS_WAIT_MDIO <<
+ PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)):
+ return (efx->phy_mode & PHY_MODE_SPECIAL) ?
+ 0 : -EIO;
+ case ((PCS_BOOT_PROGRESS_JUMP <<
+ PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_CODE_STARTED_LBN)):
+ case ((PCS_BOOT_PROGRESS_JUMP <<
+ PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) |
+ (1 << PCS_BOOT_CODE_STARTED_LBN)):
+ return (efx->phy_mode & PHY_MODE_SPECIAL) ?
+ -EIO : 0;
+ default:
+ if (boot_stat & (1 << PCS_BOOT_FATAL_ERROR_LBN))
+ return -EIO;
+ break;
+ }
+ }
- if (!count) {
- EFX_ERR(efx, "%s: PHY boot timed out. Last status "
- "%x\n", __func__,
- (boot_stat >> PCS_BOOT_PROGRESS_LBN) &
- ((1 << PCS_BOOT_PROGRESS_WIDTH) - 1));
- return -ETIMEDOUT;
- }
+ if (time_after_eq(jiffies, timeout))
+ return -ETIMEDOUT;
- return 0;
+ msleep(50);
+ }
}
static int tenxpress_init(struct efx_nic *efx)
{
int phy_id = efx->mii.phy_id;
int reg;
- int rc;
if (efx->phy_type == PHY_TYPE_SFX7101) {
/* Enable 312.5 MHz clock */
@@ -283,10 +307,6 @@ static int tenxpress_init(struct efx_nic *efx)
false);
}
- rc = tenxpress_phy_check(efx);
- if (rc < 0)
- return rc;
-
/* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
if (efx->phy_type == PHY_TYPE_SFX7101) {
mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
@@ -297,7 +317,7 @@ static int tenxpress_init(struct efx_nic *efx)
PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT);
}
- return rc;
+ return 0;
}
static int tenxpress_phy_init(struct efx_nic *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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 06/20] sfc: SFT9001: Fix speed reporting in 1G PHY loopback
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (4 preceding siblings ...)
2009-01-29 19:17 ` [PATCH 05/20] sfc: SFT9001/SFN4111T: Check PHY boot status during board initialisation Ben Hutchings
@ 2009-01-29 19:17 ` Ben Hutchings
2009-01-29 19:18 ` [PATCH 07/20] sfc: SFN4111T: Fix GPIO sharing between I2C and FLASH_CFG_1 Ben Hutchings
` (14 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:17 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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, efx->phy_op->loopbacks) ||
LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
- if (loop_reset || loop_toggle || loopback || phy_mode_change) {
+ if (loop_reset || phy_mode_change) {
int rc;
efx->phy_op->get_settings(efx, &ecmd);
@@ -562,20 +560,6 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
falcon_reset_xaui(efx);
}
- if (efx->phy_type != PHY_TYPE_SFX7101) {
- /* Only change autoneg once, on coming out or
- * going into loopback */
- if (loop_toggle)
- ecmd.autoneg = !loopback;
- if (loopback) {
- ecmd.duplex = DUPLEX_FULL;
- if (efx->loopback_mode == LOOPBACK_GPHY)
- ecmd.speed = SPEED_1000;
- else
- ecmd.speed = SPEED_10000;
- }
- }
-
rc = efx->phy_op->set_settings(efx, &ecmd);
WARN_ON(rc);
}
@@ -836,6 +820,13 @@ static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ?
DUPLEX_FULL : DUPLEX_HALF);
}
+
+ /* In loopback, the PHY automatically brings up the correct interface,
+ * but doesn't advertise the correct speed. So override it */
+ if (efx->loopback_mode == LOOPBACK_GPHY)
+ ecmd->speed = SPEED_1000;
+ else if (LOOPBACK_MASK(efx) & SFT9001_LOOPBACKS)
+ ecmd->speed = SPEED_10000;
}
static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 797a0cf..420fe15 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -19,6 +19,8 @@
#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A)
+#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \
+ (efx)->phy_type == PHY_TYPE_SFT9001B)
/* XAUI resets if link not detected */
#define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS
@@ -56,4 +58,7 @@
/* Need to keep AN enabled */
#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A
+/* Don't restart AN in near-side loopback */
+#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001
+
#endif /* EFX_WORKAROUNDS_H */
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 07/20] sfc: SFN4111T: Fix GPIO sharing between I2C and FLASH_CFG_1
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (5 preceding siblings ...)
2009-01-29 19:17 ` [PATCH 06/20] sfc: SFT9001: Fix speed reporting in 1G PHY loopback Ben Hutchings
@ 2009-01-29 19:18 ` Ben Hutchings
2009-01-29 19:19 ` [PATCH 08/20] sfc: Fix post-reset MAC selection Ben Hutchings
` (13 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:18 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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, ®, GPIO_CTL_REG_KER);
EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true);
- EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, false);
falcon_write(efx, ®, 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, ®, 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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 08/20] sfc: Fix post-reset MAC selection
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (6 preceding siblings ...)
2009-01-29 19:18 ` [PATCH 07/20] sfc: SFN4111T: Fix GPIO sharing between I2C and FLASH_CFG_1 Ben Hutchings
@ 2009-01-29 19:19 ` Ben Hutchings
2009-01-29 19:19 ` [PATCH 09/20] sfc: Reinitialise the PHY completely in case of a PHY or NIC reset Ben Hutchings
` (12 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:19 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 09/20] sfc: Reinitialise the PHY completely in case of a PHY or NIC reset
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (7 preceding siblings ...)
2009-01-29 19:19 ` [PATCH 08/20] sfc: Fix post-reset MAC selection Ben Hutchings
@ 2009-01-29 19:19 ` Ben Hutchings
2009-01-29 19:19 ` [PATCH 10/20] sfc: Test for PHYXS faults whenever we cannot test link state bits Ben Hutchings
` (11 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:19 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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, bool ok)
+int efx_reset_up(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd, bool ok)
{
int rc;
@@ -1658,6 +1661,15 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
ok = false;
}
+ if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) {
+ if (ok) {
+ rc = efx->phy_op->init(efx);
+ if (rc)
+ ok = false;
+ } else
+ efx->port_initialized = false;
+ }
+
if (ok) {
efx_init_channels(efx);
@@ -1702,7 +1714,7 @@ static int efx_reset(struct efx_nic *efx)
EFX_INFO(efx, "resetting (%d)\n", method);
- efx_reset_down(efx, &ecmd);
+ efx_reset_down(efx, method, &ecmd);
rc = falcon_reset_hw(efx, method);
if (rc) {
@@ -1721,10 +1733,10 @@ static int efx_reset(struct efx_nic *efx)
/* Leave device stopped if necessary */
if (method == RESET_TYPE_DISABLE) {
- efx_reset_up(efx, &ecmd, false);
+ efx_reset_up(efx, method, &ecmd, false);
rc = -EIO;
} else {
- rc = efx_reset_up(efx, &ecmd, true);
+ rc = efx_reset_up(efx, method, &ecmd, true);
}
out_disable:
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 0dd7a53..ac20158 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -40,9 +40,10 @@ extern void efx_reconfigure_port(struct efx_nic *efx);
extern void __efx_reconfigure_port(struct efx_nic *efx);
/* Reset handling */
-extern void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd);
-extern int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd,
- bool ok);
+extern void efx_reset_down(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd);
+extern int efx_reset_up(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd, bool ok);
/* Global */
extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index dba0d64..0a59808 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -665,6 +665,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
{
enum efx_loopback_mode loopback_mode = efx->loopback_mode;
int phy_mode = efx->phy_mode;
+ enum reset_type reset_method = RESET_TYPE_INVISIBLE;
struct ethtool_cmd ecmd;
struct efx_channel *channel;
int rc_test = 0, rc_reset = 0, rc;
@@ -718,21 +719,21 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
mutex_unlock(&efx->mac_lock);
/* free up all consumers of SRAM (including all the queues) */
- efx_reset_down(efx, &ecmd);
+ efx_reset_down(efx, reset_method, &ecmd);
rc = efx_test_chip(efx, tests);
if (rc && !rc_test)
rc_test = rc;
/* reset the chip to recover from the register test */
- rc_reset = falcon_reset_hw(efx, RESET_TYPE_ALL);
+ rc_reset = falcon_reset_hw(efx, reset_method);
/* Ensure that the phy is powered and out of loopback
* for the bist and loopback tests */
efx->phy_mode &= ~PHY_MODE_LOW_POWER;
efx->loopback_mode = LOOPBACK_NONE;
- rc = efx_reset_up(efx, &ecmd, rc_reset == 0);
+ rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0);
if (rc && !rc_reset)
rc_reset = rc;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index ec3e38b..1ab14d5 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -357,6 +357,7 @@ static int tenxpress_phy_init(struct efx_nic *efx)
rc = tenxpress_init(efx);
if (rc < 0)
goto fail;
+ mdio_clause45_set_pause(efx);
if (efx->phy_type == PHY_TYPE_SFT9001B) {
rc = device_create_file(&efx->pci_dev->dev,
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 10/20] sfc: Test for PHYXS faults whenever we cannot test link state bits
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (8 preceding siblings ...)
2009-01-29 19:19 ` [PATCH 09/20] sfc: Reinitialise the PHY completely in case of a PHY or NIC reset Ben Hutchings
@ 2009-01-29 19:19 ` Ben Hutchings
2009-01-29 19:19 ` [PATCH 11/20] sfc: Update board info for hardware monitor on SFN4111T-R5 and later Ben Hutchings
` (10 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:19 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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 marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 11/20] sfc: Update board info for hardware monitor on SFN4111T-R5 and later
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (9 preceding siblings ...)
2009-01-29 19:19 ` [PATCH 10/20] sfc: Test for PHYXS faults whenever we cannot test link state bits Ben Hutchings
@ 2009-01-29 19:19 ` Ben Hutchings
2009-01-29 19:20 ` [PATCH 12/20] sfc: SFT9001: Always enable XNP exchange on SFT9001 rev B Ben Hutchings
` (9 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:19 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 12/20] sfc: SFT9001: Always enable XNP exchange on SFT9001 rev B
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (10 preceding siblings ...)
2009-01-29 19:19 ` [PATCH 11/20] sfc: Update board info for hardware monitor on SFN4111T-R5 and later Ben Hutchings
@ 2009-01-29 19:20 ` Ben Hutchings
2009-01-29 19:20 ` [PATCH 13/20] sfc: SFX7101/SFT9001: Fix AN advertisements Ben Hutchings
` (8 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:20 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 13/20] sfc: SFX7101/SFT9001: Fix AN advertisements
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (11 preceding siblings ...)
2009-01-29 19:20 ` [PATCH 12/20] sfc: SFT9001: Always enable XNP exchange on SFT9001 rev B Ben Hutchings
@ 2009-01-29 19:20 ` Ben Hutchings
2009-01-29 19:20 ` [PATCH 14/20] sfc: Remove "XFP" from log messages that are not specific to XFP Ben Hutchings
` (7 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:20 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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 |= ADVERTISED_100baseT_Half;
if (reg & ADVERTISE_100FULL)
result |= ADVERTISED_100baseT_Full;
- if (reg & LPA_RESV)
- result |= xnp;
-
return result;
}
@@ -314,7 +311,7 @@ void mdio_clause45_get_settings(struct efx_nic *efx,
*/
void mdio_clause45_get_settings_ext(struct efx_nic *efx,
struct ethtool_cmd *ecmd,
- u32 xnp, u32 xnp_lpa)
+ u32 npage_adv, u32 npage_lpa)
{
int phy_id = efx->mii.phy_id;
int reg;
@@ -365,8 +362,8 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx,
ecmd->autoneg = AUTONEG_ENABLE;
ecmd->advertising |=
ADVERTISED_Autoneg |
- mdio_clause45_get_an(efx,
- MDIO_AN_ADVERTISE, xnp);
+ mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) |
+ npage_adv;
} else
ecmd->autoneg = AUTONEG_DISABLE;
} else
@@ -375,27 +372,30 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx,
if (ecmd->autoneg) {
/* If AN is complete, report best common mode,
* otherwise report best advertised mode. */
- u32 common = ecmd->advertising;
+ u32 modes = 0;
if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
MDIO_MMDREG_STAT1) &
- (1 << MDIO_AN_STATUS_AN_DONE_LBN)) {
- common &= mdio_clause45_get_an(efx, MDIO_AN_LPA,
- xnp_lpa);
- }
- if (common & ADVERTISED_10000baseT_Full) {
+ (1 << MDIO_AN_STATUS_AN_DONE_LBN))
+ modes = (ecmd->advertising &
+ (mdio_clause45_get_an(efx, MDIO_AN_LPA) |
+ npage_lpa));
+ if (modes == 0)
+ modes = ecmd->advertising;
+
+ if (modes & ADVERTISED_10000baseT_Full) {
ecmd->speed = SPEED_10000;
ecmd->duplex = DUPLEX_FULL;
- } else if (common & (ADVERTISED_1000baseT_Full |
- ADVERTISED_1000baseT_Half)) {
+ } else if (modes & (ADVERTISED_1000baseT_Full |
+ ADVERTISED_1000baseT_Half)) {
ecmd->speed = SPEED_1000;
- ecmd->duplex = !!(common & ADVERTISED_1000baseT_Full);
- } else if (common & (ADVERTISED_100baseT_Full |
- ADVERTISED_100baseT_Half)) {
+ ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full);
+ } else if (modes & (ADVERTISED_100baseT_Full |
+ ADVERTISED_100baseT_Half)) {
ecmd->speed = SPEED_100;
- ecmd->duplex = !!(common & ADVERTISED_100baseT_Full);
+ ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
} else {
ecmd->speed = SPEED_10;
- ecmd->duplex = !!(common & ADVERTISED_10baseT_Full);
+ ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
}
} else {
/* Report forced settings */
@@ -419,7 +419,7 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
int phy_id = efx->mii.phy_id;
struct ethtool_cmd prev;
u32 required;
- int ctrl1_bits, reg;
+ int reg;
efx->phy_op->get_settings(efx, &prev);
@@ -434,102 +434,83 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
if (prev.port != PORT_TP || ecmd->port != PORT_TP)
return -EINVAL;
- /* Check that PHY supports these settings and work out the
- * basic control bits */
- if (ecmd->duplex) {
+ /* Check that PHY supports these settings */
+ if (ecmd->autoneg) {
+ required = SUPPORTED_Autoneg;
+ } else if (ecmd->duplex) {
switch (ecmd->speed) {
- case SPEED_10:
- ctrl1_bits = BMCR_FULLDPLX;
- required = SUPPORTED_10baseT_Full;
- break;
- case SPEED_100:
- ctrl1_bits = BMCR_SPEED100 | BMCR_FULLDPLX;
- required = SUPPORTED_100baseT_Full;
- break;
- case SPEED_1000:
- ctrl1_bits = BMCR_SPEED1000 | BMCR_FULLDPLX;
- required = SUPPORTED_1000baseT_Full;
- break;
- case SPEED_10000:
- ctrl1_bits = (BMCR_SPEED1000 | BMCR_SPEED100 |
- BMCR_FULLDPLX);
- required = SUPPORTED_10000baseT_Full;
- break;
- default:
- return -EINVAL;
+ case SPEED_10: required = SUPPORTED_10baseT_Full; break;
+ case SPEED_100: required = SUPPORTED_100baseT_Full; break;
+ default: return -EINVAL;
}
} else {
switch (ecmd->speed) {
- case SPEED_10:
- ctrl1_bits = 0;
- required = SUPPORTED_10baseT_Half;
- break;
- case SPEED_100:
- ctrl1_bits = BMCR_SPEED100;
- required = SUPPORTED_100baseT_Half;
- break;
- case SPEED_1000:
- ctrl1_bits = BMCR_SPEED1000;
- required = SUPPORTED_1000baseT_Half;
- break;
- default:
- return -EINVAL;
+ case SPEED_10: required = SUPPORTED_10baseT_Half; break;
+ case SPEED_100: required = SUPPORTED_100baseT_Half; break;
+ default: return -EINVAL;
}
}
- if (ecmd->autoneg)
- required |= SUPPORTED_Autoneg;
required |= ecmd->advertising;
if (required & ~prev.supported)
return -EINVAL;
- /* Set the basic control bits */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL1);
- reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | 0x003c);
- reg |= ctrl1_bits;
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL1,
- reg);
-
- /* Set the AN registers */
- if (ecmd->autoneg != prev.autoneg ||
- ecmd->advertising != prev.advertising) {
- bool xnp = false;
-
- if (efx->phy_op->set_xnp_advertise)
- xnp = efx->phy_op->set_xnp_advertise(efx,
- ecmd->advertising);
-
- if (ecmd->autoneg) {
- reg = 0;
- if (ecmd->advertising & ADVERTISED_10baseT_Half)
- reg |= ADVERTISE_10HALF;
- if (ecmd->advertising & ADVERTISED_10baseT_Full)
- reg |= ADVERTISE_10FULL;
- if (ecmd->advertising & ADVERTISED_100baseT_Half)
- reg |= ADVERTISE_100HALF;
- if (ecmd->advertising & ADVERTISED_100baseT_Full)
- reg |= ADVERTISE_100FULL;
- if (xnp)
- reg |= ADVERTISE_RESV;
- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_ADVERTISE, reg);
- }
+ if (ecmd->autoneg) {
+ bool xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full
+ || EFX_WORKAROUND_13204(efx));
+
+ /* Set up the base page */
+ reg = ADVERTISE_CSMA;
+ if (ecmd->advertising & ADVERTISED_10baseT_Half)
+ reg |= ADVERTISE_10HALF;
+ if (ecmd->advertising & ADVERTISED_10baseT_Full)
+ reg |= ADVERTISE_10FULL;
+ if (ecmd->advertising & ADVERTISED_100baseT_Half)
+ reg |= ADVERTISE_100HALF;
+ if (ecmd->advertising & ADVERTISED_100baseT_Full)
+ reg |= ADVERTISE_100FULL;
+ if (xnp)
+ reg |= ADVERTISE_RESV;
+ else if (ecmd->advertising & (ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full))
+ reg |= ADVERTISE_NPAGE;
+ reg |= efx_fc_advertise(efx->wanted_fc);
+ mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_ADVERTISE, reg);
+
+ /* Set up the (extended) next page if necessary */
+ if (efx->phy_op->set_npage_adv)
+ efx->phy_op->set_npage_adv(efx, ecmd->advertising);
+ /* Enable and restart AN */
reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
MDIO_MMDREG_CTRL1);
- if (ecmd->autoneg)
- reg |= BMCR_ANENABLE | BMCR_ANRESTART;
- else
- reg &= ~BMCR_ANENABLE;
- if (EFX_WORKAROUND_15195(efx)
- && LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
- reg &= ~BMCR_ANRESTART;
+ 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
reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN);
mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
MDIO_MMDREG_CTRL1, reg);
+ } else {
+ /* Disable AN */
+ mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
+ MDIO_MMDREG_CTRL1,
+ __ffs(BMCR_ANENABLE), false);
+
+ /* Set the basic control bits */
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
+ MDIO_MMDREG_CTRL1);
+ reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX |
+ 0x003c);
+ if (ecmd->speed == SPEED_100)
+ reg |= BMCR_SPEED100;
+ if (ecmd->duplex)
+ reg |= BMCR_FULLDPLX;
+ mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
+ MDIO_MMDREG_CTRL1, reg);
}
return 0;
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 09bf801..8ba4977 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -155,7 +155,8 @@
#define MDIO_AN_XNP 22
#define MDIO_AN_LPA_XNP 25
-#define MDIO_AN_10GBT_ADVERTISE 32
+#define MDIO_AN_10GBT_CTRL 32
+#define MDIO_AN_10GBT_CTRL_ADV_10G_LBN 12
#define MDIO_AN_10GBT_STATUS (33)
#define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */
#define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 5f255f7..8eb411a 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -566,7 +566,7 @@ struct efx_mac_operations {
* @poll: Poll for hardware state. Serialised by the mac_lock.
* @get_settings: Get ethtool settings. Serialised by the mac_lock.
* @set_settings: Set ethtool settings. Serialised by the mac_lock.
- * @set_xnp_advertise: Set abilities advertised in Extended Next Page
+ * @set_npage_adv: Set abilities advertised in (Extended) Next Page
* (only needed where AN bit is set in mmds)
* @num_tests: Number of PHY-specific tests/results
* @test_names: Names of the tests/results
@@ -586,7 +586,7 @@ struct efx_phy_operations {
struct ethtool_cmd *ecmd);
int (*set_settings) (struct efx_nic *efx,
struct ethtool_cmd *ecmd);
- bool (*set_xnp_advertise) (struct efx_nic *efx, u32);
+ void (*set_npage_adv) (struct efx_nic *efx, u32);
u32 num_tests;
const char *const *test_names;
int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags);
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 1ab14d5..b56617f 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -181,11 +181,13 @@
#define C22EXT_STATUS_LINK_LBN 2
#define C22EXT_STATUS_LINK_WIDTH 1
-#define C22EXT_MSTSLV_REG 49162
-#define C22EXT_MSTSLV_1000_HD_LBN 10
-#define C22EXT_MSTSLV_1000_HD_WIDTH 1
-#define C22EXT_MSTSLV_1000_FD_LBN 11
-#define C22EXT_MSTSLV_1000_FD_WIDTH 1
+#define C22EXT_MSTSLV_CTRL 49161
+#define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8
+#define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9
+
+#define C22EXT_MSTSLV_STATUS 49162
+#define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10
+#define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11
/* Time to wait between powering down the LNPGA and turning off the power
* rails */
@@ -764,114 +766,76 @@ out:
return rc;
}
-static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx)
+static void
+tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy = efx->mii.phy_id;
- u32 lpa = 0;
+ int phy_id = efx->mii.phy_id;
+ u32 adv = 0, lpa = 0;
int reg;
if (efx->phy_type != PHY_TYPE_SFX7101) {
- reg = mdio_clause45_read(efx, phy, MDIO_MMD_C22EXT,
- C22EXT_MSTSLV_REG);
- if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN))
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
+ C22EXT_MSTSLV_CTRL);
+ if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN))
+ adv |= ADVERTISED_1000baseT_Full;
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
+ C22EXT_MSTSLV_STATUS);
+ if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
lpa |= ADVERTISED_1000baseT_Half;
- if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN))
+ if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
lpa |= ADVERTISED_1000baseT_Full;
}
- reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS);
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_CTRL);
+ if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN))
+ adv |= ADVERTISED_10000baseT_Full;
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_STATUS);
if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN))
lpa |= ADVERTISED_10000baseT_Full;
- return lpa;
-}
-
-static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
-{
- mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full,
- tenxpress_get_xnp_lpa(efx));
- ecmd->supported |= SUPPORTED_10000baseT_Full;
- ecmd->advertising |= ADVERTISED_10000baseT_Full;
-}
-
-static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
-{
- int phy_id = efx->mii.phy_id;
- u32 xnp_adv = 0;
- int reg;
-
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_SPEED_ENABLE_REG);
- if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN)))
- xnp_adv |= ADVERTISED_100baseT_Full;
- if (reg & (1 << PMA_PMD_1000T_ADV_LBN))
- xnp_adv |= ADVERTISED_1000baseT_Full;
- if (reg & (1 << PMA_PMD_10000T_ADV_LBN))
- xnp_adv |= ADVERTISED_10000baseT_Full;
- mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv,
- tenxpress_get_xnp_lpa(efx));
+ mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa);
- ecmd->supported |= (SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full);
-
- /* Use the vendor defined C22ext register for duplex settings */
- if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG);
- ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ?
- DUPLEX_FULL : DUPLEX_HALF);
- }
+ if (efx->phy_type != PHY_TYPE_SFX7101)
+ ecmd->supported |= (SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full);
/* In loopback, the PHY automatically brings up the correct interface,
* but doesn't advertise the correct speed. So override it */
if (efx->loopback_mode == LOOPBACK_GPHY)
ecmd->speed = SPEED_1000;
- else if (LOOPBACK_MASK(efx) & SFT9001_LOOPBACKS)
+ else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
ecmd->speed = SPEED_10000;
}
-static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy_id = efx->mii.phy_id;
- int rc;
-
- rc = mdio_clause45_set_settings(efx, ecmd);
- if (rc)
- return rc;
+ if (!ecmd->autoneg)
+ return -EINVAL;
- if (ecmd->speed != SPEED_10000 && !ecmd->autoneg)
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN,
- ecmd->duplex == DUPLEX_FULL);
+ return mdio_clause45_set_settings(efx, ecmd);
+}
- return rc;
+static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
+{
+ mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_CTRL,
+ MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
+ advertising & ADVERTISED_10000baseT_Full);
}
-static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising)
+static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
{
- int phy = efx->mii.phy_id;
- int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD,
- PMA_PMD_SPEED_ENABLE_REG);
- bool enabled;
-
- reg &= ~((1 << 2) | (1 << 3));
- if (EFX_WORKAROUND_13204(efx) &&
- (advertising & ADVERTISED_100baseT_Full))
- reg |= 1 << PMA_PMD_100TX_ADV_LBN;
- if (advertising & ADVERTISED_1000baseT_Full)
- reg |= 1 << PMA_PMD_1000T_ADV_LBN;
- if (advertising & ADVERTISED_10000baseT_Full)
- reg |= 1 << PMA_PMD_10000T_ADV_LBN;
- mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD,
- PMA_PMD_SPEED_ENABLE_REG, reg);
-
- enabled = (advertising &
- (ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full |
- ADVERTISED_10000baseT_Full));
- if (EFX_WORKAROUND_13204(efx))
- enabled |= (advertising & ADVERTISED_100baseT_Full);
- return enabled;
+ int phy_id = efx->mii.phy_id;
+
+ mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
+ C22EXT_MSTSLV_CTRL,
+ C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
+ advertising & ADVERTISED_1000baseT_Full);
+ mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_CTRL,
+ MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
+ advertising & ADVERTISED_10000baseT_Full);
}
struct efx_phy_operations falcon_sfx7101_phy_ops = {
@@ -881,8 +845,9 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = {
.poll = tenxpress_phy_poll,
.fini = tenxpress_phy_fini,
.clear_interrupt = efx_port_dummy_op_void,
- .get_settings = sfx7101_get_settings,
- .set_settings = mdio_clause45_set_settings,
+ .get_settings = tenxpress_get_settings,
+ .set_settings = tenxpress_set_settings,
+ .set_npage_adv = sfx7101_set_npage_adv,
.num_tests = ARRAY_SIZE(sfx7101_test_names),
.test_names = sfx7101_test_names,
.run_tests = sfx7101_run_tests,
@@ -897,9 +862,9 @@ struct efx_phy_operations falcon_sft9001_phy_ops = {
.poll = tenxpress_phy_poll,
.fini = tenxpress_phy_fini,
.clear_interrupt = efx_port_dummy_op_void,
- .get_settings = sft9001_get_settings,
- .set_settings = sft9001_set_settings,
- .set_xnp_advertise = sft9001_set_xnp_advertise,
+ .get_settings = tenxpress_get_settings,
+ .set_settings = tenxpress_set_settings,
+ .set_npage_adv = sft9001_set_npage_adv,
.num_tests = ARRAY_SIZE(sft9001_test_names),
.test_names = sft9001_test_names,
.run_tests = sft9001_run_tests,
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index b810dcd..78de68f 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -18,7 +18,6 @@
#define EFX_WORKAROUND_ALWAYS(efx) 1
#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
-#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A)
#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \
(efx)->phy_type == PHY_TYPE_SFT9001B)
@@ -55,9 +54,6 @@
/* Need to send XNP pages for 100BaseT */
#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001
-/* Need to keep AN enabled */
-#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A
-
/* Don't restart AN in near-side loopback */
#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 14/20] sfc: Remove "XFP" from log messages that are not specific to XFP
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (12 preceding siblings ...)
2009-01-29 19:20 ` [PATCH 13/20] sfc: SFX7101/SFT9001: Fix AN advertisements Ben Hutchings
@ 2009-01-29 19:20 ` Ben Hutchings
2009-01-29 19:20 ` [PATCH 15/20] sfc: Fix reporting of PHY id Ben Hutchings
` (6 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:20 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 15/20] sfc: Fix reporting of PHY id
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (13 preceding siblings ...)
2009-01-29 19:20 ` [PATCH 14/20] sfc: Remove "XFP" from log messages that are not specific to XFP Ben Hutchings
@ 2009-01-29 19:20 ` Ben Hutchings
2009-01-29 19:21 ` [PATCH 16/20] sfc: Add support for QT2025C PHY Ben Hutchings
` (5 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:20 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -88,9 +88,9 @@ static int xfp_phy_init(struct efx_nic *efx)
return -ENOMEM;
efx->phy_data = phy_data;
- 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));
+ EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n",
+ devid, mdio_id_oui(devid), mdio_id_model(devid),
+ mdio_id_rev(devid));
phy_data->phy_mode = efx->phy_mode;
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 16/20] sfc: Add support for QT2025C PHY
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (14 preceding siblings ...)
2009-01-29 19:20 ` [PATCH 15/20] sfc: Fix reporting of PHY id Ben Hutchings
@ 2009-01-29 19:21 ` Ben Hutchings
2009-01-29 19:21 ` [PATCH 17/20] sfc: Delete unused efx_blinker::led_num field Ben Hutchings
` (4 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:21 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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 --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index 2df467d..bb1ef77 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -7,8 +7,8 @@
* by the Free Software Foundation, incorporated herein by reference.
*/
/*
- * Driver for XFP optical PHYs (plus some support specific to the Quake 2022/32)
- * See www.amcc.com for details (search for qt2032)
+ * Driver for SFP+ and XFP optical PHYs plus some support specific to the
+ * AMCC QT20xx adapters; see www.amcc.com for details
*/
#include <linux/timer.h>
@@ -31,6 +31,21 @@
/* Quake-specific MDIO registers */
#define MDIO_QUAKE_LED0_REG (0xD006)
+/* QT2025C only */
+#define PCS_FW_HEARTBEAT_REG 0xd7ee
+#define PCS_FW_HEARTB_LBN 0
+#define PCS_FW_HEARTB_WIDTH 8
+#define PCS_UC8051_STATUS_REG 0xd7fd
+#define PCS_UC_STATUS_LBN 0
+#define PCS_UC_STATUS_WIDTH 8
+#define PCS_UC_STATUS_FW_SAVE 0x20
+#define PMA_PMD_FTX_CTRL2_REG 0xc309
+#define PMA_PMD_FTX_STATIC_LBN 13
+#define PMA_PMD_VEND1_REG 0xc001
+#define PMA_PMD_VEND1_LBTXD_LBN 15
+#define PCS_VEND1_REG 0xc000
+#define PCS_VEND1_LBTXD_LBN 5
+
void xfp_set_led(struct efx_nic *p, int led, int mode)
{
int addr = MDIO_QUAKE_LED0_REG + led;
@@ -45,7 +60,49 @@ struct xfp_phy_data {
#define XFP_MAX_RESET_TIME 500
#define XFP_RESET_WAIT 10
-/* Reset the PHYXS MMD. This is documented (for the Quake PHY) as doing
+static int qt2025c_wait_reset(struct efx_nic *efx)
+{
+ unsigned long timeout = jiffies + 10 * HZ;
+ int phy_id = efx->mii.phy_id;
+ int reg, old_counter = 0;
+
+ /* Wait for firmware heartbeat to start */
+ for (;;) {
+ int counter;
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
+ PCS_FW_HEARTBEAT_REG);
+ if (reg < 0)
+ return reg;
+ counter = ((reg >> PCS_FW_HEARTB_LBN) &
+ ((1 << PCS_FW_HEARTB_WIDTH) - 1));
+ if (old_counter == 0)
+ old_counter = counter;
+ else if (counter != old_counter)
+ break;
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+ msleep(10);
+ }
+
+ /* Wait for firmware status to look good */
+ for (;;) {
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
+ PCS_UC8051_STATUS_REG);
+ if (reg < 0)
+ return reg;
+ if ((reg &
+ ((1 << PCS_UC_STATUS_WIDTH) - 1) << PCS_UC_STATUS_LBN) >=
+ PCS_UC_STATUS_FW_SAVE)
+ break;
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+ msleep(100);
+ }
+
+ return 0;
+}
+
+/* Reset the PHYXS MMD. This is documented (for the Quake PHYs) as doing
* a complete soft reset.
*/
static int xfp_reset_phy(struct efx_nic *efx)
@@ -58,6 +115,12 @@ static int xfp_reset_phy(struct efx_nic *efx)
if (rc < 0)
goto fail;
+ if (efx->phy_type == PHY_TYPE_QT2025C) {
+ rc = qt2025c_wait_reset(efx);
+ if (rc < 0)
+ goto fail;
+ }
+
/* Wait 250ms for the PHY to complete bootup */
msleep(250);
@@ -131,12 +194,28 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
{
struct xfp_phy_data *phy_data = efx->phy_data;
- /* Reset the PHY when moving from tx off to tx on */
- if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) &&
- (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
- xfp_reset_phy(efx);
+ if (efx->phy_type == PHY_TYPE_QT2025C) {
+ /* There are several different register bits which can
+ * disable TX (and save power) on direct-attach cables
+ * or optical transceivers, varying somewhat between
+ * firmware versions. Only 'static mode' appears to
+ * cover everything. */
+ mdio_clause45_set_flag(
+ efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
+ PMA_PMD_FTX_CTRL2_REG, PMA_PMD_FTX_STATIC_LBN,
+ efx->phy_mode & PHY_MODE_TX_DISABLED ||
+ efx->phy_mode & PHY_MODE_LOW_POWER ||
+ efx->loopback_mode == LOOPBACK_PCS ||
+ efx->loopback_mode == LOOPBACK_PMAPMD);
+ } else {
+ /* Reset the PHY when moving from tx off to tx on */
+ if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) &&
+ (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
+ xfp_reset_phy(efx);
+
+ mdio_clause45_transmit_disable(efx);
+ }
- mdio_clause45_transmit_disable(efx);
mdio_clause45_phy_reconfigure(efx);
phy_data->phy_mode = efx->phy_mode;
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 17/20] sfc: Delete unused efx_blinker::led_num field
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (15 preceding siblings ...)
2009-01-29 19:21 ` [PATCH 16/20] sfc: Add support for QT2025C PHY Ben Hutchings
@ 2009-01-29 19:21 ` Ben Hutchings
2009-01-29 19:21 ` [PATCH 18/20] sfc: Clean up LED control Ben Hutchings
` (3 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:21 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 18/20] sfc: Clean up LED control
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (16 preceding siblings ...)
2009-01-29 19:21 ` [PATCH 17/20] sfc: Delete unused efx_blinker::led_num field Ben Hutchings
@ 2009-01-29 19:21 ` Ben Hutchings
2009-01-29 19:21 ` [PATCH 19/20] sfc: Add support for SFN4112F SFP+ reference design Ben Hutchings
` (2 subsequent siblings)
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:21 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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 :
QUAKE_LED_OFF);
@@ -221,7 +220,7 @@ static int sfe4002_init(struct efx_nic *efx)
return rc;
efx->board_info.monitor = sfe4002_check_hw;
efx->board_info.init_leds = sfe4002_init_leds;
- efx->board_info.set_fault_led = sfe4002_fault_led;
+ efx->board_info.set_id_led = sfe4002_set_id_led;
efx->board_info.blink = board_blink;
efx->board_info.fini = efx_fini_lm87;
return 0;
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index b0e5308..7fcdd04 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1847,8 +1847,8 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
static struct efx_board efx_dummy_board_info = {
.init = efx_port_dummy_op_int,
- .init_leds = efx_port_dummy_op_int,
- .set_fault_led = efx_port_dummy_op_blink,
+ .init_leds = efx_port_dummy_op_void,
+ .set_id_led = efx_port_dummy_op_blink,
.monitor = efx_port_dummy_op_int,
.blink = efx_port_dummy_op_blink,
.fini = efx_port_dummy_op_void,
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 1f0dc8f..44bbf65 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -411,8 +411,8 @@ struct efx_blinker {
* @major: Major rev. ('A', 'B' ...)
* @minor: Minor rev. (0, 1, ...)
* @init: Initialisation function
- * @init_leds: Sets up board LEDs
- * @set_fault_led: Turns the fault LED on or off
+ * @init_leds: Sets up board LEDs. May be called repeatedly.
+ * @set_id_led: Turns the identification LED on or off
* @blink: Starts/stops blinking
* @monitor: Board-specific health check function
* @fini: Cleanup function
@@ -428,9 +428,9 @@ struct efx_board {
/* As the LEDs are typically attached to the PHY, LEDs
* have a separate init callback that happens later than
* board init. */
- int (*init_leds)(struct efx_nic *efx);
+ void (*init_leds)(struct efx_nic *efx);
+ void (*set_id_led) (struct efx_nic *efx, bool state);
int (*monitor) (struct efx_nic *nic);
- void (*set_fault_led) (struct efx_nic *efx, bool state);
void (*blink) (struct efx_nic *efx, bool start);
void (*fini) (struct efx_nic *nic);
struct efx_blinker blinker;
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 19/20] sfc: Add support for SFN4112F SFP+ reference design
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (17 preceding siblings ...)
2009-01-29 19:21 ` [PATCH 18/20] sfc: Clean up LED control Ben Hutchings
@ 2009-01-29 19:21 ` Ben Hutchings
2009-01-29 19:22 ` [PATCH 20/20] sfc: Replace stats_enabled flag with a disable count Ben Hutchings
2009-01-29 23:26 ` [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 David Miller
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:21 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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, sfn4112f_lm87_regs);
+ if (rc)
+ return rc;
+ efx->board_info.monitor = sfn4112f_check_hw;
+ efx->board_info.init_leds = sfn4112f_init_leds;
+ efx->board_info.set_id_led = sfn4112f_set_id_led;
+ efx->board_info.blink = board_blink;
+ efx->board_info.fini = efx_fini_lm87;
+ return 0;
+}
+
/* This will get expanded as board-specific details get moved out of the
* PHY drivers. */
struct efx_board_data {
@@ -241,6 +301,8 @@ static struct efx_board_data board_data[] = {
{ EFX_BOARD_SFE4002, "SFE4002", "XFP adapter", sfe4002_init },
{ EFX_BOARD_SFN4111T, "SFN4111T", "100/1000/10GBASE-T adapter",
sfn4111t_init },
+ { EFX_BOARD_SFN4112F, "SFN4112F", "SFP+ adapter",
+ sfn4112f_init },
};
void efx_set_board_info(struct efx_nic *efx, u16 revision_info)
diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h
index d93c6c6..44942de 100644
--- a/drivers/net/sfc/boards.h
+++ b/drivers/net/sfc/boards.h
@@ -15,6 +15,7 @@ enum efx_board_type {
EFX_BOARD_SFE4001 = 1,
EFX_BOARD_SFE4002 = 2,
EFX_BOARD_SFN4111T = 0x51,
+ EFX_BOARD_SFN4112F = 0x52,
};
extern void efx_set_board_info(struct efx_nic *efx, u16 revision_info);
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 20/20] sfc: Replace stats_enabled flag with a disable count
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (18 preceding siblings ...)
2009-01-29 19:21 ` [PATCH 19/20] sfc: Add support for SFN4112F SFP+ reference design Ben Hutchings
@ 2009-01-29 19:22 ` Ben Hutchings
2009-01-29 23:26 ` [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 David Miller
20 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:22 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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 possible, but do not wait if another thread
- * is updating them (or resetting the NIC); slightly stale
- * stats are acceptable.
+ * is updating them or if MAC stats fetches are temporarily
+ * disabled; slightly stale stats are acceptable.
*/
if (!spin_trylock(&efx->stats_lock))
return stats;
- if (efx->stats_enabled) {
+ if (!efx->stats_disable_count) {
efx->mac_op->update_stats(efx);
falcon_update_nic_stats(efx);
}
@@ -1626,12 +1641,7 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method,
{
EFX_ASSERT_RESET_SERIALISED(efx);
- /* The net_dev->get_stats handler is quite slow, and will fail
- * if a fetch is pending over reset. Serialise against it. */
- spin_lock(&efx->stats_lock);
- efx->stats_enabled = false;
- spin_unlock(&efx->stats_lock);
-
+ efx_stats_disable(efx);
efx_stop_all(efx);
mutex_lock(&efx->mac_lock);
mutex_lock(&efx->spi_lock);
@@ -1682,7 +1692,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method,
if (ok) {
efx_start_all(efx);
- efx->stats_enabled = true;
+ efx_stats_enable(efx);
}
return rc;
}
@@ -1888,6 +1898,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
efx->rx_checksum_enabled = true;
spin_lock_init(&efx->netif_stop_lock);
spin_lock_init(&efx->stats_lock);
+ efx->stats_disable_count = 1;
mutex_init(&efx->mac_lock);
efx->mac_op = &efx_dummy_mac_operations;
efx->phy_op = &efx_dummy_phy_operations;
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index ac20158..55d0f13 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -36,6 +36,8 @@ extern void efx_process_channel_now(struct efx_channel *channel);
extern void efx_flush_queues(struct efx_nic *efx);
/* Ports */
+extern void efx_stats_disable(struct efx_nic *efx);
+extern void efx_stats_enable(struct efx_nic *efx);
extern void efx_reconfigure_port(struct efx_nic *efx);
extern void __efx_reconfigure_port(struct efx_nic *efx);
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 7ad5daa..9e2f0f0 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1883,7 +1883,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
/* MAC stats will fail whilst the TX fifo is draining. Serialise
* the drain sequence with the statistics fetch */
- spin_lock(&efx->stats_lock);
+ efx_stats_disable(efx);
falcon_read(efx, ®, MAC0_CTRL_REG_KER);
EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1);
@@ -1913,7 +1913,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
udelay(10);
}
- spin_unlock(&efx->stats_lock);
+ efx_stats_enable(efx);
/* If we've reset the EM block and the link is up, then
* we'll have to kick the XAUI link so the PHY can recover */
@@ -2274,6 +2274,10 @@ int falcon_switch_mac(struct efx_nic *efx)
struct efx_mac_operations *old_mac_op = efx->mac_op;
efx_oword_t nic_stat;
unsigned strap_val;
+ int rc = 0;
+
+ /* Don't try to fetch MAC stats while we're switching MACs */
+ efx_stats_disable(efx);
/* Internal loopbacks override the phy speed setting */
if (efx->loopback_mode == LOOPBACK_GMAC) {
@@ -2303,13 +2307,16 @@ int falcon_switch_mac(struct efx_nic *efx)
}
if (old_mac_op == efx->mac_op)
- return 0;
+ goto out;
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);
+ rc = falcon_reset_macs(efx);
+out:
+ efx_stats_enable(efx);
+ return rc;
}
/* This call is responsible for hooking in the MAC and PHY operations */
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 44bbf65..d21b89b 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -753,8 +753,7 @@ union efx_multicast_hash {
* &struct net_device_stats.
* @stats_buffer: DMA buffer for statistics
* @stats_lock: Statistics update lock. Serialises statistics fetches
- * @stats_enabled: Temporarily disable statistics fetches.
- * Serialised by @stats_lock
+ * @stats_disable_count: Nest count for disabling statistics fetches
* @mac_op: MAC interface
* @mac_address: Permanent MAC address
* @phy_type: PHY type
@@ -836,7 +835,7 @@ struct efx_nic {
struct efx_mac_stats mac_stats;
struct efx_buffer stats_buffer;
spinlock_t stats_lock;
- bool stats_enabled;
+ unsigned int stats_disable_count;
struct efx_mac_operations *mac_op;
unsigned char mac_address[ETH_ALEN];
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 25037c7..1353fef 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -235,12 +235,18 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
} else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
err = -EBUSY;
} else {
+ /* Reset the PHY, reconfigure the MAC and enable/disable
+ * MAC stats accordingly. */
efx->phy_mode = new_mode;
+ if (new_mode & PHY_MODE_SPECIAL)
+ efx_stats_disable(efx);
if (efx->board_info.type == EFX_BOARD_SFE4001)
err = sfe4001_poweron(efx);
else
err = sfn4111t_reset(efx);
efx_reconfigure_port(efx);
+ if (!(new_mode & PHY_MODE_SPECIAL))
+ efx_stats_enable(efx);
}
rtnl_unlock();
@@ -329,6 +335,11 @@ int sfe4001_init(struct efx_nic *efx)
efx->board_info.monitor = sfe4001_check_hw;
efx->board_info.fini = sfe4001_fini;
+ if (efx->phy_mode & PHY_MODE_SPECIAL) {
+ /* PHY won't generate a 156.25 MHz clock and MAC stats fetch
+ * will fail. */
+ efx_stats_disable(efx);
+ }
rc = sfe4001_poweron(efx);
if (rc)
goto fail_ioexp;
@@ -407,8 +418,12 @@ int sfn4111t_init(struct efx_nic *efx)
goto fail_hwmon;
do {
- if (efx->phy_mode & PHY_MODE_SPECIAL)
+ if (efx->phy_mode & PHY_MODE_SPECIAL) {
+ /* PHY may not generate a 156.25 MHz clock and MAC
+ * stats fetch will fail. */
+ efx_stats_disable(efx);
sfn4111t_reset(efx);
+ }
rc = sft9001_wait_boot(efx);
if (rc == 0)
return 0;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index b56617f..1971166 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -390,8 +390,8 @@ static int tenxpress_special_reset(struct efx_nic *efx)
/* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
* a special software reset can glitch the XGMAC sufficiently for stats
- * requests to fail. Since we don't often special_reset, just lock. */
- spin_lock(&efx->stats_lock);
+ * requests to fail. */
+ efx_stats_disable(efx);
/* Initiate reset */
reg = mdio_clause45_read(efx, efx->mii.phy_id,
@@ -406,17 +406,17 @@ static int tenxpress_special_reset(struct efx_nic *efx)
rc = mdio_clause45_wait_reset_mmds(efx,
TENXPRESS_REQUIRED_DEVS);
if (rc < 0)
- goto unlock;
+ goto out;
/* Try and reconfigure the device */
rc = tenxpress_init(efx);
if (rc < 0)
- goto unlock;
+ goto out;
/* Wait for the XGXS state machine to churn */
mdelay(10);
-unlock:
- spin_unlock(&efx->stats_lock);
+out:
+ efx_stats_enable(efx);
return rc;
}
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH 03/20] sfc: SFT9001: Enable robust link training
2009-01-29 19:17 ` [PATCH 03/20] sfc: SFT9001: Enable robust link training Ben Hutchings
@ 2009-01-29 19:23 ` Ben Hutchings
0 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:23 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
On Thu, 2009-01-29 at 19:17 +0000, Ben Hutchings wrote:
> Enable a firmware option that appears to be necessary for reliable
> operation.
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.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 04/20] sfc: SFX7101: Remove workaround for bad link training
2009-01-29 19:17 ` [PATCH 04/20] sfc: SFX7101: Remove workaround for bad " Ben Hutchings
@ 2009-01-29 19:23 ` Ben Hutchings
0 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-29 19:23 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
On Thu, 2009-01-29 at 19:17 +0000, Ben Hutchings wrote:
> 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.
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.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
` (19 preceding siblings ...)
2009-01-29 19:22 ` [PATCH 20/20] sfc: Replace stats_enabled flag with a disable count Ben Hutchings
@ 2009-01-29 23:26 ` David Miller
2009-01-30 1:05 ` Ben Hutchings
20 siblings, 1 reply; 40+ messages in thread
From: David Miller @ 2009-01-29 23:26 UTC (permalink / raw)
To: bhutchings; +Cc: netdev, linux-net-drivers
I'm not taking a blob of 20 patches to a driver outside of the merge
window, no freakin' way.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29
2009-01-29 23:26 ` [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 David Miller
@ 2009-01-30 1:05 ` Ben Hutchings
2009-01-30 1:08 ` David Miller
0 siblings, 1 reply; 40+ messages in thread
From: Ben Hutchings @ 2009-01-30 1:05 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
David Miller wrote:
>
> I'm not taking a blob of 20 patches to a driver outside of the merge
> window, no freakin' way.
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.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29
2009-01-30 1:05 ` Ben Hutchings
@ 2009-01-30 1:08 ` David Miller
2009-01-30 3:48 ` [PATCH 01/11] sfc: SFT9001: Enable robust link training Ben Hutchings
` (10 more replies)
0 siblings, 11 replies; 40+ messages in thread
From: David Miller @ 2009-01-30 1:08 UTC (permalink / raw)
To: bhutchings; +Cc: netdev, linux-net-drivers
From: Ben Hutchings <bhutchings@solarflare.com>
Date: Fri, 30 Jan 2009 01:05:43 +0000
> Please take at least the patches in group 1. I will re-send if you
> wish.
Please resend the pure bug fixes. Thank you.
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 01/11] sfc: SFT9001: Enable robust link training
2009-01-30 1:08 ` David Miller
@ 2009-01-30 3:48 ` Ben Hutchings
2009-01-30 22:09 ` David Miller
2009-01-30 3:48 ` [PATCH 02/11] sfc: SFX7101: Remove workaround for bad " Ben Hutchings
` (9 subsequent siblings)
10 siblings, 1 reply; 40+ messages in thread
From: Ben Hutchings @ 2009-01-30 3:48 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 02/11] sfc: SFX7101: Remove workaround for bad link training
2009-01-30 1:08 ` David Miller
2009-01-30 3:48 ` [PATCH 01/11] sfc: SFT9001: Enable robust link training Ben Hutchings
@ 2009-01-30 3:48 ` Ben Hutchings
2009-01-30 3:49 ` [PATCH 03/11] sfc: SFT9001: Fix speed reporting in 1G PHY loopback Ben Hutchings
` (8 subsequent siblings)
10 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-30 3:48 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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 */
#define LNPGA_PDOWN_WAIT (HZ / 5)
-static int crc_error_reset_threshold = 100;
-module_param(crc_error_reset_threshold, int, 0644);
-MODULE_PARM_DESC(crc_error_reset_threshold,
- "Max number of CRC errors before XAUI reset");
-
struct tenxpress_phy_data {
enum efx_loopback_mode loopback_mode;
- atomic_t bad_crc_count;
enum efx_phy_mode phy_mode;
int bad_lp_tries;
};
-void tenxpress_crc_err(struct efx_nic *efx)
-{
- struct tenxpress_phy_data *phy_data = efx->phy_data;
- if (phy_data != NULL)
- atomic_inc(&phy_data->bad_crc_count);
-}
-
static ssize_t show_phy_short_reach(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -627,13 +614,6 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
if (phy_data->phy_mode != PHY_MODE_NORMAL)
return;
-
- if (EFX_WORKAROUND_10750(efx) &&
- atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) {
- EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n");
- falcon_reset_xaui(efx);
- atomic_set(&phy_data->bad_crc_count, 0);
- }
}
static void tenxpress_phy_fini(struct efx_nic *efx)
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 82e03e1..797a0cf 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -18,7 +18,6 @@
#define EFX_WORKAROUND_ALWAYS(efx) 1
#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
-#define EFX_WORKAROUND_SFX7101(efx) ((efx)->phy_type == PHY_TYPE_SFX7101)
#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A)
/* XAUI resets if link not detected */
@@ -29,8 +28,6 @@
#define EFX_WORKAROUND_7884 EFX_WORKAROUND_10G
/* TX pkt parser problem with <= 16 byte TXes */
#define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS
-/* Low rate CRC errors require XAUI reset */
-#define EFX_WORKAROUND_10750 EFX_WORKAROUND_SFX7101
/* TX_EV_PKT_ERR can be caused by a dangling TX descriptor
* or a PCIe error (bug 11028) */
#define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 03/11] sfc: SFT9001: Fix speed reporting in 1G PHY loopback
2009-01-30 1:08 ` David Miller
2009-01-30 3:48 ` [PATCH 01/11] sfc: SFT9001: Enable robust link training Ben Hutchings
2009-01-30 3:48 ` [PATCH 02/11] sfc: SFX7101: Remove workaround for bad " Ben Hutchings
@ 2009-01-30 3:49 ` Ben Hutchings
2009-01-30 3:49 ` [PATCH 04/11] sfc: SFN4111T: Fix GPIO sharing between I2C and FLASH_CFG_1 Ben Hutchings
` (7 subsequent siblings)
10 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-30 3:49 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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 = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) ||
LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
- if (loop_reset || loop_toggle || loopback || phy_mode_change) {
+ if (loop_reset || phy_mode_change) {
int rc;
efx->phy_op->get_settings(efx, &ecmd);
@@ -542,20 +540,6 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
falcon_reset_xaui(efx);
}
- if (efx->phy_type != PHY_TYPE_SFX7101) {
- /* Only change autoneg once, on coming out or
- * going into loopback */
- if (loop_toggle)
- ecmd.autoneg = !loopback;
- if (loopback) {
- ecmd.duplex = DUPLEX_FULL;
- if (efx->loopback_mode == LOOPBACK_GPHY)
- ecmd.speed = SPEED_1000;
- else
- ecmd.speed = SPEED_10000;
- }
- }
-
rc = efx->phy_op->set_settings(efx, &ecmd);
WARN_ON(rc);
}
@@ -813,6 +797,13 @@ static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ?
DUPLEX_FULL : DUPLEX_HALF);
}
+
+ /* In loopback, the PHY automatically brings up the correct interface,
+ * but doesn't advertise the correct speed. So override it */
+ if (efx->loopback_mode == LOOPBACK_GPHY)
+ ecmd->speed = SPEED_1000;
+ else if (LOOPBACK_MASK(efx) & SFT9001_LOOPBACKS)
+ ecmd->speed = SPEED_10000;
}
static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 797a0cf..420fe15 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -19,6 +19,8 @@
#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A)
+#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \
+ (efx)->phy_type == PHY_TYPE_SFT9001B)
/* XAUI resets if link not detected */
#define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS
@@ -56,4 +58,7 @@
/* Need to keep AN enabled */
#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A
+/* Don't restart AN in near-side loopback */
+#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001
+
#endif /* EFX_WORKAROUNDS_H */
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 04/11] sfc: SFN4111T: Fix GPIO sharing between I2C and FLASH_CFG_1
2009-01-30 1:08 ` David Miller
` (2 preceding siblings ...)
2009-01-30 3:49 ` [PATCH 03/11] sfc: SFT9001: Fix speed reporting in 1G PHY loopback Ben Hutchings
@ 2009-01-30 3:49 ` Ben Hutchings
2009-01-30 3:49 ` [PATCH 05/11] sfc: Fix post-reset MAC selection Ben Hutchings
` (6 subsequent siblings)
10 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-30 3:49 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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, ®, GPIO_CTL_REG_KER);
EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true);
- EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, false);
falcon_write(efx, ®, 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, ®, 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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 05/11] sfc: Fix post-reset MAC selection
2009-01-30 1:08 ` David Miller
` (3 preceding siblings ...)
2009-01-30 3:49 ` [PATCH 04/11] sfc: SFN4111T: Fix GPIO sharing between I2C and FLASH_CFG_1 Ben Hutchings
@ 2009-01-30 3:49 ` Ben Hutchings
2009-01-30 3:50 ` [PATCH 06/11] sfc: Reinitialise the PHY completely in case of a PHY or NIC reset Ben Hutchings
` (5 subsequent siblings)
10 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-30 3:49 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 06/11] sfc: Reinitialise the PHY completely in case of a PHY or NIC reset
2009-01-30 1:08 ` David Miller
` (4 preceding siblings ...)
2009-01-30 3:49 ` [PATCH 05/11] sfc: Fix post-reset MAC selection Ben Hutchings
@ 2009-01-30 3:50 ` Ben Hutchings
2009-01-30 3:51 ` [PATCH 07/11] sfc: Test for PHYXS faults whenever we cannot test link state bits Ben Hutchings
` (4 subsequent siblings)
10 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-30 3:50 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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, bool ok)
+int efx_reset_up(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd, bool ok)
{
int rc;
@@ -1658,6 +1661,15 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
ok = false;
}
+ if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) {
+ if (ok) {
+ rc = efx->phy_op->init(efx);
+ if (rc)
+ ok = false;
+ } else
+ efx->port_initialized = false;
+ }
+
if (ok) {
efx_init_channels(efx);
@@ -1702,7 +1714,7 @@ static int efx_reset(struct efx_nic *efx)
EFX_INFO(efx, "resetting (%d)\n", method);
- efx_reset_down(efx, &ecmd);
+ efx_reset_down(efx, method, &ecmd);
rc = falcon_reset_hw(efx, method);
if (rc) {
@@ -1721,10 +1733,10 @@ static int efx_reset(struct efx_nic *efx)
/* Leave device stopped if necessary */
if (method == RESET_TYPE_DISABLE) {
- efx_reset_up(efx, &ecmd, false);
+ efx_reset_up(efx, method, &ecmd, false);
rc = -EIO;
} else {
- rc = efx_reset_up(efx, &ecmd, true);
+ rc = efx_reset_up(efx, method, &ecmd, true);
}
out_disable:
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 0dd7a53..ac20158 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -40,9 +40,10 @@ extern void efx_reconfigure_port(struct efx_nic *efx);
extern void __efx_reconfigure_port(struct efx_nic *efx);
/* Reset handling */
-extern void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd);
-extern int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd,
- bool ok);
+extern void efx_reset_down(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd);
+extern int efx_reset_up(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd, bool ok);
/* Global */
extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index dba0d64..0a59808 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -665,6 +665,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
{
enum efx_loopback_mode loopback_mode = efx->loopback_mode;
int phy_mode = efx->phy_mode;
+ enum reset_type reset_method = RESET_TYPE_INVISIBLE;
struct ethtool_cmd ecmd;
struct efx_channel *channel;
int rc_test = 0, rc_reset = 0, rc;
@@ -718,21 +719,21 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
mutex_unlock(&efx->mac_lock);
/* free up all consumers of SRAM (including all the queues) */
- efx_reset_down(efx, &ecmd);
+ efx_reset_down(efx, reset_method, &ecmd);
rc = efx_test_chip(efx, tests);
if (rc && !rc_test)
rc_test = rc;
/* reset the chip to recover from the register test */
- rc_reset = falcon_reset_hw(efx, RESET_TYPE_ALL);
+ rc_reset = falcon_reset_hw(efx, reset_method);
/* Ensure that the phy is powered and out of loopback
* for the bist and loopback tests */
efx->phy_mode &= ~PHY_MODE_LOW_POWER;
efx->loopback_mode = LOOPBACK_NONE;
- rc = efx_reset_up(efx, &ecmd, rc_reset == 0);
+ rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0);
if (rc && !rc_reset)
rc_reset = rc;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index bc2833f..c958461 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -337,6 +337,7 @@ static int tenxpress_phy_init(struct efx_nic *efx)
rc = tenxpress_init(efx);
if (rc < 0)
goto fail;
+ mdio_clause45_set_pause(efx);
if (efx->phy_type == PHY_TYPE_SFT9001B) {
rc = device_create_file(&efx->pci_dev->dev,
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 07/11] sfc: Test for PHYXS faults whenever we cannot test link state bits
2009-01-30 1:08 ` David Miller
` (5 preceding siblings ...)
2009-01-30 3:50 ` [PATCH 06/11] sfc: Reinitialise the PHY completely in case of a PHY or NIC reset Ben Hutchings
@ 2009-01-30 3:51 ` Ben Hutchings
2009-01-30 3:51 ` [PATCH 08/11] sfc: Update board info for hardware monitor on SFN4111T-R5 and later Ben Hutchings
` (3 subsequent siblings)
10 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-30 3:51 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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 marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 08/11] sfc: Update board info for hardware monitor on SFN4111T-R5 and later
2009-01-30 1:08 ` David Miller
` (6 preceding siblings ...)
2009-01-30 3:51 ` [PATCH 07/11] sfc: Test for PHYXS faults whenever we cannot test link state bits Ben Hutchings
@ 2009-01-30 3:51 ` Ben Hutchings
2009-01-30 3:52 ` [PATCH 09/11] sfc: SFT9001: Always enable XNP exchange on SFT9001 rev B Ben Hutchings
` (2 subsequent siblings)
10 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-30 3:51 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 09/11] sfc: SFT9001: Always enable XNP exchange on SFT9001 rev B
2009-01-30 1:08 ` David Miller
` (7 preceding siblings ...)
2009-01-30 3:51 ` [PATCH 08/11] sfc: Update board info for hardware monitor on SFN4111T-R5 and later Ben Hutchings
@ 2009-01-30 3:52 ` Ben Hutchings
2009-01-30 3:59 ` [PATCH 10/11] sfc: SFX7101/SFT9001: Fix AN advertisements Ben Hutchings
2009-01-30 4:00 ` [PATCH 11/11] sfc: Replace stats_enabled flag with a disable count Ben Hutchings
10 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-30 3:52 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 10/11] sfc: SFX7101/SFT9001: Fix AN advertisements
2009-01-30 1:08 ` David Miller
` (8 preceding siblings ...)
2009-01-30 3:52 ` [PATCH 09/11] sfc: SFT9001: Always enable XNP exchange on SFT9001 rev B Ben Hutchings
@ 2009-01-30 3:59 ` Ben Hutchings
2009-01-30 4:00 ` [PATCH 11/11] sfc: Replace stats_enabled flag with a disable count Ben Hutchings
10 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-30 3:59 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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)
{
int phy_id = efx->mii.phy_id;
u32 result = 0;
@@ -281,9 +281,6 @@ static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp)
result |= ADVERTISED_100baseT_Half;
if (reg & ADVERTISE_100FULL)
result |= ADVERTISED_100baseT_Full;
- if (reg & LPA_RESV)
- result |= xnp;
-
return result;
}
@@ -313,7 +310,7 @@ void mdio_clause45_get_settings(struct efx_nic *efx,
*/
void mdio_clause45_get_settings_ext(struct efx_nic *efx,
struct ethtool_cmd *ecmd,
- u32 xnp, u32 xnp_lpa)
+ u32 npage_adv, u32 npage_lpa)
{
int phy_id = efx->mii.phy_id;
int reg;
@@ -364,8 +361,8 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx,
ecmd->autoneg = AUTONEG_ENABLE;
ecmd->advertising |=
ADVERTISED_Autoneg |
- mdio_clause45_get_an(efx,
- MDIO_AN_ADVERTISE, xnp);
+ mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) |
+ npage_adv;
} else
ecmd->autoneg = AUTONEG_DISABLE;
} else
@@ -374,27 +371,30 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx,
if (ecmd->autoneg) {
/* If AN is complete, report best common mode,
* otherwise report best advertised mode. */
- u32 common = ecmd->advertising;
+ u32 modes = 0;
if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
MDIO_MMDREG_STAT1) &
- (1 << MDIO_AN_STATUS_AN_DONE_LBN)) {
- common &= mdio_clause45_get_an(efx, MDIO_AN_LPA,
- xnp_lpa);
- }
- if (common & ADVERTISED_10000baseT_Full) {
+ (1 << MDIO_AN_STATUS_AN_DONE_LBN))
+ modes = (ecmd->advertising &
+ (mdio_clause45_get_an(efx, MDIO_AN_LPA) |
+ npage_lpa));
+ if (modes == 0)
+ modes = ecmd->advertising;
+
+ if (modes & ADVERTISED_10000baseT_Full) {
ecmd->speed = SPEED_10000;
ecmd->duplex = DUPLEX_FULL;
- } else if (common & (ADVERTISED_1000baseT_Full |
- ADVERTISED_1000baseT_Half)) {
+ } else if (modes & (ADVERTISED_1000baseT_Full |
+ ADVERTISED_1000baseT_Half)) {
ecmd->speed = SPEED_1000;
- ecmd->duplex = !!(common & ADVERTISED_1000baseT_Full);
- } else if (common & (ADVERTISED_100baseT_Full |
- ADVERTISED_100baseT_Half)) {
+ ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full);
+ } else if (modes & (ADVERTISED_100baseT_Full |
+ ADVERTISED_100baseT_Half)) {
ecmd->speed = SPEED_100;
- ecmd->duplex = !!(common & ADVERTISED_100baseT_Full);
+ ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
} else {
ecmd->speed = SPEED_10;
- ecmd->duplex = !!(common & ADVERTISED_10baseT_Full);
+ ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
}
} else {
/* Report forced settings */
@@ -418,7 +418,7 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
int phy_id = efx->mii.phy_id;
struct ethtool_cmd prev;
u32 required;
- int ctrl1_bits, reg;
+ int reg;
efx->phy_op->get_settings(efx, &prev);
@@ -433,102 +433,83 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
if (prev.port != PORT_TP || ecmd->port != PORT_TP)
return -EINVAL;
- /* Check that PHY supports these settings and work out the
- * basic control bits */
- if (ecmd->duplex) {
+ /* Check that PHY supports these settings */
+ if (ecmd->autoneg) {
+ required = SUPPORTED_Autoneg;
+ } else if (ecmd->duplex) {
switch (ecmd->speed) {
- case SPEED_10:
- ctrl1_bits = BMCR_FULLDPLX;
- required = SUPPORTED_10baseT_Full;
- break;
- case SPEED_100:
- ctrl1_bits = BMCR_SPEED100 | BMCR_FULLDPLX;
- required = SUPPORTED_100baseT_Full;
- break;
- case SPEED_1000:
- ctrl1_bits = BMCR_SPEED1000 | BMCR_FULLDPLX;
- required = SUPPORTED_1000baseT_Full;
- break;
- case SPEED_10000:
- ctrl1_bits = (BMCR_SPEED1000 | BMCR_SPEED100 |
- BMCR_FULLDPLX);
- required = SUPPORTED_10000baseT_Full;
- break;
- default:
- return -EINVAL;
+ case SPEED_10: required = SUPPORTED_10baseT_Full; break;
+ case SPEED_100: required = SUPPORTED_100baseT_Full; break;
+ default: return -EINVAL;
}
} else {
switch (ecmd->speed) {
- case SPEED_10:
- ctrl1_bits = 0;
- required = SUPPORTED_10baseT_Half;
- break;
- case SPEED_100:
- ctrl1_bits = BMCR_SPEED100;
- required = SUPPORTED_100baseT_Half;
- break;
- case SPEED_1000:
- ctrl1_bits = BMCR_SPEED1000;
- required = SUPPORTED_1000baseT_Half;
- break;
- default:
- return -EINVAL;
+ case SPEED_10: required = SUPPORTED_10baseT_Half; break;
+ case SPEED_100: required = SUPPORTED_100baseT_Half; break;
+ default: return -EINVAL;
}
}
- if (ecmd->autoneg)
- required |= SUPPORTED_Autoneg;
required |= ecmd->advertising;
if (required & ~prev.supported)
return -EINVAL;
- /* Set the basic control bits */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL1);
- reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | 0x003c);
- reg |= ctrl1_bits;
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL1,
- reg);
-
- /* Set the AN registers */
- if (ecmd->autoneg != prev.autoneg ||
- ecmd->advertising != prev.advertising) {
- bool xnp = false;
-
- if (efx->phy_op->set_xnp_advertise)
- xnp = efx->phy_op->set_xnp_advertise(efx,
- ecmd->advertising);
-
- if (ecmd->autoneg) {
- reg = 0;
- if (ecmd->advertising & ADVERTISED_10baseT_Half)
- reg |= ADVERTISE_10HALF;
- if (ecmd->advertising & ADVERTISED_10baseT_Full)
- reg |= ADVERTISE_10FULL;
- if (ecmd->advertising & ADVERTISED_100baseT_Half)
- reg |= ADVERTISE_100HALF;
- if (ecmd->advertising & ADVERTISED_100baseT_Full)
- reg |= ADVERTISE_100FULL;
- if (xnp)
- reg |= ADVERTISE_RESV;
- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_ADVERTISE, reg);
- }
+ if (ecmd->autoneg) {
+ bool xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full
+ || EFX_WORKAROUND_13204(efx));
+
+ /* Set up the base page */
+ reg = ADVERTISE_CSMA;
+ if (ecmd->advertising & ADVERTISED_10baseT_Half)
+ reg |= ADVERTISE_10HALF;
+ if (ecmd->advertising & ADVERTISED_10baseT_Full)
+ reg |= ADVERTISE_10FULL;
+ if (ecmd->advertising & ADVERTISED_100baseT_Half)
+ reg |= ADVERTISE_100HALF;
+ if (ecmd->advertising & ADVERTISED_100baseT_Full)
+ reg |= ADVERTISE_100FULL;
+ if (xnp)
+ reg |= ADVERTISE_RESV;
+ else if (ecmd->advertising & (ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full))
+ reg |= ADVERTISE_NPAGE;
+ reg |= efx_fc_advertise(efx->wanted_fc);
+ mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_ADVERTISE, reg);
+
+ /* Set up the (extended) next page if necessary */
+ if (efx->phy_op->set_npage_adv)
+ efx->phy_op->set_npage_adv(efx, ecmd->advertising);
+ /* Enable and restart AN */
reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
MDIO_MMDREG_CTRL1);
- if (ecmd->autoneg)
- reg |= BMCR_ANENABLE | BMCR_ANRESTART;
- else
- reg &= ~BMCR_ANENABLE;
- if (EFX_WORKAROUND_15195(efx)
- && LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
- reg &= ~BMCR_ANRESTART;
+ 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
reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN);
mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
MDIO_MMDREG_CTRL1, reg);
+ } else {
+ /* Disable AN */
+ mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
+ MDIO_MMDREG_CTRL1,
+ __ffs(BMCR_ANENABLE), false);
+
+ /* Set the basic control bits */
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
+ MDIO_MMDREG_CTRL1);
+ reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX |
+ 0x003c);
+ if (ecmd->speed == SPEED_100)
+ reg |= BMCR_SPEED100;
+ if (ecmd->duplex)
+ reg |= BMCR_FULLDPLX;
+ mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
+ MDIO_MMDREG_CTRL1, reg);
}
return 0;
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 09bf801..8ba4977 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -155,7 +155,8 @@
#define MDIO_AN_XNP 22
#define MDIO_AN_LPA_XNP 25
-#define MDIO_AN_10GBT_ADVERTISE 32
+#define MDIO_AN_10GBT_CTRL 32
+#define MDIO_AN_10GBT_CTRL_ADV_10G_LBN 12
#define MDIO_AN_10GBT_STATUS (33)
#define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */
#define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 5f255f7..8eb411a 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -566,7 +566,7 @@ struct efx_mac_operations {
* @poll: Poll for hardware state. Serialised by the mac_lock.
* @get_settings: Get ethtool settings. Serialised by the mac_lock.
* @set_settings: Set ethtool settings. Serialised by the mac_lock.
- * @set_xnp_advertise: Set abilities advertised in Extended Next Page
+ * @set_npage_adv: Set abilities advertised in (Extended) Next Page
* (only needed where AN bit is set in mmds)
* @num_tests: Number of PHY-specific tests/results
* @test_names: Names of the tests/results
@@ -586,7 +586,7 @@ struct efx_phy_operations {
struct ethtool_cmd *ecmd);
int (*set_settings) (struct efx_nic *efx,
struct ethtool_cmd *ecmd);
- bool (*set_xnp_advertise) (struct efx_nic *efx, u32);
+ void (*set_npage_adv) (struct efx_nic *efx, u32);
u32 num_tests;
const char *const *test_names;
int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags);
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index c958461..412d209 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -179,11 +179,13 @@
#define C22EXT_STATUS_LINK_LBN 2
#define C22EXT_STATUS_LINK_WIDTH 1
-#define C22EXT_MSTSLV_REG 49162
-#define C22EXT_MSTSLV_1000_HD_LBN 10
-#define C22EXT_MSTSLV_1000_HD_WIDTH 1
-#define C22EXT_MSTSLV_1000_FD_LBN 11
-#define C22EXT_MSTSLV_1000_FD_WIDTH 1
+#define C22EXT_MSTSLV_CTRL 49161
+#define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8
+#define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9
+
+#define C22EXT_MSTSLV_STATUS 49162
+#define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10
+#define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11
/* Time to wait between powering down the LNPGA and turning off the power
* rails */
@@ -741,114 +743,76 @@ reset:
return rc;
}
-static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx)
+static void
+tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy = efx->mii.phy_id;
- u32 lpa = 0;
+ int phy_id = efx->mii.phy_id;
+ u32 adv = 0, lpa = 0;
int reg;
if (efx->phy_type != PHY_TYPE_SFX7101) {
- reg = mdio_clause45_read(efx, phy, MDIO_MMD_C22EXT,
- C22EXT_MSTSLV_REG);
- if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN))
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
+ C22EXT_MSTSLV_CTRL);
+ if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN))
+ adv |= ADVERTISED_1000baseT_Full;
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
+ C22EXT_MSTSLV_STATUS);
+ if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
lpa |= ADVERTISED_1000baseT_Half;
- if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN))
+ if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
lpa |= ADVERTISED_1000baseT_Full;
}
- reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS);
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_CTRL);
+ if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN))
+ adv |= ADVERTISED_10000baseT_Full;
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_STATUS);
if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN))
lpa |= ADVERTISED_10000baseT_Full;
- return lpa;
-}
-
-static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
-{
- mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full,
- tenxpress_get_xnp_lpa(efx));
- ecmd->supported |= SUPPORTED_10000baseT_Full;
- ecmd->advertising |= ADVERTISED_10000baseT_Full;
-}
-
-static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
-{
- int phy_id = efx->mii.phy_id;
- u32 xnp_adv = 0;
- int reg;
-
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_SPEED_ENABLE_REG);
- if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN)))
- xnp_adv |= ADVERTISED_100baseT_Full;
- if (reg & (1 << PMA_PMD_1000T_ADV_LBN))
- xnp_adv |= ADVERTISED_1000baseT_Full;
- if (reg & (1 << PMA_PMD_10000T_ADV_LBN))
- xnp_adv |= ADVERTISED_10000baseT_Full;
-
- mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv,
- tenxpress_get_xnp_lpa(efx));
- ecmd->supported |= (SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full);
+ mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa);
- /* Use the vendor defined C22ext register for duplex settings */
- if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG);
- ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ?
- DUPLEX_FULL : DUPLEX_HALF);
- }
+ if (efx->phy_type != PHY_TYPE_SFX7101)
+ ecmd->supported |= (SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full);
/* In loopback, the PHY automatically brings up the correct interface,
* but doesn't advertise the correct speed. So override it */
if (efx->loopback_mode == LOOPBACK_GPHY)
ecmd->speed = SPEED_1000;
- else if (LOOPBACK_MASK(efx) & SFT9001_LOOPBACKS)
+ else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
ecmd->speed = SPEED_10000;
}
-static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy_id = efx->mii.phy_id;
- int rc;
-
- rc = mdio_clause45_set_settings(efx, ecmd);
- if (rc)
- return rc;
+ if (!ecmd->autoneg)
+ return -EINVAL;
- if (ecmd->speed != SPEED_10000 && !ecmd->autoneg)
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN,
- ecmd->duplex == DUPLEX_FULL);
+ return mdio_clause45_set_settings(efx, ecmd);
+}
- return rc;
+static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
+{
+ mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_CTRL,
+ MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
+ advertising & ADVERTISED_10000baseT_Full);
}
-static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising)
+static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
{
- int phy = efx->mii.phy_id;
- int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD,
- PMA_PMD_SPEED_ENABLE_REG);
- bool enabled;
-
- reg &= ~((1 << 2) | (1 << 3));
- if (EFX_WORKAROUND_13204(efx) &&
- (advertising & ADVERTISED_100baseT_Full))
- reg |= 1 << PMA_PMD_100TX_ADV_LBN;
- if (advertising & ADVERTISED_1000baseT_Full)
- reg |= 1 << PMA_PMD_1000T_ADV_LBN;
- if (advertising & ADVERTISED_10000baseT_Full)
- reg |= 1 << PMA_PMD_10000T_ADV_LBN;
- mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD,
- PMA_PMD_SPEED_ENABLE_REG, reg);
-
- enabled = (advertising &
- (ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full |
- ADVERTISED_10000baseT_Full));
- if (EFX_WORKAROUND_13204(efx))
- enabled |= (advertising & ADVERTISED_100baseT_Full);
- return enabled;
+ int phy_id = efx->mii.phy_id;
+
+ mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
+ C22EXT_MSTSLV_CTRL,
+ C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
+ advertising & ADVERTISED_1000baseT_Full);
+ mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_CTRL,
+ MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
+ advertising & ADVERTISED_10000baseT_Full);
}
struct efx_phy_operations falcon_sfx7101_phy_ops = {
@@ -858,8 +822,9 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = {
.poll = tenxpress_phy_poll,
.fini = tenxpress_phy_fini,
.clear_interrupt = efx_port_dummy_op_void,
- .get_settings = sfx7101_get_settings,
- .set_settings = mdio_clause45_set_settings,
+ .get_settings = tenxpress_get_settings,
+ .set_settings = tenxpress_set_settings,
+ .set_npage_adv = sfx7101_set_npage_adv,
.num_tests = ARRAY_SIZE(sfx7101_test_names),
.test_names = sfx7101_test_names,
.run_tests = sfx7101_run_tests,
@@ -874,9 +839,9 @@ struct efx_phy_operations falcon_sft9001_phy_ops = {
.poll = tenxpress_phy_poll,
.fini = tenxpress_phy_fini,
.clear_interrupt = efx_port_dummy_op_void,
- .get_settings = sft9001_get_settings,
- .set_settings = sft9001_set_settings,
- .set_xnp_advertise = sft9001_set_xnp_advertise,
+ .get_settings = tenxpress_get_settings,
+ .set_settings = tenxpress_set_settings,
+ .set_npage_adv = sft9001_set_npage_adv,
.num_tests = ARRAY_SIZE(sft9001_test_names),
.test_names = sft9001_test_names,
.run_tests = sft9001_run_tests,
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index b810dcd..78de68f 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -18,7 +18,6 @@
#define EFX_WORKAROUND_ALWAYS(efx) 1
#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
-#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A)
#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \
(efx)->phy_type == PHY_TYPE_SFT9001B)
@@ -55,9 +54,6 @@
/* Need to send XNP pages for 100BaseT */
#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001
-/* Need to keep AN enabled */
-#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A
-
/* Don't restart AN in near-side loopback */
#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* [PATCH 11/11] sfc: Replace stats_enabled flag with a disable count
2009-01-30 1:08 ` David Miller
` (9 preceding siblings ...)
2009-01-30 3:59 ` [PATCH 10/11] sfc: SFX7101/SFT9001: Fix AN advertisements Ben Hutchings
@ 2009-01-30 4:00 ` Ben Hutchings
10 siblings, 0 replies; 40+ messages in thread
From: Ben Hutchings @ 2009-01-30 4:00 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
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 possible, but do not wait if another thread
- * is updating them (or resetting the NIC); slightly stale
- * stats are acceptable.
+ * is updating them or if MAC stats fetches are temporarily
+ * disabled; slightly stale stats are acceptable.
*/
if (!spin_trylock(&efx->stats_lock))
return stats;
- if (efx->stats_enabled) {
+ if (!efx->stats_disable_count) {
efx->mac_op->update_stats(efx);
falcon_update_nic_stats(efx);
}
@@ -1626,12 +1641,7 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method,
{
EFX_ASSERT_RESET_SERIALISED(efx);
- /* The net_dev->get_stats handler is quite slow, and will fail
- * if a fetch is pending over reset. Serialise against it. */
- spin_lock(&efx->stats_lock);
- efx->stats_enabled = false;
- spin_unlock(&efx->stats_lock);
-
+ efx_stats_disable(efx);
efx_stop_all(efx);
mutex_lock(&efx->mac_lock);
mutex_lock(&efx->spi_lock);
@@ -1682,7 +1692,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method,
if (ok) {
efx_start_all(efx);
- efx->stats_enabled = true;
+ efx_stats_enable(efx);
}
return rc;
}
@@ -1888,6 +1898,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
efx->rx_checksum_enabled = true;
spin_lock_init(&efx->netif_stop_lock);
spin_lock_init(&efx->stats_lock);
+ efx->stats_disable_count = 1;
mutex_init(&efx->mac_lock);
efx->mac_op = &efx_dummy_mac_operations;
efx->phy_op = &efx_dummy_phy_operations;
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index ac20158..55d0f13 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -36,6 +36,8 @@ extern void efx_process_channel_now(struct efx_channel *channel);
extern void efx_flush_queues(struct efx_nic *efx);
/* Ports */
+extern void efx_stats_disable(struct efx_nic *efx);
+extern void efx_stats_enable(struct efx_nic *efx);
extern void efx_reconfigure_port(struct efx_nic *efx);
extern void __efx_reconfigure_port(struct efx_nic *efx);
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index d9412f8..d5378e6 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1883,7 +1883,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
/* MAC stats will fail whilst the TX fifo is draining. Serialise
* the drain sequence with the statistics fetch */
- spin_lock(&efx->stats_lock);
+ efx_stats_disable(efx);
falcon_read(efx, ®, MAC0_CTRL_REG_KER);
EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1);
@@ -1913,7 +1913,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
udelay(10);
}
- spin_unlock(&efx->stats_lock);
+ efx_stats_enable(efx);
/* If we've reset the EM block and the link is up, then
* we'll have to kick the XAUI link so the PHY can recover */
@@ -2273,6 +2273,10 @@ int falcon_switch_mac(struct efx_nic *efx)
struct efx_mac_operations *old_mac_op = efx->mac_op;
efx_oword_t nic_stat;
unsigned strap_val;
+ int rc = 0;
+
+ /* Don't try to fetch MAC stats while we're switching MACs */
+ efx_stats_disable(efx);
/* Internal loopbacks override the phy speed setting */
if (efx->loopback_mode == LOOPBACK_GMAC) {
@@ -2302,13 +2306,16 @@ int falcon_switch_mac(struct efx_nic *efx)
}
if (old_mac_op == efx->mac_op)
- return 0;
+ goto out;
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);
+ rc = falcon_reset_macs(efx);
+out:
+ efx_stats_enable(efx);
+ return rc;
}
/* This call is responsible for hooking in the MAC and PHY operations */
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 8eb411a..e019ad1 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -754,8 +754,7 @@ union efx_multicast_hash {
* &struct net_device_stats.
* @stats_buffer: DMA buffer for statistics
* @stats_lock: Statistics update lock. Serialises statistics fetches
- * @stats_enabled: Temporarily disable statistics fetches.
- * Serialised by @stats_lock
+ * @stats_disable_count: Nest count for disabling statistics fetches
* @mac_op: MAC interface
* @mac_address: Permanent MAC address
* @phy_type: PHY type
@@ -837,7 +836,7 @@ struct efx_nic {
struct efx_mac_stats mac_stats;
struct efx_buffer stats_buffer;
spinlock_t stats_lock;
- bool stats_enabled;
+ unsigned int stats_disable_count;
struct efx_mac_operations *mac_op;
unsigned char mac_address[ETH_ALEN];
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 853057e..cb25ae5 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -235,12 +235,18 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
} else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
err = -EBUSY;
} else {
+ /* Reset the PHY, reconfigure the MAC and enable/disable
+ * MAC stats accordingly. */
efx->phy_mode = new_mode;
+ if (new_mode & PHY_MODE_SPECIAL)
+ efx_stats_disable(efx);
if (efx->board_info.type == EFX_BOARD_SFE4001)
err = sfe4001_poweron(efx);
else
err = sfn4111t_reset(efx);
efx_reconfigure_port(efx);
+ if (!(new_mode & PHY_MODE_SPECIAL))
+ efx_stats_enable(efx);
}
rtnl_unlock();
@@ -329,6 +335,11 @@ int sfe4001_init(struct efx_nic *efx)
efx->board_info.monitor = sfe4001_check_hw;
efx->board_info.fini = sfe4001_fini;
+ if (efx->phy_mode & PHY_MODE_SPECIAL) {
+ /* PHY won't generate a 156.25 MHz clock and MAC stats fetch
+ * will fail. */
+ efx_stats_disable(efx);
+ }
rc = sfe4001_poweron(efx);
if (rc)
goto fail_ioexp;
@@ -405,8 +416,10 @@ int sfn4111t_init(struct efx_nic *efx)
if (rc)
goto fail_hwmon;
- if (efx->phy_mode & PHY_MODE_SPECIAL)
+ if (efx->phy_mode & PHY_MODE_SPECIAL) {
+ efx_stats_disable(efx);
sfn4111t_reset(efx);
+ }
return 0;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 412d209..f0efd24 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -370,8 +370,8 @@ static int tenxpress_special_reset(struct efx_nic *efx)
/* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
* a special software reset can glitch the XGMAC sufficiently for stats
- * requests to fail. Since we don't often special_reset, just lock. */
- spin_lock(&efx->stats_lock);
+ * requests to fail. */
+ efx_stats_disable(efx);
/* Initiate reset */
reg = mdio_clause45_read(efx, efx->mii.phy_id,
@@ -386,17 +386,17 @@ static int tenxpress_special_reset(struct efx_nic *efx)
rc = mdio_clause45_wait_reset_mmds(efx,
TENXPRESS_REQUIRED_DEVS);
if (rc < 0)
- goto unlock;
+ goto out;
/* Try and reconfigure the device */
rc = tenxpress_init(efx);
if (rc < 0)
- goto unlock;
+ goto out;
/* Wait for the XGXS state machine to churn */
mdelay(10);
-unlock:
- spin_unlock(&efx->stats_lock);
+out:
+ efx_stats_enable(efx);
return rc;
}
--
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.
^ permalink raw reply related [flat|nested] 40+ messages in thread
* Re: [PATCH 01/11] sfc: SFT9001: Enable robust link training
2009-01-30 3:48 ` [PATCH 01/11] sfc: SFT9001: Enable robust link training Ben Hutchings
@ 2009-01-30 22:09 ` David Miller
2009-01-31 0:04 ` Ben Hutchings
0 siblings, 1 reply; 40+ messages in thread
From: David Miller @ 2009-01-30 22:09 UTC (permalink / raw)
To: bhutchings; +Cc: netdev, linux-net-drivers
From: Ben Hutchings <bhutchings@solarflare.com>
Date: Fri, 30 Jan 2009 03:48:10 +0000
> 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>
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 :-)
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 01/11] sfc: SFT9001: Enable robust link training
2009-01-31 0:04 ` Ben Hutchings
@ 2009-01-31 0:02 ` David Miller
0 siblings, 0 replies; 40+ messages in thread
From: David Miller @ 2009-01-31 0:02 UTC (permalink / raw)
To: bhutchings; +Cc: netdev, linux-net-drivers
From: Ben Hutchings <bhutchings@solarflare.com>
Date: Sat, 31 Jan 2009 00:04:15 +0000
> On Fri, 2009-01-30 at 14:09 -0800, David Miller wrote:
> > From: Ben Hutchings <bhutchings@solarflare.com>
> > Date: Fri, 30 Jan 2009 03:48:10 +0000
> >
> > > 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>
> >
> > 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.
>
> 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-
> off means?
Sure, but it is even more meaningful if the person who actually
wrote the changes signs off on it 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.
>
> Are you saying that a spurious self-test failure is not a serious bug?
Normal users will not run the self-test giblet, and it has
not been reported as a 2.6.29 regression on lkml.
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 01/11] sfc: SFT9001: Enable robust link training
2009-01-30 22:09 ` David Miller
@ 2009-01-31 0:04 ` Ben Hutchings
2009-01-31 0:02 ` David Miller
0 siblings, 1 reply; 40+ messages in thread
From: Ben Hutchings @ 2009-01-31 0:04 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
On Fri, 2009-01-30 at 14:09 -0800, David Miller wrote:
> From: Ben Hutchings <bhutchings@solarflare.com>
> Date: Fri, 30 Jan 2009 03:48:10 +0000
>
> > 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>
>
> 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.
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-
off means?
> 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.
Are you saying that a spurious self-test failure is not a serious bug?
> You have been warned :-)
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.
^ permalink raw reply [flat|nested] 40+ messages in thread
end of thread, other threads:[~2009-01-31 0:02 UTC | newest]
Thread overview: 40+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-29 19:12 [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 Ben Hutchings
2009-01-29 19:15 ` [PATCH 01/20] sfc: SFT9001: Include non-breaking cable diagnostics in online self-tests Ben Hutchings
2009-01-29 19:16 ` [PATCH 02/20] sfc: Fix test for MDIO read failure Ben Hutchings
2009-01-29 19:17 ` [PATCH 03/20] sfc: SFT9001: Enable robust link training Ben Hutchings
2009-01-29 19:23 ` Ben Hutchings
2009-01-29 19:17 ` [PATCH 04/20] sfc: SFX7101: Remove workaround for bad " Ben Hutchings
2009-01-29 19:23 ` Ben Hutchings
2009-01-29 19:17 ` [PATCH 05/20] sfc: SFT9001/SFN4111T: Check PHY boot status during board initialisation Ben Hutchings
2009-01-29 19:17 ` [PATCH 06/20] sfc: SFT9001: Fix speed reporting in 1G PHY loopback Ben Hutchings
2009-01-29 19:18 ` [PATCH 07/20] sfc: SFN4111T: Fix GPIO sharing between I2C and FLASH_CFG_1 Ben Hutchings
2009-01-29 19:19 ` [PATCH 08/20] sfc: Fix post-reset MAC selection Ben Hutchings
2009-01-29 19:19 ` [PATCH 09/20] sfc: Reinitialise the PHY completely in case of a PHY or NIC reset Ben Hutchings
2009-01-29 19:19 ` [PATCH 10/20] sfc: Test for PHYXS faults whenever we cannot test link state bits Ben Hutchings
2009-01-29 19:19 ` [PATCH 11/20] sfc: Update board info for hardware monitor on SFN4111T-R5 and later Ben Hutchings
2009-01-29 19:20 ` [PATCH 12/20] sfc: SFT9001: Always enable XNP exchange on SFT9001 rev B Ben Hutchings
2009-01-29 19:20 ` [PATCH 13/20] sfc: SFX7101/SFT9001: Fix AN advertisements Ben Hutchings
2009-01-29 19:20 ` [PATCH 14/20] sfc: Remove "XFP" from log messages that are not specific to XFP Ben Hutchings
2009-01-29 19:20 ` [PATCH 15/20] sfc: Fix reporting of PHY id Ben Hutchings
2009-01-29 19:21 ` [PATCH 16/20] sfc: Add support for QT2025C PHY Ben Hutchings
2009-01-29 19:21 ` [PATCH 17/20] sfc: Delete unused efx_blinker::led_num field Ben Hutchings
2009-01-29 19:21 ` [PATCH 18/20] sfc: Clean up LED control Ben Hutchings
2009-01-29 19:21 ` [PATCH 19/20] sfc: Add support for SFN4112F SFP+ reference design Ben Hutchings
2009-01-29 19:22 ` [PATCH 20/20] sfc: Replace stats_enabled flag with a disable count Ben Hutchings
2009-01-29 23:26 ` [PATCH 00/20] sfc: Fixes and new PHY support for 2.6.29 David Miller
2009-01-30 1:05 ` Ben Hutchings
2009-01-30 1:08 ` David Miller
2009-01-30 3:48 ` [PATCH 01/11] sfc: SFT9001: Enable robust link training Ben Hutchings
2009-01-30 22:09 ` David Miller
2009-01-31 0:04 ` Ben Hutchings
2009-01-31 0:02 ` David Miller
2009-01-30 3:48 ` [PATCH 02/11] sfc: SFX7101: Remove workaround for bad " Ben Hutchings
2009-01-30 3:49 ` [PATCH 03/11] sfc: SFT9001: Fix speed reporting in 1G PHY loopback Ben Hutchings
2009-01-30 3:49 ` [PATCH 04/11] sfc: SFN4111T: Fix GPIO sharing between I2C and FLASH_CFG_1 Ben Hutchings
2009-01-30 3:49 ` [PATCH 05/11] sfc: Fix post-reset MAC selection Ben Hutchings
2009-01-30 3:50 ` [PATCH 06/11] sfc: Reinitialise the PHY completely in case of a PHY or NIC reset Ben Hutchings
2009-01-30 3:51 ` [PATCH 07/11] sfc: Test for PHYXS faults whenever we cannot test link state bits Ben Hutchings
2009-01-30 3:51 ` [PATCH 08/11] sfc: Update board info for hardware monitor on SFN4111T-R5 and later Ben Hutchings
2009-01-30 3:52 ` [PATCH 09/11] sfc: SFT9001: Always enable XNP exchange on SFT9001 rev B Ben Hutchings
2009-01-30 3:59 ` [PATCH 10/11] sfc: SFX7101/SFT9001: Fix AN advertisements Ben Hutchings
2009-01-30 4:00 ` [PATCH 11/11] sfc: Replace stats_enabled flag with a disable count Ben Hutchings
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).