sfc: Add support for SFC9000 family (2)
Subsystems (2)
PATCH 10/12 sfc: Add support for SFC9000 family (2)
This integrates support for the SFC9000 family of 10G Ethernet controllers and LAN-on-motherboard chips, starting with the SFL9021 'Siena' and SFC9020 'Bethpage'.
Credit for this code is largely due to my colleagues at Solarflare:
Guido Barzini
Steve Hodgson
Kieran Mansley
Matthew Slattery
Neil Turton
--- drivers/net/sfc/Kconfig | 13 +- drivers/net/sfc/Makefile | 7 +- drivers/net/sfc/bitfield.h | 2 + drivers/net/sfc/efx.c | 26 ++++ drivers/net/sfc/efx.h | 2 + drivers/net/sfc/enum.h | 2 + drivers/net/sfc/ethtool.c | 3 + drivers/net/sfc/mac.h | 3 + drivers/net/sfc/mtd.c | 267 ++++++++++++++++++++++++++++++++++++++++- drivers/net/sfc/net_driver.h | 10 ++- drivers/net/sfc/nic.c | 63 ++++++++-- drivers/net/sfc/nic.h | 23 ++++ drivers/net/sfc/phy.h | 17 +++ drivers/net/sfc/workarounds.h | 5 + 14 files changed, 414 insertions(+), 29 deletions(-)
drivers/net/sfc/Kconfig +7 -6
@@ -1,5 +1,5 @@ config SFC - tristate "Solarflare Solarstorm SFC4000 support" + tristate "Solarflare Solarstorm SFC4000/SFC9000-family support" depends on PCI && INET select MDIO select CRC32
@@ -7,15 +7,16 @@ config SFC select I2C_ALGOBIT help This driver supports 10-gigabit Ethernet cards based on - the Solarflare Communications Solarstorm SFC4000 controller. + the Solarflare Communications Solarstorm SFC4000 and + SFC9000-family controllers. To compile this driver as a module, choose M here. The module will be called sfc. config SFC_MTD - bool "Solarflare Solarstorm SFC4000 flash MTD support" + bool "Solarflare Solarstorm SFC4000/SFC9000-family MTD support" depends on SFC && MTD && !(SFC=y && MTD=m) default y help - This exposes the on-board flash memory as an MTD device (e.g. - /dev/mtd1). This makes it possible to upload new boot code - to the NIC. + This exposes the on-board flash memory as MTD devices (e.g. + /dev/mtd1). This makes it possible to upload new firmware + to the NIC.
drivers/net/sfc/Makefile +4 -3
@@ -1,6 +1,7 @@ -sfc-y += efx.o nic.o falcon.o tx.o rx.o falcon_gmac.o \ - falcon_xmac.o selftest.o ethtool.o qt202x_phy.o \ - mdio_10g.o tenxpress.o falcon_boards.o +sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o \ + falcon_gmac.o falcon_xmac.o mcdi_mac.o \ + selftest.o ethtool.o qt202x_phy.o mdio_10g.o \ + tenxpress.o falcon_boards.o mcdi.o mcdi_phy.o sfc-$(CONFIG_SFC_MTD) += mtd.o obj-$(CONFIG_SFC) += sfc.o
drivers/net/sfc/bitfield.h +2 -0
@@ -37,6 +37,8 @@#define EFX_DWORD_2_WIDTH 32#define EFX_DWORD_3_LBN 96#define EFX_DWORD_3_WIDTH 32 +#define EFX_QWORD_0_LBN 0 +#define EFX_QWORD_0_WIDTH 64/* Specified attribute (e.g. LBN) of the specified field */ #define EFX_VAL (field, attribute) field ## _ ## attribute
drivers/net/sfc/efx.c +26 -0
@@ -25,6 +25,8 @@#include "mdio_10g.h" #include "nic.h" +#include "mcdi.h" +/************************************************************************** * * Type name strings
@@ -84,6 +86,7 @@ const char *efx_reset_type_names[] = { [RESET_TYPE_RX_DESC_FETCH] = "RX_DESC_FETCH", [RESET_TYPE_TX_DESC_FETCH] = "TX_DESC_FETCH", [RESET_TYPE_TX_SKIP] = "TX_SKIP", + [RESET_TYPE_MC_FAILURE] = "MC_FAILURE", };#define EFX_MAX_MTU (9 * 1024)
@@ -1191,6 +1194,15 @@ static void efx_start_all(struct efx_nic *efx)efx_nic_enable_interrupts (efx); +/* Switch to event based MCDI completions after enabling interrupts. +* If a reset has been scheduled, then we need to stay in polled mode. +* Rather than serialising efx_mcdi_mode_event() [which sleeps] and +* reset_pending [modified from an atomic context], we instead guarantee +* that efx_mcdi_mode_poll() isn't reverted erroneously */ +efx_mcdi_mode_event (efx); +if (efx->reset_pending !=RESET_TYPE_NONE ) +efx_mcdi_mode_poll (efx); +/* Start the hardware monitor if there is one. Otherwise (we're link * event driven), we have to poll the PHY because after an event queue * flush, we could have a missed a link state change */
@@ -1242,6 +1254,9 @@ static void efx_stop_all(struct efx_nic *efx) efx->type->stop_stats (efx); +/* Switch to MCDI polling on Siena before disabling interrupts */ +efx_mcdi_mode_poll (efx); +/* Disable interrupts and wait for ISR to complete */ efx_nic_disable_interrupts (efx);if (efx->legacy_irq)
@@ -1445,6 +1460,8 @@ static int efx_net_open(struct net_device *net_dev)return -EIO ;if (efx->phy_mode &PHY_MODE_SPECIAL )return -EBUSY ; +if (efx_mcdi_poll_reboot (efx) &&efx_reset (efx,RESET_TYPE_ALL )) +return -EIO ;/* Notify the kernel of the link state polled during driver load, * before the monitor starts running */
@@ -1895,6 +1912,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)case RESET_TYPE_TX_SKIP : method =RESET_TYPE_INVISIBLE ;break ; +case RESET_TYPE_MC_FAILURE :default : method =RESET_TYPE_ALL ;break ;
@@ -1908,6 +1926,10 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) efx->reset_pending = method; +/* efx_process_channel() will no longer read events once a +* reset is scheduled. So switch back to poll'd MCDI completions. */ +efx_mcdi_mode_poll (efx); +queue_work (reset_workqueue, &efx->reset_work); }
@@ -1923,6 +1945,10 @@ static struct pci_device_id efx_pci_table[] __devinitdata = { .driver_data = (unsigned long) &falcon_a1_nic_type}, {PCI_DEVICE(EFX_VENDID_SFC, FALCON_B_P_DEVID), .driver_data = (unsigned long) &falcon_b0_nic_type}, + {PCI_DEVICE(EFX_VENDID_SFC, BETHPAGE_A_P_DEVID), + .driver_data = (unsigned long) &siena_a0_nic_type}, + {PCI_DEVICE(EFX_VENDID_SFC, SIENA_A_P_DEVID), + .driver_data = (unsigned long) &siena_a0_nic_type}, {0} /* end of list */ };
drivers/net/sfc/efx.h +2 -0
@@ -18,6 +18,8 @@#define FALCON_A_P_DEVID 0x0703#define FALCON_A_S_DEVID 0x6703#define FALCON_B_P_DEVID 0x0710 +#define BETHPAGE_A_P_DEVID 0x0803 +#define SIENA_A_P_DEVID 0x0813/* Solarstorm controllers use BAR 0 for I/O space and BAR 2(&3) for memory */ #define EFX_MEM_BAR 2
drivers/net/sfc/enum.h +2 -0
@@ -144,6 +144,7 @@ enum efx_loopback_mode {* @RESET_TYPE_RX_DESC_FETCH: pcie error during rx descriptor fetch * @RESET_TYPE_TX_DESC_FETCH: pcie error during tx descriptor fetch * @RESET_TYPE_TX_SKIP: hardware completed empty tx descriptors +* @RESET_TYPE_MC_FAILURE: MC reboot/assertion */ enum reset_type {RESET_TYPE_NONE =-1 ,
@@ -158,6 +159,7 @@ enum reset_type {RESET_TYPE_RX_DESC_FETCH ,RESET_TYPE_TX_DESC_FETCH ,RESET_TYPE_TX_SKIP , +RESET_TYPE_MC_FAILURE , RESET_TYPE_MAX, };
drivers/net/sfc/ethtool.c +3 -0
@@ -236,6 +236,9 @@ static void efx_ethtool_get_drvinfo(struct net_device *net_dev,strlcpy (info->driver,EFX_DRIVER_NAME ,sizeof (info->driver));strlcpy (info->version,EFX_DRIVER_VERSION ,sizeof (info->version)); +if (efx_nic_rev (efx) >=EFX_REV_SIENA_A0 ) +siena_print_fwver (efx, info->fw_version, +sizeof (info->fw_version));strlcpy (info->bus_info,pci_name (efx->pci_dev),sizeof (info->bus_info)); }
drivers/net/sfc/mac.h +3 -0
@@ -15,6 +15,9 @@extern struct efx_mac_operations falcon_gmac_operations;extern struct efx_mac_operations falcon_xmac_operations; +extern struct efx_mac_operations efx_mcdi_mac_operations;extern void falcon_reconfigure_xmac_core (struct efx_nic *efx); +extern int efx_mcdi_mac_stats (struct efx_nic *efx,dma_addr_t dma_addr, +u32 dma_len,int enable,int clear);#endif
drivers/net/sfc/mtd.c +262 -5
305 lines not on this page · raw message
drivers/net/sfc/net_driver.h +9 -1
@@ -706,6 +706,7 @@ union efx_multicast_hash {* @phy_op: PHY interface * @phy_data: PHY private data (including PHY-specific stats) * @mdio: PHY MDIO interface +* @mdio_bus: PHY MDIO bus ID (only used by Siena) * @phy_mode: PHY operating mode. Serialised by @mac_lock. * @xmac_poll_required: XMAC link state needs polling * @link_advertising: Autonegotiation advertising flags
@@ -756,6 +757,7 @@ struct efx_nic {struct efx_buffer irq_status;volatile signed int last_irq_cpu; +unsigned long irq_zero_count;struct efx_spi_device *spi_flash;struct efx_spi_device *spi_eeprom;
@@ -766,7 +768,7 @@ struct efx_nic {unsigned n_rx_nodesc_drop_cnt; -struct falcon_nic_data *nic_data; +void *nic_data;struct mutex mac_lock;struct work_struct mac_work;
@@ -792,6 +794,7 @@ struct efx_nic {struct efx_phy_operations *phy_op;void *phy_data;struct mdio_if_info mdio; +unsigned int mdio_bus;enum efx_phy_mode phy_mode;bool xmac_poll_required;
@@ -824,6 +827,11 @@ static inline const char *efx_dev_name(struct efx_nic *efx)return efx_dev_registered (efx) ? efx->name :"" ; } +static inline unsigned int efx_port_num (struct efx_nic *efx) +{ +return PCI_FUNC (efx->pci_dev->devfn); +} +/** * struct efx_nic_type - Efx device type definition * @probe: Probe the controller
drivers/net/sfc/nic.c +49 -14
115 lines not on this page · raw message
drivers/net/sfc/nic.h +23 -0
@@ -14,6 +14,7 @@#include <linux/i2c-algo-bit.h> #include "net_driver.h" #include "efx.h" +#include "mcdi.h" /* * Falcon hardware control
@@ -23,6 +24,7 @@ enum {EFX_REV_FALCON_A0 =0 ,EFX_REV_FALCON_A1 =1 ,EFX_REV_FALCON_B0 =2 , + EFX_REV_SIENA_A0 = 3, };static inline int efx_nic_rev (struct efx_nic *efx)
@@ -32,6 +34,10 @@ static inline int efx_nic_rev(struct efx_nic *efx)extern u32 efx_nic_fpga_ver (struct efx_nic *efx); +static inline bool efx_nic_has_mc (struct efx_nic *efx) +{ +return efx_nic_rev (efx) >=EFX_REV_SIENA_A0 ; +}/* NIC has two interlinked PCI functions for the same port. */ static inline bool efx_nic_is_dual_func (struct efx_nic *efx) {
@@ -123,8 +129,25 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx)return &data->board; } +/** +* struct siena_nic_data - Siena NIC state +* @fw_version: Management controller firmware version +* @fw_build: Firmware build number +* @mcdi: Management-Controller-to-Driver Interface +* @wol_filter_id: Wake-on-LAN packet filter id +*/ +struct siena_nic_data { +u64 fw_version; +u32 fw_build; +struct efx_mcdi_iface mcdi; +int wol_filter_id; +}; + +extern void siena_print_fwver (struct efx_nic *efx,char *buf,size_t len); +extern struct efx_nic_type falcon_a1_nic_type;extern struct efx_nic_type falcon_b0_nic_type; +extern struct efx_nic_type siena_a0_nic_type;/************************************************************************** *
drivers/net/sfc/phy.h +17 -0
@@ -41,4 +41,21 @@ extern struct efx_phy_operations falcon_qt202x_phy_ops;extern void falcon_qt202x_set_led (struct efx_nic *p,int led,int state); +/**************************************************************************** +* Siena managed PHYs +*/ +extern struct efx_phy_operations efx_mcdi_phy_ops; + +extern int efx_mcdi_mdio_read (struct efx_nic *efx,unsigned int bus, +unsigned int prtad,unsigned int devad, +u16 addr,u16 *value_out,u32 *status_out); +extern int efx_mcdi_mdio_write (struct efx_nic *efx,unsigned int bus, +unsigned int prtad,unsigned int devad, +u16 addr,u16 value,u32 *status_out); +extern void efx_mcdi_phy_decode_link (struct efx_nic *efx, +struct efx_link_state *link_state, +u32 speed,u32 flags,u32 fcntl); +extern int efx_mcdi_phy_reconfigure (struct efx_nic *efx); +extern void efx_mcdi_phy_check_fcntl (struct efx_nic *efx,u32 lpa); +#endif
drivers/net/sfc/workarounds.h +5 -0
@@ -18,6 +18,7 @@#define EFX_WORKAROUND_ALWAYS (efx) 1#define EFX_WORKAROUND_FALCON_A (efx) (efx_nic_rev(efx) <= EFX_REV_FALCON_A1)#define EFX_WORKAROUND_FALCON_AB (efx) (efx_nic_rev(efx) <= EFX_REV_FALCON_B0) +#define EFX_WORKAROUND_SIENA (efx) (efx_nic_rev(efx) == EFX_REV_SIENA_A0)#define EFX_WORKAROUND_10G (efx) EFX_IS10G(efx)#define EFX_WORKAROUND_SFT9001 (efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \ (efx)->phy_type == PHY_TYPE_SFT9001B)
@@ -35,6 +36,10 @@#define EFX_WORKAROUND_11482 EFX_WORKAROUND_FALCON_AB/* Truncated IPv4 packets can confuse the TX packet parser */ #define EFX_WORKAROUND_15592 EFX_WORKAROUND_FALCON_AB +/* Legacy ISR read can return zero once */ +#define EFX_WORKAROUND_15783 EFX_WORKAROUND_SIENA +/* Legacy interrupt storm when interrupt fifo fills */ +#define EFX_WORKAROUND_17213 EFX_WORKAROUND_SIENA/* Spurious parity errors in TSORT buffers */ #define EFX_WORKAROUND_5129 EFX_WORKAROUND_FALCON_A
Signature · 9 lines
1.6.5.3 -- Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked.
From: Ben Hutchings <[email protected]>
Date: Mon, 30 Nov 2009 01:15:41 +0000
Quoted 6 lines
This integrates support for the SFC9000 family of 10G Ethernet controllers and LAN-on-motherboard chips, starting with the SFL9021 'Siena' and SFC9020 'Bethpage'.
Credit for this code is largely due to my colleagues at Solarflare:
Quoted 7 lines
Guido Barzini
Steve Hodgson
Kieran Mansley
Matthew Slattery
Neil TurtonSigned-off-by Ben Hutchings <[email protected]>
Applied.