|
@@ -39,7 +39,7 @@ static const char i40e_driver_string[] =
|
|
|
|
|
|
#define DRV_VERSION_MAJOR 1
|
|
#define DRV_VERSION_MAJOR 1
|
|
#define DRV_VERSION_MINOR 2
|
|
#define DRV_VERSION_MINOR 2
|
|
-#define DRV_VERSION_BUILD 10
|
|
|
|
|
|
+#define DRV_VERSION_BUILD 11
|
|
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
|
|
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
|
|
__stringify(DRV_VERSION_MINOR) "." \
|
|
__stringify(DRV_VERSION_MINOR) "." \
|
|
__stringify(DRV_VERSION_BUILD) DRV_KERN
|
|
__stringify(DRV_VERSION_BUILD) DRV_KERN
|
|
@@ -2399,20 +2399,20 @@ static void i40e_config_xps_tx_ring(struct i40e_ring *ring)
|
|
struct i40e_vsi *vsi = ring->vsi;
|
|
struct i40e_vsi *vsi = ring->vsi;
|
|
cpumask_var_t mask;
|
|
cpumask_var_t mask;
|
|
|
|
|
|
- if (ring->q_vector && ring->netdev) {
|
|
|
|
- /* Single TC mode enable XPS */
|
|
|
|
- if (vsi->tc_config.numtc <= 1 &&
|
|
|
|
- !test_and_set_bit(__I40E_TX_XPS_INIT_DONE, &ring->state)) {
|
|
|
|
|
|
+ if (!ring->q_vector || !ring->netdev)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ /* Single TC mode enable XPS */
|
|
|
|
+ if (vsi->tc_config.numtc <= 1) {
|
|
|
|
+ if (!test_and_set_bit(__I40E_TX_XPS_INIT_DONE, &ring->state))
|
|
netif_set_xps_queue(ring->netdev,
|
|
netif_set_xps_queue(ring->netdev,
|
|
&ring->q_vector->affinity_mask,
|
|
&ring->q_vector->affinity_mask,
|
|
ring->queue_index);
|
|
ring->queue_index);
|
|
- } else if (alloc_cpumask_var(&mask, GFP_KERNEL)) {
|
|
|
|
- /* Disable XPS to allow selection based on TC */
|
|
|
|
- bitmap_zero(cpumask_bits(mask), nr_cpumask_bits);
|
|
|
|
- netif_set_xps_queue(ring->netdev, mask,
|
|
|
|
- ring->queue_index);
|
|
|
|
- free_cpumask_var(mask);
|
|
|
|
- }
|
|
|
|
|
|
+ } else if (alloc_cpumask_var(&mask, GFP_KERNEL)) {
|
|
|
|
+ /* Disable XPS to allow selection based on TC */
|
|
|
|
+ bitmap_zero(cpumask_bits(mask), nr_cpumask_bits);
|
|
|
|
+ netif_set_xps_queue(ring->netdev, mask, ring->queue_index);
|
|
|
|
+ free_cpumask_var(mask);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3831,6 +3831,8 @@ static void i40e_reset_interrupt_capability(struct i40e_pf *pf)
|
|
pci_disable_msix(pf->pdev);
|
|
pci_disable_msix(pf->pdev);
|
|
kfree(pf->msix_entries);
|
|
kfree(pf->msix_entries);
|
|
pf->msix_entries = NULL;
|
|
pf->msix_entries = NULL;
|
|
|
|
+ kfree(pf->irq_pile);
|
|
|
|
+ pf->irq_pile = NULL;
|
|
} else if (pf->flags & I40E_FLAG_MSI_ENABLED) {
|
|
} else if (pf->flags & I40E_FLAG_MSI_ENABLED) {
|
|
pci_disable_msi(pf->pdev);
|
|
pci_disable_msi(pf->pdev);
|
|
}
|
|
}
|
|
@@ -6933,15 +6935,14 @@ static int i40e_reserve_msix_vectors(struct i40e_pf *pf, int vectors)
|
|
*
|
|
*
|
|
* Work with the OS to set up the MSIX vectors needed.
|
|
* Work with the OS to set up the MSIX vectors needed.
|
|
*
|
|
*
|
|
- * Returns 0 on success, negative on failure
|
|
|
|
|
|
+ * Returns the number of vectors reserved or negative on failure
|
|
**/
|
|
**/
|
|
static int i40e_init_msix(struct i40e_pf *pf)
|
|
static int i40e_init_msix(struct i40e_pf *pf)
|
|
{
|
|
{
|
|
- i40e_status err = 0;
|
|
|
|
struct i40e_hw *hw = &pf->hw;
|
|
struct i40e_hw *hw = &pf->hw;
|
|
int other_vecs = 0;
|
|
int other_vecs = 0;
|
|
int v_budget, i;
|
|
int v_budget, i;
|
|
- int vec;
|
|
|
|
|
|
+ int v_actual;
|
|
|
|
|
|
if (!(pf->flags & I40E_FLAG_MSIX_ENABLED))
|
|
if (!(pf->flags & I40E_FLAG_MSIX_ENABLED))
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
@@ -6990,9 +6991,9 @@ static int i40e_init_msix(struct i40e_pf *pf)
|
|
|
|
|
|
for (i = 0; i < v_budget; i++)
|
|
for (i = 0; i < v_budget; i++)
|
|
pf->msix_entries[i].entry = i;
|
|
pf->msix_entries[i].entry = i;
|
|
- vec = i40e_reserve_msix_vectors(pf, v_budget);
|
|
|
|
|
|
+ v_actual = i40e_reserve_msix_vectors(pf, v_budget);
|
|
|
|
|
|
- if (vec != v_budget) {
|
|
|
|
|
|
+ if (v_actual != v_budget) {
|
|
/* If we have limited resources, we will start with no vectors
|
|
/* If we have limited resources, we will start with no vectors
|
|
* for the special features and then allocate vectors to some
|
|
* for the special features and then allocate vectors to some
|
|
* of these features based on the policy and at the end disable
|
|
* of these features based on the policy and at the end disable
|
|
@@ -7005,22 +7006,24 @@ static int i40e_init_msix(struct i40e_pf *pf)
|
|
pf->num_vmdq_msix = 0;
|
|
pf->num_vmdq_msix = 0;
|
|
}
|
|
}
|
|
|
|
|
|
- if (vec < I40E_MIN_MSIX) {
|
|
|
|
|
|
+ if (v_actual < I40E_MIN_MSIX) {
|
|
pf->flags &= ~I40E_FLAG_MSIX_ENABLED;
|
|
pf->flags &= ~I40E_FLAG_MSIX_ENABLED;
|
|
kfree(pf->msix_entries);
|
|
kfree(pf->msix_entries);
|
|
pf->msix_entries = NULL;
|
|
pf->msix_entries = NULL;
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
|
|
|
|
- } else if (vec == I40E_MIN_MSIX) {
|
|
|
|
|
|
+ } else if (v_actual == I40E_MIN_MSIX) {
|
|
/* Adjust for minimal MSIX use */
|
|
/* Adjust for minimal MSIX use */
|
|
pf->num_vmdq_vsis = 0;
|
|
pf->num_vmdq_vsis = 0;
|
|
pf->num_vmdq_qps = 0;
|
|
pf->num_vmdq_qps = 0;
|
|
pf->num_lan_qps = 1;
|
|
pf->num_lan_qps = 1;
|
|
pf->num_lan_msix = 1;
|
|
pf->num_lan_msix = 1;
|
|
|
|
|
|
- } else if (vec != v_budget) {
|
|
|
|
|
|
+ } else if (v_actual != v_budget) {
|
|
|
|
+ int vec;
|
|
|
|
+
|
|
/* reserve the misc vector */
|
|
/* reserve the misc vector */
|
|
- vec--;
|
|
|
|
|
|
+ vec = v_actual - 1;
|
|
|
|
|
|
/* Scale vector usage down */
|
|
/* Scale vector usage down */
|
|
pf->num_vmdq_msix = 1; /* force VMDqs to only one vector */
|
|
pf->num_vmdq_msix = 1; /* force VMDqs to only one vector */
|
|
@@ -7070,7 +7073,7 @@ static int i40e_init_msix(struct i40e_pf *pf)
|
|
pf->flags &= ~I40E_FLAG_FCOE_ENABLED;
|
|
pf->flags &= ~I40E_FLAG_FCOE_ENABLED;
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
- return err;
|
|
|
|
|
|
+ return v_actual;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -7147,11 +7150,12 @@ err_out:
|
|
**/
|
|
**/
|
|
static void i40e_init_interrupt_scheme(struct i40e_pf *pf)
|
|
static void i40e_init_interrupt_scheme(struct i40e_pf *pf)
|
|
{
|
|
{
|
|
- int err = 0;
|
|
|
|
|
|
+ int vectors = 0;
|
|
|
|
+ ssize_t size;
|
|
|
|
|
|
if (pf->flags & I40E_FLAG_MSIX_ENABLED) {
|
|
if (pf->flags & I40E_FLAG_MSIX_ENABLED) {
|
|
- err = i40e_init_msix(pf);
|
|
|
|
- if (err) {
|
|
|
|
|
|
+ vectors = i40e_init_msix(pf);
|
|
|
|
+ if (vectors < 0) {
|
|
pf->flags &= ~(I40E_FLAG_MSIX_ENABLED |
|
|
pf->flags &= ~(I40E_FLAG_MSIX_ENABLED |
|
|
#ifdef I40E_FCOE
|
|
#ifdef I40E_FCOE
|
|
I40E_FLAG_FCOE_ENABLED |
|
|
I40E_FLAG_FCOE_ENABLED |
|
|
@@ -7171,18 +7175,26 @@ static void i40e_init_interrupt_scheme(struct i40e_pf *pf)
|
|
if (!(pf->flags & I40E_FLAG_MSIX_ENABLED) &&
|
|
if (!(pf->flags & I40E_FLAG_MSIX_ENABLED) &&
|
|
(pf->flags & I40E_FLAG_MSI_ENABLED)) {
|
|
(pf->flags & I40E_FLAG_MSI_ENABLED)) {
|
|
dev_info(&pf->pdev->dev, "MSI-X not available, trying MSI\n");
|
|
dev_info(&pf->pdev->dev, "MSI-X not available, trying MSI\n");
|
|
- err = pci_enable_msi(pf->pdev);
|
|
|
|
- if (err) {
|
|
|
|
- dev_info(&pf->pdev->dev, "MSI init failed - %d\n", err);
|
|
|
|
|
|
+ vectors = pci_enable_msi(pf->pdev);
|
|
|
|
+ if (vectors < 0) {
|
|
|
|
+ dev_info(&pf->pdev->dev, "MSI init failed - %d\n",
|
|
|
|
+ vectors);
|
|
pf->flags &= ~I40E_FLAG_MSI_ENABLED;
|
|
pf->flags &= ~I40E_FLAG_MSI_ENABLED;
|
|
}
|
|
}
|
|
|
|
+ vectors = 1; /* one MSI or Legacy vector */
|
|
}
|
|
}
|
|
|
|
|
|
if (!(pf->flags & (I40E_FLAG_MSIX_ENABLED | I40E_FLAG_MSI_ENABLED)))
|
|
if (!(pf->flags & (I40E_FLAG_MSIX_ENABLED | I40E_FLAG_MSI_ENABLED)))
|
|
dev_info(&pf->pdev->dev, "MSI-X and MSI not available, falling back to Legacy IRQ\n");
|
|
dev_info(&pf->pdev->dev, "MSI-X and MSI not available, falling back to Legacy IRQ\n");
|
|
|
|
|
|
|
|
+ /* set up vector assignment tracking */
|
|
|
|
+ size = sizeof(struct i40e_lump_tracking) + (sizeof(u16) * vectors);
|
|
|
|
+ pf->irq_pile = kzalloc(size, GFP_KERNEL);
|
|
|
|
+ pf->irq_pile->num_entries = vectors;
|
|
|
|
+ pf->irq_pile->search_hint = 0;
|
|
|
|
+
|
|
/* track first vector for misc interrupts */
|
|
/* track first vector for misc interrupts */
|
|
- err = i40e_get_lump(pf, pf->irq_pile, 1, I40E_PILE_VALID_BIT-1);
|
|
|
|
|
|
+ (void)i40e_get_lump(pf, pf->irq_pile, 1, I40E_PILE_VALID_BIT - 1);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -7560,22 +7572,14 @@ static int i40e_sw_init(struct i40e_pf *pf)
|
|
pf->qp_pile->num_entries = pf->hw.func_caps.num_tx_qp;
|
|
pf->qp_pile->num_entries = pf->hw.func_caps.num_tx_qp;
|
|
pf->qp_pile->search_hint = 0;
|
|
pf->qp_pile->search_hint = 0;
|
|
|
|
|
|
- /* set up vector assignment tracking */
|
|
|
|
- size = sizeof(struct i40e_lump_tracking)
|
|
|
|
- + (sizeof(u16) * pf->hw.func_caps.num_msix_vectors);
|
|
|
|
- pf->irq_pile = kzalloc(size, GFP_KERNEL);
|
|
|
|
- if (!pf->irq_pile) {
|
|
|
|
- kfree(pf->qp_pile);
|
|
|
|
- err = -ENOMEM;
|
|
|
|
- goto sw_init_done;
|
|
|
|
- }
|
|
|
|
- pf->irq_pile->num_entries = pf->hw.func_caps.num_msix_vectors;
|
|
|
|
- pf->irq_pile->search_hint = 0;
|
|
|
|
-
|
|
|
|
pf->tx_timeout_recovery_level = 1;
|
|
pf->tx_timeout_recovery_level = 1;
|
|
|
|
|
|
mutex_init(&pf->switch_mutex);
|
|
mutex_init(&pf->switch_mutex);
|
|
|
|
|
|
|
|
+ /* If NPAR is enabled nudge the Tx scheduler */
|
|
|
|
+ if (pf->hw.func_caps.npar_enable && (!i40e_get_npar_bw_setting(pf)))
|
|
|
|
+ i40e_set_npar_bw_setting(pf);
|
|
|
|
+
|
|
sw_init_done:
|
|
sw_init_done:
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
@@ -9455,6 +9459,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
struct i40e_pf *pf;
|
|
struct i40e_pf *pf;
|
|
struct i40e_hw *hw;
|
|
struct i40e_hw *hw;
|
|
static u16 pfs_found;
|
|
static u16 pfs_found;
|
|
|
|
+ u32 ioremap_len;
|
|
u16 link_status;
|
|
u16 link_status;
|
|
int err = 0;
|
|
int err = 0;
|
|
u32 len;
|
|
u32 len;
|
|
@@ -9503,8 +9508,11 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
|
|
|
hw = &pf->hw;
|
|
hw = &pf->hw;
|
|
hw->back = pf;
|
|
hw->back = pf;
|
|
- hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
|
|
|
|
- pci_resource_len(pdev, 0));
|
|
|
|
|
|
+
|
|
|
|
+ ioremap_len = min_t(int, pci_resource_len(pdev, 0),
|
|
|
|
+ I40E_MAX_CSR_SPACE);
|
|
|
|
+
|
|
|
|
+ hw->hw_addr = ioremap(pci_resource_start(pdev, 0), ioremap_len);
|
|
if (!hw->hw_addr) {
|
|
if (!hw->hw_addr) {
|
|
err = -EIO;
|
|
err = -EIO;
|
|
dev_info(&pdev->dev, "ioremap(0x%04x, 0x%04x) failed: 0x%x\n",
|
|
dev_info(&pdev->dev, "ioremap(0x%04x, 0x%04x) failed: 0x%x\n",
|
|
@@ -9582,7 +9590,6 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
dev_info(&pdev->dev,
|
|
dev_info(&pdev->dev,
|
|
"The driver for the device detected an older version of the NVM image than expected. Please update the NVM image.\n");
|
|
"The driver for the device detected an older version of the NVM image than expected. Please update the NVM image.\n");
|
|
|
|
|
|
-
|
|
|
|
i40e_verify_eeprom(pf);
|
|
i40e_verify_eeprom(pf);
|
|
|
|
|
|
/* Rev 0 hardware was never productized */
|
|
/* Rev 0 hardware was never productized */
|
|
@@ -9833,7 +9840,6 @@ err_configure_lan_hmc:
|
|
(void)i40e_shutdown_lan_hmc(hw);
|
|
(void)i40e_shutdown_lan_hmc(hw);
|
|
err_init_lan_hmc:
|
|
err_init_lan_hmc:
|
|
kfree(pf->qp_pile);
|
|
kfree(pf->qp_pile);
|
|
- kfree(pf->irq_pile);
|
|
|
|
err_sw_init:
|
|
err_sw_init:
|
|
err_adminq_setup:
|
|
err_adminq_setup:
|
|
(void)i40e_shutdown_adminq(hw);
|
|
(void)i40e_shutdown_adminq(hw);
|
|
@@ -9933,7 +9939,6 @@ static void i40e_remove(struct pci_dev *pdev)
|
|
}
|
|
}
|
|
|
|
|
|
kfree(pf->qp_pile);
|
|
kfree(pf->qp_pile);
|
|
- kfree(pf->irq_pile);
|
|
|
|
kfree(pf->vsi);
|
|
kfree(pf->vsi);
|
|
|
|
|
|
iounmap(pf->hw.hw_addr);
|
|
iounmap(pf->hw.hw_addr);
|