Commit bd08b532 authored by David S. Miller's avatar David S. Miller

Merge branch 'sfc-bogus-interrupt-mode-fallbacks'

Edward Cree says:

====================
sfc: prevent bogus interrupt-mode fallbacks

EF10 VFs only support MSI-X interrupts, not MSI or legacy.  This series
 stops the probe logic from trying to fallback to those if MSI-X interrupt
 probe fails.  It also prevents selecting them with the interrupt_mode
 module parameter.
This avoids producing messages like "failed to hook legacy IRQ 0" and "IRQ
 handler type mismatch for IRQ 0", and ensures that the relevant error
 (from the attempt to enable MSI-X) is reported to the caller.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9b8e1056 62980cb6
...@@ -6456,6 +6456,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = { ...@@ -6456,6 +6456,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.rx_ts_offset = ES_DZ_RX_PREFIX_TSTAMP_OFST, .rx_ts_offset = ES_DZ_RX_PREFIX_TSTAMP_OFST,
.can_rx_scatter = true, .can_rx_scatter = true,
.always_rx_scatter = true, .always_rx_scatter = true,
.min_interrupt_mode = EFX_INT_MODE_MSIX,
.max_interrupt_mode = EFX_INT_MODE_MSIX, .max_interrupt_mode = EFX_INT_MODE_MSIX,
.timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH, .timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH,
.offload_features = EF10_OFFLOAD_FEATURES, .offload_features = EF10_OFFLOAD_FEATURES,
...@@ -6588,6 +6589,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = { ...@@ -6588,6 +6589,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.can_rx_scatter = true, .can_rx_scatter = true,
.always_rx_scatter = true, .always_rx_scatter = true,
.option_descriptors = true, .option_descriptors = true,
.min_interrupt_mode = EFX_INT_MODE_LEGACY,
.max_interrupt_mode = EFX_INT_MODE_MSIX, .max_interrupt_mode = EFX_INT_MODE_MSIX,
.timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH, .timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH,
.offload_features = EF10_OFFLOAD_FEATURES, .offload_features = EF10_OFFLOAD_FEATURES,
......
...@@ -1420,9 +1420,12 @@ static int efx_probe_interrupts(struct efx_nic *efx) ...@@ -1420,9 +1420,12 @@ static int efx_probe_interrupts(struct efx_nic *efx)
xentries, 1, n_channels); xentries, 1, n_channels);
if (rc < 0) { if (rc < 0) {
/* Fall back to single channel MSI */ /* Fall back to single channel MSI */
efx->interrupt_mode = EFX_INT_MODE_MSI;
netif_err(efx, drv, efx->net_dev, netif_err(efx, drv, efx->net_dev,
"could not enable MSI-X\n"); "could not enable MSI-X\n");
if (efx->type->min_interrupt_mode >= EFX_INT_MODE_MSI)
efx->interrupt_mode = EFX_INT_MODE_MSI;
else
return rc;
} else if (rc < n_channels) { } else if (rc < n_channels) {
netif_err(efx, drv, efx->net_dev, netif_err(efx, drv, efx->net_dev,
"WARNING: Insufficient MSI-X vectors" "WARNING: Insufficient MSI-X vectors"
...@@ -1465,7 +1468,10 @@ static int efx_probe_interrupts(struct efx_nic *efx) ...@@ -1465,7 +1468,10 @@ static int efx_probe_interrupts(struct efx_nic *efx)
} else { } else {
netif_err(efx, drv, efx->net_dev, netif_err(efx, drv, efx->net_dev,
"could not enable MSI\n"); "could not enable MSI\n");
efx->interrupt_mode = EFX_INT_MODE_LEGACY; if (efx->type->min_interrupt_mode >= EFX_INT_MODE_LEGACY)
efx->interrupt_mode = EFX_INT_MODE_LEGACY;
else
return rc;
} }
} }
...@@ -2935,7 +2941,7 @@ static const struct efx_phy_operations efx_dummy_phy_operations = { ...@@ -2935,7 +2941,7 @@ static const struct efx_phy_operations efx_dummy_phy_operations = {
static int efx_init_struct(struct efx_nic *efx, static int efx_init_struct(struct efx_nic *efx,
struct pci_dev *pci_dev, struct net_device *net_dev) struct pci_dev *pci_dev, struct net_device *net_dev)
{ {
int i; int rc = -ENOMEM, i;
/* Initialise common structures */ /* Initialise common structures */
INIT_LIST_HEAD(&efx->node); INIT_LIST_HEAD(&efx->node);
...@@ -2976,8 +2982,15 @@ static int efx_init_struct(struct efx_nic *efx, ...@@ -2976,8 +2982,15 @@ static int efx_init_struct(struct efx_nic *efx,
} }
/* Higher numbered interrupt modes are less capable! */ /* Higher numbered interrupt modes are less capable! */
if (WARN_ON_ONCE(efx->type->max_interrupt_mode >
efx->type->min_interrupt_mode)) {
rc = -EIO;
goto fail;
}
efx->interrupt_mode = max(efx->type->max_interrupt_mode, efx->interrupt_mode = max(efx->type->max_interrupt_mode,
interrupt_mode); interrupt_mode);
efx->interrupt_mode = min(efx->type->min_interrupt_mode,
interrupt_mode);
/* Would be good to use the net_dev name, but we're too early */ /* Would be good to use the net_dev name, but we're too early */
snprintf(efx->workqueue_name, sizeof(efx->workqueue_name), "sfc%s", snprintf(efx->workqueue_name, sizeof(efx->workqueue_name), "sfc%s",
...@@ -2990,7 +3003,7 @@ static int efx_init_struct(struct efx_nic *efx, ...@@ -2990,7 +3003,7 @@ static int efx_init_struct(struct efx_nic *efx,
fail: fail:
efx_fini_struct(efx); efx_fini_struct(efx);
return -ENOMEM; return rc;
} }
static void efx_fini_struct(struct efx_nic *efx) static void efx_fini_struct(struct efx_nic *efx)
......
...@@ -1142,8 +1142,10 @@ struct efx_udp_tunnel { ...@@ -1142,8 +1142,10 @@ struct efx_udp_tunnel {
* @can_rx_scatter: NIC is able to scatter packets to multiple buffers * @can_rx_scatter: NIC is able to scatter packets to multiple buffers
* @always_rx_scatter: NIC will always scatter packets to multiple buffers * @always_rx_scatter: NIC will always scatter packets to multiple buffers
* @option_descriptors: NIC supports TX option descriptors * @option_descriptors: NIC supports TX option descriptors
* @min_interrupt_mode: Lowest capability interrupt mode supported
* from &enum efx_int_mode.
* @max_interrupt_mode: Highest capability interrupt mode supported * @max_interrupt_mode: Highest capability interrupt mode supported
* from &enum efx_init_mode. * from &enum efx_int_mode.
* @timer_period_max: Maximum period of interrupt timer (in ticks) * @timer_period_max: Maximum period of interrupt timer (in ticks)
* @offload_features: net_device feature flags for protocol offload * @offload_features: net_device feature flags for protocol offload
* features implemented in hardware * features implemented in hardware
...@@ -1306,6 +1308,7 @@ struct efx_nic_type { ...@@ -1306,6 +1308,7 @@ struct efx_nic_type {
bool can_rx_scatter; bool can_rx_scatter;
bool always_rx_scatter; bool always_rx_scatter;
bool option_descriptors; bool option_descriptors;
unsigned int min_interrupt_mode;
unsigned int max_interrupt_mode; unsigned int max_interrupt_mode;
unsigned int timer_period_max; unsigned int timer_period_max;
netdev_features_t offload_features; netdev_features_t offload_features;
......
...@@ -1069,6 +1069,7 @@ const struct efx_nic_type siena_a0_nic_type = { ...@@ -1069,6 +1069,7 @@ const struct efx_nic_type siena_a0_nic_type = {
.rx_buffer_padding = 0, .rx_buffer_padding = 0,
.can_rx_scatter = true, .can_rx_scatter = true,
.option_descriptors = false, .option_descriptors = false,
.min_interrupt_mode = EFX_INT_MODE_LEGACY,
.max_interrupt_mode = EFX_INT_MODE_MSIX, .max_interrupt_mode = EFX_INT_MODE_MSIX,
.timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH, .timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH,
.offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
......
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