Commit 8880f4ec authored by Ben Hutchings's avatar Ben Hutchings Committed by David S. Miller
Browse files

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

Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent afd4aea0
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
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
	  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.
+4 −3
Original line number Diff line number Diff line
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 −0
Original line number Diff line number Diff line
@@ -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
+26 −0
Original line number Diff line number Diff line
@@ -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 */
};

+2 −0
Original line number Diff line number Diff line
@@ -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
Loading