summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/sfc/siena.c
diff options
context:
space:
mode:
authorAlexandre Rames <arames@solarflare.com>2013-01-14 21:20:22 +0400
committerBen Hutchings <bhutchings@solarflare.com>2013-03-08 00:22:04 +0400
commit626950db84c065925ee10c2e833da265cbda8800 (patch)
treed4acb18c4b3554f80ff7a21bfeb63dd56420474f /drivers/net/ethernet/sfc/siena.c
parent634ab72c39b3df78ac7d6ccd4a50133059bae14f (diff)
downloadlinux-626950db84c065925ee10c2e833da265cbda8800.tar.xz
sfc: Add AER and EEH support for Siena
The Linux side of EEH is triggered by MMIO reads, but this driver's data path does not issue any MMIO reads (except in legacy interrupt mode). Therefore add a monitor function to poll EEH periodically. When preparing to reset the device based on our own error detection, also poll EEH and defer to its recovery mechanism if appropriate. [bwh: Use a separate condition for the initial link poll; fix some style errors] Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc/siena.c')
-rw-r--r--drivers/net/ethernet/sfc/siena.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index ba40f67e4f05..e07ff0d3f26b 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -202,7 +202,7 @@ out:
static enum reset_type siena_map_reset_reason(enum reset_type reason)
{
- return RESET_TYPE_ALL;
+ return RESET_TYPE_RECOVER_OR_ALL;
}
static int siena_map_reset_flags(u32 *flags)
@@ -245,6 +245,22 @@ static int siena_reset_hw(struct efx_nic *efx, enum reset_type method)
return efx_mcdi_reset_port(efx);
}
+#ifdef CONFIG_EEH
+/* When a PCI device is isolated from the bus, a subsequent MMIO read is
+ * required for the kernel EEH mechanisms to notice. As the Solarflare driver
+ * was written to minimise MMIO read (for latency) then a periodic call to check
+ * the EEH status of the device is required so that device recovery can happen
+ * in a timely fashion.
+ */
+static void siena_monitor(struct efx_nic *efx)
+{
+ struct eeh_dev *eehdev =
+ of_node_to_eeh_dev(pci_device_to_OF_node(efx->pci_dev));
+
+ eeh_dev_check_failure(eehdev);
+}
+#endif
+
static int siena_probe_nvconfig(struct efx_nic *efx)
{
u32 caps = 0;
@@ -665,7 +681,11 @@ const struct efx_nic_type siena_a0_nic_type = {
.init = siena_init_nic,
.dimension_resources = siena_dimension_resources,
.fini = efx_port_dummy_op_void,
+#ifdef CONFIG_EEH
+ .monitor = siena_monitor,
+#else
.monitor = NULL,
+#endif
.map_reset_reason = siena_map_reset_reason,
.map_reset_flags = siena_map_reset_flags,
.reset = siena_reset_hw,