diff options
author | David S. Miller <davem@davemloft.net> | 2014-01-21 14:46:56 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-21 14:46:56 -0800 |
commit | 3ea5ad27dc6791e2443c8a66fcdb04f180abf2ae (patch) | |
tree | d6402b968a3e49b5bc06213153efa2c66ddd5a26 | |
parent | 6e6a50c254220acb19bd338ce433b1770e4a7a3c (diff) | |
parent | 13c92e82e821d87e388a73ffeddeb62d753dab96 (diff) |
Merge branch 'sfc'
Shradha Shah says:
====================
Bug Fixes for SFC driver
I am taking over the upstream patch submission work for the
sfc driver from Ben Hutchings.
These patches are bug fixes to the sfc driver involving
replacement of the PORT RESET MC command and fixing transposed
ptp_{under,over}size_sync_window_statistics
The PORT_RESET bug fix is needed for all versions supporting EF10
i.e all versions including and after 3.12.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/sfc/ef10.c | 31 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/mcdi.c | 14 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/ptp.c | 4 |
3 files changed, 39 insertions, 10 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 4dfc2296600d..174a92f5fe51 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -683,6 +683,17 @@ static int efx_ef10_init_nic(struct efx_nic *efx) return 0; } +static void efx_ef10_reset_mc_allocations(struct efx_nic *efx) +{ + struct efx_ef10_nic_data *nic_data = efx->nic_data; + + /* All our allocations have been reset */ + nic_data->must_realloc_vis = true; + nic_data->must_restore_filters = true; + nic_data->must_restore_piobufs = true; + nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID; +} + static int efx_ef10_map_reset_flags(u32 *flags) { enum { @@ -713,6 +724,19 @@ static int efx_ef10_map_reset_flags(u32 *flags) return -EINVAL; } +static int efx_ef10_reset(struct efx_nic *efx, enum reset_type reset_type) +{ + int rc = efx_mcdi_reset(efx, reset_type); + + /* If it was a port reset, trigger reallocation of MC resources. + * Note that on an MC reset nothing needs to be done now because we'll + * detect the MC reset later and handle it then. + */ + if (reset_type == RESET_TYPE_ALL && !rc) + efx_ef10_reset_mc_allocations(efx); + return rc; +} + #define EF10_DMA_STAT(ext_name, mcdi_name) \ [EF10_STAT_ ## ext_name] = \ { #ext_name, 64, 8 * MC_CMD_MAC_ ## mcdi_name } @@ -1078,10 +1102,7 @@ static int efx_ef10_mcdi_poll_reboot(struct efx_nic *efx) nic_data->warm_boot_count = rc; /* All our allocations have been reset */ - nic_data->must_realloc_vis = true; - nic_data->must_restore_filters = true; - nic_data->must_restore_piobufs = true; - nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID; + efx_ef10_reset_mc_allocations(efx); /* The datapath firmware might have been changed */ nic_data->must_check_datapath_caps = true; @@ -3571,7 +3592,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = { .fini = efx_port_dummy_op_void, .map_reset_reason = efx_mcdi_map_reset_reason, .map_reset_flags = efx_ef10_map_reset_flags, - .reset = efx_mcdi_reset, + .reset = efx_ef10_reset, .probe_port = efx_mcdi_port_probe, .remove_port = efx_mcdi_port_remove, .fini_dmaq = efx_ef10_fini_dmaq, diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 0d5d7b5325e8..eb59abb57e85 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -1471,9 +1471,17 @@ void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) NULL, 0, NULL); } -static int efx_mcdi_reset_port(struct efx_nic *efx) +static int efx_mcdi_reset_func(struct efx_nic *efx) { - return efx_mcdi_rpc(efx, MC_CMD_ENTITY_RESET, NULL, 0, NULL, 0, NULL); + MCDI_DECLARE_BUF(inbuf, MC_CMD_ENTITY_RESET_IN_LEN); + int rc; + + BUILD_BUG_ON(MC_CMD_ENTITY_RESET_OUT_LEN != 0); + MCDI_POPULATE_DWORD_1(inbuf, ENTITY_RESET_IN_FLAG, + ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1); + rc = efx_mcdi_rpc(efx, MC_CMD_ENTITY_RESET, inbuf, sizeof(inbuf), + NULL, 0, NULL); + return rc; } static int efx_mcdi_reset_mc(struct efx_nic *efx) @@ -1510,7 +1518,7 @@ int efx_mcdi_reset(struct efx_nic *efx, enum reset_type method) if (method == RESET_TYPE_WORLD) return efx_mcdi_reset_mc(efx); else - return efx_mcdi_reset_port(efx); + return efx_mcdi_reset_func(efx); } static int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type, diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index 7aa070813960..eb75fbd11a01 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -753,9 +753,9 @@ efx_ptp_process_times(struct efx_nic *efx, MCDI_DECLARE_STRUCT_PTR(synch_buf), if (window < SYNCHRONISATION_GRANULARITY_NS) { ++ptp->invalid_sync_windows; } else if (corrected >= MAX_SYNCHRONISATION_NS) { - ++ptp->undersize_sync_windows; - } else if (corrected < ptp->min_synchronisation_ns) { ++ptp->oversize_sync_windows; + } else if (corrected < ptp->min_synchronisation_ns) { + ++ptp->undersize_sync_windows; } else { ngood++; last_good = i; |