sfc version 2.3
Subsystems (2)
cover sfc version 2.3
The big changes here are to add support for Solarflare's new multi-speed PHY and reference design. There are also a number of small fixes, clean- up and new features.
Ben.
Ben Hutchings (31):
sfc: Board support fixes
sfc: Change SPI lengths to type size_t
sfc: Do not use pci_disable_device() to disable bus mastering
sfc: Remove unneeded register write
sfc: Correct interpretation of second param to ethtool phys_id()
sfc: Clean up waits for flash/EEPROM operations
sfc: Work around unreliable strap pins
sfc: Restore phy_flash_cfg module parameter
sfc: Provide hints to irqbalance daemon
sfc: Abbreviate self-test names so they are not truncated
sfc: Don't count RX checksum errors during loopback self-test
sfc: Remove MII extension cruft
sfc: Add support for MMDs numbered >15
sfc: Add phy_type device attribute
sfc: Clean up board identification
sfc: Clean up MDIO flag setting
sfc: Add support for sub-10G speeds
sfc: Implement auto-negotiation
sfc: Rework MAC, PHY and board event handling
sfc: Add support for Solarflare 10Xpress SFT9001
sfc: Add support for SFN4111T
sfc: Fix format arguments for warning about MSI-X allocation
sfc: Generate unique names for per-NIC workqueues
sfc: Remove leading spaces
sfc: Specify a meaningful component for loopback RX-side and PHY
tests
sfc: Use mutex_lock_interruptible() for ethtool EEPROM access
sfc: Use model numbers for PHY type names
sfc: Treat probe as unsuccessful if it scheduled a reset
sfc: Use kzalloc() to ensure struct efx_spi_device is fully
initialised
sfc: Fix synchronisation of efx_mtd_{probe,rename,remove}
sfc: Version 2.3
Neil Turton (1):
sfc: Add option to use a separate channel for TX completions
Steve Hodgson (1):
sfc: Make reset_workqueue driver-global rather than per-NIC
drivers/net/sfc/Makefile | 4 +- drivers/net/sfc/boards.c | 70 ++--- drivers/net/sfc/boards.h | 14 +- drivers/net/sfc/efx.c | 331 ++++++++++++------- drivers/net/sfc/enum.h | 32 +- drivers/net/sfc/ethtool.c | 137 ++++++--- drivers/net/sfc/falcon.c | 472 ++++++++++++++++----------- drivers/net/sfc/falcon.h | 3 + drivers/net/sfc/falcon_gmac.c | 229 +++++++++++++ drivers/net/sfc/falcon_hwdefs.h | 160 +++++++++ drivers/net/sfc/falcon_xmac.c | 261 +++------------ drivers/net/sfc/gmii.h | 137 +-------- drivers/net/sfc/mac.h | 16 +- drivers/net/sfc/mdio_10g.c | 453 ++++++++++++++++++-------- drivers/net/sfc/mdio_10g.h | 52 +++- drivers/net/sfc/mtd.c | 2 +- drivers/net/sfc/net_driver.h | 113 ++++++- drivers/net/sfc/phy.h | 7 +- drivers/net/sfc/selftest.c | 41 ++- drivers/net/sfc/selftest.h | 2 - drivers/net/sfc/sfe4001.c | 153 +++++++-- drivers/net/sfc/spi.h | 2 +- drivers/net/sfc/tenxpress.c | 686 +++++++++++++++++++++++++++++---------- drivers/net/sfc/workarounds.h | 12 +- drivers/net/sfc/xfp_phy.c | 38 +-- 25 files changed, 2232 insertions(+), 1195 deletions(-) create mode 100644 drivers/net/sfc/falcon_gmac.c
Signature · 3 lines
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.
PATCH 1/33 sfc: Board support fixes
Set dummy monitor method for unrecognised boards.
Clean up board resources if efx_pci_probe_main() fails after board has been initialised.
--- drivers/net/sfc/efx.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/net/sfc/efx.c +2 -0
@@ -1743,6 +1743,7 @@ 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, + .monitor = efx_port_dummy_op_int, .blink = efx_port_dummy_op_blink, .fini = efx_port_dummy_op_void, };
@@ -1983,6 +1984,7 @@ static int efx_pci_probe_main(struct efx_nic *efx)efx_fini_port (efx); fail5: fail4: + efx->board_info.fini (efx); fail3:efx_fini_napi (efx); fail2:
Signature · 3 lines
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.
Re: [PATCH 01/33] sfc: Board support fixes
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:48:26 +0000
Quoted 6 lines
Set dummy monitor method for unrecognised boards.
Clean up board resources if
efx_pci_probe_main()fails after board has been initialised.Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 2/33 sfc: Change SPI lengths to type size_t
In reply to Ben HutchingsBased on a patch by Andrew Morton.
--- drivers/net/sfc/falcon.c | 19 ++++++++++--------- 1 files changed, 10 insertions(+), 9 deletions(-)
drivers/net/sfc/falcon.c +10 -9
@@ -1605,7 +1605,7 @@ void falcon_fini_interrupt(struct efx_nic *efx)************************************************************************** */ -#define FALCON_SPI_MAX_LEN ((unsigned) sizeof(efx_oword_t)) +#define FALCON_SPI_MAX_LEN sizeof(efx_oword_t)/* Wait for SPI command completion */ static int falcon_spi_wait (struct efx_nic *efx)
@@ -1630,7 +1630,7 @@ static int falcon_spi_wait(struct efx_nic *efx)int falcon_spi_cmd (const struct efx_spi_device *spi,unsigned int command,int address, -const void *in,void *out,unsigned int len) +const void *in,void *out,size_t len) {struct efx_nic *efx = spi->efx;bool addressed = (address >=0 );
@@ -1686,8 +1686,8 @@ int falcon_spi_cmd(const struct efx_spi_device *spi,return 0 ; } -static unsigned int -falcon_spi_write_limit (const struct efx_spi_device *spi,unsigned int start) +static size_t +falcon_spi_write_limit (const struct efx_spi_device *spi,size_t start) {return min (FALCON_SPI_MAX_LEN , (spi->block_size - (start & (spi->block_size -1 ))));
@@ -1725,12 +1725,12 @@ int falcon_spi_fast_wait(const struct efx_spi_device *spi)int falcon_spi_read (const struct efx_spi_device *spi,loff_t start,size_t len,size_t *retlen,u8 *buffer) { -unsigned int command, block_len, pos =0 ; +size_t block_len, pos =0 ; +unsigned int command;int rc =0 ;while (pos < len) { - block_len =min ((unsigned int )len - pos, -FALCON_SPI_MAX_LEN ); + block_len =min (len - pos,FALCON_SPI_MAX_LEN ); command =efx_spi_munge_command (spi,SPI_READ , start + pos); rc = falcon_spi_cmd(spi, command, start + pos, NULL,
@@ -1756,7 +1756,8 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, size_t len, size_t *retlen, const u8 *buffer) { u8 verify_buffer[FALCON_SPI_MAX_LEN]; -unsigned int command, block_len, pos =0 ; +size_t block_len, pos =0 ; +unsigned int command;int rc =0 ;while (pos < len) {
@@ -1764,7 +1765,7 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,if (rc)break ; - block_len =min ((unsigned int )len - pos, + block_len =min (len - pos,falcon_spi_write_limit (spi, start + pos)); command =efx_spi_munge_command (spi,SPI_WRITE , start + pos); rc = falcon_spi_cmd(spi, command, start + pos,
Signature · 3 lines
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.
Re: [PATCH 02/33] sfc: Change SPI lengths to type size_t
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:48:51 +0000
Quoted 3 lines
Based on a patch by Andrew Morton.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
David Miller
maintainerRe: [PATCH 02/33] sfc: Change SPI lengths to type size_t
In reply to Ben HutchingsFrom: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:48:51 +0000
Quoted 3 lines
Based on a patch by Andrew Morton.
Signed-off-by Ben Hutchings <[email protected]>
Sigh, this isn't what you actually build tested, that's for sure:
drivers/net/sfc/falcon.c:1664: error: conflicting types for 'falcon_spi_cmd' drivers/net/sfc/spi.h:71: error: previous declaration of 'falcon_spi_cmd' was here
I'll fix it up this time, but never will I do this again.
Test what you send me.
Re: [PATCH 02/33] sfc: Change SPI lengths to type size_t
Quoted 9 lines · David Miller
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:48:51 +0000Quoted 3 lines
Based on a patch by Andrew Morton.
Signed-off-by Ben Hutchings <[email protected]>Sigh, this isn't what you actually build tested, that's for sure:
Of course it is. But it looks like I forgot to test the final version of this patch on a 64-bit architecture. On i386 size_t = unsigned.
Quoted 4 lines
drivers/net/sfc/falcon.c:1664: error: conflicting types for 'falcon_spi_cmd'drivers/net/sfc/spi.h:71: error: previous declaration of 'falcon_spi_cmd' was hereI'll fix it up this time, but never will I do this again.
Thanks.
Ben.
Quoted 1 line
Test what you send me.
Signature · 3 lines
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.
PATCH 3/33 sfc: Do not use pci_disable_device() to disable bus mastering
In reply to Ben Hutchingspci_disable_device() disables many features, like MSI-X, which we never reenable in efx_reset(). Further, calls to pci_enable_device() and pci_disable_device() must be matched since the nesting count was introduced.
--- drivers/net/sfc/falcon.c | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-)
drivers/net/sfc/falcon.c +13 -2
@@ -1344,6 +1344,17 @@ static inline void falcon_irq_ack_a1(struct efx_nic *efx)falcon_readl (efx, ®,WORK_AROUND_BROKEN_PCI_READS_REG_KER_A1 ); } +static void efx_pci_clear_master (struct pci_dev *dev) +{ +u16 command; + +if (dev->is_busmaster && + !pci_read_config_word (dev,PCI_COMMAND , &command) && + !pci_write_config_word (dev,PCI_COMMAND , + command & ~PCI_COMMAND_MASTER )) + dev->is_busmaster = false; +} +/* Process a fatal interrupt * Disable bus mastering ASAP and schedule a reset */
@@ -1375,9 +1386,9 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) }/* Disable both devices */ -pci_disable_device (efx->pci_dev); +efx_pci_clear_master (efx->pci_dev);if (FALCON_IS_DUAL_FUNC (efx)) -pci_disable_device (nic_data->pci_dev2); +efx_pci_clear_master (nic_data->pci_dev2);falcon_disable_interrupts (efx);if (++n_int_errors <FALCON_MAX_INT_ERRORS ) {
Signature · 3 lines
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.
David Miller
maintainerRe: [PATCH 03/33] sfc: Do not use pci_disable_device() to disable bus mastering
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:49:14 +0000
Quoted 6 lines
pci_disable_device()disables many features, like MSI-X, which we never reenable inefx_reset(). Further, calls topci_enable_device()andpci_disable_device()must be matched since the nesting count was introduced.Signed-off-by Ben Hutchings <[email protected]>
Since the PCI layer provides interfaces which do manage this setting, there is no way you should be doing this behind it's back.
You know why?
Because someone is going to change some of the internals of this stuff in the PIC layer and it will break your driver.
Please instead submit an interface to the PCI layer maintainers that does what you want, then use it.
Patch not applied.
Re: [PATCH 03/33] sfc: Do not use pci_disable_device() to disable bus mastering
Quoted 14 lines · David Miller
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:49:14 +0000Quoted 6 lines
pci_disable_device()disables many features, like MSI-X, which we never reenable inefx_reset(). Further, calls topci_enable_device()andpci_disable_device()must be matched since the nesting count was introduced.Signed-off-by Ben Hutchings <[email protected]>Since the PCI layer provides interfaces which do manage this setting, there is no way you should be doing this behind it's back.
Quoted 8 lines
You know why?
Because someone is going to change some of the internals of this stuff in the PIC layer and it will break your driver.
Please instead submit an interface to the PCI layer maintainers that does what you want, then use it.
I did ask on #linux-pci why this didn't exist; apparently it wasn't considered to be worth providing. So obviously I can submit a patch to the PCI layer but I'm not sure it would be accepted.
Ben.
Quoted 1 line
Patch not applied.
Signature · 3 lines
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.
PATCH 4/33 sfc: Remove unneeded register write
In reply to Ben HutchingsThis was only ever needed for an FPGA version of Falcon.
--- drivers/net/sfc/falcon.c | 9 --------- 1 files changed, 0 insertions(+), 9 deletions(-)
drivers/net/sfc/falcon.c +0 -9
@@ -2881,15 +2881,6 @@ int falcon_init_nic(struct efx_nic *efx)unsigned thresh;int rc; -/* Set up the address region register. This is only needed -* for the B0 FPGA, but since we are just pushing in the -* reset defaults this may as well be unconditional. */ -EFX_POPULATE_OWORD_4 (temp,ADR_REGION0 ,0 , -ADR_REGION1 , (1 <<16 ), -ADR_REGION2 , (2 <<16 ), -ADR_REGION3 , (3 <<16 )); -falcon_write (efx, &temp,ADR_REGION_REG_KER ); -/* Use on-chip SRAM */ falcon_read (efx, &temp,NIC_STAT_REG );EFX_SET_OWORD_FIELD (temp,ONCHIP_SRAM ,1 );
Signature · 3 lines
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.
Re: [PATCH 04/33] sfc: Remove unneeded register write
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:49:31 +0000
Quoted 3 lines
This was only ever needed for an FPGA version of Falcon.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 5/33 sfc: Correct interpretation of second param to ethtool phys_id()
In reply to Ben HutchingsA value of 0 means indefinite repetition (until interrupted).
--- drivers/net/sfc/ethtool.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-)
drivers/net/sfc/ethtool.c +6 -2
@@ -182,12 +182,16 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = {*/ /* Identify device by flashing LEDs */ -static int efx_ethtool_phys_id (struct net_device *net_dev,u32 seconds) +static int efx_ethtool_phys_id (struct net_device *net_dev,u32 count) {struct efx_nic *efx =netdev_priv (net_dev); efx->board_info.blink (efx,1 ); -schedule_timeout_interruptible (seconds *HZ ); +set_current_state (TASK_INTERRUPTIBLE ); +if (count) +schedule_timeout (count *HZ ); +else +schedule (); efx->board_info.blink (efx,0 );return 0 ; }
Signature · 3 lines
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.
Re: [PATCH 05/33] sfc: Correct interpretation of second param to ethtool phys_id()
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:49:50 +0000
Quoted 3 lines
A value of 0 means indefinite repetition (until interrupted).
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 6/33 sfc: Make reset_workqueue driver-global rather than per-NIC
In reply to Ben HutchingsFrom: Steve Hodgson <[email protected]>
Each reset is serialised by the rtnl_lock anyway, so there's no win per-NIC.
--- drivers/net/sfc/efx.c | 45 ++++++++++++++++++----------------------- drivers/net/sfc/net_driver.h | 2 - 2 files changed, 20 insertions(+), 27 deletions(-)
drivers/net/sfc/efx.c +20 -25
@@ -39,6 +39,12 @@*/ static struct workqueue_struct *refill_workqueue; +/* Reset workqueue. If any NIC has a hardware failure then a reset will be +* queued onto this work queue. This is not a per-nic work queue, because +* efx_reset_work() acquires the rtnl lock, so resets are naturally serialised. +*/ +static struct workqueue_struct *reset_workqueue; +/************************************************************************** * * Configurable values
@@ -1697,7 +1703,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) efx->reset_pending = method; -queue_work (efx->reset_workqueue, &efx->reset_work); +queue_work (reset_workqueue, &efx->reset_work); }/**************************************************************************
@@ -1763,7 +1769,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,struct efx_channel *channel;struct efx_tx_queue *tx_queue;struct efx_rx_queue *rx_queue; -int i, rc; +int i;/* Initialise common structures */ memset (efx,0 ,sizeof (*efx));
@@ -1832,33 +1838,14 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, interrupt_mode); efx->workqueue =create_singlethread_workqueue ("sfc_work" ); -if (!efx->workqueue) { - rc = -ENOMEM ; - goto fail1; - } - - efx->reset_workqueue =create_singlethread_workqueue ("sfc_reset" ); -if (!efx->reset_workqueue) { - rc = -ENOMEM ; - goto fail2; - } +if (!efx->workqueue) +return -ENOMEM ;return 0 ; - - fail2: -destroy_workqueue (efx->workqueue); - efx->workqueue =NULL ; - - fail1: -return rc; }static void efx_fini_struct (struct efx_nic *efx) { -if (efx->reset_workqueue) { -destroy_workqueue (efx->reset_workqueue); - efx->reset_workqueue =NULL ; - }if (efx->workqueue) {destroy_workqueue (efx->workqueue); efx->workqueue =NULL ;
@@ -1923,7 +1910,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev)* scheduled from this point because efx_stop_all() has been * called, we are no longer registered with driverlink, and * the net_device's have been removed. */ -flush_workqueue (efx->reset_workqueue); +cancel_work_sync (&efx->reset_work);efx_pci_remove_main (efx);
@@ -2045,7 +2032,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,* scheduled since efx_stop_all() has been called, and we * have not and never have been registered with either * the rtnetlink or driverlink layers. */ -flush_workqueue (efx->reset_workqueue); +cancel_work_sync (&efx->reset_work);/* Retry if a recoverably reset event has been scheduled */ if ((efx->reset_pending != RESET_TYPE_INVISIBLE) &&
@@ -2121,6 +2108,11 @@ static int __init efx_init_module(void) rc = -ENOMEM ; goto err_refill; } + reset_workqueue =create_singlethread_workqueue ("sfc_reset" ); +if (!reset_workqueue) { + rc = -ENOMEM ; + goto err_reset; + } rc =pci_register_driver (&efx_pci_driver);if (rc <0 )
@@ -2129,6 +2121,8 @@ static int __init efx_init_module(void)return 0 ; err_pci: +destroy_workqueue (reset_workqueue); + err_reset:destroy_workqueue (refill_workqueue); err_refill:unregister_netdevice_notifier (&efx_netdev_notifier);
@@ -2141,6 +2135,7 @@ static void __exit efx_exit_module(void)printk (KERN_INFO "Solarflare NET driver unloading\n" );pci_unregister_driver (&efx_pci_driver); +destroy_workqueue (reset_workqueue);destroy_workqueue (refill_workqueue);unregister_netdevice_notifier (&efx_netdev_notifier);
drivers/net/sfc/net_driver.h +0 -2
@@ -635,7 +635,6 @@ union efx_multicast_hash {* @legacy_irq: IRQ number * @workqueue: Workqueue for port reconfigures and the HW monitor. * Work items do not hold and must not acquire RTNL. -* @reset_workqueue: Workqueue for resets. Work item will acquire RTNL. * @reset_work: Scheduled reset workitem * @monitor_work: Hardware monitor workitem * @membase_phys: Memory BAR value as physical address
@@ -711,7 +710,6 @@ struct efx_nic {const struct efx_nic_type *type;int legacy_irq;struct workqueue_struct *workqueue; -struct workqueue_struct *reset_workqueue;struct work_struct reset_work;struct delayed_work monitor_work;resource_size_t membase_phys;
Signature · 3 lines
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.
Re: [PATCH 06/33] sfc: Make reset_workqueue driver-global rather than per-NIC
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:50:38 +0000
Quoted 6 lines
From: Steve Hodgson <[email protected]>
Each reset is serialised by the
rtnl_lockanyway, so there's no win per-NIC.Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 7/33 sfc: Clean up waits for flash/EEPROM operations
In reply to Ben HutchingsMake falcon_spi_wait() ignore the write timer - it is only relevant to write commands, it only works for the device that contains VPD, and it might not be initialised properly at all.
Rename falcon_spi_fast_wait() to falcon_spi_wait_write(), reflecting its use, and make it wait up to 10 ms (not 1 ms) since buffered writes to EEPROM may take this long to complete.
Make both wait functions sleep instead of busy-waiting.
Replace wait for command completion at top of falcon_spi_cmd() with a single poll; no command should be running when the function starts.
Correct some comments.
--- drivers/net/sfc/falcon.c | 58 +++++++++++++++++++++++++++++---------------- drivers/net/sfc/mtd.c | 2 +- drivers/net/sfc/spi.h | 2 +- 3 files changed, 39 insertions(+), 23 deletions(-)
drivers/net/sfc/falcon.c +37 -21
@@ -1618,24 +1618,37 @@ void falcon_fini_interrupt(struct efx_nic *efx)#define FALCON_SPI_MAX_LEN sizeof(efx_oword_t) +static int falcon_spi_poll (struct efx_nic *efx) +{ +efx_oword_t reg; +falcon_read (efx, ®,EE_SPI_HCMD_REG_KER ); +return EFX_OWORD_FIELD (reg,EE_SPI_HCMD_CMD_EN ) ? -EBUSY :0 ; +} +/* Wait for SPI command completion */ static int falcon_spi_wait (struct efx_nic *efx) { -unsigned long timeout = jiffies +DIV_ROUND_UP (HZ ,10 ); -efx_oword_t reg; -bool cmd_en, timer_active; +/* Most commands will finish quickly, so we start polling at +* very short intervals. Sometimes the command may have to +* wait for VPD or expansion ROM access outside of our +* control, so we allow up to 100 ms. */ +unsigned long timeout = jiffies +1 +DIV_ROUND_UP (HZ ,10 ); +int i; + +for (i =0 ; i <10 ; i++) { +if (!falcon_spi_poll (efx)) +return 0 ; +udelay (10 ); + }for (;;) { -falcon_read (efx, ®,EE_SPI_HCMD_REG_KER ); - cmd_en =EFX_OWORD_FIELD (reg,EE_SPI_HCMD_CMD_EN ); - timer_active =EFX_OWORD_FIELD (reg,EE_WR_TIMER_ACTIVE ); -if (!cmd_en && !timer_active) +if (!falcon_spi_poll (efx))return 0 ;if (time_after_eq (jiffies, timeout)) {EFX_ERR (efx,"timed out waiting for SPI\n" );return -ETIMEDOUT ; } -cpu_relax (); +schedule_timeout_uninterruptible (1 ); } }
@@ -1654,8 +1667,8 @@ int falcon_spi_cmd(const struct efx_spi_device *spi,return -EINVAL ;BUG_ON (!mutex_is_locked (&efx->spi_lock)); -/* Check SPI not currently being accessed */ - rc =falcon_spi_wait (efx); +/* Check that previous command is not still running */ + rc =falcon_spi_poll (efx);if (rc)return rc;
@@ -1711,26 +1724,29 @@ efx_spi_munge_command(const struct efx_spi_device *spi,return command | (((address >>8 ) & spi->munge_address) <<3 ); } -int falcon_spi_fast_wait (const struct efx_spi_device *spi) +/* Wait up to 10 ms for buffered write completion */ +int falcon_spi_wait_write (const struct efx_spi_device *spi) { +struct efx_nic *efx = spi->efx; +unsigned long timeout = jiffies +1 +DIV_ROUND_UP (HZ ,100 );u8 status; -int i, rc; - -/* Wait up to 1000us for flash/EEPROM to finish a fast operation. */ -for (i =0 ; i <50 ; i++) { -udelay (20 ); +int rc; +for (;;) { rc =falcon_spi_cmd (spi,SPI_RDSR ,-1 ,NULL , &status,sizeof (status));if (rc)return rc;if (!(status &SPI_STATUS_NRDY ))return 0 ; +if (time_after_eq (jiffies, timeout)) { +EFX_ERR (efx,"SPI write timeout on device %d" +" last status=0x%02x\n" , + spi->device_id, status); +return -ETIMEDOUT ; + } +schedule_timeout_uninterruptible (1 ); } -EFX_ERR (spi->efx, -"timed out waiting for device %d last status=0x%02x\n" , - spi->device_id, status); -return -ETIMEDOUT ; } int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
@@ -1784,7 +1800,7 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,if (rc)break ; - rc =falcon_spi_fast_wait (spi); + rc =falcon_spi_wait_write (spi);if (rc)break ;
drivers/net/sfc/mtd.c +1 -1
@@ -76,7 +76,7 @@ static int efx_spi_unlock(const struct efx_spi_device *spi) rc =falcon_spi_cmd (spi,SPI_WRSR ,-1 , &status,NULL ,sizeof (status));if (rc)return rc; - rc =falcon_spi_fast_wait (spi); + rc =falcon_spi_wait_write (spi);if (rc)return rc;
drivers/net/sfc/spi.h +1 -1
@@ -69,7 +69,7 @@ struct efx_spi_device {int falcon_spi_cmd (const struct efx_spi_device *spi,unsigned int command,int address,const void * in,void *out,unsigned int len); -int falcon_spi_fast_wait (const struct efx_spi_device *spi); +int falcon_spi_wait_write (const struct efx_spi_device *spi);int falcon_spi_read (const struct efx_spi_device *spi,loff_t start,size_t len,size_t *retlen,u8 *buffer); int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
Signature · 3 lines
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.
Re: [PATCH 07/33] sfc: Clean up waits for flash/EEPROM operations
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:51:01 +0000
Quoted 8 lines
Make
falcon_spi_wait()ignore the write timer - it is only relevant to write commands, it only works for the device that contains VPD, and it might not be initialised properly at all.Rename
falcon_spi_fast_wait()tofalcon_spi_wait_write(), reflecting its use, and make it wait up to 10 ms (not 1 ms) since buffered writes to EEPROM may take this long to complete.
Quoted 8 lines
Make both wait functions sleep instead of busy-waiting.
Replace wait for command completion at top of
falcon_spi_cmd()with a single poll; no command should be running when the function starts.Correct some comments.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 8/33 sfc: Work around unreliable strap pins
In reply to Ben HutchingsThe SFC4000 has strap pins indicating the presence of SPI flash and/or EEPROM. These pins are also used for GPIO, and in some cases they may be read wrongly at reset. However, on production boards it must boot from one or the other device, so we can assume the boot device is present and read the board config from there.
--- drivers/net/sfc/falcon.c | 110 +++++++++++++++++---------------------------- 1 files changed, 42 insertions(+), 68 deletions(-)
drivers/net/sfc/falcon.c +44 -70
@@ -70,6 +70,20 @@ static int disable_dma_stats;#define RX_DC_ENTRIES_ORDER 2#define RX_DC_BASE 0x100000 +static const unsigned int +/* "Large" EEPROM device: Atmel AT25640 or similar +* 8 KB, 16-bit address, 32 B write block */ +large_eeprom_type = ((13 <<SPI_DEV_TYPE_SIZE_LBN ) + | (2 <<SPI_DEV_TYPE_ADDR_LEN_LBN ) + | (5 <<SPI_DEV_TYPE_BLOCK_SIZE_LBN )), +/* Default flash device: Atmel AT25F1024 +* 128 KB, 24-bit address, 32 KB erase block, 256 B write block */ +default_flash_type = ((17 <<SPI_DEV_TYPE_SIZE_LBN ) + | (3 <<SPI_DEV_TYPE_ADDR_LEN_LBN ) + | (0x52 <<SPI_DEV_TYPE_ERASE_CMD_LBN ) + | (15 <<SPI_DEV_TYPE_ERASE_SIZE_LBN ) + | (8 <<SPI_DEV_TYPE_BLOCK_SIZE_LBN )); +/* RX FIFO XOFF watermark * * When the amount of the RX FIFO increases used increases past this
@@ -2281,12 +2295,15 @@ int falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out)__le16 *word, *limit;u32 csum; + spi = efx->spi_flash ? efx->spi_flash : efx->spi_eeprom; +if (!spi) +return -EINVAL ; + region =kmalloc (FALCON_NVCONFIG_END ,GFP_KERNEL );if (!region)return -ENOMEM ; nvconfig = region +NVCONFIG_OFFSET ; - spi = efx->spi_flash ? efx->spi_flash : efx->spi_eeprom;mutex_lock (&efx->spi_lock); rc =falcon_spi_read (spi,0 ,FALCON_NVCONFIG_END ,NULL , region);mutex_unlock (&efx->spi_lock);
@@ -2724,80 +2741,37 @@ static int falcon_probe_nic_variant(struct efx_nic *efx)static void falcon_probe_spi_devices (struct efx_nic *efx) {efx_oword_t nic_stat, gpio_ctl, ee_vpd_cfg; -bool has_flash, has_eeprom, boot_is_external; +int boot_dev;falcon_read (efx, &gpio_ctl,GPIO_CTL_REG_KER );falcon_read (efx, &nic_stat,NIC_STAT_REG );falcon_read (efx, &ee_vpd_cfg,EE_VPD_CFG_REG_KER ); - has_flash =EFX_OWORD_FIELD (nic_stat,SF_PRST ); - has_eeprom =EFX_OWORD_FIELD (nic_stat,EE_PRST ); - boot_is_external =EFX_OWORD_FIELD (gpio_ctl,BOOTED_USING_NVDEVICE ); - -if (has_flash) { -/* Default flash SPI device: Atmel AT25F1024 -* 128 KB, 24-bit address, 32 KB erase block, -* 256 B write block -*/ -u32 flash_device_type = - (17 <<SPI_DEV_TYPE_SIZE_LBN ) - | (3 <<SPI_DEV_TYPE_ADDR_LEN_LBN ) - | (0x52 <<SPI_DEV_TYPE_ERASE_CMD_LBN ) - | (15 <<SPI_DEV_TYPE_ERASE_SIZE_LBN ) - | (8 <<SPI_DEV_TYPE_BLOCK_SIZE_LBN ); - -falcon_spi_device_init (efx, &efx->spi_flash, -EE_SPI_FLASH , flash_device_type); - -if (!boot_is_external) { -/* Disable VPD and set clock dividers to safe -* values for initial programming. -*/ -EFX_LOG (efx,"Booted from internal ASIC settings;" -" setting SPI config\n" ); -EFX_POPULATE_OWORD_3 (ee_vpd_cfg,EE_VPD_EN ,0 , -/* 125 MHz / 7 ~= 20 MHz */ -EE_SF_CLOCK_DIV ,7 , -/* 125 MHz / 63 ~= 2 MHz */ -EE_EE_CLOCK_DIV ,63 ); -falcon_write (efx, &ee_vpd_cfg,EE_VPD_CFG_REG_KER ); - } - } - -if (has_eeprom) { -u32 eeprom_device_type; - -/* If it has no flash, it must have a large EEPROM -* for chip config; otherwise check whether 9-bit -* addressing is used for VPD configuration -*/ -if (has_flash && - (!boot_is_external || -EFX_OWORD_FIELD (ee_vpd_cfg,EE_VPD_EN_AD9_MODE ))) { -/* Default SPI device: Atmel AT25040 or similar -* 512 B, 9-bit address, 8 B write block -*/ - eeprom_device_type = - (9 <<SPI_DEV_TYPE_SIZE_LBN ) - | (1 <<SPI_DEV_TYPE_ADDR_LEN_LBN ) - | (3 <<SPI_DEV_TYPE_BLOCK_SIZE_LBN ); - }else { -/* "Large" SPI device: Atmel AT25640 or similar -* 8 KB, 16-bit address, 32 B write block -*/ - eeprom_device_type = - (13 <<SPI_DEV_TYPE_SIZE_LBN ) - | (2 <<SPI_DEV_TYPE_ADDR_LEN_LBN ) - | (5 <<SPI_DEV_TYPE_BLOCK_SIZE_LBN ); - } - -falcon_spi_device_init (efx, &efx->spi_eeprom, -EE_SPI_EEPROM , eeprom_device_type); - } - -EFX_LOG (efx,"flash is %s, EEPROM is %s\n" , - (has_flash ?"present" :"absent" ), - (has_eeprom ?"present" :"absent" )); +if (EFX_OWORD_FIELD (gpio_ctl,BOOTED_USING_NVDEVICE )) { + boot_dev = (EFX_OWORD_FIELD (nic_stat,SF_PRST ) ? +EE_SPI_FLASH :EE_SPI_EEPROM ); +EFX_LOG (efx,"Booted from %s\n" , + boot_dev ==EE_SPI_FLASH ?"flash" :"EEPROM" ); + }else { +/* Disable VPD and set clock dividers to safe +* values for initial programming. */ + boot_dev =-1 ; +EFX_LOG (efx,"Booted from internal ASIC settings;" +" setting SPI config\n" ); +EFX_POPULATE_OWORD_3 (ee_vpd_cfg,EE_VPD_EN ,0 , +/* 125 MHz / 7 ~= 20 MHz */ +EE_SF_CLOCK_DIV ,7 , +/* 125 MHz / 63 ~= 2 MHz */ +EE_EE_CLOCK_DIV ,63 ); +falcon_write (efx, &ee_vpd_cfg,EE_VPD_CFG_REG_KER ); + } + +if (boot_dev ==EE_SPI_FLASH ) +falcon_spi_device_init (efx, &efx->spi_flash,EE_SPI_FLASH , + default_flash_type); +if (boot_dev ==EE_SPI_EEPROM ) +falcon_spi_device_init (efx, &efx->spi_eeprom,EE_SPI_EEPROM , + large_eeprom_type); }int falcon_probe_nic (struct efx_nic *efx)
Signature · 3 lines
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.
Re: [PATCH 08/33] sfc: Work around unreliable strap pins
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:51:28 +0000
Quoted 7 lines
The SFC4000 has strap pins indicating the presence of SPI flash and/or EEPROM. These pins are also used for GPIO, and in some cases they may be read wrongly at reset. However, on production boards it must boot from one or the other device, so we can assume the boot device is present and read the board config from there.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 9/33 sfc: Restore phy_flash_cfg module parameter
In reply to Ben HutchingsThis is needed for recovery in case a PHY firmware upgrade is aborted.
--- drivers/net/sfc/efx.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/net/sfc/efx.c +7 -0
@@ -129,6 +129,10 @@ static unsigned int rss_cpus;module_param (rss_cpus, uint,0444 );MODULE_PARM_DESC (rss_cpus,"Number of CPUs to use for Receive-Side Scaling" ); +static int phy_flash_cfg; +module_param (phy_flash_cfg, int,0644 ); +MODULE_PARM_DESC (phy_flash_cfg,"Set PHYs into reflash mode initially" ); +/************************************************************************** * * Utility functions and prototypes
@@ -609,6 +613,9 @@ static int efx_probe_port(struct efx_nic *efx)if (rc) goto err; +if (phy_flash_cfg) + efx->phy_mode =PHY_MODE_SPECIAL ; +/* Sanity check MAC address */ if (is_valid_ether_addr (efx->mac_address)) {memcpy (efx->net_dev->dev_addr, efx->mac_address,ETH_ALEN );
Signature · 3 lines
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.
Re: [PATCH 09/33] sfc: Restore phy_flash_cfg module parameter
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:51:48 +0000
Quoted 3 lines
This is needed for recovery in case a PHY firmware upgrade is aborted.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 13/33 sfc: Don't count RX checksum errors during loopback self-test
In reply to Ben HutchingsThe loopback self-test checks that IP packets with incorrect checksums are not altered when sent on a queue with checksum generation off. These should not contribute to RX error statistics.
--- drivers/net/sfc/falcon.c | 13 ++++++++----- 1 files changed, 8 insertions(+), 5 deletions(-)
drivers/net/sfc/falcon.c +8 -5
@@ -784,15 +784,18 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, rx_ev_buf_owner_id_err | rx_ev_eth_crc_err | rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err); -/* Count errors that are not in MAC stats. */ +/* Count errors that are not in MAC stats. Ignore expected +* checksum errors during self-test. */ if (rx_ev_frm_trunc) ++rx_queue->channel->n_rx_frm_trunc;else if (rx_ev_tobe_disc) ++rx_queue->channel->n_rx_tobe_disc; -else if (rx_ev_ip_hdr_chksum_err) - ++rx_queue->channel->n_rx_ip_hdr_chksum_err; -else if (rx_ev_tcp_udp_chksum_err) - ++rx_queue->channel->n_rx_tcp_udp_chksum_err; +else if (!efx->loopback_selftest) { +if (rx_ev_ip_hdr_chksum_err) + ++rx_queue->channel->n_rx_ip_hdr_chksum_err; +else if (rx_ev_tcp_udp_chksum_err) + ++rx_queue->channel->n_rx_tcp_udp_chksum_err; + }if (rx_ev_ip_frag_err) ++rx_queue->channel->n_rx_ip_frag_err;
Signature · 3 lines
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.
Re: [PATCH 13/33] sfc: Don't count RX checksum errors during loopback self-test
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:53:07 +0000
Quoted 5 lines
The loopback self-test checks that IP packets with incorrect checksums are not altered when sent on a queue with checksum generation off. These should not contribute to RX error statistics.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 14/33 sfc: Remove MII extension cruft
In reply to Ben HutchingsReplace efx_nic::link_options bitfield with link_speed (speed in Mbit/s) and link_fd (full duplex flag).
Remove broken auto-negotiation functions.
--- drivers/net/sfc/efx.c | 23 +------ drivers/net/sfc/ethtool.c | 1 - drivers/net/sfc/falcon.c | 16 ++--- drivers/net/sfc/falcon_xmac.c | 1 - drivers/net/sfc/gmii.h | 137 +---------------------------------------- drivers/net/sfc/net_driver.h | 6 +- drivers/net/sfc/tenxpress.c | 4 +- drivers/net/sfc/xfp_phy.c | 4 +- 8 files changed, 18 insertions(+), 174 deletions(-)
drivers/net/sfc/efx.c +2 -21
@@ -21,7 +21,6 @@#include <linux/ethtool.h> #include <linux/topology.h> #include "net_driver.h" -#include "gmii.h" #include "ethtool.h" #include "tx.h" #include "rx.h"
@@ -551,26 +550,8 @@ static void efx_link_status_changed(struct efx_nic *efx)/* Status message for kernel log */ if (efx->link_up) { -struct mii_if_info *gmii = &efx->mii; -unsigned adv, lpa; -/* NONE here means direct XAUI from the controller, with no -* MDIO-attached device we can query. */ -if (efx->phy_type !=PHY_TYPE_NONE ) { - adv =gmii_advertised (gmii); - lpa =gmii_lpa (gmii); - }else { - lpa =GM_LPA_10000 |LPA_DUPLEX ; - adv = lpa; - } -EFX_INFO (efx,"link up at %dMbps %s-duplex " -"(adv %04x lpa %04x) (MTU %d)%s\n" , - (efx->link_options &GM_LPA_10000 ?10000 : - (efx->link_options &GM_LPA_1000 ?1000 : - (efx->link_options &GM_LPA_100 ?100 : -10 ))), - (efx->link_options &GM_LPA_DUPLEX ? -"full" :"half" ), - adv, lpa, +EFX_INFO (efx,"link up at %uMbps %s-duplex (MTU %d)%s\n" , + efx->link_speed, efx->link_fd ?"full" :"half" , efx->net_dev->mtu, (efx->promiscuous ?" [PROMISC]" :"" )); }else {
drivers/net/sfc/ethtool.c +0 -1
@@ -16,7 +16,6 @@#include "efx.h" #include "ethtool.h" #include "falcon.h" -#include "gmii.h" #include "spi.h" #include "mac.h"
drivers/net/sfc/falcon.c +7 -9
@@ -15,11 +15,11 @@#include <linux/seq_file.h> #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> +#include <linux/mii.h> #include "net_driver.h" #include "bitfield.h" #include "efx.h" #include "mac.h" -#include "gmii.h" #include "spi.h" #include "falcon.h" #include "falcon_hwdefs.h"
@@ -1926,14 +1926,12 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)int link_speed;bool tx_fc; -if (efx->link_options &GM_LPA_10000 ) - link_speed =0x3 ; -else if (efx->link_options &GM_LPA_1000 ) - link_speed =0x2 ; -else if (efx->link_options &GM_LPA_100 ) - link_speed =0x1 ; -else - link_speed =0x0 ; +switch (efx->link_speed) { +case 10000 : link_speed =3 ;break ; +case 1000 : link_speed =2 ;break ; +case 100 : link_speed =1 ;break ; +default : link_speed =0 ;break ; + }/* MAC_LINK_STATUS controls MAC backpressure but doesn't work * as advertised. Disable to ensure packets are not * indefinitely held and TX queue can be flushed at any point
drivers/net/sfc/falcon_xmac.c +0 -1
@@ -15,7 +15,6 @@#include "falcon_hwdefs.h" #include "falcon_io.h" #include "mac.h" -#include "gmii.h" #include "mdio_10g.h" #include "phy.h" #include "boards.h"
drivers/net/sfc/gmii.h +1 -136
147 lines not on this page · raw message
drivers/net/sfc/net_driver.h +4 -2
@@ -694,7 +694,8 @@ union efx_multicast_hash {* @mii: PHY interface * @phy_mode: PHY operating mode. Serialised by @mac_lock. * @link_up: Link status -* @link_options: Link options (MII/GMII format) +* @link_fd: Link is full duplex +* @link_speed: Link speed (Mbps) * @n_link_state_changes: Number of times the link has changed state * @promiscuous: Promiscuous flag. Protected by netif_tx_lock. * @multicast_hash: Multicast hash table
@@ -772,7 +773,8 @@ struct efx_nic {enum efx_phy_mode phy_mode;bool link_up; -unsigned int link_options; +bool link_fd; +unsigned int link_speed;unsigned int n_link_state_changes;bool promiscuous;
drivers/net/sfc/tenxpress.c +2 -2
@@ -10,7 +10,6 @@#include <linux/delay.h> #include <linux/seq_file.h> #include "efx.h" -#include "gmii.h" #include "mdio_10g.h" #include "falcon.h" #include "phy.h"
@@ -362,7 +361,8 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx) phy_data->loopback_mode = efx->loopback_mode; phy_data->phy_mode = efx->phy_mode; efx->link_up =tenxpress_link_ok (efx, false); - efx->link_options =GM_LPA_10000FULL ; + efx->link_speed =10000 ; + efx->link_fd = true; }static void tenxpress_phy_clear_interrupt (struct efx_nic *efx)
drivers/net/sfc/xfp_phy.c +2 -2
@@ -14,7 +14,6 @@#include <linux/timer.h> #include <linux/delay.h> #include "efx.h" -#include "gmii.h" #include "mdio_10g.h" #include "xenpack.h" #include "phy.h"
@@ -154,7 +153,8 @@ static void xfp_phy_reconfigure(struct efx_nic *efx) phy_data->phy_mode = efx->phy_mode; efx->link_up =xfp_link_ok (efx); - efx->link_options =GM_LPA_10000FULL ; + efx->link_speed =10000 ; + efx->link_fd = true; }
Signature · 3 lines
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.
Re: [PATCH 14/33] sfc: Remove MII extension cruft
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:53:24 +0000
Quoted 6 lines
Replace
efx_nic::link_optionsbitfield withlink_speed(speed in Mbit/s) andlink_fd(full duplex flag).Remove broken auto-negotiation functions.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 15/33 sfc: Add support for MMDs numbered >15
In reply to Ben HutchingsCombine DEVS0 and DEVS1 registers into a 32-bit mask instead of reading just DEVS0.
--- drivers/net/sfc/mdio_10g.c | 24 +++++++++++++----------- drivers/net/sfc/mdio_10g.h | 8 ++++---- drivers/net/sfc/tenxpress.c | 6 +++--- drivers/net/sfc/xfp_phy.c | 8 ++++---- 4 files changed, 24 insertions(+), 22 deletions(-)
drivers/net/sfc/mdio_10g.c +13 -11
@@ -121,16 +121,18 @@ 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 devices, mmd =0 ; -int probe_mmd; +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_DEVS0_PHYXS ) ?MDIO_MMD_PHYXS : + 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 ); + 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 ) {
@@ -175,14 +177,14 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)else if (efx_phy_mode_disabled (efx->phy_mode))return false;else if (efx->loopback_mode ==LOOPBACK_PHYXS ) - mmd_mask &= ~(MDIO_MMDREG_DEVS0_PHYXS | -MDIO_MMDREG_DEVS0_PCS | -MDIO_MMDREG_DEVS0_PMAPMD ); + mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS | +MDIO_MMDREG_DEVS_PCS | +MDIO_MMDREG_DEVS_PMAPMD );else if (efx->loopback_mode ==LOOPBACK_PCS ) - mmd_mask &= ~(MDIO_MMDREG_DEVS0_PCS | -MDIO_MMDREG_DEVS0_PMAPMD ); + mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS | +MDIO_MMDREG_DEVS_PMAPMD );else if (efx->loopback_mode ==LOOPBACK_PMAPMD ) - mmd_mask &= ~MDIO_MMDREG_DEVS0_PMAPMD ; + mmd_mask &= ~MDIO_MMDREG_DEVS_PMAPMD ;while (mmd_mask) {if (mmd_mask &1 ) {
drivers/net/sfc/mdio_10g.h +4 -4
@@ -73,14 +73,14 @@#define MDIO_ID_MODEL (_id32) ((_id32 >> 4) & 0x3f)#define MDIO_ID_OUI (_id32) (_id32 >> 10) -/* Bits in MMDREG_DEVS0. Someone thoughtfully layed things out +/* Bits in MMDREG_DEVS0/1. Someone thoughtfully layed things out * so the 'bit present' bit number of an MMD is the number of * that MMD */ #define DEV_PRESENT_BIT (_b) (1 << _b) -#define MDIO_MMDREG_DEVS0_PHYXS DEV_PRESENT_BIT(MDIO_MMD_PHYXS) -#define MDIO_MMDREG_DEVS0_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS) -#define MDIO_MMDREG_DEVS0_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD) +#define MDIO_MMDREG_DEVS_PHYXS DEV_PRESENT_BIT(MDIO_MMD_PHYXS) +#define MDIO_MMDREG_DEVS_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS) +#define MDIO_MMDREG_DEVS_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)/* Bits in MMDREG_STAT2 */ #define MDIO_MMDREG_STAT2_PRESENT_VAL (2)
drivers/net/sfc/tenxpress.c +3 -3
@@ -19,9 +19,9 @@/* We expect these MMDs to be in the package */ /* AN not here as mdio_check_mmds() requires STAT2 support */ -#define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS0_PMAPMD | \ - MDIO_MMDREG_DEVS0_PCS | \ - MDIO_MMDREG_DEVS0_PHYXS) +#define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PMAPMD | \ + MDIO_MMDREG_DEVS_PCS | \ + MDIO_MMDREG_DEVS_PHYXS)#define TENXPRESS_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \ (1 << LOOPBACK_PCS) | \
drivers/net/sfc/xfp_phy.c +4 -4
@@ -19,9 +19,9 @@#include "phy.h" #include "mac.h" -#define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS0_PCS | \ - MDIO_MMDREG_DEVS0_PMAPMD | \ - MDIO_MMDREG_DEVS0_PHYXS) +#define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PCS | \ + MDIO_MMDREG_DEVS_PMAPMD | \ + MDIO_MMDREG_DEVS_PHYXS)#define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) | \ (1 << LOOPBACK_PMAPMD) | \
@@ -64,7 +64,7 @@ static int xfp_reset_phy(struct efx_nic *efx)/* Check that all the MMDs we expect are present and responding. We * expect faults on some if the link is down, but not on the PHY XS */ rc =mdio_clause45_check_mmds (efx,XFP_REQUIRED_DEVS , -MDIO_MMDREG_DEVS0_PHYXS ); +MDIO_MMDREG_DEVS_PHYXS );if (rc <0 ) goto fail;
Signature · 3 lines
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.
Re: [PATCH 15/33] sfc: Add support for MMDs numbered >15
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:53:40 +0000
Quoted 4 lines
Combine DEVS0 and DEVS1 registers into a 32-bit mask instead of reading just DEVS0.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 16/33 sfc: Add phy_type device attribute
In reply to Ben Hutchings--- drivers/net/sfc/efx.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)
drivers/net/sfc/efx.c +19 -0
@@ -1496,6 +1496,14 @@ static struct notifier_block efx_netdev_notifier = { .notifier_call = efx_netdev_event, }; +static ssize_t +show_phy_type (struct device *dev,struct device_attribute *attr,char *buf) +{ +struct efx_nic *efx =pci_get_drvdata (to_pci_dev (dev)); +return sprintf (buf,"%d\n" , efx->phy_type); +} +static DEVICE_ATTR(phy_type, 0644, show_phy_type, NULL); +static int efx_register_netdev (struct efx_nic *efx) {struct net_device *net_dev = efx->net_dev;
@@ -1522,7 +1530,17 @@ static int efx_register_netdev(struct efx_nic *efx)strcpy (efx->name, net_dev->name);efx_set_channel_names (efx); + rc =device_create_file (&efx->pci_dev->dev, &dev_attr_phy_type); +if (rc) { +EFX_ERR (efx,"failed to init net dev attributes\n" ); + goto fail_registered; + } +return 0 ; + +fail_registered: +unregister_netdev (net_dev); +return rc; }static void efx_unregister_netdev (struct efx_nic *efx)
@@ -1542,6 +1560,7 @@ static void efx_unregister_netdev(struct efx_nic *efx)if (efx_dev_registered (efx)) {strlcpy (efx->name,pci_name (efx->pci_dev),sizeof (efx->name)); +device_remove_file (&efx->pci_dev->dev, &dev_attr_phy_type);unregister_netdev (efx->net_dev); } }
Signature · 3 lines
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.
Re: [PATCH 16/33] sfc: Add phy_type device attribute
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:54:02 +0000
Quoted 1 line
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 17/33 sfc: Clean up board identification
In reply to Ben HutchingsRemove kluge for development boards with unspecified board type.
Remove assumption of contiguous board type code assignments.
--- drivers/net/sfc/boards.c | 68 ++++++++++++--------------------------------- drivers/net/sfc/boards.h | 7 +--- 2 files changed, 20 insertions(+), 55 deletions(-)
drivers/net/sfc/boards.c +18 -50
@@ -1,6 +1,6 @@/**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards -* Copyright 2007 Solarflare Communications Inc. +* Copyright 2007-2008 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published
@@ -231,70 +231,38 @@ static int sfe4002_init(struct efx_nic *efx)/* This will get expanded as board-specific details get moved out of the * PHY drivers. */ struct efx_board_data { +enum efx_board_type type;const char *ref_model;const char *gen_type;int (*init) (struct efx_nic *nic); }; -static int dummy_init (struct efx_nic *nic) -{ -return 0 ; -}static struct efx_board_data board_data[] = { - [EFX_BOARD_INVALID ] = - {NULL ,NULL , dummy_init}, - [EFX_BOARD_SFE4001 ] = - {"SFE4001" ,"10GBASE-T adapter" , sfe4001_init}, - [EFX_BOARD_SFE4002 ] = - {"SFE4002" ,"XFP adapter" , sfe4002_init}, + {EFX_BOARD_SFE4001 ,"SFE4001" ,"10GBASE-T adapter" , sfe4001_init }, + {EFX_BOARD_SFE4002 ,"SFE4002" ,"XFP adapter" , sfe4002_init }, }; -int efx_set_board_info (struct efx_nic *efx,u16 revision_info) +void efx_set_board_info (struct efx_nic *efx,u16 revision_info) { -int rc =0 ; -struct efx_board_data *data; +struct efx_board_data *data =NULL ; +int i; -if (BOARD_TYPE (revision_info) >=EFX_BOARD_MAX ) { -EFX_ERR (efx,"squashing unknown board type %d\n" , -BOARD_TYPE (revision_info)); - revision_info =0 ; - } - -if (BOARD_TYPE (revision_info) ==0 ) { - efx->board_info.major =0 ; - efx->board_info.minor =0 ; -/* For early boards that don't have revision info. there is -* only 1 board for each PHY type, so we can work it out, with -* the exception of the PHY-less boards. */ -switch (efx->phy_type) { -case PHY_TYPE_10XPRESS : - efx->board_info.type =EFX_BOARD_SFE4001 ; -break ; -case PHY_TYPE_XFP : - efx->board_info.type =EFX_BOARD_SFE4002 ; -break ; -default : - efx->board_info.type =0 ; -break ; - } - }else { - efx->board_info.type =BOARD_TYPE (revision_info); - efx->board_info.major =BOARD_MAJOR (revision_info); - efx->board_info.minor =BOARD_MINOR (revision_info); - } + efx->board_info.type =BOARD_TYPE (revision_info); + efx->board_info.major =BOARD_MAJOR (revision_info); + efx->board_info.minor =BOARD_MINOR (revision_info); - data = &board_data[efx->board_info.type]; +for (i =0 ; i <ARRAY_SIZE (board_data); i++) +if (board_data[i].type == efx->board_info.type) + data = &board_data[i]; -/* Report the board model number or generic type for recognisable -* boards. */ -if (efx->board_info.type !=0 ) +if (data) {EFX_INFO (efx,"board is %s rev %c%d\n" , (efx->pci_dev->subsystem_vendor ==EFX_VENDID_SFC ) ? data->ref_model : data->gen_type,'A' + efx->board_info.major, efx->board_info.minor); - - efx->board_info.init = data->init; - -return rc; + efx->board_info.init = data->init; + }else { +EFX_ERR (efx,"unknown board type %d\n" , efx->board_info.type); + } }
drivers/net/sfc/boards.h +2 -5
@@ -1,6 +1,6 @@/**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards -* Copyright 2007 Solarflare Communications Inc. +* Copyright 2007-2008 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published
@@ -12,14 +12,11 @@/* Board IDs (must fit in 8 bits) */ enum efx_board_type { -EFX_BOARD_INVALID =0 ,EFX_BOARD_SFE4001 =1 ,/* SFE4001 (10GBASE-T) */ EFX_BOARD_SFE4002 =2 , -/* Insert new types before here */ -EFX_BOARD_MAX }; -extern int efx_set_board_info (struct efx_nic *efx,u16 revision_info); +extern void efx_set_board_info (struct efx_nic *efx,u16 revision_info);extern int sfe4001_init (struct efx_nic *efx);#endif
Signature · 3 lines
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.
Re: [PATCH 17/33] sfc: Clean up board identification
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:54:19 +0000
Quoted 5 lines
Remove kluge for development boards with unspecified board type.
Remove assumption of contiguous board type code assignments.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 18/33 sfc: Clean up MDIO flag setting
In reply to Ben HutchingsWe often want to set or clear a flag in an MDIO register, but avoid writing if no change is required since this can have side-effects. Encapsulate this in a function, mdio_clause45_set_flag().
--- drivers/net/sfc/mdio_10g.c | 87 ++++++++++++++------------------------------ drivers/net/sfc/mdio_10g.h | 4 ++ 2 files changed, 32 insertions(+), 59 deletions(-)
drivers/net/sfc/mdio_10g.c +28 -59
@@ -205,61 +205,24 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)void mdio_clause45_transmit_disable (struct efx_nic *efx) { -int phy_id = efx->mii.phy_id; -int ctrl1, ctrl2; - - ctrl1 = ctrl2 =mdio_clause45_read (efx, phy_id,MDIO_MMD_PMAPMD , -MDIO_MMDREG_TXDIS ); -if (efx->phy_mode &PHY_MODE_TX_DISABLED ) - ctrl2 |= (1 <<MDIO_MMDREG_TXDIS_GLOBAL_LBN ); -else - ctrl1 &= ~(1 <<MDIO_MMDREG_TXDIS_GLOBAL_LBN ); -if (ctrl1 != ctrl2) -mdio_clause45_write (efx, phy_id,MDIO_MMD_PMAPMD , -MDIO_MMDREG_TXDIS , ctrl2); +mdio_clause45_set_flag (efx, efx->mii.phy_id,MDIO_MMD_PMAPMD , +MDIO_MMDREG_TXDIS ,MDIO_MMDREG_TXDIS_GLOBAL_LBN , + efx->phy_mode &PHY_MODE_TX_DISABLED ); }void mdio_clause45_phy_reconfigure (struct efx_nic *efx) {int phy_id = efx->mii.phy_id; -int ctrl1, ctrl2; - -/* Handle (with debouncing) PMA/PMD loopback */ - ctrl1 = ctrl2 =mdio_clause45_read (efx, phy_id,MDIO_MMD_PMAPMD , -MDIO_MMDREG_CTRL1 ); - -if (efx->loopback_mode ==LOOPBACK_PMAPMD ) - ctrl2 |= (1 <<MDIO_PMAPMD_CTRL1_LBACK_LBN ); -else - ctrl2 &= ~(1 <<MDIO_PMAPMD_CTRL1_LBACK_LBN ); - -if (ctrl1 != ctrl2) -mdio_clause45_write (efx, phy_id,MDIO_MMD_PMAPMD , -MDIO_MMDREG_CTRL1 , ctrl2); - -/* Handle (with debouncing) PCS loopback */ - ctrl1 = ctrl2 =mdio_clause45_read (efx, phy_id,MDIO_MMD_PCS , -MDIO_MMDREG_CTRL1 ); -if (efx->loopback_mode ==LOOPBACK_PCS ) - ctrl2 |= (1 <<MDIO_MMDREG_CTRL1_LBACK_LBN ); -else - ctrl2 &= ~(1 <<MDIO_MMDREG_CTRL1_LBACK_LBN ); -if (ctrl1 != ctrl2) -mdio_clause45_write (efx, phy_id,MDIO_MMD_PCS , -MDIO_MMDREG_CTRL1 , ctrl2); - -/* Handle (with debouncing) PHYXS network loopback */ - ctrl1 = ctrl2 =mdio_clause45_read (efx, phy_id,MDIO_MMD_PHYXS , -MDIO_MMDREG_CTRL1 ); -if (efx->loopback_mode ==LOOPBACK_NETWORK ) - ctrl2 |= (1 <<MDIO_MMDREG_CTRL1_LBACK_LBN ); -else - ctrl2 &= ~(1 <<MDIO_MMDREG_CTRL1_LBACK_LBN ); - -if (ctrl1 != ctrl2) -mdio_clause45_write (efx, phy_id,MDIO_MMD_PHYXS , -MDIO_MMDREG_CTRL1 , ctrl2); +mdio_clause45_set_flag (efx, phy_id,MDIO_MMD_PMAPMD , +MDIO_MMDREG_CTRL1 ,MDIO_PMAPMD_CTRL1_LBACK_LBN , + efx->loopback_mode ==LOOPBACK_PMAPMD ); +mdio_clause45_set_flag (efx, phy_id,MDIO_MMD_PCS , +MDIO_MMDREG_CTRL1 ,MDIO_MMDREG_CTRL1_LBACK_LBN , + efx->loopback_mode ==LOOPBACK_PCS ); +mdio_clause45_set_flag (efx, phy_id,MDIO_MMD_PHYXS , +MDIO_MMDREG_CTRL1 ,MDIO_MMDREG_CTRL1_LBACK_LBN , + efx->loopback_mode ==LOOPBACK_NETWORK ); } static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx,
@@ -267,21 +230,13 @@ static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx, {int phy = efx->mii.phy_id;int stat =mdio_clause45_read (efx, phy, mmd,MDIO_MMDREG_STAT1 ); -int ctrl1, ctrl2;EFX_TRACE (efx,"Setting low power mode for MMD %d to %d\n" , mmd, lpower);if (stat & (1 <<MDIO_MMDREG_STAT1_LPABLE_LBN )) { - ctrl1 = ctrl2 =mdio_clause45_read (efx, phy, - mmd,MDIO_MMDREG_CTRL1 ); -if (lpower) - ctrl2 |= (1 <<MDIO_MMDREG_CTRL1_LPOWER_LBN ); -else - ctrl2 &= ~(1 <<MDIO_MMDREG_CTRL1_LPOWER_LBN ); -if (ctrl1 != ctrl2) -mdio_clause45_write (efx, phy, mmd, -MDIO_MMDREG_CTRL1 , ctrl2); +mdio_clause45_set_flag (efx, phy, mmd,MDIO_MMDREG_CTRL1 , +MDIO_MMDREG_CTRL1_LPOWER_LBN , lpower); } }
@@ -395,3 +350,17 @@ int mdio_clause45_set_settings(struct efx_nic *efx,return 0 ;return -EOPNOTSUPP ; } + +void mdio_clause45_set_flag (struct efx_nic *efx,u8 prt,u8 dev, +u16 addr,int bit,bool sense) +{ +int old_val =mdio_clause45_read (efx, prt, dev, addr); +int new_val; + +if (sense) + new_val = old_val | (1 << bit); +else + new_val = old_val & ~(1 << bit); +if (old_val != new_val) +mdio_clause45_write (efx, prt, dev, addr, new_val); +}
drivers/net/sfc/mdio_10g.h +4 -0
@@ -259,4 +259,8 @@ extern int mdio_clause45_set_settings(struct efx_nic *efx,extern int mdio_clause45_wait_reset_mmds (struct efx_nic *efx,unsigned int mmd_mask); +/* Set or clear flag, debouncing */ +extern void mdio_clause45_set_flag (struct efx_nic *efx,u8 prt,u8 dev, +u16 addr,int bit,bool sense); +#endif /* EFX_MDIO_10G_H */
Signature · 3 lines
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.
Re: [PATCH 18/33] sfc: Clean up MDIO flag setting
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:54:34 +0000
Quoted 5 lines
We often want to set or clear a flag in an MDIO register, but avoid writing if no change is required since this can have side-effects. Encapsulate this in a function,
mdio_clause45_set_flag().Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 19/33 sfc: Add support for sub-10G speeds
In reply to Ben HutchingsThe SFC4000 has a separate MAC for use at sub-10G speeds. Introduce an efx_mac_operations structure with implementations for the two MACs. Switch between the MACs as necessary.
PHY settings are independent of the MAC, so add get_settings() and set_settings() to efx_phy_operations. Also add macs field to indicate which MACs the PHY is connected to.
--- drivers/net/sfc/Makefile | 4 +- drivers/net/sfc/efx.c | 62 +++++++--- drivers/net/sfc/enum.h | 29 +++-- drivers/net/sfc/ethtool.c | 38 +++---- drivers/net/sfc/falcon.c | 179 +++++++++++++++++++++++------- drivers/net/sfc/falcon.h | 3 + drivers/net/sfc/falcon_gmac.c | 233 +++++++++++++++++++++++++++++++++++++++ drivers/net/sfc/falcon_hwdefs.h | 156 ++++++++++++++++++++++++++ drivers/net/sfc/falcon_xmac.c | 222 +++++-------------------------------- drivers/net/sfc/mac.h | 16 +-- drivers/net/sfc/net_driver.h | 31 +++++ drivers/net/sfc/selftest.c | 26 ++--- drivers/net/sfc/selftest.h | 2 - drivers/net/sfc/sfe4001.c | 2 +- drivers/net/sfc/tenxpress.c | 10 +- drivers/net/sfc/xfp_phy.c | 7 +- 16 files changed, 699 insertions(+), 321 deletions(-) create mode 100644 drivers/net/sfc/falcon_gmac.c
drivers/net/sfc/Makefile +2 -2
@@ -1,5 +1,5 @@ -sfc-y += efx.o falcon.o tx.o rx.o falcon_xmac.o \ - selftest.o ethtool.o xfp_phy.o \ +sfc-y += efx.o falcon.o tx.o rx.o falcon_gmac.o \ + falcon_xmac.o selftest.o ethtool.o xfp_phy.o \ mdio_10g.o tenxpress.o boards.o sfe4001.o sfc-$(CONFIG_SFC_MTD) += mtd.o
drivers/net/sfc/efx.c +43 -19
149 lines not on this page · raw message
drivers/net/sfc/enum.h +16 -13
@@ -1,6 +1,6 @@/**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards -* Copyright 2007 Solarflare Communications Inc. +* Copyright 2007-2008 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published
@@ -13,22 +13,24 @@/** * enum efx_loopback_mode - loopback modes * @LOOPBACK_NONE: no loopback -* @LOOPBACK_XGMII: loopback within MAC at XGMII level -* @LOOPBACK_XGXS: loopback within MAC at XGXS level -* @LOOPBACK_XAUI: loopback within MAC at XAUI level -* @LOOPBACK_PHYXS: loopback within PHY at PHYXS level -* @LOOPBACK_PCS: loopback within PHY at PCS level -* @LOOPBACK_PMAPMD: loopback within PHY at PMAPMD level +* @LOOPBACK_GMAC: loopback within GMAC at unspecified level +* @LOOPBACK_XGMII: loopback within XMAC at XGMII level +* @LOOPBACK_XGXS: loopback within XMAC at XGXS level +* @LOOPBACK_XAUI: loopback within XMAC at XAUI level +* @LOOPBACK_GPHY: loopback within 1G PHY at unspecified level +* @LOOPBACK_PHYXS: loopback within 10G PHY at PHYXS level +* @LOOPBACK_PCS: loopback within 10G PHY at PCS level +* @LOOPBACK_PMAPMD: loopback within 10G PHY at PMAPMD level * @LOOPBACK_NETWORK: reflecting loopback (even further than furthest!) */ /* Please keep in order and up-to-date w.r.t the following two #defines */ enum efx_loopback_mode {LOOPBACK_NONE =0 , -LOOPBACK_MAC =1 , +LOOPBACK_GMAC =1 ,LOOPBACK_XGMII =2 ,LOOPBACK_XGXS =3 ,LOOPBACK_XAUI =4 , -LOOPBACK_PHY =5 , +LOOPBACK_GPHY =5 ,LOOPBACK_PHYXS =6 ,LOOPBACK_PCS =7 ,LOOPBACK_PMAPMD =8 ,
@@ -45,15 +47,16 @@ extern const char *efx_loopback_mode_names[];LOOPBACK_MODE_NAME (efx->loopback_mode) /* These loopbacks occur within the controller */ -#define LOOPBACKS_10G_INTERNAL ((1 << LOOPBACK_XGMII)| \ - (1 << LOOPBACK_XGXS) | \ - (1 << LOOPBACK_XAUI)) +#define LOOPBACKS_INTERNAL ((1 << LOOPBACK_GMAC) | \ + (1 << LOOPBACK_XGMII)| \ + (1 << LOOPBACK_XGXS) | \ + (1 << LOOPBACK_XAUI))#define LOOPBACK_MASK (_efx) \ (1 << (_efx)->loopback_mode)#define LOOPBACK_INTERNAL (_efx) \ - (!!(LOOPBACKS_10G_INTERNAL & LOOPBACK_MASK(_efx))) + (!!(LOOPBACKS_INTERNAL & LOOPBACK_MASK(_efx)))#define LOOPBACK_OUT_OF (_from, _to, _mask) \ ((LOOPBACK_MASK(_from) & (_mask)) && !(LOOPBACK_MASK(_to) & (_mask)))
drivers/net/sfc/ethtool.c +17 -21
@@ -17,15 +17,14 @@#include "ethtool.h" #include "falcon.h" #include "spi.h" -#include "mac.h" const char *efx_loopback_mode_names[] = { [LOOPBACK_NONE ] ="NONE" , - [LOOPBACK_MAC ] ="MAC" , + [LOOPBACK_GMAC ] ="GMAC" , [LOOPBACK_XGMII ] ="XGMII" , [LOOPBACK_XGXS ] ="XGXS" , [LOOPBACK_XAUI ] ="XAUI" , - [LOOPBACK_PHY ] ="PHY" , + [LOOPBACK_GPHY ] ="GPHY" , [LOOPBACK_PHYXS ] ="PHYXS" , [LOOPBACK_PCS ] ="PCS" , [LOOPBACK_PMAPMD ] ="PMA/PMD" ,
@@ -200,13 +199,15 @@ int efx_ethtool_get_settings(struct net_device *net_dev, struct ethtool_cmd *ecmd) {struct efx_nic *efx =netdev_priv (net_dev); -int rc;mutex_lock (&efx->mac_lock); - rc =falcon_xmac_get_settings (efx, ecmd); + efx->phy_op->get_settings (efx, ecmd);mutex_unlock (&efx->mac_lock); -return rc; +/* Falcon GMAC does not support 1000Mbps HD */ + ecmd->supported &= ~SUPPORTED_1000baseT_Half; + +return 0 ; }/* This must be called with rtnl_lock held. */
@@ -216,8 +217,15 @@ int efx_ethtool_set_settings(struct net_device *net_dev,struct efx_nic *efx =netdev_priv (net_dev);int rc; +/* Falcon GMAC does not support 1000Mbps HD */ +if (ecmd->speed ==SPEED_1000 && ecmd->duplex !=DUPLEX_FULL ) { +EFX_LOG (efx,"rejecting unsupported 1000Mbps HD" +" setting\n" ); +return -EINVAL ; + } +mutex_lock (&efx->mac_lock); - rc =falcon_xmac_set_settings (efx, ecmd); + rc = efx->phy_op->set_settings (efx, ecmd);mutex_unlock (&efx->mac_lock);if (!rc)efx_reconfigure_port (efx);
@@ -362,10 +370,6 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx, EFX_PORT_NAME, "phy", NULL);/* Loopback tests */ -efx_fill_test (n++, strings, data, &tests->loopback_speed, -EFX_PORT_NAME ,"loopback.speed" ,NULL ); -efx_fill_test (n++, strings, data, &tests->loopback_full_duplex, -EFX_PORT_NAME ,"loopback.full_duplex" ,NULL );for (mode =LOOPBACK_NONE ; mode <=LOOPBACK_TEST_MAX ; mode++) {if (!(efx->loopback_modes & (1 << mode)))continue ;
@@ -671,22 +675,14 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, {struct efx_nic *efx =netdev_priv (net_dev);enum efx_fc_type flow_control = efx->flow_control; -int rc; flow_control &= ~(EFX_FC_RX |EFX_FC_TX |EFX_FC_AUTO ); flow_control |= pause->rx_pause ?EFX_FC_RX :0 ; flow_control |= pause->tx_pause ?EFX_FC_TX :0 ; flow_control |= pause->autoneg ?EFX_FC_AUTO :0 ; -/* Try to push the pause parameters */ -mutex_lock (&efx->mac_lock); - rc =falcon_xmac_set_pause (efx, flow_control); -mutex_unlock (&efx->mac_lock); - -if (!rc) -efx_reconfigure_port (efx); - -return rc; +efx_reconfigure_port (efx); +return 0 ; } static void efx_ethtool_get_pauseparam(struct net_device *net_dev,
drivers/net/sfc/falcon.c +141 -38
270 lines not on this page · raw message
drivers/net/sfc/falcon.h +3 -0
@@ -12,6 +12,7 @@#define EFX_FALCON_H #include "net_driver.h" +#include "efx.h" /* * Falcon hardware control
@@ -65,6 +66,7 @@ extern int falcon_probe_port(struct efx_nic *efx);extern void falcon_remove_port (struct efx_nic *efx);/* MAC/PHY */ +extern int falcon_switch_mac (struct efx_nic *efx);extern bool falcon_xaui_link_ok (struct efx_nic *efx);extern int falcon_dma_stats (struct efx_nic *efx,unsigned int done_offset);
@@ -77,6 +79,7 @@ extern int falcon_init_interrupt(struct efx_nic *efx);extern void falcon_enable_interrupts (struct efx_nic *efx);extern void falcon_generate_test_event (struct efx_channel *channel,unsigned int magic); +extern void falcon_sim_phy_event (struct efx_nic *efx);extern void falcon_generate_interrupt (struct efx_nic *efx);extern void falcon_set_int_moderation (struct efx_channel *channel);extern void falcon_disable_interrupts (struct efx_nic *efx);
drivers/net/sfc/falcon_gmac.c new file +233 -0
233 lines not on this page · raw message
drivers/net/sfc/falcon_hwdefs.h +156 -0
228 lines not on this page · raw message
drivers/net/sfc/falcon_xmac.c +31 -191
288 lines not on this page · raw message
drivers/net/sfc/mac.h +3 -13
@@ -1,7 +1,7 @@/**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. -* Copyright 2006-2007 Solarflare Communications Inc. +* Copyright 2006-2008 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published
@@ -13,17 +13,7 @@#include "net_driver.h" -extern int falcon_init_xmac (struct efx_nic *efx); -extern void falcon_reconfigure_xmac (struct efx_nic *efx); -extern void falcon_update_stats_xmac (struct efx_nic *efx); -extern void falcon_fini_xmac (struct efx_nic *efx); -extern int falcon_check_xmac (struct efx_nic *efx); -extern void falcon_xmac_sim_phy_event (struct efx_nic *efx); -extern int falcon_xmac_get_settings (struct efx_nic *efx, -struct ethtool_cmd *ecmd); -extern int falcon_xmac_set_settings (struct efx_nic *efx, -struct ethtool_cmd *ecmd); -extern int falcon_xmac_set_pause (struct efx_nic *efx, -enum efx_fc_type pause_params); +extern struct efx_mac_operations falcon_gmac_operations; +extern struct efx_mac_operations falcon_xmac_operations;#endif
drivers/net/sfc/net_driver.h +31 -0
@@ -463,6 +463,8 @@ enum phy_type {#define PHY_ADDR_INVALID 0xff +#define EFX_IS10G (efx) ((efx)->link_speed == 10000) +enum nic_state {STATE_INIT =0 ,STATE_RUNNING =1 ,
@@ -503,6 +505,24 @@ enum efx_fc_type { EFX_FC_AUTO = 4, }; +/* Supported MAC bit-mask */ +enum efx_mac_type { +EFX_GMAC =1 , +EFX_XMAC =2 , +}; + +/** +* struct efx_mac_operations - Efx MAC operations table +* @reconfigure: Reconfigure MAC. Serialised by the mac_lock +* @update_stats: Update statistics +* @check_hw: Check hardware. Serialised by the mac_lock +*/ +struct efx_mac_operations { +void (*reconfigure) (struct efx_nic *efx); +void (*update_stats) (struct efx_nic *efx); +int (*check_hw) (struct efx_nic *efx); +}; +/** * struct efx_phy_operations - Efx PHY operations table * @init: Initialise PHY
@@ -511,16 +531,23 @@ enum efx_fc_type {* @clear_interrupt: Clear down interrupt * @blink: Blink LEDs * @check_hw: Check hardware +* @get_settings: Get ethtool settings. Serialised by the mac_lock. +* @set_settings: Set ethtool settings. Serialised by the mac_lock. * @mmds: MMD presence mask * @loopbacks: Supported loopback modes mask */ struct efx_phy_operations { +enum efx_mac_type macs;int (*init) (struct efx_nic *efx);void (*fini) (struct efx_nic *efx);void (*reconfigure) (struct efx_nic *efx);void (*clear_interrupt) (struct efx_nic *efx);int (*check_hw) (struct efx_nic *efx);int (*test) (struct efx_nic *efx); +void (*get_settings) (struct efx_nic *efx, +struct ethtool_cmd *ecmd); +int (*set_settings) (struct efx_nic *efx, +struct ethtool_cmd *ecmd);int mmds;unsigned loopbacks; };
@@ -686,6 +713,7 @@ union efx_multicast_hash {* @stats_lock: Statistics update lock. Serialises statistics fetches * @stats_enabled: Temporarily disable statistics fetches. * Serialised by @stats_lock +* @mac_op: MAC interface * @mac_address: Permanent MAC address * @phy_type: PHY type * @phy_lock: PHY access lock
@@ -693,6 +721,7 @@ union efx_multicast_hash {* @phy_data: PHY private data (including PHY-specific stats) * @mii: PHY interface * @phy_mode: PHY operating mode. Serialised by @mac_lock. +* @mac_up: MAC link state * @link_up: Link status * @link_fd: Link is full duplex * @link_speed: Link speed (Mbps)
@@ -763,6 +792,7 @@ struct efx_nic {spinlock_t stats_lock;bool stats_enabled; +struct efx_mac_operations *mac_op;unsigned char mac_address[ETH_ALEN ];enum phy_type phy_type;
@@ -772,6 +802,7 @@ struct efx_nic {struct mii_if_info mii;enum efx_phy_mode phy_mode; +bool mac_up;bool link_up;bool link_fd;unsigned int link_speed;
drivers/net/sfc/selftest.c +11 -15
@@ -26,7 +26,6 @@#include "selftest.h" #include "boards.h" #include "workarounds.h" -#include "mac.h" #include "spi.h" #include "falcon_io.h" #include "mdio_10g.h"
@@ -105,9 +104,11 @@ static int efx_test_mii(struct efx_nic *efx, struct efx_self_tests *tests) goto out; } - rc =mdio_clause45_check_mmds (efx, efx->phy_op->mmds,0 ); -if (rc) - goto out; +if (EFX_IS10G (efx)) { + rc =mdio_clause45_check_mmds (efx, efx->phy_op->mmds,0 ); +if (rc) + goto out; + } out:mutex_unlock (&efx->mac_lock);
@@ -598,7 +599,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct ethtool_cmd ecmd, do { struct efx_channel *channel = &efx->channel[0]; - falcon_check_xmac(efx); + efx->mac_op->check_hw(efx); schedule_timeout_uninterruptible(HZ / 10); if (channel->work_pending) efx_process_channel_now(channel);
@@ -606,13 +607,12 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct ethtool_cmd ecmd,flush_workqueue (efx->workqueue);rmb (); -/* efx->link_up can be 1 even if the XAUI link is down, -* (bug5762). Usually, it's not worth bothering with the -* difference, but for selftests, we need that extra -* guarantee that the link is really, really, up. -*/ +/* We need both the phy and xaui links to be ok. +* rather than relying on the falcon_xmac irq/poll +* regime, just poll xaui directly */ link_up = efx->link_up; -if (!falcon_xaui_link_ok (efx)) +if (link_up &&EFX_IS10G (efx) && + !falcon_xaui_link_ok (efx)) link_up = false; }while ((++count <20 ) && !link_up);
@@ -721,7 +721,6 @@ int efx_offline_test(struct efx_nic *efx,if (ecmd_test.autoneg ==AUTONEG_ENABLE ) { ecmd_test.autoneg =AUTONEG_DISABLE ; ecmd_test.duplex =DUPLEX_FULL ; - ecmd_test.speed =SPEED_10000 ; } efx->loopback_mode =LOOPBACK_NONE ;
@@ -732,9 +731,6 @@ int efx_offline_test(struct efx_nic *efx,return rc; } - tests->loopback_speed = ecmd_test.speed; - tests->loopback_full_duplex = ecmd_test.duplex; - rc =efx_test_phy (efx, tests);if (rc && !rc2) rc2 = rc;
drivers/net/sfc/selftest.h +0 -2
@@ -39,8 +39,6 @@ struct efx_self_tests {/* offline tests */ int registers;int phy; -int loopback_speed; -int loopback_full_duplex;struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX +1 ]; };
drivers/net/sfc/sfe4001.c +1 -1
@@ -176,7 +176,7 @@ static int sfe4001_check_hw(struct efx_nic *efx)s32 status;/* If XAUI link is up then do not monitor */ -if (EFX_WORKAROUND_7884 (efx) &&falcon_xaui_link_ok (efx)) +if (EFX_WORKAROUND_7884 (efx) && efx->mac_up)return 0 ;/* Check the powered status of the PHY. Lack of power implies that
drivers/net/sfc/tenxpress.c +6 -4
@@ -1,6 +1,6 @@/**************************************************************************** -* Driver for Solarflare 802.3an compliant PHY -* Copyright 2007 Solarflare Communications Inc. +* Driver for Solarflare Solarstorm network controllers and boards +* Copyright 2007-2008 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published
@@ -15,7 +15,6 @@#include "phy.h" #include "falcon_hwdefs.h" #include "boards.h" -#include "mac.h" /* We expect these MMDs to be in the package */ /* AN not here as mdio_check_mmds() requires STAT2 support */
@@ -381,7 +380,7 @@ static int tenxpress_phy_check_hw(struct efx_nic *efx) link_ok =tenxpress_link_ok (efx, true);if (link_ok != efx->link_up) -falcon_xmac_sim_phy_event (efx); +falcon_sim_phy_event (efx);if (phy_data->phy_mode !=PHY_MODE_NORMAL )return 0 ;
@@ -453,12 +452,15 @@ static int tenxpress_phy_test(struct efx_nic *efx) }struct efx_phy_operations falcon_tenxpress_phy_ops = { + .macs =EFX_XMAC , .init = tenxpress_phy_init, .reconfigure = tenxpress_phy_reconfigure, .check_hw = tenxpress_phy_check_hw, .fini = tenxpress_phy_fini, .clear_interrupt = tenxpress_phy_clear_interrupt, .test = tenxpress_phy_test, + .get_settings = mdio_clause45_get_settings, + .set_settings = mdio_clause45_set_settings, .mmds =TENXPRESS_REQUIRED_DEVS , .loopbacks =TENXPRESS_LOOPBACKS , };
drivers/net/sfc/xfp_phy.c +5 -2
@@ -17,7 +17,7 @@#include "mdio_10g.h" #include "xenpack.h" #include "phy.h" -#include "mac.h" +#include "falcon.h" #define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PCS | \ MDIO_MMDREG_DEVS_PMAPMD | \
@@ -125,7 +125,7 @@ static int xfp_phy_check_hw(struct efx_nic *efx)int link_up =xfp_link_ok (efx);/* Simulate a PHY event if link state has changed */ if (link_up != efx->link_up) -falcon_xmac_sim_phy_event (efx); +falcon_sim_phy_event (efx); rc = efx->board_info.monitor (efx);if (rc) {
@@ -169,11 +169,14 @@ static void xfp_phy_fini(struct efx_nic *efx) }struct efx_phy_operations falcon_xfp_phy_ops = { + .macs =EFX_XMAC , .init = xfp_phy_init, .reconfigure = xfp_phy_reconfigure, .check_hw = xfp_phy_check_hw, .fini = xfp_phy_fini, .clear_interrupt = xfp_phy_clear_interrupt, + .get_settings = mdio_clause45_get_settings, + .set_settings = mdio_clause45_set_settings, .mmds =XFP_REQUIRED_DEVS , .loopbacks =XFP_LOOPBACKS , };
Signature · 3 lines
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.
Re: [PATCH 19/33] sfc: Add support for sub-10G speeds
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:54:51 +0000
Quoted 9 lines
The SFC4000 has a separate MAC for use at sub-10G speeds. Introduce an
efx_mac_operationsstructure with implementations for the two MACs. Switch between the MACs as necessary.PHY settings are independent of the MAC, so add
get_settings()andset_settings()toefx_phy_operations. Also add macs field to indicate which MACs the PHY is connected to.Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 20/33 sfc: Implement auto-negotiation
In reply to Ben HutchingsAdd infrastructure for auto-negotiation of speed, duplex and flow control.
When using 10Xpress, auto-negotiate flow control. While we're at it, clean up the code to warn when partner is not 10GBASE-T capable.
--- drivers/net/sfc/ethtool.c | 57 ++++++- drivers/net/sfc/falcon.c | 6 +- drivers/net/sfc/falcon_gmac.c | 4 +- drivers/net/sfc/falcon_xmac.c | 2 +- drivers/net/sfc/mdio_10g.c | 348 ++++++++++++++++++++++++++++++++--------- drivers/net/sfc/mdio_10g.h | 32 ++++ drivers/net/sfc/net_driver.h | 38 +++++- drivers/net/sfc/tenxpress.c | 138 +++++++++-------- drivers/net/sfc/xfp_phy.c | 1 + 9 files changed, 472 insertions(+), 154 deletions(-)
drivers/net/sfc/ethtool.c +48 -9
@@ -12,11 +12,13 @@#include <linux/ethtool.h> #include <linux/rtnetlink.h> #include "net_driver.h" +#include "workarounds.h" #include "selftest.h" #include "efx.h" #include "ethtool.h" #include "falcon.h" #include "spi.h" +#include "mdio_10g.h" const char *efx_loopback_mode_names[] = { [LOOPBACK_NONE ] ="NONE" ,
@@ -674,14 +676,51 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, struct ethtool_pauseparam *pause) {struct efx_nic *efx =netdev_priv (net_dev); -enum efx_fc_type flow_control = efx->flow_control; +enum efx_fc_type wanted_fc; +bool reset; - flow_control &= ~(EFX_FC_RX |EFX_FC_TX |EFX_FC_AUTO ); - flow_control |= pause->rx_pause ?EFX_FC_RX :0 ; - flow_control |= pause->tx_pause ?EFX_FC_TX :0 ; - flow_control |= pause->autoneg ?EFX_FC_AUTO :0 ; + wanted_fc = ((pause->rx_pause ?EFX_FC_RX :0 ) | + (pause->tx_pause ?EFX_FC_TX :0 ) | + (pause->autoneg ?EFX_FC_AUTO :0 )); + +if ((wanted_fc &EFX_FC_TX ) && !(wanted_fc &EFX_FC_RX )) { +EFX_LOG (efx,"Flow control unsupported: tx ON rx OFF\n" ); +return -EINVAL ; + } + +if (!(efx->phy_op->mmds &DEV_PRESENT_BIT (MDIO_MMD_AN )) && + (wanted_fc &EFX_FC_AUTO )) { +EFX_LOG (efx,"PHY does not support flow control " +"autonegotiation\n" ); +return -EINVAL ; + } + +/* TX flow control may automatically turn itself off if the +* link partner (intermittently) stops responding to pause +* frames. There isn't any indication that this has happened, +* so the best we do is leave it up to the user to spot this +* and fix it be cycling transmit flow control on this end. */ + reset = (wanted_fc &EFX_FC_TX ) && !(efx->wanted_fc &EFX_FC_TX ); +if (EFX_WORKAROUND_11482 (efx) && reset) { +if (falcon_rev (efx) >=FALCON_REV_B0 ) { +/* Recover by resetting the EM block */ +if (efx->link_up) +falcon_drain_tx_fifo (efx); + }else { +/* Schedule a reset to recover */ +efx_schedule_reset (efx,RESET_TYPE_INVISIBLE ); + } + } + +/* Try to push the pause parameters */ +mutex_lock (&efx->mac_lock); + + efx->wanted_fc = wanted_fc; +mdio_clause45_set_pause (efx); +__efx_reconfigure_port (efx); + +mutex_unlock (&efx->mac_lock); -efx_reconfigure_port (efx);return 0 ; }
@@ -690,9 +729,9 @@ static void efx_ethtool_get_pauseparam(struct net_device *net_dev, {struct efx_nic *efx =netdev_priv (net_dev); - pause->rx_pause = !!(efx->flow_control &EFX_FC_RX ); - pause->tx_pause = !!(efx->flow_control &EFX_FC_TX ); - pause->autoneg = !!(efx->flow_control &EFX_FC_AUTO ); + pause->rx_pause = !!(efx->wanted_fc &EFX_FC_RX ); + pause->tx_pause = !!(efx->wanted_fc &EFX_FC_TX ); + pause->autoneg = !!(efx->wanted_fc &EFX_FC_AUTO ); }
drivers/net/sfc/falcon.c +3 -3
@@ -2009,7 +2009,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)/* Transmission of pause frames when RX crosses the threshold is * covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL. * Action on receipt of pause frames is controller by XM_DIS_FCNTL */ - tx_fc = !!(efx->flow_control &EFX_FC_TX ); + tx_fc = !!(efx->link_fc &EFX_FC_TX );falcon_read (efx, ®,RX_CFG_REG_KER );EFX_SET_OWORD_FIELD_VER (efx, reg,RX_XOFF_MAC_EN , tx_fc);
@@ -2339,9 +2339,9 @@ int falcon_probe_port(struct efx_nic *efx)/* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ if (falcon_rev (efx) >=FALCON_REV_B0 ) - efx->flow_control =EFX_FC_RX |EFX_FC_TX ; + efx->wanted_fc =EFX_FC_RX |EFX_FC_TX ;else - efx->flow_control =EFX_FC_RX ; + efx->wanted_fc =EFX_FC_RX ;/* Allocate buffer for stats */ rc = falcon_alloc_buffer(efx, &efx->stats_buffer,
drivers/net/sfc/falcon_gmac.c +2 -2
@@ -31,8 +31,8 @@ static void falcon_reconfigure_gmac(struct efx_nic *efx)efx_oword_t reg;/* Configuration register 1 */ - tx_fc = (efx->flow_control &EFX_FC_TX ) || !efx->link_fd; - rx_fc = !!(efx->flow_control &EFX_FC_RX ); + tx_fc = (efx->link_fc &EFX_FC_TX ) || !efx->link_fd; + rx_fc = !!(efx->link_fc &EFX_FC_RX ); loopback = (efx->loopback_mode ==LOOPBACK_GMAC ); bytemode = (efx->link_speed ==1000 );
drivers/net/sfc/falcon_xmac.c +1 -1
@@ -142,7 +142,7 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx) {unsigned int max_frame_len;efx_oword_t reg; -bool rx_fc = !!(efx->flow_control &EFX_FC_RX ); +bool rx_fc = !!(efx->link_fc &EFX_FC_RX );/* Configure MAC - cut-thru mode is hard wired on */ EFX_POPULATE_DWORD_3(reg,
drivers/net/sfc/mdio_10g.c +277 -71
411 lines not on this page · raw message
drivers/net/sfc/mdio_10g.h +32 -0
@@ -81,6 +81,17 @@#define MDIO_MMDREG_DEVS_PHYXS DEV_PRESENT_BIT(MDIO_MMD_PHYXS)#define MDIO_MMDREG_DEVS_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS)#define MDIO_MMDREG_DEVS_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD) +#define MDIO_MMDREG_DEVS_AN DEV_PRESENT_BIT(MDIO_MMD_AN) + +/* Bits in MMDREG_SPEED */ +#define MDIO_MMDREG_SPEED_10G_LBN 0 +#define MDIO_MMDREG_SPEED_10G_WIDTH 1 +#define MDIO_MMDREG_SPEED_1000M_LBN 4 +#define MDIO_MMDREG_SPEED_1000M_WIDTH 1 +#define MDIO_MMDREG_SPEED_100M_LBN 5 +#define MDIO_MMDREG_SPEED_100M_WIDTH 1 +#define MDIO_MMDREG_SPEED_10M_LBN 6 +#define MDIO_MMDREG_SPEED_10M_WIDTH 1/* Bits in MMDREG_STAT2 */ #define MDIO_MMDREG_STAT2_PRESENT_VAL (2)
@@ -119,12 +130,20 @@#define MDIO_PHYXS_LANE_ALIGNED_LBN (12)/* AN registers */ +#define MDIO_AN_CTRL_XNP_LBN 13#define MDIO_AN_STATUS (1)#define MDIO_AN_STATUS_XNP_LBN (7)#define MDIO_AN_STATUS_PAGE_LBN (6)#define MDIO_AN_STATUS_AN_DONE_LBN (5)#define MDIO_AN_STATUS_LP_AN_CAP_LBN (0) +#define MDIO_AN_ADVERTISE 16 +#define MDIO_AN_ADVERTISE_XNP_LBN 12 +#define MDIO_AN_LPA 19 +#define MDIO_AN_XNP 22 +#define MDIO_AN_LPA_XNP 25 + +#define MDIO_AN_10GBT_ADVERTISE 32#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 */
@@ -251,10 +270,23 @@ extern void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,extern void mdio_clause45_get_settings (struct efx_nic *efx,struct ethtool_cmd *ecmd); +/* Read (some of) the PHY settings over MDIO */ +extern void +mdio_clause45_get_settings_ext (struct efx_nic *efx,struct ethtool_cmd *ecmd, +u32 xnp,u32 xnp_lpa); +/* Set (some of) the PHY settings over MDIO */ extern int mdio_clause45_set_settings (struct efx_nic *efx,struct ethtool_cmd *ecmd); +/* Set pause parameters to be advertised through AN (if available) */ +extern void mdio_clause45_set_pause (struct efx_nic *efx); + +/* Get pause parameters from AN if available (otherwise return +* requested pause parameters) +*/ +enum efx_fc_type mdio_clause45_get_pause (struct efx_nic *efx); +/* Wait for specified MMDs to exit reset within a timeout */ extern int mdio_clause45_wait_reset_mmds (struct efx_nic *efx,unsigned int mmd_mask);
drivers/net/sfc/net_driver.h +36 -2
@@ -511,6 +511,35 @@ enum efx_mac_type { EFX_XMAC = 2, }; +static inline unsigned int efx_fc_advertise (enum efx_fc_type wanted_fc) +{ +unsigned int adv =0 ; +if (wanted_fc &EFX_FC_RX ) + adv =ADVERTISE_PAUSE_CAP |ADVERTISE_PAUSE_ASYM ; +if (wanted_fc &EFX_FC_TX ) + adv ^=ADVERTISE_PAUSE_ASYM ; +return adv; +} + +static inline enum efx_fc_type efx_fc_resolve (enum efx_fc_type wanted_fc, +unsigned int lpa) +{ +unsigned int adv =efx_fc_advertise (wanted_fc); + +if (!(wanted_fc &EFX_FC_AUTO )) +return wanted_fc; + +if (adv & lpa &ADVERTISE_PAUSE_CAP ) +return EFX_FC_RX |EFX_FC_TX ; +if (adv & lpa &ADVERTISE_PAUSE_ASYM ) { +if (adv &ADVERTISE_PAUSE_CAP ) +return EFX_FC_RX ; +if (lpa &ADVERTISE_PAUSE_CAP ) +return EFX_FC_TX ; + } +return 0 ; +} +/** * struct efx_mac_operations - Efx MAC operations table * @reconfigure: Reconfigure MAC. Serialised by the mac_lock
@@ -533,6 +562,8 @@ struct efx_mac_operations {* @check_hw: Check hardware * @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 +* (only needed where AN bit is set in mmds) * @mmds: MMD presence mask * @loopbacks: Supported loopback modes mask */
@@ -548,6 +579,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 );int mmds;unsigned loopbacks; };
@@ -724,11 +756,12 @@ union efx_multicast_hash {* @mac_up: MAC link state * @link_up: Link status * @link_fd: Link is full duplex +* @link_fc: Actualy flow control flags * @link_speed: Link speed (Mbps) * @n_link_state_changes: Number of times the link has changed state * @promiscuous: Promiscuous flag. Protected by netif_tx_lock. * @multicast_hash: Multicast hash table -* @flow_control: Flow control flags - separate RX/TX so can't use link_options +* @wanted_fc: Wanted flow control flags * @reconfigure_work: work item for dealing with PHY events * @loopback_mode: Loopback status * @loopback_modes: Supported loopback mode bitmask
@@ -805,12 +838,13 @@ struct efx_nic {bool mac_up;bool link_up;bool link_fd; +enum efx_fc_type link_fc;unsigned int link_speed;unsigned int n_link_state_changes;bool promiscuous;union efx_multicast_hash multicast_hash; -enum efx_fc_type flow_control; +enum efx_fc_type wanted_fc;struct work_struct reconfigure_work;atomic_t rx_reset;
drivers/net/sfc/tenxpress.c +72 -66
195 lines not on this page · raw message
drivers/net/sfc/xfp_phy.c +1 -0
@@ -155,6 +155,7 @@ static void xfp_phy_reconfigure(struct efx_nic *efx) efx->link_up =xfp_link_ok (efx); efx->link_speed =10000 ; efx->link_fd = true; + efx->link_fc = efx->wanted_fc; }
Signature · 3 lines
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.
Re: [PATCH 20/33] sfc: Implement auto-negotiation
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:55:10 +0000
Quoted 8 lines
Add infrastructure for auto-negotiation of speed, duplex and flow control.
When using 10Xpress, auto-negotiate flow control. While we're at it, clean up the code to warn when partner is not 10GBASE-T capable.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 21/33 sfc: Rework MAC, PHY and board event handling
In reply to Ben HutchingsFrom: Steve Hodgson <[email protected]>
MAC, PHY and board events may be separately enabled and signalled. Our current arrangement of chaining the polling functions can result in events being missed. Change them to be more independent.
--- drivers/net/sfc/efx.c | 63 ++++++++++++++++++++++++++------------- drivers/net/sfc/falcon.c | 20 +++++------- drivers/net/sfc/falcon_gmac.c | 8 +---- drivers/net/sfc/falcon_hwdefs.h | 2 + drivers/net/sfc/falcon_xmac.c | 42 +++++++++++++------------ drivers/net/sfc/net_driver.h | 24 ++++++++------ drivers/net/sfc/selftest.c | 6 ++- drivers/net/sfc/tenxpress.c | 44 ++++++++------------------ drivers/net/sfc/xfp_phy.c | 16 +-------- 9 files changed, 111 insertions(+), 114 deletions(-)
drivers/net/sfc/efx.c +42 -21
@@ -612,10 +612,9 @@ void efx_reconfigure_port(struct efx_nic *efx)/* Asynchronous efx_reconfigure_port work item. To speed up efx_flush_all() * we don't efx_reconfigure_port() if the port is disabled. Care is taken * in efx_stop_all() and efx_start_port() to prevent PHY events being lost */ -static void efx_reconfigure_work (struct work_struct *data) +static void efx_phy_work (struct work_struct *data) { - struct efx_nic *efx = container_of(data, struct efx_nic, - reconfigure_work); + struct efx_nic *efx = container_of(data, struct efx_nic, phy_work);mutex_lock (&efx->mac_lock);if (efx->port_enabled)
@@ -623,6 +622,16 @@ static void efx_reconfigure_work(struct work_struct *data)mutex_unlock (&efx->mac_lock); } +static void efx_mac_work (struct work_struct *data) +{ + struct efx_nic *efx = container_of(data, struct efx_nic, mac_work); + +mutex_lock (&efx->mac_lock); +if (efx->port_enabled) + efx->mac_op->irq (efx); +mutex_unlock (&efx->mac_lock); +} +static int efx_probe_port (struct efx_nic *efx) {int rc;
@@ -688,7 +697,7 @@ fail:/* Allow efx_reconfigure_port() to be scheduled, and close the window * between efx_stop_port and efx_flush_all whereby a previously scheduled -* efx_reconfigure_port() may have been cancelled */ +* efx_phy_work()/efx_mac_work() may have been cancelled */ static void efx_start_port (struct efx_nic *efx) {EFX_LOG (efx,"start port\n" );
@@ -697,13 +706,14 @@ static void efx_start_port(struct efx_nic *efx)mutex_lock (&efx->mac_lock); efx->port_enabled = true;__efx_reconfigure_port (efx); + efx->mac_op->irq (efx);mutex_unlock (&efx->mac_lock); } -/* Prevent efx_reconfigure_work and efx_monitor() from executing, and -* efx_set_multicast_list() from scheduling efx_reconfigure_work. -* efx_reconfigure_work can still be scheduled via NAPI processing -* until efx_flush_all() is called */ +/* Prevent efx_phy_work, efx_mac_work, and efx_monitor() from executing, +* and efx_set_multicast_list() from scheduling efx_phy_work. efx_phy_work +* and efx_mac_work may still be scheduled via NAPI processing until +* efx_flush_all() is called */ static void efx_stop_port (struct efx_nic *efx) {EFX_LOG (efx,"stop port\n" );
@@ -1094,7 +1104,8 @@ static void efx_flush_all(struct efx_nic *efx)cancel_delayed_work_sync (&rx_queue->work);/* Stop scheduled port reconfigurations */ -cancel_work_sync (&efx->reconfigure_work); +cancel_work_sync (&efx->mac_work); +cancel_work_sync (&efx->phy_work); }
@@ -1131,7 +1142,7 @@ static void efx_stop_all(struct efx_nic *efx)* window to loose phy events */ efx_stop_port (efx); -/* Flush reconfigure_work, refill_workqueue, monitor_work */ +/* Flush efx_phy_work, efx_mac_work, refill_workqueue, monitor_work */ efx_flush_all (efx);/* Isolate the MAC from the TX and RX engines, so that queue
@@ -1203,24 +1214,31 @@ static void efx_monitor(struct work_struct *data) { struct efx_nic *efx = container_of(data, struct efx_nic, monitor_work.work); +int rc;EFX_TRACE (efx,"hardware monitor executing on CPU %d\n" ,raw_smp_processor_id ()); -/* If the mac_lock is already held then it is likely a port * reconfiguration is already in place, which will likely do * most of the work of check_hw() anyway. */ -if (!mutex_trylock (&efx->mac_lock)) { -queue_delayed_work (efx->workqueue, &efx->monitor_work, - efx_monitor_interval); -return ; +if (!mutex_trylock (&efx->mac_lock)) + goto out_requeue; +if (!efx->port_enabled) + goto out_unlock; + rc = efx->board_info.monitor (efx); +if (rc) { +EFX_ERR (efx,"Board sensor %s; shutting down PHY\n" , + (rc == -ERANGE ) ?"reported fault" :"failed" ); + efx->phy_mode |=PHY_MODE_LOW_POWER ; +falcon_sim_phy_event (efx); } + efx->phy_op->poll (efx); + efx->mac_op->poll (efx); -if (efx->port_enabled) - efx->mac_op->check_hw (efx); +out_unlock:mutex_unlock (&efx->mac_lock); - +out_requeue:queue_delayed_work (efx->workqueue, &efx->monitor_work, efx_monitor_interval); }
@@ -1477,7 +1495,7 @@ static void efx_set_multicast_list(struct net_device *net_dev)return ;if (changed) -queue_work (efx->workqueue, &efx->reconfigure_work); +queue_work (efx->workqueue, &efx->phy_work);/* Create and activate new global multicast hash table */ falcon_set_multicast_hash (efx);
@@ -1800,12 +1818,14 @@ void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {}static struct efx_mac_operations efx_dummy_mac_operations = { .reconfigure = efx_port_dummy_op_void, + .poll = efx_port_dummy_op_void, + .irq = efx_port_dummy_op_void, };static struct efx_phy_operations efx_dummy_phy_operations = { .init = efx_port_dummy_op_int, .reconfigure = efx_port_dummy_op_void, - .check_hw = efx_port_dummy_op_int, + .poll = efx_port_dummy_op_void, .fini = efx_port_dummy_op_void, .clear_interrupt = efx_port_dummy_op_void, };
@@ -1857,7 +1877,8 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, efx->mac_op = &efx_dummy_mac_operations; efx->phy_op = &efx_dummy_phy_operations; efx->mii.dev = net_dev; -INIT_WORK (&efx->reconfigure_work, efx_reconfigure_work); +INIT_WORK (&efx->phy_work, efx_phy_work); +INIT_WORK (&efx->mac_work, efx_mac_work);atomic_set (&efx->netif_stop_count,1 );for (i =0 ; i <EFX_MAX_CHANNELS ; i++) {
drivers/net/sfc/falcon.c +9 -11
@@ -910,22 +910,20 @@ static void falcon_handle_global_event(struct efx_channel *channel, efx_qword_t *event) {struct efx_nic *efx = channel->efx; -bool is_phy_event = false, handled = false; +bool handled = false; -/* Check for interrupt on either port. Some boards have a -* single PHY wired to the interrupt line for port 1. */ if (EFX_QWORD_FIELD (*event,G_PHY0_INTR ) ||EFX_QWORD_FIELD (*event,G_PHY1_INTR ) || -EFX_QWORD_FIELD (*event,XG_PHY_INTR )) - is_phy_event = true; +EFX_QWORD_FIELD (*event,XG_PHY_INTR ) || +EFX_QWORD_FIELD (*event,XFP_PHY_INTR )) { + efx->phy_op->clear_interrupt (efx); +queue_work (efx->workqueue, &efx->phy_work); + handled = true; + }if ((falcon_rev (efx) >=FALCON_REV_B0 ) && -EFX_QWORD_FIELD (*event,XG_MNT_INTR_B0 )) - is_phy_event = true; - -if (is_phy_event) { - efx->phy_op->clear_interrupt (efx); -queue_work (efx->workqueue, &efx->reconfigure_work); +EFX_QWORD_FIELD (*event,XG_MNT_INTR_B0 )) { +queue_work (efx->workqueue, &efx->mac_work); handled = true; }
drivers/net/sfc/falcon_gmac.c +2 -6
@@ -221,13 +221,9 @@ static void falcon_update_stats_gmac(struct efx_nic *efx) mac_stats->rx_lt64 = mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64; } -static int falcon_check_gmac (struct efx_nic *efx) -{ -return efx->phy_op->check_hw (efx); -} -struct efx_mac_operations falcon_gmac_operations = { .reconfigure = falcon_reconfigure_gmac, .update_stats = falcon_update_stats_gmac, - .check_hw = falcon_check_gmac, + .irq = efx_port_dummy_op_void, + .poll = efx_port_dummy_op_void, };
drivers/net/sfc/falcon_hwdefs.h +2 -0
@@ -1051,6 +1051,8 @@#define XG_MNT_INTR_B0_WIDTH 1#define RX_RECOVERY_A1_LBN 11#define RX_RECOVERY_A1_WIDTH 1 +#define XFP_PHY_INTR_LBN 10 +#define XFP_PHY_INTR_WIDTH 1#define XG_PHY_INTR_LBN 9#define XG_PHY_INTR_WIDTH 1#define G_PHY1_INTR_LBN 8
drivers/net/sfc/falcon_xmac.c +22 -20
55 lines not on this page · raw message
drivers/net/sfc/net_driver.h +14 -10
@@ -544,12 +544,14 @@ static inline enum efx_fc_type efx_fc_resolve(enum efx_fc_type wanted_fc,* struct efx_mac_operations - Efx MAC operations table * @reconfigure: Reconfigure MAC. Serialised by the mac_lock * @update_stats: Update statistics -* @check_hw: Check hardware. Serialised by the mac_lock +* @irq: Hardware MAC event callback. Serialised by the mac_lock +* @poll: Poll for hardware state. Serialised by the mac_lock */ struct efx_mac_operations {void (*reconfigure) (struct efx_nic *efx);void (*update_stats) (struct efx_nic *efx); -int (*check_hw) (struct efx_nic *efx); +void (*irq) (struct efx_nic *efx); +void (*poll) (struct efx_nic *efx); };/**
@@ -559,7 +561,7 @@ struct efx_mac_operations {* @reconfigure: Reconfigure PHY (e.g. for new link parameters) * @clear_interrupt: Clear down interrupt * @blink: Blink LEDs -* @check_hw: Check hardware +* @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
@@ -573,7 +575,7 @@ struct efx_phy_operations {void (*fini) (struct efx_nic *efx);void (*reconfigure) (struct efx_nic *efx);void (*clear_interrupt) (struct efx_nic *efx); -int (*check_hw) (struct efx_nic *efx); +void (*poll) (struct efx_nic *efx);int (*test) (struct efx_nic *efx);void (*get_settings) (struct efx_nic *efx,struct ethtool_cmd *ecmd);
@@ -728,10 +730,10 @@ union efx_multicast_hash {* @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode, * @port_inhibited, efx_monitor() and efx_reconfigure_port() * @port_enabled: Port enabled indicator. -* Serialises efx_stop_all(), efx_start_all() and efx_monitor() and -* efx_reconfigure_work with kernel interfaces. Safe to read under any -* one of the rtnl_lock, mac_lock, or netif_tx_lock, but all three must -* be held to modify it. +* Serialises efx_stop_all(), efx_start_all(), efx_monitor(), +* efx_phy_work(), and efx_mac_work() with kernel interfaces. Safe to read +* under any one of the rtnl_lock, mac_lock, or netif_tx_lock, but all +* three must be held to modify it. * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock * @port_initialized: Port initialized? * @net_dev: Operating system network device. Consider holding the rtnl lock
@@ -762,7 +764,8 @@ union efx_multicast_hash {* @promiscuous: Promiscuous flag. Protected by netif_tx_lock. * @multicast_hash: Multicast hash table * @wanted_fc: Wanted flow control flags -* @reconfigure_work: work item for dealing with PHY events +* @phy_work: work item for dealing with PHY events +* @mac_work: work item for dealing with MAC events * @loopback_mode: Loopback status * @loopback_modes: Supported loopback mode bitmask * @loopback_selftest: Offline self-test private state
@@ -810,6 +813,7 @@ struct efx_nic {struct falcon_nic_data *nic_data;struct mutex mac_lock; +struct work_struct mac_work;bool port_enabled;bool port_inhibited;
@@ -830,6 +834,7 @@ struct efx_nic {enum phy_type phy_type;spinlock_t phy_lock; +struct work_struct phy_work;struct efx_phy_operations *phy_op;void *phy_data;struct mii_if_info mii;
@@ -845,7 +850,6 @@ struct efx_nic {bool promiscuous;union efx_multicast_hash multicast_hash;enum efx_fc_type wanted_fc; -struct work_struct reconfigure_work;atomic_t rx_reset;enum efx_loopback_mode loopback_mode;
drivers/net/sfc/selftest.c +4 -2
@@ -594,12 +594,14 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct ethtool_cmd ecmd, efx->loopback_mode = mode;efx_reconfigure_port (efx); -/* Wait for the PHY to signal the link is up */ +/* Wait for the PHY to signal the link is up. Interrupts +* are enabled for PHY's using LASI, otherwise we poll() +* quickly */ count =0 ; do { struct efx_channel *channel = &efx->channel[0]; - efx->mac_op->check_hw(efx); + efx->phy_op->poll(efx); schedule_timeout_uninterruptible(HZ / 10); if (channel->work_pending) efx_process_channel_now(channel);
drivers/net/sfc/tenxpress.c +14 -30
73 lines not on this page · raw message
drivers/net/sfc/xfp_phy.c +2 -14
@@ -119,24 +119,12 @@ static int xfp_link_ok(struct efx_nic *efx)return mdio_clause45_links_ok (efx,XFP_REQUIRED_DEVS ); } -static int xfp_phy_check_hw (struct efx_nic *efx) +static void xfp_phy_poll (struct efx_nic *efx) { -int rc =0 ;int link_up =xfp_link_ok (efx);/* Simulate a PHY event if link state has changed */ if (link_up != efx->link_up)falcon_sim_phy_event (efx); - - rc = efx->board_info.monitor (efx); -if (rc) { -struct xfp_phy_data *phy_data = efx->phy_data; -EFX_ERR (efx,"XFP sensor alert; putting PHY into low power\n" ); - efx->phy_mode |=PHY_MODE_LOW_POWER ; -mdio_clause45_set_mmds_lpower (efx,1 ,XFP_REQUIRED_DEVS ); - phy_data->phy_mode |=PHY_MODE_LOW_POWER ; - } - -return rc; }static void xfp_phy_reconfigure (struct efx_nic *efx)
@@ -173,7 +161,7 @@ struct efx_phy_operations falcon_xfp_phy_ops = { .macs = EFX_XMAC, .init = xfp_phy_init, .reconfigure = xfp_phy_reconfigure, - .check_hw = xfp_phy_check_hw, + .poll = xfp_phy_poll, .fini = xfp_phy_fini, .clear_interrupt = xfp_phy_clear_interrupt, .get_settings = mdio_clause45_get_settings,
Signature · 3 lines
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.
Re: [PATCH 21/33] sfc: Rework MAC, PHY and board event handling
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:55:47 +0000
Quoted 7 lines
From: Steve Hodgson <[email protected]>
MAC, PHY and board events may be separately enabled and signalled. Our current arrangement of chaining the polling functions can result in events being missed. Change them to be more independent.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 22/33 sfc: Add support for Solarflare 10Xpress SFT9001
In reply to Ben HutchingsAdd type codes for the new PHY and rename the SFX7101 type code.
Add definition of clause 22 extension MMD.
Adapt the 10Xpress SFX7101 code to support the SFT9001 as well. Clean up register definitions.
--- drivers/net/sfc/enum.h | 3 + drivers/net/sfc/ethtool.c | 3 + drivers/net/sfc/falcon.c | 10 +- drivers/net/sfc/mdio_10g.h | 8 + drivers/net/sfc/net_driver.h | 4 +- drivers/net/sfc/phy.h | 7 +- drivers/net/sfc/tenxpress.c | 528 +++++++++++++++++++++++++++++++++-------- drivers/net/sfc/workarounds.h | 9 +- 8 files changed, 467 insertions(+), 105 deletions(-)
drivers/net/sfc/enum.h +3 -0
@@ -58,6 +58,9 @@ extern const char *efx_loopback_mode_names[];#define LOOPBACK_INTERNAL (_efx) \ (!!(LOOPBACKS_INTERNAL & LOOPBACK_MASK(_efx))) +#define LOOPBACK_CHANGED (_from, _to, _mask) \ + (!!((LOOPBACK_MASK(_from) ^ LOOPBACK_MASK(_to)) & (_mask))) +#define LOOPBACK_OUT_OF (_from, _to, _mask) \ ((LOOPBACK_MASK(_from) & (_mask)) && !(LOOPBACK_MASK(_to) & (_mask)))
drivers/net/sfc/ethtool.c +3 -0
@@ -219,6 +219,9 @@ 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"
drivers/net/sfc/falcon.c +7 -3
@@ -826,7 +826,7 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,#endif if (unlikely (rx_ev_eth_crc_err &&EFX_WORKAROUND_10750 (efx) && - efx->phy_type ==PHY_TYPE_10XPRESS )) + efx->phy_type ==PHY_TYPE_SFX7101 ))tenxpress_crc_err (efx); }
@@ -2256,8 +2256,12 @@ static void falcon_init_mdio(struct mii_if_info *gmii)static int falcon_probe_phy (struct efx_nic *efx) {switch (efx->phy_type) { -case PHY_TYPE_10XPRESS : - efx->phy_op = &falcon_tenxpress_phy_ops; +case PHY_TYPE_SFX7101 : + efx->phy_op = &falcon_sfx7101_phy_ops; +break ; +case PHY_TYPE_SFT9001A : +case PHY_TYPE_SFT9001B : + efx->phy_op = &falcon_sft9001_phy_ops;break ;case PHY_TYPE_XFP : efx->phy_op = &falcon_xfp_phy_ops;
drivers/net/sfc/mdio_10g.h +8 -0
@@ -33,6 +33,8 @@#define MDIO_MMD_TC (6)/* Auto negotiation */ #define MDIO_MMD_AN (7) +/* Clause 22 extension */ +#define MDIO_MMD_C22EXT 29/* Generic register locations */ #define MDIO_MMDREG_CTRL1 (0)
@@ -82,6 +84,7 @@#define MDIO_MMDREG_DEVS_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS)#define MDIO_MMDREG_DEVS_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)#define MDIO_MMDREG_DEVS_AN DEV_PRESENT_BIT(MDIO_MMD_AN) +#define MDIO_MMDREG_DEVS_C22EXT DEV_PRESENT_BIT(MDIO_MMD_C22EXT)/* Bits in MMDREG_SPEED */ #define MDIO_MMDREG_SPEED_10G_LBN 0
@@ -125,6 +128,11 @@#define MDIO_PMAPMD_CTRL2_10_BT (0xf)#define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf) +/* PMA 10GBT registers */ +#define MDIO_PMAPMD_10GBT_TXPWR (131) +#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN (0) +#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_WIDTH (1) +/* PHY XGXS lane state */ #define MDIO_PHYXS_LANE_STATE (0x18)#define MDIO_PHYXS_LANE_ALIGNED_LBN (12)
drivers/net/sfc/net_driver.h +3 -1
@@ -455,9 +455,11 @@ enum phy_type {PHY_TYPE_NONE =0 ,PHY_TYPE_CX4_RTMR =1 ,PHY_TYPE_1G_ALASKA =2 , -PHY_TYPE_10XPRESS =3 , +PHY_TYPE_SFX7101 =3 ,PHY_TYPE_XFP =4 ,PHY_TYPE_PM8358 =6 , +PHY_TYPE_SFT9001A =8 , +PHY_TYPE_SFT9001B =10 ,PHY_TYPE_MAX /* Insert any new items before this */ };
drivers/net/sfc/phy.h +4 -3
@@ -1,6 +1,6 @@/**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards -* Copyright 2007 Solarflare Communications Inc. +* Copyright 2007-2008 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published
@@ -11,9 +11,10 @@#define EFX_PHY_H /**************************************************************************** -* 10Xpress (SFX7101) PHY +* 10Xpress (SFX7101 and SFT9001) PHYs */ -extern struct efx_phy_operations falcon_tenxpress_phy_ops; +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);
drivers/net/sfc/tenxpress.c +431 -97
722 lines not on this page · raw message
drivers/net/sfc/workarounds.h +8 -1
@@ -17,6 +17,8 @@#define EFX_WORKAROUND_ALWAYS (efx) 1#define EFX_WORKAROUND_FALCON_A (efx) (falcon_rev(efx) <= FALCON_REV_A1) +#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 */ #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS
@@ -27,7 +29,7 @@/* 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_ALWAYS +#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
@@ -51,4 +53,9 @@/* Leak overlength packets rather than free */ #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A +/* Need to send XNP pages for 100BaseT */ +#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001A +/* Need to keep AN enabled */ +#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A +#endif /* EFX_WORKAROUNDS_H */
Signature · 3 lines
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.
Re: [PATCH 22/33] sfc: Add support for Solarflare 10Xpress SFT9001
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:56:06 +0000
Quoted 8 lines
Add type codes for the new PHY and rename the SFX7101 type code.
Add definition of clause 22 extension MMD.
Adapt the 10Xpress SFX7101 code to support the SFT9001 as well. Clean up register definitions.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 23/33 sfc: Add support for SFN4111T
In reply to Ben HutchingsAdd support code for the SFN4111T 100/1000/10GBASE-T reference design, based in part on the existing code for the SFE4001.
--- drivers/net/sfc/boards.c | 2 + drivers/net/sfc/boards.h | 7 ++- drivers/net/sfc/falcon.c | 7 ++ drivers/net/sfc/falcon_hwdefs.h | 2 + drivers/net/sfc/selftest.c | 11 +++- drivers/net/sfc/sfe4001.c | 153 +++++++++++++++++++++++++++++++-------- drivers/net/sfc/workarounds.h | 3 +- 7 files changed, 150 insertions(+), 35 deletions(-)
drivers/net/sfc/boards.c +2 -0
@@ -241,6 +241,8 @@ struct efx_board_data {static struct efx_board_data board_data[] = { {EFX_BOARD_SFE4001 ,"SFE4001" ,"10GBASE-T adapter" , sfe4001_init }, {EFX_BOARD_SFE4002 ,"SFE4002" ,"XFP adapter" , sfe4002_init }, + {EFX_BOARD_SFN4111T ,"SFN4111T" ,"100/1000/10GBASE-T adapter" , + sfn4111t_init }, };void efx_set_board_info (struct efx_nic *efx,u16 revision_info)
drivers/net/sfc/boards.h +6 -1
@@ -12,11 +12,16 @@/* Board IDs (must fit in 8 bits) */ enum efx_board_type { -EFX_BOARD_SFE4001 =1 ,/* SFE4001 (10GBASE-T) */ +EFX_BOARD_SFE4001 =1 ,EFX_BOARD_SFE4002 =2 , +EFX_BOARD_SFN4111T =0x51 , };extern void efx_set_board_info (struct efx_nic *efx,u16 revision_info); + +/* SFE4001 (10GBASE-T) */ extern int sfe4001_init (struct efx_nic *efx); +/* SFN4111T (100/1000/10GBASE-T) */ +extern int sfn4111t_init (struct efx_nic *efx);#endif
drivers/net/sfc/falcon.c +7 -0
@@ -2982,6 +2982,13 @@ int falcon_init_nic(struct efx_nic *efx)EFX_SET_OWORD_FIELD (temp,ONCHIP_SRAM ,1 );falcon_write (efx, &temp,NIC_STAT_REG ); +/* Set the source of the GMAC clock */ +if (falcon_rev (efx) ==FALCON_REV_B0 ) { +falcon_read (efx, &temp,GPIO_CTL_REG_KER ); +EFX_SET_OWORD_FIELD (temp,GPIO_USE_NIC_CLK , true); +falcon_write (efx, &temp,GPIO_CTL_REG_KER ); + } +/* Set buffer table mode */ EFX_POPULATE_OWORD_1 (temp,BUF_TBL_MODE ,BUF_TBL_MODE_FULL );falcon_write (efx, &temp,BUF_TBL_CFG_REG_KER );
drivers/net/sfc/falcon_hwdefs.h +2 -0
@@ -136,6 +136,8 @@/* GPIO control register */ #define GPIO_CTL_REG_KER 0x0210 +#define GPIO_USE_NIC_CLK_LBN (30) +#define GPIO_USE_NIC_CLK_WIDTH (1)#define GPIO_OUTPUTS_LBN (16)#define GPIO_OUTPUTS_WIDTH (4)#define GPIO_INPUTS_LBN (8)
drivers/net/sfc/selftest.c +9 -2
@@ -702,8 +702,15 @@ int efx_offline_test(struct efx_nic *efx,*/ mutex_lock (&efx->mac_lock); efx->port_inhibited = true; -if (efx->loopback_modes) - efx->loopback_mode =__ffs (efx->loopback_modes); +if (efx->loopback_modes) { +/* We need the 312 clock from the PHY to test the XMAC +* registers, so move into XGMII loopback if available */ +if (efx->loopback_modes & (1 <<LOOPBACK_XGMII )) + efx->loopback_mode =LOOPBACK_XGMII ; +else + efx->loopback_mode =__ffs (efx->loopback_modes); + } +__efx_reconfigure_port (efx);mutex_unlock (&efx->mac_lock);
drivers/net/sfc/sfe4001.c +122 -31
193 lines not on this page · raw message
drivers/net/sfc/workarounds.h +2 -1
@@ -17,6 +17,7 @@#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)
@@ -25,7 +26,7 @@/* RX PCIe double split performance issue */ #define EFX_WORKAROUND_7575 EFX_WORKAROUND_ALWAYS/* Bit-bashed I2C reads cause performance drop */ -#define EFX_WORKAROUND_7884 EFX_WORKAROUND_ALWAYS +#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 */
Signature · 3 lines
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.
Re: [PATCH 23/33] sfc: Add support for SFN4111T
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:56:24 +0000
Quoted 4 lines
Add support code for the SFN4111T 100/1000/10GBASE-T reference design, based in part on the existing code for the SFE4001.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 25/33 sfc: Generate unique names for per-NIC workqueues
In reply to Ben Hutchings--- drivers/net/sfc/efx.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
drivers/net/sfc/efx.c +4 -1
@@ -1854,6 +1854,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,struct efx_channel *channel;struct efx_tx_queue *tx_queue;struct efx_rx_queue *rx_queue; +char name[16 ];int i;/* Initialise common structures */
@@ -1924,7 +1925,9 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, efx->interrupt_mode =max (efx->type->max_interrupt_mode, interrupt_mode); - efx->workqueue =create_singlethread_workqueue ("sfc_work" ); +/* Would be good to use the net_dev name, but we're too early */ +snprintf (name,sizeof (name),"sfc%s" ,pci_name (pci_dev)); + efx->workqueue =create_singlethread_workqueue (name);if (!efx->workqueue)return -ENOMEM ;
Signature · 3 lines
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.
David Miller
maintainerRe: [PATCH 25/33] sfc: Generate unique names for per-NIC workqueues
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:56:57 +0000
Quoted 5 lines
drivers/net/sfc/efx.c +1
-0@@ -1854,6 +1854,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,struct efx_channel *channel;struct efx_tx_queue *tx_queue;struct efx_rx_queue *rx_queue; +char name[16 ];
...
drivers/net/sfc/efx.c static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, · line 1931
Quoted 9 lines
drivers/net/sfc/efx.c +3
-1@@ -1924,7 +1925,9 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, efx->interrupt_mode =max (efx->type->max_interrupt_mode, interrupt_mode); - efx->workqueue =create_singlethread_workqueue ("sfc_work" ); +/* Would be good to use the net_dev name, but we're too early */ +snprintf (name,sizeof (name),"sfc%s" ,pci_name (pci_dev)); + efx->workqueue =create_singlethread_workqueue (name);if (!efx->workqueue)
This change is buggy.
create_singlethread_workqueue() is going to reference this name buffer on the stack for the life of the workqueue, but once this function returns that reference will no longer be valid.
You'll need to use kmalloc()'d memory and free it later, or something like that.
Patch not applied.
Re: [PATCH 25/33] sfc: Generate unique names for per-NIC workqueues
Quoted 21 lines · David Miller
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:56:57 +0000Quoted 5 lines
drivers/net/sfc/efx.c +1
-0@@ -1854,6 +1854,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,struct efx_channel *channel;struct efx_tx_queue *tx_queue;struct efx_rx_queue *rx_queue; +char name[16 ];...
drivers/net/sfc/efx.c static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, · line 1931
Quoted 9 lines
drivers/net/sfc/efx.c +3
-1@@ -1924,7 +1925,9 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, efx->interrupt_mode =max (efx->type->max_interrupt_mode, interrupt_mode); - efx->workqueue =create_singlethread_workqueue ("sfc_work" ); +/* Would be good to use the net_dev name, but we're too early */ +snprintf (name,sizeof (name),"sfc%s" ,pci_name (pci_dev)); + efx->workqueue =create_singlethread_workqueue (name);if (!efx->workqueue)This change is buggy.
Quoted 4 lines
create_singlethread_workqueue()is going to reference this name buffer on the stack for the life of the workqueue, but once this function returns that reference will no longer be valid.
No, it's copied into the "comm" field of task_struct.
Ben.
Signature · 3 lines
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.
David Miller
maintainerRe: [PATCH 25/33] sfc: Generate unique names for per-NIC workqueues
From: Ben Hutchings <[email protected]>
Date: Sat, 13 Dec 2008 06:23:03 +0000
Quoted 7 lines
Quoted 4 lines · David Miller
create_singlethread_workqueue()is going to reference this name buffer on the stack for the life of the workqueue, but once this function returns that reference will no longer be valid.No, it's copied into the "comm" field of
task_struct.
Hmmm...
create_singlethread_workqueue(name...
--> __create_workqueue(name... --> __create_workqueue_key(name...
which goes:
wq->cpu_wq = alloc_percpu(struct cpu_workqueue_struct); ... wq->name = name;
Which looks like a dynamic memory assumption to me.
Re: [PATCH 25/33] sfc: Generate unique names for per-NIC workqueues
Quoted 17 lines · David Miller
From: Ben Hutchings <[email protected]>
Date: Sat, 13 Dec 2008 06:23:03 +0000Quoted 7 lines
Quoted 4 lines · David Miller
create_singlethread_workqueue()is going to reference this name buffer on the stack for the life of the workqueue, but once this function returns that reference will no longer be valid.No, it's copied into the "comm" field of
task_struct.Hmmm...
create_singlethread_workqueue(name...
--> __create_workqueue(name... --> __create_workqueue_key(name...
Quoted 6 lines
which goes:
wq->cpu_wq = alloc_percpu(struct cpu_workqueue_struct); ... wq->name = name;Which looks like a dynamic memory assumption to me.
If you look carefully you'll see that wq->name is never used after initialisation of single-threaded workqueues. But I'd agree it's not nice to have that dangling pointer around, so I'll respin this.
Ben.
Signature · 3 lines
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.
PATCH 26/33 sfc: Remove leading spaces
In reply to Ben Hutchings--- drivers/net/sfc/falcon.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/sfc/falcon.c +2 -2
@@ -2940,10 +2940,10 @@ int falcon_probe_nic(struct efx_nic *efx) goto fail5;/* Initialise I2C adapter */ - efx->i2c_adap.owner =THIS_MODULE ; + efx->i2c_adap.owner =THIS_MODULE ; nic_data->i2c_data = falcon_i2c_bit_operations; nic_data->i2c_data.data = efx; - efx->i2c_adap.algo_data = &nic_data->i2c_data; + efx->i2c_adap.algo_data = &nic_data->i2c_data; efx->i2c_adap.dev.parent = &efx->pci_dev->dev;strlcpy (efx->i2c_adap.name,"SFC4000 GPIO" ,sizeof (efx->i2c_adap.name)); rc =i2c_bit_add_bus (&efx->i2c_adap);
Signature · 3 lines
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.
Re: [PATCH 26/33] sfc: Remove leading spaces
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:57:18 +0000
Quoted 2 lines
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 27/33 sfc: Specify a meaningful component for loopback RX-side and PHY tests
In reply to Ben HutchingsOur ethtool self-test result names each begin with a component name. For some results this is "port0", which is not very meaningful. Change that to "rx" or "phy" as appropriate.
--- drivers/net/sfc/ethtool.c | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-)
drivers/net/sfc/ethtool.c +8 -6
@@ -274,8 +274,11 @@ static void efx_fill_test(unsigned int test_index,/* Fill string, if applicable */ if (strings) { -snprintf (unit_str.name,sizeof (unit_str.name), - unit_format, unit_id); +if (strchr (unit_format,'%' )) +snprintf (unit_str.name,sizeof (unit_str.name), + unit_format, unit_id); +else +strcpy (unit_str.name, unit_format);snprintf (test_str.name,sizeof (test_str.name), test_format, test_id); snprintf(strings[test_index].name,
@@ -284,7 +287,6 @@ static void efx_fill_test(unsigned int test_index, } } -#define EFX_PORT_NAME "port%d", 0#define EFX_CHANNEL_NAME (_channel) "chan%d", _channel->channel#define EFX_TX_QUEUE_NAME (_tx_queue) "txq%d", _tx_queue->queue#define EFX_RX_QUEUE_NAME (_rx_queue) "rxq%d", _rx_queue->queue
@@ -320,11 +322,11 @@ static int efx_fill_loopback_test(struct efx_nic *efx, }efx_fill_test (test_index++, strings, data, &lb_tests->rx_good, -EFX_PORT_NAME , +"rx" ,0 ,EFX_LOOPBACK_NAME (mode,"rx_good" ));efx_fill_test (test_index++, strings, data, &lb_tests->rx_bad, -EFX_PORT_NAME , +"rx" ,0 ,EFX_LOOPBACK_NAME (mode,"rx_bad" ));return test_index;
@@ -372,7 +374,7 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,efx_fill_test (n++, strings, data, &tests->registers,"core" ,0 ,"registers" ,NULL );efx_fill_test (n++, strings, data, &tests->phy, -EFX_PORT_NAME ,"phy" ,NULL ); +"phy" ,0 ,"bist" ,NULL );/* Loopback tests */ for (mode =LOOPBACK_NONE ; mode <=LOOPBACK_TEST_MAX ; mode++) {
Signature · 3 lines
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.
Re: [PATCH 27/33] sfc: Specify a meaningful component for loopback RX-side and PHY tests
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:57:34 +0000
Quoted 5 lines
Our ethtool self-test result names each begin with a component name. For some results this is "port0", which is not very meaningful. Change that to "rx" or "phy" as appropriate.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 28/33 sfc: Use mutex_lock_interruptible() for ethtool EEPROM access
In reply to Ben Hutchingsethtool must contend with the MTD driver for the SPI bus lock, which may carry out long operations such as flash erase. Allow it to be interrupted while waiting.
--- drivers/net/sfc/ethtool.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-)
drivers/net/sfc/ethtool.c +8 -2
@@ -568,10 +568,13 @@ static int efx_ethtool_get_eeprom(struct net_device *net_dev,size_t len;int rc; -mutex_lock (&efx->spi_lock); + rc =mutex_lock_interruptible (&efx->spi_lock); +if (rc) +return rc; rc =falcon_spi_read (spi, eeprom->offset +EFX_EEPROM_BOOTCONFIG_START , eeprom->len, &len, buf);mutex_unlock (&efx->spi_lock); + eeprom->magic =EFX_ETHTOOL_EEPROM_MAGIC ; eeprom->len = len;return rc;
@@ -588,10 +591,13 @@ static int efx_ethtool_set_eeprom(struct net_device *net_dev,if (eeprom->magic !=EFX_ETHTOOL_EEPROM_MAGIC )return -EINVAL ; -mutex_lock (&efx->spi_lock); + rc =mutex_lock_interruptible (&efx->spi_lock); +if (rc) +return rc; rc =falcon_spi_write (spi, eeprom->offset +EFX_EEPROM_BOOTCONFIG_START , eeprom->len, &len, buf);mutex_unlock (&efx->spi_lock); + eeprom->len = len;return rc; }
Signature · 3 lines
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.
Re: [PATCH 28/33] sfc: Use mutex_lock_interruptible() for ethtool EEPROM access
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:59:23 +0000
Quoted 5 lines
ethtool must contend with the MTD driver for the SPI bus lock, which may carry out long operations such as flash erase. Allow it to be interrupted while waiting.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 29/33 sfc: Use model numbers for PHY type names
In reply to Ben HutchingsSome of the PHY type names are overly generic. Change them to include the model numbers of the PHYs they represent.
Correct the model number reference at the top of xfp_phy.c.
--- drivers/net/sfc/falcon.c | 2 +- drivers/net/sfc/net_driver.h | 6 +++--- drivers/net/sfc/xfp_phy.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-)
drivers/net/sfc/falcon.c +1 -1
@@ -2263,7 +2263,7 @@ static int falcon_probe_phy(struct efx_nic *efx)case PHY_TYPE_SFT9001B : efx->phy_op = &falcon_sft9001_phy_ops;break ; -case PHY_TYPE_XFP : +case PHY_TYPE_QT2022C2 : efx->phy_op = &falcon_xfp_phy_ops;break ;default :
drivers/net/sfc/net_driver.h +3 -3
@@ -453,10 +453,10 @@ enum efx_int_mode {enum phy_type {PHY_TYPE_NONE =0 , -PHY_TYPE_CX4_RTMR =1 , -PHY_TYPE_1G_ALASKA =2 , +PHY_TYPE_TXC43128 =1 , +PHY_TYPE_88E1111 =2 ,PHY_TYPE_SFX7101 =3 , -PHY_TYPE_XFP =4 , +PHY_TYPE_QT2022C2 =4 ,PHY_TYPE_PM8358 =6 ,PHY_TYPE_SFT9001A =8 ,PHY_TYPE_SFT9001B =10 ,
drivers/net/sfc/xfp_phy.c +1 -1
@@ -7,7 +7,7 @@* by the Free Software Foundation, incorporated herein by reference. */ /* -* Driver for XFP optical PHYs (plus some support specific to the Quake 2032) +* Driver for XFP optical PHYs (plus some support specific to the Quake 2022/32) * See www.amcc.com for details (search for qt2032) */
Signature · 3 lines
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.
Re: [PATCH 29/33] sfc: Use model numbers for PHY type names
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:59:44 +0000
Quoted 6 lines
Some of the PHY type names are overly generic. Change them to include the model numbers of the PHYs they represent.
Correct the model number reference at the top of
xfp_phy.c.Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 30/33 sfc: Treat probe as unsuccessful if it scheduled a reset
In reply to Ben HutchingsFrom: Steve Hodgson <[email protected]>
efx_pci_probe_main() can return success despite a reset being scheduled. Catch this and retry or abort probe depending on the reset type.
--- drivers/net/sfc/efx.c | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-)
drivers/net/sfc/efx.c +11 -2
@@ -2115,8 +2115,6 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,* we're in STATE_INIT. */ for (i =0 ; i <5 ; i++) { rc =efx_pci_probe_main (efx); -if (rc ==0 ) -break ;/* Serialise against efx_reset(). No more resets will be * scheduled since efx_stop_all() has been called, and we
@@ -2124,6 +2122,17 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,* the rtnetlink or driverlink layers. */ cancel_work_sync (&efx->reset_work); +if (rc ==0 ) { +if (efx->reset_pending !=RESET_TYPE_NONE ) { +/* If there was a scheduled reset during +* probe, the NIC is probably hosed anyway */ +efx_pci_remove_main (efx); + rc = -EIO ; + }else { +break ; + } + } +/* Retry if a recoverably reset event has been scheduled */ if ((efx->reset_pending !=RESET_TYPE_INVISIBLE ) && (efx->reset_pending !=RESET_TYPE_ALL ))
Signature · 3 lines
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.
Re: [PATCH 30/33] sfc: Treat probe as unsuccessful if it scheduled a reset
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 13:00:12 +0000
Quoted 6 lines
From: Steve Hodgson <[email protected]>
efx_pci_probe_main()can return success despite a reset being scheduled. Catch this and retry or abort probe depending on the reset type.Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 31/33 sfc: Use kzalloc() to ensure struct efx_spi_device is fully initialised
In reply to Ben HutchingsCurrently the mtd field is not initialised early enough.
--- drivers/net/sfc/falcon.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/sfc/falcon.c +1 -1
@@ -2701,7 +2701,7 @@ static int falcon_spi_device_init(struct efx_nic *efx,struct efx_spi_device *spi_device;if (device_type !=0 ) { - spi_device =kmalloc (sizeof (*spi_device),GFP_KERNEL ); + spi_device =kzalloc (sizeof (*spi_device),GFP_KERNEL );if (!spi_device)return -ENOMEM ; spi_device->device_id = device_id;
Signature · 3 lines
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.
Re: [PATCH 31/33] sfc: Use kzalloc() to ensure struct efx_spi_device is fully initialised
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 13:00:30 +0000
Quoted 3 lines
Currently the mtd field is not initialised early enough.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 10/33 sfc: Add option to use a separate channel for TX completions
From: Neil Turton <[email protected]>
In a bidirectional forwarding test, we find that the best performance is achieved by sending the TX completion interrupts from one NIC to a CPU which shares an L2 cache with RX completion interrupts from the other NIC. To facilitate this, add an option (through a module parameter) to create separate channels for RX and TX completion with separate IRQs when MSI-X is available.
--- drivers/net/sfc/efx.c | 41 ++++++++++++++++++++++++++--------------- drivers/net/sfc/net_driver.h | 2 ++ 2 files changed, 28 insertions(+), 15 deletions(-)
drivers/net/sfc/efx.c +26 -15
@@ -64,13 +64,15 @@ MODULE_PARM_DESC(lro, "Large receive offload acceleration");/* * Use separate channels for TX and RX events * -* Set this to 1 to use separate channels for TX and RX. It allows us to -* apply a higher level of interrupt moderation to TX events. +* Set this to 1 to use separate channels for TX and RX. It allows us +* to control interrupt affinity separately for TX and RX. * -* This is forced to 0 for MSI interrupt mode as the interrupt vector -* is not written +* This is only used in MSI-X interrupt mode */ -static unsigned int separate_tx_and_rx_channels = true; +static unsigned int separate_tx_channels; +module_param (separate_tx_channels, uint,0644 ); +MODULE_PARM_DESC (separate_tx_channels, +"Use separate channels for TX and RX" );/* This is the weight assigned to each of the (per-channel) virtual * NAPI devices.
@@ -846,26 +848,33 @@ static void efx_probe_interrupts(struct efx_nic *efx)if (efx->interrupt_mode ==EFX_INT_MODE_MSIX ) {struct msix_entry xentries[EFX_MAX_CHANNELS ];int wanted_ints; +int rx_queues;/* We want one RX queue and interrupt per CPU package * (or as specified by the rss_cpus module parameter). * We will need one channel per interrupt. */ - wanted_ints = rss_cpus ? rss_cpus :efx_wanted_rx_queues (); - efx->n_rx_queues =min (wanted_ints, max_channels); + rx_queues = rss_cpus ? rss_cpus :efx_wanted_rx_queues (); + wanted_ints = rx_queues + (separate_tx_channels ?1 :0 ); + wanted_ints =min (wanted_ints, max_channels); -for (i =0 ; i < efx->n_rx_queues; i++) +for (i =0 ; i < wanted_ints; i++) xentries[i].entry = i; - rc =pci_enable_msix (efx->pci_dev, xentries, efx->n_rx_queues); + rc =pci_enable_msix (efx->pci_dev, xentries, wanted_ints);if (rc >0 ) { -EFX_BUG_ON_PARANOID (rc >= efx->n_rx_queues); - efx->n_rx_queues = rc; +EFX_ERR (efx,"WARNING: Insufficient MSI-X vectors" +" available (%d < %d).\n" , wanted_ints, rc); +EFX_ERR (efx,"WARNING: Performance may be reduced.\n" ); +EFX_BUG_ON_PARANOID (rc >= wanted_ints); + wanted_ints = rc; rc =pci_enable_msix (efx->pci_dev, xentries, - efx->n_rx_queues); + wanted_ints); }if (rc ==0 ) { -for (i =0 ; i < efx->n_rx_queues; i++) + efx->n_rx_queues =min (rx_queues, wanted_ints); + efx->n_channels = wanted_ints; +for (i =0 ; i < wanted_ints; i++) efx->channel[i].irq = xentries[i].vector; }else {/* Fall back to single channel MSI */
@@ -877,6 +886,7 @@ static void efx_probe_interrupts(struct efx_nic *efx)/* Try single interrupt MSI */ if (efx->interrupt_mode ==EFX_INT_MODE_MSI ) { efx->n_rx_queues =1 ; + efx->n_channels =1 ; rc =pci_enable_msi (efx->pci_dev);if (rc ==0 ) { efx->channel[0 ].irq = efx->pci_dev->irq;
@@ -889,6 +899,7 @@ static void efx_probe_interrupts(struct efx_nic *efx)/* Assume legacy interrupts */ if (efx->interrupt_mode ==EFX_INT_MODE_LEGACY ) { efx->n_rx_queues =1 ; + efx->n_channels =1 + (separate_tx_channels ?1 :0 ); efx->legacy_irq = efx->pci_dev->irq; } }
@@ -913,8 +924,8 @@ static void efx_set_channels(struct efx_nic *efx)struct efx_rx_queue *rx_queue;efx_for_each_tx_queue (tx_queue, efx) { -if (!EFX_INT_MODE_USE_MSI (efx) && separate_tx_and_rx_channels) - tx_queue->channel = &efx->channel[1 ]; +if (separate_tx_channels) + tx_queue->channel = &efx->channel[efx->n_channels-1 ];else tx_queue->channel = &efx->channel[0 ]; tx_queue->channel->used_flags |=EFX_USED_BY_TX ;
drivers/net/sfc/net_driver.h +2 -0
@@ -649,6 +649,7 @@ union efx_multicast_hash {* @rx_queue: RX DMA queues * @channel: Channels * @n_rx_queues: Number of RX queues +* @n_channels: Number of channels in use * @rx_buffer_len: RX buffer length * @rx_buffer_order: Order (log2) of number of pages for each RX buffer * @irq_status: Interrupt status buffer
@@ -728,6 +729,7 @@ struct efx_nic {struct efx_channel channel[EFX_MAX_CHANNELS ];int n_rx_queues; +int n_channels;unsigned int rx_buffer_len;unsigned int rx_buffer_order;
Signature · 3 lines
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.
Re: [PATCH 10/33] sfc: Add option to use a separate channel for TX completions
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:52:16 +0000
Quoted 10 lines
From: Neil Turton <[email protected]>
In a bidirectional forwarding test, we find that the best performance is achieved by sending the TX completion interrupts from one NIC to a CPU which shares an L2 cache with RX completion interrupts from the other NIC. To facilitate this, add an option (through a module parameter) to create separate channels for RX and TX completion with separate IRQs when MSI-X is available.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 11/33 sfc: Provide hints to irqbalance daemon
In reply to a message not in the archiveAllocate IRQs with the name format <device>[-<type>]-<number> so that future versions of irqbalanced understand what we're doing.
--- drivers/net/sfc/efx.c | 24 ++++++++++++++++++++++++ drivers/net/sfc/falcon.c | 2 +- drivers/net/sfc/net_driver.h | 2 ++ 3 files changed, 27 insertions(+), 1 deletions(-)
drivers/net/sfc/efx.c +24 -0
@@ -356,6 +356,27 @@ static int efx_probe_channel(struct efx_channel *channel) } +static void efx_set_channel_names (struct efx_nic *efx) +{ +struct efx_channel *channel; +const char *type ="" ; +int number; + +efx_for_each_channel (channel, efx) { + number = channel->channel; +if (efx->n_channels > efx->n_rx_queues) { +if (channel->channel < efx->n_rx_queues) { + type ="-rx" ; + }else { + type ="-tx" ; + number -= efx->n_rx_queues; + } + } +snprintf (channel->name,sizeof (channel->name), +"%s%s-%d" , efx->name, type, number); + } +} +/* Channels are shutdown and reinitialised whilst the NIC is running * to propagate configuration changes (mtu, checksum offload), or * to clear hardware error conditions
@@ -1002,6 +1023,7 @@ static int efx_probe_all(struct efx_nic *efx) goto fail3; } } +efx_set_channel_names (efx);return 0 ;
@@ -1483,6 +1505,7 @@ static int efx_netdev_event(struct notifier_block *this,strcpy (efx->name, net_dev->name);efx_mtd_rename (efx); +efx_set_channel_names (efx); }return NOTIFY_DONE ;
@@ -1516,6 +1539,7 @@ static int efx_register_netdev(struct efx_nic *efx)return rc; }strcpy (efx->name, net_dev->name); +efx_set_channel_names (efx);return 0 ; }
drivers/net/sfc/falcon.c +1 -1
@@ -1585,7 +1585,7 @@ int falcon_init_interrupt(struct efx_nic *efx)efx_for_each_channel (channel, efx) { rc =request_irq (channel->irq, falcon_msi_interrupt,IRQF_PROBE_SHARED ,/* Not shared */ - efx->name, channel); + channel->name, channel);if (rc) {EFX_ERR (efx,"failed to hook IRQ %d\n" , channel->irq); goto fail2;
drivers/net/sfc/net_driver.h +2 -0
@@ -327,6 +327,7 @@ enum efx_rx_alloc_method {* * @efx: Associated Efx NIC * @channel: Channel instance number +* @name: Name for channel and IRQ * @used_flags: Channel is used by net driver * @enabled: Channel enabled indicator * @irq: IRQ number (MSI and MSI-X only)
@@ -357,6 +358,7 @@ enum efx_rx_alloc_method {struct efx_channel {struct efx_nic *efx;int channel; +char name[IFNAMSIZ +6 ];int used_flags;bool enabled;int irq;
Signature · 3 lines
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.
Re: [PATCH 11/33] sfc: Provide hints to irqbalance daemon
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:52:30 +0000
Quoted 4 lines
Allocate IRQs with the name format <device>[-<type>]-<number> so that future versions of irqbalanced understand what we're doing.
Signed-off-by Ben Hutchings <[email protected]>
Applied, thanks for doing this Ben.
PATCH 12/33 sfc: Abbreviate self-test names so they are not truncated
In reply to a message not in the archiveChange "channel" to "chan".
Shorten PHY loopback names.
--- drivers/net/sfc/ethtool.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-)
drivers/net/sfc/ethtool.c +8 -8
@@ -27,9 +27,9 @@ const char *efx_loopback_mode_names[] = { [LOOPBACK_XGXS] = "XGXS", [LOOPBACK_XAUI] = "XAUI", [LOOPBACK_PHY] = "PHY", - [LOOPBACK_PHYXS] = "PHY(XS)", - [LOOPBACK_PCS] = "PHY(PCS)", - [LOOPBACK_PMAPMD] = "PHY(PMAPMD)", + [LOOPBACK_PHYXS] = "PHYXS", + [LOOPBACK_PCS] = "PCS", + [LOOPBACK_PMAPMD] = "PMA/PMD", [LOOPBACK_NETWORK] = "NETWORK", };
@@ -242,10 +242,10 @@ static void efx_ethtool_get_drvinfo(struct net_device *net_dev,* @strings: Ethtool strings, or %NULL * @data: Ethtool test results, or %NULL * @test: Pointer to test result (used only if data != %NULL) -* @unit_format: Unit name format (e.g. "channel\%d") -* @unit_id: Unit id (e.g. 0 for "channel0") +* @unit_format: Unit name format (e.g. "chan\%d") +* @unit_id: Unit id (e.g. 0 for "chan0") * @test_format: Test name format (e.g. "loopback.\%s.tx.sent") -* @test_id: Test id (e.g. "PHY" for "loopback.PHY.tx_sent") +* @test_id: Test id (e.g. "PHYXS" for "loopback.PHYXS.tx_sent") * * Fill in an individual self-test entry. */
@@ -268,12 +268,12 @@ static void efx_fill_test(unsigned int test_index, test_format, test_id);snprintf (strings[test_index].name,sizeof (strings[test_index].name), -"%-9s%-17s" , unit_str.name, test_str.name); +"%-6s %-24s" , unit_str.name, test_str.name); } }#define EFX_PORT_NAME "port%d", 0 -#define EFX_CHANNEL_NAME (_channel) "channel%d", _channel->channel +#define EFX_CHANNEL_NAME (_channel) "chan%d", _channel->channel#define EFX_TX_QUEUE_NAME (_tx_queue) "txq%d", _tx_queue->queue#define EFX_RX_QUEUE_NAME (_rx_queue) "rxq%d", _rx_queue->queue#define EFX_LOOPBACK_NAME (_mode, _counter) \
Signature · 3 lines
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.
Re: [PATCH 12/33] sfc: Abbreviate self-test names so they are not truncated
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 12:52:45 +0000
Quoted 5 lines
Change "channel" to "chan".
Shorten PHY loopback names.
Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 24/33 sfc: Fix format arguments for warning about MSI-X allocation
In reply to a message not in the archive--- drivers/net/sfc/efx.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/sfc/efx.c +1 -1
@@ -899,7 +899,7 @@ static void efx_probe_interrupts(struct efx_nic *efx) rc =pci_enable_msix (efx->pci_dev, xentries, wanted_ints);if (rc >0 ) {EFX_ERR (efx,"WARNING: Insufficient MSI-X vectors" -" available (%d < %d).\n" , wanted_ints, rc); +" available (%d < %d).\n" , rc, wanted_ints);EFX_ERR (efx,"WARNING: Performance may be reduced.\n" );EFX_BUG_ON_PARANOID (rc >= wanted_ints); wanted_ints = rc;
Signature · 3 lines
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.
Re: [PATCH 24/33] sfc: Fix format arguments for warning about MSI-X allocation
Quoted 10 lines · Ben Hutchings
Signed-off-by Ben Hutchings <[email protected]>--- drivers/net/sfc/efx.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)drivers/net/sfc/efx.c +0
-0
drivers/net/sfc/efx.c static void efx_probe_interrupts(struct efx_nic *efx) · line 905
Quoted 8 lines
drivers/net/sfc/efx.c +1
-1@@ -899,7 +899,7 @@ static void efx_probe_interrupts(struct efx_nic *efx) rc =pci_enable_msix (efx->pci_dev, xentries, wanted_ints);if (rc >0 ) {EFX_ERR (efx,"WARNING: Insufficient MSI-X vectors" -" available (%d < %d).\n" , wanted_ints, rc); +" available (%d < %d).\n" , rc, wanted_ints);EFX_ERR (efx,"WARNING: Performance may be reduced.\n" );EFX_BUG_ON_PARANOID (rc >= wanted_ints); wanted_ints = rc;
I thought this warning was already present, but it is actually introduced by patch 10/33. There's no point in introducing it wrongly, so please combine the two. Or I can post the combined patch myself.
Ben.
Signature · 3 lines
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.
David Miller
maintainerRe: [PATCH 24/33] sfc: Fix format arguments for warning about MSI-X allocation
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 20:34:47 +0000
Quoted 3 lines
I thought this warning was already present, but it is actually introduced by patch 10/33. There's no point in introducing it wrongly, so please combine the two. Or I can post the combined patch myself.
I'll take care of this, thanks Ben.
PATCH 32/33 sfc: Fix synchronisation of efx_mtd_{probe,rename,remove}
In reply to a message not in the archiveCurrently efx_mtd_rename() can race with the probe() and remove() functions.
Move probe() before device registration and remove() after unregistration. Move initialisation/update of all names based on the netdev name into a new function and call it under the RTNL immediately after registration.
--- drivers/net/sfc/efx.c | 33 ++++++++++++++++++--------------- 1 files changed, 18 insertions(+), 15 deletions(-)
drivers/net/sfc/efx.c +18 -15
@@ -1517,18 +1517,21 @@ static const struct net_device_ops efx_netdev_ops = {#endif }; +static void efx_update_name (struct efx_nic *efx) +{ +strcpy (efx->name, efx->net_dev->name); +efx_mtd_rename (efx); +efx_set_channel_names (efx); +} +static int efx_netdev_event (struct notifier_block *this,unsigned long event,void *ptr) {struct net_device *net_dev = ptr; -if (net_dev->netdev_ops == &efx_netdev_ops && event ==NETDEV_CHANGENAME ) { -struct efx_nic *efx =netdev_priv (net_dev); - -strcpy (efx->name, net_dev->name); -efx_mtd_rename (efx); -efx_set_channel_names (efx); - } +if (net_dev->netdev_ops == &efx_netdev_ops && + event ==NETDEV_CHANGENAME ) +efx_update_name (netdev_priv (net_dev));return NOTIFY_DONE ; }
@@ -1568,8 +1571,10 @@ static int efx_register_netdev(struct efx_nic *efx)EFX_ERR (efx,"could not register net dev\n" );return rc; } -strcpy (efx->name, net_dev->name); -efx_set_channel_names (efx); + +rtnl_lock (); +efx_update_name (efx); +rtnl_unlock (); rc =device_create_file (&efx->pci_dev->dev, &dev_attr_phy_type);if (rc) {
@@ -1981,8 +1986,6 @@ static void efx_pci_remove(struct pci_dev *pci_dev)if (!efx)return ; -efx_mtd_remove (efx); -/* Mark the NIC as fini, then stop the interface */ rtnl_lock (); efx->state =STATE_FINI ;
@@ -1996,6 +1999,8 @@ static void efx_pci_remove(struct pci_dev *pci_dev)efx_unregister_netdev (efx); +efx_mtd_remove (efx); +/* Wait for any scheduled resets to complete. No more will be * scheduled from this point because efx_stop_all() has been * called, we are no longer registered with driverlink, and
@@ -2149,17 +2154,15 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,/* Switch to the running state before we expose the device to * the OS. This is to ensure that the initial gathering of * MAC stats succeeds. */ -rtnl_lock (); efx->state =STATE_RUNNING ; -rtnl_unlock (); + +efx_mtd_probe (efx);/* allowed to fail */ rc =efx_register_netdev (efx);if (rc) goto fail5;EFX_LOG (efx,"initialisation successful\n" ); - -efx_mtd_probe (efx);/* allowed to fail */ return 0 ; fail5:
Signature · 3 lines
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.
Re: [PATCH 32/33] sfc: Fix synchronisation of efx_mtd_{probe,rename,remove}
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 13:00:51 +0000
Quoted 9 lines
Currently
efx_mtd_rename()can race with theprobe()andremove()functions.Move
probe()before device registration andremove()after unregistration. Move initialisation/update of all names based on the netdev name into a new function and call it under the RTNL immediately after registration.Signed-off-by Ben Hutchings <[email protected]>
Applied.
PATCH 33/33 sfc: Version 2.3
In reply to a message not in the archive--- drivers/net/sfc/net_driver.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/sfc/net_driver.h +1 -1
@@ -42,7 +42,7 @@#ifndef EFX_DRIVER_NAME #define EFX_DRIVER_NAME "sfc"#endif -#define EFX_DRIVER_VERSION "2.2" +#define EFX_DRIVER_VERSION "2.3"#ifdef EFX_ENABLE_DEBUG #define EFX_BUG_ON_PARANOID (x) BUG_ON(x)
Signature · 3 lines
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.
David Miller
maintainerRe: [PATCH 33/33] sfc: Version 2.3
From: Ben Hutchings <[email protected]>
Date: Fri, 12 Dec 2008 13:01:06 +0000
Quoted 2 lines
Signed-off-by Ben Hutchings <[email protected]>
Also applied.