Skip to content

Commit

Permalink
sfc: Add support for SFC9000 family (2)
Browse files Browse the repository at this point in the history
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

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Ben Hutchings authored and David S. Miller committed Nov 30, 2009
1 parent afd4aea commit 8880f4e
Show file tree
Hide file tree
Showing 14 changed files with 414 additions and 29 deletions.
13 changes: 7 additions & 6 deletions drivers/net/sfc/Kconfig
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
config SFC
tristate "Solarflare Solarstorm SFC4000 support"
tristate "Solarflare Solarstorm SFC4000/SFC9000-family support"
depends on PCI && INET
select MDIO
select CRC32
select I2C
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.
7 changes: 4 additions & 3 deletions drivers/net/sfc/Makefile
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions drivers/net/sfc/bitfield.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 26 additions & 0 deletions drivers/net/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "mdio_10g.h"
#include "nic.h"

#include "mcdi.h"

/**************************************************************************
*
* Type name strings
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}

Expand All @@ -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 */
};

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/sfc/efx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/sfc/enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
};

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/sfc/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/sfc/mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading

0 comments on commit 8880f4e

Please sign in to comment.