|
@@ -1420,9 +1420,12 @@ static int efx_probe_interrupts(struct efx_nic *efx)
|
|
|
xentries, 1, n_channels);
|
|
|
if (rc < 0) {
|
|
|
/* Fall back to single channel MSI */
|
|
|
- efx->interrupt_mode = EFX_INT_MODE_MSI;
|
|
|
netif_err(efx, drv, efx->net_dev,
|
|
|
"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) {
|
|
|
netif_err(efx, drv, efx->net_dev,
|
|
|
"WARNING: Insufficient MSI-X vectors"
|
|
@@ -1465,7 +1468,10 @@ static int efx_probe_interrupts(struct efx_nic *efx)
|
|
|
} else {
|
|
|
netif_err(efx, drv, efx->net_dev,
|
|
|
"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 = {
|
|
|
static int efx_init_struct(struct efx_nic *efx,
|
|
|
struct pci_dev *pci_dev, struct net_device *net_dev)
|
|
|
{
|
|
|
- int i;
|
|
|
+ int rc = -ENOMEM, i;
|
|
|
|
|
|
/* Initialise common structures */
|
|
|
INIT_LIST_HEAD(&efx->node);
|
|
@@ -2976,8 +2982,15 @@ static int efx_init_struct(struct efx_nic *efx,
|
|
|
}
|
|
|
|
|
|
/* 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,
|
|
|
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 */
|
|
|
snprintf(efx->workqueue_name, sizeof(efx->workqueue_name), "sfc%s",
|
|
@@ -2990,7 +3003,7 @@ static int efx_init_struct(struct efx_nic *efx,
|
|
|
|
|
|
fail:
|
|
|
efx_fini_struct(efx);
|
|
|
- return -ENOMEM;
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
static void efx_fini_struct(struct efx_nic *efx)
|