sfc: Change entity reset on MC reboot to a new datapath-only reset.
authorJon Cooper <jcooper@solarflare.com>
Wed, 20 May 2015 10:11:35 +0000 (11:11 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 21 May 2015 22:43:54 +0000 (18:43 -0400)
Currently we do an entity reset when we detect an MC reboot.
This messes up SRIOV because it leaves VFs orphaned. The extra
reset is rather redundant anyway, since the MC reboot will have
basically reset everything.

This change replaces the entity reset after MC reboot with a
simpler datapath reset that reallocates resources but doesn't
perform the entity reset.

Signed-off-by: Shradha Shah <sshah@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/ef10.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/enum.h
drivers/net/ethernet/sfc/mcdi.c

index e8d760cb4cd08fe4999b496049fc381b9111f5e2..525808f34036b5de786d78cb0c51bbf63bebb70e 100644 (file)
@@ -866,6 +866,14 @@ static void efx_ef10_reset_mc_allocations(struct efx_nic *efx)
        nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID;
 }
 
+static enum reset_type efx_ef10_map_reset_reason(enum reset_type reason)
+{
+       if (reason == RESET_TYPE_MC_FAILURE)
+               return RESET_TYPE_DATAPATH;
+
+       return efx_mcdi_map_reset_reason(reason);
+}
+
 static int efx_ef10_map_reset_flags(u32 *flags)
 {
        enum {
@@ -3940,7 +3948,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
        .dimension_resources = efx_ef10_dimension_resources,
        .init = efx_ef10_init_nic,
        .fini = efx_port_dummy_op_void,
-       .map_reset_reason = efx_mcdi_map_reset_reason,
+       .map_reset_reason = efx_ef10_map_reset_reason,
        .map_reset_flags = efx_ef10_map_reset_flags,
        .reset = efx_ef10_reset,
        .probe_port = efx_mcdi_port_probe,
@@ -4040,7 +4048,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
        .dimension_resources = efx_ef10_dimension_resources,
        .init = efx_ef10_init_nic,
        .fini = efx_port_dummy_op_void,
-       .map_reset_reason = efx_mcdi_map_reset_reason,
+       .map_reset_reason = efx_ef10_map_reset_reason,
        .map_reset_flags = efx_ef10_map_reset_flags,
        .reset = efx_ef10_reset,
        .probe_port = efx_mcdi_port_probe,
index abb9c0e5817b0c49e971bb9d171db25fbe314aab..0ca6e77055305480c08825aedf18032e191c1542 100644 (file)
@@ -77,6 +77,7 @@ const char *const efx_reset_type_names[] = {
        [RESET_TYPE_RECOVER_OR_ALL]     = "RECOVER_OR_ALL",
        [RESET_TYPE_WORLD]              = "WORLD",
        [RESET_TYPE_RECOVER_OR_DISABLE] = "RECOVER_OR_DISABLE",
+       [RESET_TYPE_DATAPATH]           = "DATAPATH",
        [RESET_TYPE_MC_BIST]            = "MC_BIST",
        [RESET_TYPE_DISABLE]            = "DISABLE",
        [RESET_TYPE_TX_WATCHDOG]        = "TX_WATCHDOG",
@@ -2430,7 +2431,8 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method)
        efx_disable_interrupts(efx);
 
        mutex_lock(&efx->mac_lock);
-       if (efx->port_initialized && method != RESET_TYPE_INVISIBLE)
+       if (efx->port_initialized && method != RESET_TYPE_INVISIBLE &&
+           method != RESET_TYPE_DATAPATH)
                efx->phy_op->fini(efx);
        efx->type->fini(efx);
 }
@@ -2459,7 +2461,8 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
        if (!ok)
                goto fail;
 
-       if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) {
+       if (efx->port_initialized && method != RESET_TYPE_INVISIBLE &&
+           method != RESET_TYPE_DATAPATH) {
                rc = efx->phy_op->init(efx);
                if (rc)
                        goto fail;
@@ -2655,6 +2658,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
        case RESET_TYPE_WORLD:
        case RESET_TYPE_DISABLE:
        case RESET_TYPE_RECOVER_OR_DISABLE:
+       case RESET_TYPE_DATAPATH:
        case RESET_TYPE_MC_BIST:
        case RESET_TYPE_MCDI_TIMEOUT:
                method = type;
index d1dbb5fb31bb515b6926d981bf8eab0aafa6deae..c94f56271dd451eba1990720034ccc217cdf5ed2 100644 (file)
@@ -143,6 +143,7 @@ enum efx_loopback_mode {
  * @RESET_TYPE_WORLD: Reset as much as possible
  * @RESET_TYPE_RECOVER_OR_DISABLE: Try to recover. Apply RESET_TYPE_DISABLE if
  * unsuccessful.
+ * @RESET_TYPE_DATAPATH: Reset datapath only.
  * @RESET_TYPE_MC_BIST: MC entering BIST mode.
  * @RESET_TYPE_DISABLE: Reset datapath, MAC and PHY; leave NIC disabled
  * @RESET_TYPE_TX_WATCHDOG: reset due to TX watchdog
@@ -159,6 +160,7 @@ enum reset_type {
        RESET_TYPE_ALL,
        RESET_TYPE_WORLD,
        RESET_TYPE_RECOVER_OR_DISABLE,
+       RESET_TYPE_DATAPATH,
        RESET_TYPE_MC_BIST,
        RESET_TYPE_DISABLE,
        RESET_TYPE_MAX_METHOD,
index fcee7614a2cbc06167f568148a3bc27385213264..8267a1c75771e0076db3378d701773d29ce8693f 100644 (file)
@@ -1558,7 +1558,9 @@ int efx_mcdi_reset(struct efx_nic *efx, enum reset_type method)
        if (rc)
                return rc;
 
-       if (method == RESET_TYPE_WORLD)
+       if (method == RESET_TYPE_DATAPATH)
+               return 0;
+       else if (method == RESET_TYPE_WORLD)
                return efx_mcdi_reset_mc(efx);
        else
                return efx_mcdi_reset_func(efx);