summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-01-21 14:46:56 -0800
committerDavid S. Miller <davem@davemloft.net>2014-01-21 14:46:56 -0800
commit3ea5ad27dc6791e2443c8a66fcdb04f180abf2ae (patch)
treed6402b968a3e49b5bc06213153efa2c66ddd5a26
parent6e6a50c254220acb19bd338ce433b1770e4a7a3c (diff)
parent13c92e82e821d87e388a73ffeddeb62d753dab96 (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.c31
-rw-r--r--drivers/net/ethernet/sfc/mcdi.c14
-rw-r--r--drivers/net/ethernet/sfc/ptp.c4
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;