Commit 1ef68ec4 authored by David S. Miller's avatar David S. Miller

Merge branch 'sfc-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc

Ben Hutchings says:

====================
Some bug fixes and future-proofing for the recently added SFC9120
support:

1. Minimal support for the 40G configuration.
2. Disable the incomplete PTP/hardware timestamping support.
3. Reset MAC stats properly after a firmware upgrade.
4. Re-check the datapath firmware capabilities after the controller is
reset.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 3f96a532 a915ccc9
...@@ -7,7 +7,7 @@ config SFC ...@@ -7,7 +7,7 @@ config SFC
select I2C_ALGOBIT select I2C_ALGOBIT
select PTP_1588_CLOCK select PTP_1588_CLOCK
---help--- ---help---
This driver supports 10-gigabit Ethernet cards based on This driver supports 10/40-gigabit Ethernet cards based on
the Solarflare SFC4000, SFC9000-family and SFC9100-family the Solarflare SFC4000, SFC9000-family and SFC9100-family
controllers. controllers.
......
...@@ -94,7 +94,7 @@ static unsigned int efx_ef10_mem_map_size(struct efx_nic *efx) ...@@ -94,7 +94,7 @@ static unsigned int efx_ef10_mem_map_size(struct efx_nic *efx)
return resource_size(&efx->pci_dev->resource[EFX_MEM_BAR]); return resource_size(&efx->pci_dev->resource[EFX_MEM_BAR]);
} }
static int efx_ef10_init_capabilities(struct efx_nic *efx) static int efx_ef10_init_datapath_caps(struct efx_nic *efx)
{ {
MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_OUT_LEN); MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_OUT_LEN);
struct efx_ef10_nic_data *nic_data = efx->nic_data; struct efx_ef10_nic_data *nic_data = efx->nic_data;
...@@ -107,16 +107,27 @@ static int efx_ef10_init_capabilities(struct efx_nic *efx) ...@@ -107,16 +107,27 @@ static int efx_ef10_init_capabilities(struct efx_nic *efx)
outbuf, sizeof(outbuf), &outlen); outbuf, sizeof(outbuf), &outlen);
if (rc) if (rc)
return rc; return rc;
if (outlen < sizeof(outbuf)) {
netif_err(efx, drv, efx->net_dev,
"unable to read datapath firmware capabilities\n");
return -EIO;
}
if (outlen >= sizeof(outbuf)) { nic_data->datapath_caps =
nic_data->datapath_caps = MCDI_DWORD(outbuf, GET_CAPABILITIES_OUT_FLAGS1);
MCDI_DWORD(outbuf, GET_CAPABILITIES_OUT_FLAGS1);
if (!(nic_data->datapath_caps & if (!(nic_data->datapath_caps &
(1 << MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_LBN))) { (1 << MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_LBN))) {
netif_err(efx, drv, efx->net_dev, netif_err(efx, drv, efx->net_dev,
"Capabilities don't indicate TSO support.\n"); "current firmware does not support TSO\n");
return -ENODEV; return -ENODEV;
} }
if (!(nic_data->datapath_caps &
(1 << MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_LBN))) {
netif_err(efx, probe, efx->net_dev,
"current firmware does not support an RX prefix\n");
return -ENODEV;
} }
return 0; return 0;
...@@ -217,21 +228,13 @@ static int efx_ef10_probe(struct efx_nic *efx) ...@@ -217,21 +228,13 @@ static int efx_ef10_probe(struct efx_nic *efx)
if (rc) if (rc)
goto fail3; goto fail3;
rc = efx_ef10_init_capabilities(efx); rc = efx_ef10_init_datapath_caps(efx);
if (rc < 0) if (rc < 0)
goto fail3; goto fail3;
efx->rx_packet_len_offset = efx->rx_packet_len_offset =
ES_DZ_RX_PREFIX_PKTLEN_OFST - ES_DZ_RX_PREFIX_SIZE; ES_DZ_RX_PREFIX_PKTLEN_OFST - ES_DZ_RX_PREFIX_SIZE;
if (!(nic_data->datapath_caps &
(1 << MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_LBN))) {
netif_err(efx, probe, efx->net_dev,
"current firmware does not support an RX prefix\n");
rc = -ENODEV;
goto fail3;
}
rc = efx_mcdi_port_get_number(efx); rc = efx_mcdi_port_get_number(efx);
if (rc < 0) if (rc < 0)
goto fail3; goto fail3;
...@@ -260,8 +263,6 @@ static int efx_ef10_probe(struct efx_nic *efx) ...@@ -260,8 +263,6 @@ static int efx_ef10_probe(struct efx_nic *efx)
if (rc) if (rc)
goto fail3; goto fail3;
efx_ptp_probe(efx);
return 0; return 0;
fail3: fail3:
...@@ -342,6 +343,13 @@ static int efx_ef10_init_nic(struct efx_nic *efx) ...@@ -342,6 +343,13 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
struct efx_ef10_nic_data *nic_data = efx->nic_data; struct efx_ef10_nic_data *nic_data = efx->nic_data;
int rc; int rc;
if (nic_data->must_check_datapath_caps) {
rc = efx_ef10_init_datapath_caps(efx);
if (rc)
return rc;
nic_data->must_check_datapath_caps = false;
}
if (nic_data->must_realloc_vis) { if (nic_data->must_realloc_vis) {
/* We cannot let the number of VIs change now */ /* We cannot let the number of VIs change now */
rc = efx_ef10_alloc_vis(efx, nic_data->n_allocated_vis, rc = efx_ef10_alloc_vis(efx, nic_data->n_allocated_vis,
...@@ -710,6 +718,14 @@ static int efx_ef10_mcdi_poll_reboot(struct efx_nic *efx) ...@@ -710,6 +718,14 @@ static int efx_ef10_mcdi_poll_reboot(struct efx_nic *efx)
nic_data->must_restore_filters = true; nic_data->must_restore_filters = true;
nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID; nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID;
/* The datapath firmware might have been changed */
nic_data->must_check_datapath_caps = true;
/* MAC statistics have been cleared on the NIC; clear the local
* statistic that we update with efx_update_diff_stat().
*/
nic_data->stats[EF10_STAT_rx_bad_bytes] = 0;
return -EIO; return -EIO;
} }
......
...@@ -556,6 +556,7 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec ...@@ -556,6 +556,7 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec
case 100: caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN; break; case 100: caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN; break;
case 1000: caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN; break; case 1000: caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN; break;
case 10000: caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN; break; case 10000: caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN; break;
case 40000: caps = 1 << MC_CMD_PHY_CAP_40000FDX_LBN; break;
default: return -EINVAL; default: return -EINVAL;
} }
} else { } else {
...@@ -841,6 +842,7 @@ static unsigned int efx_mcdi_event_link_speed[] = { ...@@ -841,6 +842,7 @@ static unsigned int efx_mcdi_event_link_speed[] = {
[MCDI_EVENT_LINKCHANGE_SPEED_100M] = 100, [MCDI_EVENT_LINKCHANGE_SPEED_100M] = 100,
[MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000, [MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000,
[MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000, [MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000,
[MCDI_EVENT_LINKCHANGE_SPEED_40G] = 40000,
}; };
void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev) void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
......
...@@ -400,6 +400,8 @@ enum { ...@@ -400,6 +400,8 @@ enum {
* @rx_rss_context: Firmware handle for our RSS context * @rx_rss_context: Firmware handle for our RSS context
* @stats: Hardware statistics * @stats: Hardware statistics
* @workaround_35388: Flag: firmware supports workaround for bug 35388 * @workaround_35388: Flag: firmware supports workaround for bug 35388
* @must_check_datapath_caps: Flag: @datapath_caps needs to be revalidated
* after MC reboot
* @datapath_caps: Capabilities of datapath firmware (FLAGS1 field of * @datapath_caps: Capabilities of datapath firmware (FLAGS1 field of
* %MC_CMD_GET_CAPABILITIES response) * %MC_CMD_GET_CAPABILITIES response)
*/ */
...@@ -413,6 +415,7 @@ struct efx_ef10_nic_data { ...@@ -413,6 +415,7 @@ struct efx_ef10_nic_data {
u32 rx_rss_context; u32 rx_rss_context;
u64 stats[EF10_STAT_COUNT]; u64 stats[EF10_STAT_COUNT];
bool workaround_35388; bool workaround_35388;
bool must_check_datapath_caps;
u32 datapath_caps; u32 datapath_caps;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment