sfc: various updates
Subsystems (2)
cover sfc: various updates
The following patch series restores some features that were omitted from our initial submission. It also includes some minor clean-ups and bug fixes.
Ben.
Signature · 2 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job.
PATCH 1/9 Add TSO support
The SFC4000 controller does not have hardware support for TSO, and the core GSO code incurs a high cost in allocating and freeing skbs. This TSO implementation uses lightweight packet header structures and is substantially faster.
--- drivers/net/sfc/efx.c | 4 +- drivers/net/sfc/ethtool.c | 27 ++ drivers/net/sfc/net_driver.h | 14 + drivers/net/sfc/tx.c | 664 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 708 insertions(+), 1 deletions(-)
drivers/net/sfc/efx.c +3 -1
@@ -1873,6 +1873,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, tx_queue->queue = i; tx_queue->buffer =NULL ; tx_queue->channel = &efx->channel[0 ];/* for safety */ + tx_queue->tso_headers_free =NULL ; }for (i =0 ; i <EFX_MAX_RX_QUEUES ; i++) { rx_queue = &efx->rx_queue[i];
@@ -2071,7 +2072,8 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, net_dev =alloc_etherdev (sizeof (*efx));if (!net_dev)return -ENOMEM ; - net_dev->features |=NETIF_F_IP_CSUM |NETIF_F_SG |NETIF_F_HIGHDMA ; + net_dev->features |= (NETIF_F_IP_CSUM |NETIF_F_SG | +NETIF_F_HIGHDMA |NETIF_F_TSO );if (lro) net_dev->features |=NETIF_F_LRO ; efx = net_dev->priv;
drivers/net/sfc/ethtool.c +27 -0
@@ -272,6 +272,22 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, } } +static int efx_ethtool_set_tso (struct net_device *net_dev,u32 enable) +{ +int rc; + +/* Our TSO requires TX checksumming, so force TX checksumming +* on when TSO is enabled. +*/ +if (enable) { + rc =efx_ethtool_set_tx_csum (net_dev,1 ); +if (rc) +return rc; + } + +return ethtool_op_set_tso (net_dev, enable); +} +static int efx_ethtool_set_tx_csum (struct net_device *net_dev,u32 enable) {struct efx_nic *efx = net_dev->priv;
@@ -283,6 +299,15 @@ static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable)efx_flush_queues (efx); +/* Our TSO requires TX checksumming, so disable TSO when +* checksumming is disabled +*/ +if (!enable) { + rc =efx_ethtool_set_tso (net_dev,0 ); +if (rc) +return rc; + } +return 0 ; }
@@ -451,6 +476,8 @@ struct ethtool_ops efx_ethtool_ops = { .set_tx_csum = efx_ethtool_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, + .get_tso = ethtool_op_get_tso, + .set_tso = efx_ethtool_set_tso, .get_flags = ethtool_op_get_flags, .set_flags = ethtool_op_set_flags, .get_strings = efx_ethtool_get_strings,
drivers/net/sfc/net_driver.h +14 -0
@@ -134,6 +134,8 @@ struct efx_special_buffer {* Set only on the final fragment of a packet; %NULL for all other * fragments. When this fragment completes, then we can free this * skb. +* @tsoh: The associated TSO header structure, or %NULL if this +* buffer is not a TSO header. * @dma_addr: DMA address of the fragment. * @len: Length of this fragment. * This field is zero when the queue slot is empty.
@@ -144,6 +146,7 @@ struct efx_special_buffer {*/ struct efx_tx_buffer {const struct sk_buff *skb; +struct efx_tso_header *tsoh;dma_addr_t dma_addr;unsigned short len;unsigned char continuation;
@@ -187,6 +190,13 @@ struct efx_tx_buffer {* variable indicates that the queue is full. This is to * avoid cache-line ping-pong between the xmit path and the * completion path. +* @tso_headers_free: A list of TSO headers allocated for this TX queue +* that are not in use, and so available for new TSO sends. The list +* is protected by the TX queue lock. +* @tso_bursts: Number of times TSO xmit invoked by kernel +* @tso_long_headers: Number of packets with headers too long for standard +* blocks +* @tso_packets: Number of packets via the TSO xmit path */ struct efx_tx_queue {/* Members which don't change on the fast path */
@@ -206,6 +216,10 @@ struct efx_tx_queue {unsigned int insert_count____cacheline_aligned_in_smp ;unsigned int write_count;unsigned int old_read_count; +struct efx_tso_header *tso_headers_free; +unsigned int tso_bursts; +unsigned int tso_long_headers; +unsigned int tso_packets; };/**
drivers/net/sfc/tx.c +664 -0
691 lines not on this page · raw message
Signature · 2 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job.
Re: [PATCH 1/9] Add TSO support
Quoted 5 lines · Ben Hutchings
The SFC4000 controller does not have hardware support for TSO, and the core GSO code incurs a high cost in allocating and freeing skbs. This TSO implementation uses lightweight packet header structures and is substantially faster.
Quoted 7 lines
Signed-off-by Ben Hutchings <[email protected]>--- drivers/net/sfc/efx.c | 4 +- drivers/net/sfc/ethtool.c | 27 ++ drivers/net/sfc/net_driver.h | 14 + drivers/net/sfc/tx.c | 664 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 708 insertions(+), 1 deletions(-)
applied 1-9, with two comments:
1) your subject line is missing a useful prefix. see
http://linux.yyz.us/patch-format.html
2) normally TSO addition would not be permitting during the bug-fixes-only phase of the kernel development (2.6.26-rc is current), but since the driver is new, it is reasonable because there can be no regressions
PATCH 2/9 Add phy_flash_cfg module parameter and implementation
In reply to Ben HutchingsThe 10Xpress PHY supports flash upgrades through MDIO, but needs to be put in upgrade mode at power-up. This adds a module parameter and other logic to support that.
--- drivers/net/sfc/boards.h | 2 ++ drivers/net/sfc/falcon_xmac.c | 4 ++++ drivers/net/sfc/sfe4001.c | 14 ++++++++++++++ drivers/net/sfc/tenxpress.c | 10 ++++++---- 4 files changed, 26 insertions(+), 4 deletions(-)
drivers/net/sfc/boards.h +2 -0
@@ -22,5 +22,7 @@ enum efx_board_type {extern int efx_set_board_info (struct efx_nic *efx,u16 revision_info);extern int sfe4001_poweron (struct efx_nic *efx);extern void sfe4001_poweroff (struct efx_nic *efx); +/* Are we putting the PHY into flash config mode */ +extern unsigned int sfe4001_phy_flash_cfg;#endif
drivers/net/sfc/falcon_xmac.c +4 -0
@@ -69,6 +69,10 @@ static int falcon_reset_xmac(struct efx_nic *efx)udelay (10 ); } +/* This often fails when DSP is disabled, ignore it */ +if (sfe4001_phy_flash_cfg !=0 ) +return 0 ; +EFX_ERR (efx,"timed out waiting for XMAC core reset\n" );return -ETIMEDOUT ; }
drivers/net/sfc/sfe4001.c +14 -0
@@ -130,6 +130,15 @@ void sfe4001_poweroff(struct efx_nic *efx) (void )efx_i2c_read (i2c,MAX6647 ,RSL , &in,1 ); } +/* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected +* to the FLASH_CFG_1 input on the DSP. We must keep it high at power- +* up to allow writing the flash (done through MDIO from userland). +*/ +unsigned int sfe4001_phy_flash_cfg; +module_param_named (phy_flash_cfg, sfe4001_phy_flash_cfg, uint,0444 ); +MODULE_PARM_DESC (phy_flash_cfg, +"Force PHY to enter flash configuration mode" ); +/* This board uses an I2C expander to provider power to the PHY, which needs to * be turned on before the PHY can be used. * Context: Process context, rtnl lock held
@@ -203,6 +212,8 @@ int sfe4001_poweron(struct efx_nic *efx) out =0xff & ~((1 <<P0_EN_1V2_LBN ) | (1 <<P0_EN_2V5_LBN ) | (1 <<P0_EN_3V3X_LBN ) | (1 <<P0_EN_5V_LBN ) | (1 <<P0_X_TRST_LBN )); +if (sfe4001_phy_flash_cfg) + out |=1 <<P0_EN_3V3X_LBN ; rc =efx_i2c_write (i2c,PCA9539 ,P0_OUT , &out,1 );if (rc)
@@ -226,6 +237,9 @@ int sfe4001_poweron(struct efx_nic *efx)if (in & (1 <<P1_AFE_PWD_LBN )) goto done; +/* DSP doesn't look powered in flash config mode */ +if (sfe4001_phy_flash_cfg) + goto done; }while (++count <20 );EFX_INFO (efx,"timed out waiting for power\n" );
drivers/net/sfc/tenxpress.c +6 -4
@@ -199,10 +199,12 @@ static int tenxpress_phy_init(struct efx_nic *efx)tenxpress_set_state (efx,TENXPRESS_STATUS_NORMAL ); - rc =mdio_clause45_wait_reset_mmds (efx, -TENXPRESS_REQUIRED_DEVS ); -if (rc <0 ) - goto fail; +if (!sfe4001_phy_flash_cfg) { + rc =mdio_clause45_wait_reset_mmds (efx, +TENXPRESS_REQUIRED_DEVS ); +if (rc <0 ) + goto fail; + } rc =mdio_clause45_check_mmds (efx,TENXPRESS_REQUIRED_DEVS ,0 );if (rc <0 )
Signature · 2 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job.
PATCH 3/9 Removed bogus 'fall-thru' comments
In reply to Ben HutchingsFall-through is expected outside a switch statement.
--- drivers/net/sfc/falcon.c | 2 -- drivers/net/sfc/rx.c | 1 - 2 files changed, 0 insertions(+), 3 deletions(-)
drivers/net/sfc/falcon.c +0 -2
@@ -2468,14 +2468,12 @@ int falcon_probe_nic(struct efx_nic *efx) fail5:falcon_free_buffer (efx, &efx->irq_status); fail4: -/* fall-thru */ fail3:if (nic_data->pci_dev2) {pci_dev_put (nic_data->pci_dev2); nic_data->pci_dev2 =NULL ; } fail2: -/* fall-thru */ fail1:kfree (efx->nic_data);return rc;
drivers/net/sfc/rx.c +0 -1
@@ -736,7 +736,6 @@ void __efx_rx_packet(struct efx_channel *channel,/* Update allocation strategy method */ channel->rx_alloc_level +=RX_ALLOC_FACTOR_SKB ; -/* fall-thru */ done: efx->net_dev->last_rx = jiffies; }
Signature · 2 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job.
Re: [PATCH 3/9] Removed bogus 'fall-thru' comments
Quoted 17 lines · Ben Hutchings
Fall-through is expected outside a switch statement.
Signed-off-by Ben Hutchings <[email protected]>--- drivers/net/sfc/falcon.c | 2 -- drivers/net/sfc/rx.c | 1 - 2 files changed, 0 insertions(+), 3 deletions(-)drivers/net/sfc/falcon.c +0
-1@@ -2468,14 +2468,12 @@ int falcon_probe_nic(struct efx_nic *efx) fail5:falcon_free_buffer (efx, &efx->irq_status); fail4: -/* fall-thru */
drivers/net/sfc/falcon.c int falcon_probe_nic(struct efx_nic *efx) · line 2479
Quoted 10 lines
drivers/net/sfc/falcon.c +0
-1fail3:if (nic_data->pci_dev2) {pci_dev_put (nic_data->pci_dev2); nic_data->pci_dev2 =NULL ; } fail2: -/* fall-thru */ fail1:kfree (efx->nic_data);return rc;
Is there really any point in keeping those extra goto targets? I'd suggest that you simply eliminate the extra ones completely.
Signature · 1 line
i.
Re: [PATCH 3/9] Removed bogus 'fall-thru' comments
Quoted 24 lines · Ilpo Järvinen
Quoted 22 lines · Ben Hutchings
Fall-through is expected outside a switch statement.
Signed-off-by Ben Hutchings <[email protected]>--- drivers/net/sfc/falcon.c | 2 -- drivers/net/sfc/rx.c | 1 - 2 files changed, 0 insertions(+), 3 deletions(-)drivers/net/sfc/falcon.c +0
-1@@ -2468,14 +2468,12 @@ int falcon_probe_nic(struct efx_nic *efx) fail5:falcon_free_buffer (efx, &efx->irq_status); fail4: -/* fall-thru */ fail3:if (nic_data->pci_dev2) {pci_dev_put (nic_data->pci_dev2); nic_data->pci_dev2 =NULL ; }
Quoted 8 lines
drivers/net/sfc/falcon.c int falcon_probe_nic(struct efx_nic *efx) · line 2479
Quoted 5 lines
drivers/net/sfc/falcon.c +0
-1fail2: -/* fall-thru */ fail1:kfree (efx->nic_data);return rc;Is there really any point in keeping those extra goto targets? I'd suggest that you simply eliminate the extra ones completely.
I think we'll do that at some point, along with giving them meaningful names rather than numbers. But not right now.
Ben.
Signature · 2 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job.
PATCH 4/9 Remove garbage from comment
In reply to Ben Hutchings--- drivers/net/sfc/mdio_10g.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/sfc/mdio_10g.h +1 -1
@@ -95,7 +95,7 @@#define MDIO_PMAPMD_CTRL2_10_BT (0xf)#define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf) -/* /\* PHY XGXS lane state *\/ */ +/* PHY XGXS lane state */ #define MDIO_PHYXS_LANE_STATE (0x18)#define MDIO_PHYXS_LANE_ALIGNED_LBN (12)
Signature · 2 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job.
PATCH 5/9 Remove kernel-doc comments for removed members of struct efx_nic
In reply to Ben Hutchings--- drivers/net/sfc/net_driver.h | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-)
drivers/net/sfc/net_driver.h +0 -2
@@ -667,8 +667,6 @@ union efx_multicast_hash {* @phy_op: PHY interface * @phy_data: PHY private data (including PHY-specific stats) * @mii: PHY interface -* @phy_powered: PHY power state -* @tx_disabled: PHY transmitter turned off * @link_up: Link status * @link_options: Link options (MII/GMII format) * @n_link_state_changes: Number of times the link has changed state
Signature · 2 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job.
PATCH 6/9 Fix code formatting
In reply to Ben Hutchings--- drivers/net/sfc/falcon_xmac.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/sfc/falcon_xmac.c +2 -2
@@ -32,7 +32,7 @@ (FALCON_XMAC_REGBANK + ((mac_reg) * FALCON_XMAC_REG_SIZE))void falcon_xmac_writel (struct efx_nic *efx, -efx_dword_t *value,unsigned int mac_reg) +efx_dword_t *value,unsigned int mac_reg) {efx_oword_t temp;
@@ -227,7 +227,7 @@ static int falcon_xgmii_status(struct efx_nic *efx)/* The ISR latches, so clear it and re-read */ falcon_xmac_readl (efx, ®,XM_MGT_INT_REG_MAC_B0 );falcon_xmac_readl (efx, ®,XM_MGT_INT_REG_MAC_B0 ); - +if (EFX_DWORD_FIELD (reg,XM_LCLFLT ) ||EFX_DWORD_FIELD (reg,XM_RMTFLT )) {EFX_INFO (efx,"MGT_INT: " EFX_DWORD_FMT "\n" ,EFX_DWORD_VAL (reg));
Signature · 2 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job.
PATCH 7/9 Remove unused macro EFX_XAUI_RETRAIN_MAX
In reply to Ben Hutchings--- drivers/net/sfc/falcon_xmac.c | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-)
drivers/net/sfc/falcon_xmac.c +0 -2
@@ -495,8 +495,6 @@ void falcon_update_stats_xmac(struct efx_nic *efx) (mac_stats->rx_bytes - mac_stats->rx_good_bytes); } -#define EFX_XAUI_RETRAIN_MAX 8 -int falcon_check_xmac (struct efx_nic *efx) {unsigned xaui_link_ok;
Signature · 2 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job.
PATCH 8/9 Increment rx_reset when reported as driver event
In reply to Ben HutchingsAn RX_RESET event can be reported either as a global or as a driver event. We were counting only global events.
--- drivers/net/sfc/falcon.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/net/sfc/falcon.c +1 -0
@@ -1129,6 +1129,7 @@ static void falcon_handle_driver_event(struct efx_channel *channel,case RX_RECOVERY_EV_DECODE :EFX_ERR (efx,"channel %d seen DRIVER RX_RESET event. " "Resetting.\n" , channel->channel); +atomic_inc (&efx->rx_reset); efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ? RESET_TYPE_RX_RECOVERY :
Signature · 2 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job.
PATCH 9/9 sfc: Add self-test support
In reply to Ben HutchingsAdd a set of self-tests accessible thorugh ethtool.
Add hardware loopback and TX disable control code to support them.
--- drivers/net/sfc/Makefile | 4 +- drivers/net/sfc/enum.h | 49 +++ drivers/net/sfc/ethtool.c | 232 +++++++++++++- drivers/net/sfc/falcon.c | 5 +- drivers/net/sfc/falcon_hwdefs.h | 16 +- drivers/net/sfc/falcon_xmac.c | 72 ++++- drivers/net/sfc/mdio_10g.c | 78 +++++ drivers/net/sfc/mdio_10g.h | 22 ++ drivers/net/sfc/net_driver.h | 14 + drivers/net/sfc/rx.c | 10 + drivers/net/sfc/selftest.c | 717 +++++++++++++++++++++++++++++++++++++++ drivers/net/sfc/selftest.h | 50 +++ drivers/net/sfc/tenxpress.c | 81 +++++ drivers/net/sfc/xfp_phy.c | 36 ++ 14 files changed, 1379 insertions(+), 7 deletions(-) create mode 100644 drivers/net/sfc/selftest.c create mode 100644 drivers/net/sfc/selftest.h
drivers/net/sfc/Makefile +2 -2
@@ -1,5 +1,5 @@ sfc-y += efx.o falcon.o tx.o rx.o falcon_xmac.o \ - i2c-direct.o ethtool.o xfp_phy.o mdio_10g.o \ - tenxpress.o boards.o sfe4001.o + i2c-direct.o selftest.o ethtool.o xfp_phy.o \ + mdio_10g.o tenxpress.o boards.o sfe4001.o obj-$(CONFIG_SFC) += sfc.o
drivers/net/sfc/enum.h +49 -0
55 lines not on this page · raw message
drivers/net/sfc/ethtool.c +231 -1
278 lines not on this page · raw message
drivers/net/sfc/falcon.c +4 -1
@@ -1732,7 +1732,8 @@ void falcon_drain_tx_fifo(struct efx_nic *efx)efx_oword_t temp;int count; -if (FALCON_REV (efx) <FALCON_REV_B0 ) +if ((FALCON_REV (efx) <FALCON_REV_B0 ) || + (efx->loopback_mode !=LOOPBACK_NONE ))return ;falcon_read (efx, &temp,MAC0_CTRL_REG_KER );
@@ -2092,6 +2093,8 @@ static int falcon_probe_phy(struct efx_nic *efx) efx->phy_type);return -1 ; } + + efx->loopback_modes =LOOPBACKS_10G_INTERNAL | efx->phy_op->loopbacks;return 0 ; }
drivers/net/sfc/falcon_hwdefs.h +15 -1
@@ -636,6 +636,14 @@#define XX_HIDRVA_WIDTH 1#define XX_LODRVA_LBN 8#define XX_LODRVA_WIDTH 1 +#define XX_LPBKD_LBN 3 +#define XX_LPBKD_WIDTH 1 +#define XX_LPBKC_LBN 2 +#define XX_LPBKC_WIDTH 1 +#define XX_LPBKB_LBN 1 +#define XX_LPBKB_WIDTH 1 +#define XX_LPBKA_LBN 0 +#define XX_LPBKA_WIDTH 1#define XX_TXDRV_CTL_REG_MAC 0x12#define XX_DEQD_LBN 28
@@ -656,8 +664,14 @@#define XX_DTXA_WIDTH 4/* XAUI XGXS core status register */ -#define XX_FORCE_SIG_DECODE_FORCED 0xff#define XX_CORE_STAT_REG_MAC 0x16 +#define XX_FORCE_SIG_LBN 24 +#define XX_FORCE_SIG_WIDTH 8 +#define XX_FORCE_SIG_DECODE_FORCED 0xff +#define XX_XGXS_LB_EN_LBN 23 +#define XX_XGXS_LB_EN_WIDTH 1 +#define XX_XGMII_LB_EN_LBN 22 +#define XX_XGMII_LB_EN_WIDTH 1#define XX_ALIGN_DONE_LBN 20#define XX_ALIGN_DONE_WIDTH 1#define XX_SYNC_STAT_LBN 16
drivers/net/sfc/falcon_xmac.c +70 -2
110 lines not on this page · raw message
drivers/net/sfc/mdio_10g.c +78 -0
96 lines not on this page · raw message
drivers/net/sfc/mdio_10g.h +22 -0
@@ -44,11 +44,16 @@#define MDIO_MMDREG_DEVS1 (6)#define MDIO_MMDREG_CTRL2 (7)#define MDIO_MMDREG_STAT2 (8) +#define MDIO_MMDREG_TXDIS (9)/* Bits in MMDREG_CTRL1 */ /* Reset */ #define MDIO_MMDREG_CTRL1_RESET_LBN (15)#define MDIO_MMDREG_CTRL1_RESET_WIDTH (1) +/* Loopback */ +/* Loopback bit for WIS, PCS, PHYSX and DTEXS */ +#define MDIO_MMDREG_CTRL1_LBACK_LBN (14) +#define MDIO_MMDREG_CTRL1_LBACK_WIDTH (1)/* Bits in MMDREG_STAT1 */ #define MDIO_MMDREG_STAT1_FAULT_LBN (7)
@@ -56,6 +61,9 @@/* Link state */ #define MDIO_MMDREG_STAT1_LINK_LBN (2)#define MDIO_MMDREG_STAT1_LINK_WIDTH (1) +/* Low power ability */ +#define MDIO_MMDREG_STAT1_LPABLE_LBN (1) +#define MDIO_MMDREG_STAT1_LPABLE_WIDTH (1)/* Bits in ID reg */ #define MDIO_ID_REV (_id32) (_id32 & 0xf)
@@ -76,6 +84,14 @@#define MDIO_MMDREG_STAT2_PRESENT_LBN (14)#define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2) +/* Bits in MMDREG_TXDIS */ +#define MDIO_MMDREG_TXDIS_GLOBAL_LBN (0) +#define MDIO_MMDREG_TXDIS_GLOBAL_WIDTH (1) + +/* MMD-specific bits, ordered by MMD, then register */ +#define MDIO_PMAPMD_CTRL1_LBACK_LBN (0) +#define MDIO_PMAPMD_CTRL1_LBACK_WIDTH (1) +/* PMA type (4 bits) */ #define MDIO_PMAPMD_CTRL2_10G_CX4 (0x0)#define MDIO_PMAPMD_CTRL2_10G_EW (0x1)
@@ -217,6 +233,12 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,extern int mdio_clause45_links_ok (struct efx_nic *efx,unsigned int mmd_mask); +/* Generic transmit disable support though PMAPMD */ +extern void mdio_clause45_transmit_disable (struct efx_nic *efx); + +/* Generic part of reconfigure: set/clear loopback bits */ +extern void mdio_clause45_phy_reconfigure (struct efx_nic *efx); +/* Read (some of) the PHY settings over MDIO */ extern void mdio_clause45_get_settings (struct efx_nic *efx,struct ethtool_cmd *ecmd);
drivers/net/sfc/net_driver.h +14 -0
@@ -448,6 +448,9 @@ struct efx_board {struct efx_blinker blinker; }; +#define STRING_TABLE_LOOKUP (val, member) \ + member ## _names[val] +enum efx_int_mode {/* Be careful if altering to correct macro below */ EFX_INT_MODE_MSIX =0 ,
@@ -520,6 +523,7 @@ enum efx_fc_type {* @check_hw: Check hardware * @reset_xaui: Reset XAUI side of PHY for (software sequenced reset) * @mmds: MMD presence mask +* @loopbacks: Supported loopback modes mask */ struct efx_phy_operations {int (*init) (struct efx_nic *efx);
@@ -529,6 +533,7 @@ struct efx_phy_operations {int (*check_hw) (struct efx_nic *efx);void (*reset_xaui) (struct efx_nic *efx);int mmds; +unsigned loopbacks; };/*
@@ -667,6 +672,7 @@ union efx_multicast_hash {* @phy_op: PHY interface * @phy_data: PHY private data (including PHY-specific stats) * @mii: PHY interface +* @tx_disabled: PHY transmitter turned off * @link_up: Link status * @link_options: Link options (MII/GMII format) * @n_link_state_changes: Number of times the link has changed state
@@ -674,6 +680,9 @@ union efx_multicast_hash {* @multicast_hash: Multicast hash table * @flow_control: Flow control flags - separate RX/TX so can't use link_options * @reconfigure_work: work item for dealing with PHY events +* @loopback_mode: Loopback status +* @loopback_modes: Supported loopback mode bitmask +* @loopback_selftest: Offline self-test private state * * The @priv field of the corresponding &struct net_device points to * this.
@@ -733,6 +742,7 @@ struct efx_nic {struct efx_phy_operations *phy_op;void *phy_data;struct mii_if_info mii; +unsigned tx_disabled;int link_up;unsigned int link_options;
@@ -744,6 +754,10 @@ struct efx_nic {struct work_struct reconfigure_work;atomic_t rx_reset; +enum efx_loopback_mode loopback_mode; +unsigned int loopback_modes; + +void *loopback_selftest; };/**
drivers/net/sfc/rx.c +10 -0
@@ -19,6 +19,7 @@#include "rx.h" #include "efx.h" #include "falcon.h" +#include "selftest.h" #include "workarounds.h" /* Number of RX descriptors pushed at once. */
@@ -683,6 +684,15 @@ void __efx_rx_packet(struct efx_channel *channel,struct sk_buff *skb;int lro = efx->net_dev->features &NETIF_F_LRO ; +/* If we're in loopback test, then pass the packet directly to the +* loopback layer, and free the rx_buf here +*/ +if (unlikely (efx->loopback_selftest)) { +efx_loopback_rx_packet (efx, rx_buf->data, rx_buf->len); +efx_free_rx_buffer (efx, rx_buf); + goto done; + } +if (rx_buf->skb) {prefetch (skb_shinfo (rx_buf->skb));
drivers/net/sfc/selftest.c new file +717 -0
717 lines not on this page · raw message
drivers/net/sfc/selftest.h new file +50 -0
50 lines not on this page · raw message
drivers/net/sfc/tenxpress.c +81 -0
127 lines not on this page · raw message
drivers/net/sfc/xfp_phy.c +36 -0
@@ -24,6 +24,10 @@ MDIO_MMDREG_DEVS0_PMAPMD | \ MDIO_MMDREG_DEVS0_PHYXS) +#define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) | \ + (1 << LOOPBACK_PMAPMD) | \ + (1 << LOOPBACK_NETWORK)) +/****************************************************************************/ /* Quake-specific MDIO registers */ #define MDIO_QUAKE_LED0_REG (0xD006)
@@ -35,6 +39,10 @@ void xfp_set_led(struct efx_nic *p, int led, int mode) mode); } +struct xfp_phy_data { +int tx_disabled; +}; +#define XFP_MAX_RESET_TIME 500#define XFP_RESET_WAIT 10
@@ -72,18 +80,31 @@ static int xfp_reset_phy(struct efx_nic *efx)static int xfp_phy_init (struct efx_nic *efx) { +struct xfp_phy_data *phy_data;u32 devid =mdio_clause45_read_id (efx,MDIO_MMD_PHYXS );int rc; + phy_data =kzalloc (sizeof (struct xfp_phy_data ),GFP_KERNEL ); + efx->phy_data = (void *) phy_data; +EFX_INFO (efx,"XFP: PHY ID reg %x (OUI %x model %x revision" " %x)\n" , devid,MDIO_ID_OUI (devid),MDIO_ID_MODEL (devid),MDIO_ID_REV (devid)); + phy_data->tx_disabled = efx->tx_disabled; + rc =xfp_reset_phy (efx);EFX_INFO (efx,"XFP: PHY init %s.\n" , rc ?"failed" :"successful" ); +if (rc <0 ) + goto fail; +return 0 ; + + fail: +kfree (efx->phy_data); + efx->phy_data =NULL ;return rc; }
@@ -110,6 +131,16 @@ static int xfp_phy_check_hw(struct efx_nic *efx)static void xfp_phy_reconfigure (struct efx_nic *efx) { +struct xfp_phy_data *phy_data = efx->phy_data; + +/* Reset the PHY when moving from tx off to tx on */ +if (phy_data->tx_disabled && !efx->tx_disabled) +xfp_reset_phy (efx); + +mdio_clause45_transmit_disable (efx); +mdio_clause45_phy_reconfigure (efx); + + phy_data->tx_disabled = efx->tx_disabled; efx->link_up =xfp_link_ok (efx); efx->link_options =GM_LPA_10000FULL ; }
@@ -119,6 +150,10 @@ static void xfp_phy_fini(struct efx_nic *efx) {/* Clobber the LED if it was blinking */ efx->board_info.blink (efx,0 ); + +/* Free the context block */ +kfree (efx->phy_data); + efx->phy_data =NULL ; }struct efx_phy_operations falcon_xfp_phy_ops = {
@@ -129,4 +164,5 @@ struct efx_phy_operations falcon_xfp_phy_ops = { .clear_interrupt = xfp_phy_clear_interrupt, .reset_xaui = efx_port_dummy_op_void, .mmds = XFP_REQUIRED_DEVS, + .loopbacks = XFP_LOOPBACKS, };
Signature · 2 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job.