|
@@ -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 9
|
|
|
|
|
|
+#define DRV_VERSION_BUILD 10
|
|
#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
|
|
@@ -1566,6 +1566,12 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
|
|
|
|
|
|
/* Set actual Tx/Rx queue pairs */
|
|
/* Set actual Tx/Rx queue pairs */
|
|
vsi->num_queue_pairs = offset;
|
|
vsi->num_queue_pairs = offset;
|
|
|
|
+ if ((vsi->type == I40E_VSI_MAIN) && (numtc == 1)) {
|
|
|
|
+ if (vsi->req_queue_pairs > 0)
|
|
|
|
+ vsi->num_queue_pairs = vsi->req_queue_pairs;
|
|
|
|
+ else
|
|
|
|
+ vsi->num_queue_pairs = pf->num_lan_msix;
|
|
|
|
+ }
|
|
|
|
|
|
/* Scheduler section valid can only be set for ADD VSI */
|
|
/* Scheduler section valid can only be set for ADD VSI */
|
|
if (is_add) {
|
|
if (is_add) {
|
|
@@ -4101,7 +4107,7 @@ static u8 i40e_pf_get_num_tc(struct i40e_pf *pf)
|
|
if (pf->hw.func_caps.iscsi)
|
|
if (pf->hw.func_caps.iscsi)
|
|
enabled_tc = i40e_get_iscsi_tc_map(pf);
|
|
enabled_tc = i40e_get_iscsi_tc_map(pf);
|
|
else
|
|
else
|
|
- enabled_tc = pf->hw.func_caps.enabled_tcmap;
|
|
|
|
|
|
+ return 1; /* Only TC0 */
|
|
|
|
|
|
/* At least have TC0 */
|
|
/* At least have TC0 */
|
|
enabled_tc = (enabled_tc ? enabled_tc : 0x1);
|
|
enabled_tc = (enabled_tc ? enabled_tc : 0x1);
|
|
@@ -4151,11 +4157,11 @@ static u8 i40e_pf_get_tc_map(struct i40e_pf *pf)
|
|
if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
|
|
if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
|
|
return i40e_dcb_get_enabled_tc(&pf->hw.local_dcbx_config);
|
|
return i40e_dcb_get_enabled_tc(&pf->hw.local_dcbx_config);
|
|
|
|
|
|
- /* MPF enabled and iSCSI PF type */
|
|
|
|
|
|
+ /* MFP enabled and iSCSI PF type */
|
|
if (pf->hw.func_caps.iscsi)
|
|
if (pf->hw.func_caps.iscsi)
|
|
return i40e_get_iscsi_tc_map(pf);
|
|
return i40e_get_iscsi_tc_map(pf);
|
|
else
|
|
else
|
|
- return pf->hw.func_caps.enabled_tcmap;
|
|
|
|
|
|
+ return i40e_pf_get_default_tc(pf);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -4545,6 +4551,11 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf)
|
|
struct i40e_hw *hw = &pf->hw;
|
|
struct i40e_hw *hw = &pf->hw;
|
|
int err = 0;
|
|
int err = 0;
|
|
|
|
|
|
|
|
+ /* Do not enable DCB for SW1 and SW2 images even if the FW is capable */
|
|
|
|
+ if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
|
|
|
|
+ (pf->hw.aq.fw_maj_ver < 4))
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
/* Get the initial DCB configuration */
|
|
/* Get the initial DCB configuration */
|
|
err = i40e_init_dcb(hw);
|
|
err = i40e_init_dcb(hw);
|
|
if (!err) {
|
|
if (!err) {
|
|
@@ -5155,7 +5166,6 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf,
|
|
struct i40e_aqc_lldp_get_mib *mib =
|
|
struct i40e_aqc_lldp_get_mib *mib =
|
|
(struct i40e_aqc_lldp_get_mib *)&e->desc.params.raw;
|
|
(struct i40e_aqc_lldp_get_mib *)&e->desc.params.raw;
|
|
struct i40e_hw *hw = &pf->hw;
|
|
struct i40e_hw *hw = &pf->hw;
|
|
- struct i40e_dcbx_config *dcbx_cfg = &hw->local_dcbx_config;
|
|
|
|
struct i40e_dcbx_config tmp_dcbx_cfg;
|
|
struct i40e_dcbx_config tmp_dcbx_cfg;
|
|
bool need_reconfig = false;
|
|
bool need_reconfig = false;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
@@ -5188,8 +5198,10 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf,
|
|
|
|
|
|
memset(&tmp_dcbx_cfg, 0, sizeof(tmp_dcbx_cfg));
|
|
memset(&tmp_dcbx_cfg, 0, sizeof(tmp_dcbx_cfg));
|
|
/* Store the old configuration */
|
|
/* Store the old configuration */
|
|
- tmp_dcbx_cfg = *dcbx_cfg;
|
|
|
|
|
|
+ memcpy(&tmp_dcbx_cfg, &hw->local_dcbx_config, sizeof(tmp_dcbx_cfg));
|
|
|
|
|
|
|
|
+ /* Reset the old DCBx configuration data */
|
|
|
|
+ memset(&hw->local_dcbx_config, 0, sizeof(hw->local_dcbx_config));
|
|
/* Get updated DCBX data from firmware */
|
|
/* Get updated DCBX data from firmware */
|
|
ret = i40e_get_dcb_config(&pf->hw);
|
|
ret = i40e_get_dcb_config(&pf->hw);
|
|
if (ret) {
|
|
if (ret) {
|
|
@@ -5198,20 +5210,22 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf,
|
|
}
|
|
}
|
|
|
|
|
|
/* No change detected in DCBX configs */
|
|
/* No change detected in DCBX configs */
|
|
- if (!memcmp(&tmp_dcbx_cfg, dcbx_cfg, sizeof(tmp_dcbx_cfg))) {
|
|
|
|
|
|
+ if (!memcmp(&tmp_dcbx_cfg, &hw->local_dcbx_config,
|
|
|
|
+ sizeof(tmp_dcbx_cfg))) {
|
|
dev_dbg(&pf->pdev->dev, "No change detected in DCBX configuration.\n");
|
|
dev_dbg(&pf->pdev->dev, "No change detected in DCBX configuration.\n");
|
|
goto exit;
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
|
|
- need_reconfig = i40e_dcb_need_reconfig(pf, &tmp_dcbx_cfg, dcbx_cfg);
|
|
|
|
|
|
+ need_reconfig = i40e_dcb_need_reconfig(pf, &tmp_dcbx_cfg,
|
|
|
|
+ &hw->local_dcbx_config);
|
|
|
|
|
|
- i40e_dcbnl_flush_apps(pf, dcbx_cfg);
|
|
|
|
|
|
+ i40e_dcbnl_flush_apps(pf, &tmp_dcbx_cfg, &hw->local_dcbx_config);
|
|
|
|
|
|
if (!need_reconfig)
|
|
if (!need_reconfig)
|
|
goto exit;
|
|
goto exit;
|
|
|
|
|
|
/* Enable DCB tagging only when more than one TC */
|
|
/* Enable DCB tagging only when more than one TC */
|
|
- if (i40e_dcb_get_num_tc(dcbx_cfg) > 1)
|
|
|
|
|
|
+ if (i40e_dcb_get_num_tc(&hw->local_dcbx_config) > 1)
|
|
pf->flags |= I40E_FLAG_DCB_ENABLED;
|
|
pf->flags |= I40E_FLAG_DCB_ENABLED;
|
|
else
|
|
else
|
|
pf->flags &= ~I40E_FLAG_DCB_ENABLED;
|
|
pf->flags &= ~I40E_FLAG_DCB_ENABLED;
|
|
@@ -6305,13 +6319,14 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- msleep(75);
|
|
|
|
- ret = i40e_aq_set_link_restart_an(&pf->hw, true, NULL);
|
|
|
|
- if (ret) {
|
|
|
|
- dev_info(&pf->pdev->dev, "link restart failed, aq_err=%d\n",
|
|
|
|
- pf->hw.aq.asq_last_status);
|
|
|
|
|
|
+ if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
|
|
|
|
+ (pf->hw.aq.fw_maj_ver < 4)) {
|
|
|
|
+ msleep(75);
|
|
|
|
+ ret = i40e_aq_set_link_restart_an(&pf->hw, true, NULL);
|
|
|
|
+ if (ret)
|
|
|
|
+ dev_info(&pf->pdev->dev, "link restart failed, aq_err=%d\n",
|
|
|
|
+ pf->hw.aq.asq_last_status);
|
|
}
|
|
}
|
|
-
|
|
|
|
/* reinit the misc interrupt */
|
|
/* reinit the misc interrupt */
|
|
if (pf->flags & I40E_FLAG_MSIX_ENABLED)
|
|
if (pf->flags & I40E_FLAG_MSIX_ENABLED)
|
|
ret = i40e_setup_misc_vector(pf);
|
|
ret = i40e_setup_misc_vector(pf);
|
|
@@ -6698,6 +6713,8 @@ static int i40e_vsi_mem_alloc(struct i40e_pf *pf, enum i40e_vsi_type type)
|
|
vsi->idx = vsi_idx;
|
|
vsi->idx = vsi_idx;
|
|
vsi->rx_itr_setting = pf->rx_itr_default;
|
|
vsi->rx_itr_setting = pf->rx_itr_default;
|
|
vsi->tx_itr_setting = pf->tx_itr_default;
|
|
vsi->tx_itr_setting = pf->tx_itr_default;
|
|
|
|
+ vsi->rss_table_size = (vsi->type == I40E_VSI_MAIN) ?
|
|
|
|
+ pf->rss_table_size : 64;
|
|
vsi->netdev_registered = false;
|
|
vsi->netdev_registered = false;
|
|
vsi->work_limit = I40E_DEFAULT_IRQ_WORK;
|
|
vsi->work_limit = I40E_DEFAULT_IRQ_WORK;
|
|
INIT_LIST_HEAD(&vsi->mac_filter_list);
|
|
INIT_LIST_HEAD(&vsi->mac_filter_list);
|
|
@@ -6921,7 +6938,8 @@ static int i40e_init_msix(struct i40e_pf *pf)
|
|
* If we can't get what we want, we'll simplify to nearly nothing
|
|
* If we can't get what we want, we'll simplify to nearly nothing
|
|
* and try again. If that still fails, we punt.
|
|
* and try again. If that still fails, we punt.
|
|
*/
|
|
*/
|
|
- pf->num_lan_msix = pf->num_lan_qps - (pf->rss_size_max - pf->rss_size);
|
|
|
|
|
|
+ pf->num_lan_msix = min_t(int, num_online_cpus(),
|
|
|
|
+ hw->func_caps.num_msix_vectors);
|
|
pf->num_vmdq_msix = pf->num_vmdq_qps;
|
|
pf->num_vmdq_msix = pf->num_vmdq_qps;
|
|
other_vecs = 1;
|
|
other_vecs = 1;
|
|
other_vecs += (pf->num_vmdq_vsis * pf->num_vmdq_msix);
|
|
other_vecs += (pf->num_vmdq_vsis * pf->num_vmdq_msix);
|
|
@@ -7189,6 +7207,7 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf)
|
|
static int i40e_config_rss(struct i40e_pf *pf)
|
|
static int i40e_config_rss(struct i40e_pf *pf)
|
|
{
|
|
{
|
|
u32 rss_key[I40E_PFQF_HKEY_MAX_INDEX + 1];
|
|
u32 rss_key[I40E_PFQF_HKEY_MAX_INDEX + 1];
|
|
|
|
+ struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
|
|
struct i40e_hw *hw = &pf->hw;
|
|
struct i40e_hw *hw = &pf->hw;
|
|
u32 lut = 0;
|
|
u32 lut = 0;
|
|
int i, j;
|
|
int i, j;
|
|
@@ -7206,6 +7225,8 @@ static int i40e_config_rss(struct i40e_pf *pf)
|
|
wr32(hw, I40E_PFQF_HENA(0), (u32)hena);
|
|
wr32(hw, I40E_PFQF_HENA(0), (u32)hena);
|
|
wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
|
|
wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
|
|
|
|
|
|
|
|
+ vsi->rss_size = min_t(int, pf->rss_size, vsi->num_queue_pairs);
|
|
|
|
+
|
|
/* Check capability and Set table size and register per hw expectation*/
|
|
/* Check capability and Set table size and register per hw expectation*/
|
|
reg_val = rd32(hw, I40E_PFQF_CTL_0);
|
|
reg_val = rd32(hw, I40E_PFQF_CTL_0);
|
|
if (hw->func_caps.rss_table_size == 512) {
|
|
if (hw->func_caps.rss_table_size == 512) {
|
|
@@ -7227,7 +7248,7 @@ static int i40e_config_rss(struct i40e_pf *pf)
|
|
* If LAN VSI is the only consumer for RSS then this requirement
|
|
* If LAN VSI is the only consumer for RSS then this requirement
|
|
* is not necessary.
|
|
* is not necessary.
|
|
*/
|
|
*/
|
|
- if (j == pf->rss_size)
|
|
|
|
|
|
+ if (j == vsi->rss_size)
|
|
j = 0;
|
|
j = 0;
|
|
/* lut = 4-byte sliding window of 4 lut entries */
|
|
/* lut = 4-byte sliding window of 4 lut entries */
|
|
lut = (lut << 8) | (j &
|
|
lut = (lut << 8) | (j &
|
|
@@ -7251,15 +7272,19 @@ static int i40e_config_rss(struct i40e_pf *pf)
|
|
**/
|
|
**/
|
|
int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count)
|
|
int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count)
|
|
{
|
|
{
|
|
|
|
+ struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
|
|
|
|
+ int new_rss_size;
|
|
|
|
+
|
|
if (!(pf->flags & I40E_FLAG_RSS_ENABLED))
|
|
if (!(pf->flags & I40E_FLAG_RSS_ENABLED))
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
- queue_count = min_t(int, queue_count, pf->rss_size_max);
|
|
|
|
|
|
+ new_rss_size = min_t(int, queue_count, pf->rss_size_max);
|
|
|
|
|
|
- if (queue_count != pf->rss_size) {
|
|
|
|
|
|
+ if (queue_count != vsi->num_queue_pairs) {
|
|
|
|
+ vsi->req_queue_pairs = queue_count;
|
|
i40e_prep_for_reset(pf);
|
|
i40e_prep_for_reset(pf);
|
|
|
|
|
|
- pf->rss_size = queue_count;
|
|
|
|
|
|
+ pf->rss_size = new_rss_size;
|
|
|
|
|
|
i40e_reset_and_rebuild(pf, true);
|
|
i40e_reset_and_rebuild(pf, true);
|
|
i40e_config_rss(pf);
|
|
i40e_config_rss(pf);
|
|
@@ -7432,6 +7457,7 @@ static int i40e_sw_init(struct i40e_pf *pf)
|
|
*/
|
|
*/
|
|
pf->rss_size_max = 0x1 << pf->hw.func_caps.rss_table_entry_width;
|
|
pf->rss_size_max = 0x1 << pf->hw.func_caps.rss_table_entry_width;
|
|
pf->rss_size = 1;
|
|
pf->rss_size = 1;
|
|
|
|
+ pf->rss_table_size = pf->hw.func_caps.rss_table_size;
|
|
pf->rss_size_max = min_t(int, pf->rss_size_max,
|
|
pf->rss_size_max = min_t(int, pf->rss_size_max,
|
|
pf->hw.func_caps.num_tx_qp);
|
|
pf->hw.func_caps.num_tx_qp);
|
|
if (pf->hw.func_caps.rss) {
|
|
if (pf->hw.func_caps.rss) {
|
|
@@ -9258,7 +9284,11 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
|
|
pf->flags &= ~I40E_FLAG_DCB_CAPABLE;
|
|
pf->flags &= ~I40E_FLAG_DCB_CAPABLE;
|
|
dev_info(&pf->pdev->dev, "not enough queues for DCB. DCB is disabled.\n");
|
|
dev_info(&pf->pdev->dev, "not enough queues for DCB. DCB is disabled.\n");
|
|
}
|
|
}
|
|
- pf->num_lan_qps = pf->rss_size_max;
|
|
|
|
|
|
+ pf->num_lan_qps = max_t(int, pf->rss_size_max,
|
|
|
|
+ num_online_cpus());
|
|
|
|
+ pf->num_lan_qps = min_t(int, pf->num_lan_qps,
|
|
|
|
+ pf->hw.func_caps.num_tx_qp);
|
|
|
|
+
|
|
queues_left -= pf->num_lan_qps;
|
|
queues_left -= pf->num_lan_qps;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -9662,13 +9692,14 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
if (err)
|
|
if (err)
|
|
dev_info(&pf->pdev->dev, "set phy mask fail, aq_err %d\n", err);
|
|
dev_info(&pf->pdev->dev, "set phy mask fail, aq_err %d\n", err);
|
|
|
|
|
|
- msleep(75);
|
|
|
|
- err = i40e_aq_set_link_restart_an(&pf->hw, true, NULL);
|
|
|
|
- if (err) {
|
|
|
|
- dev_info(&pf->pdev->dev, "link restart failed, aq_err=%d\n",
|
|
|
|
- pf->hw.aq.asq_last_status);
|
|
|
|
|
|
+ if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
|
|
|
|
+ (pf->hw.aq.fw_maj_ver < 4)) {
|
|
|
|
+ msleep(75);
|
|
|
|
+ err = i40e_aq_set_link_restart_an(&pf->hw, true, NULL);
|
|
|
|
+ if (err)
|
|
|
|
+ dev_info(&pf->pdev->dev, "link restart failed, aq_err=%d\n",
|
|
|
|
+ pf->hw.aq.asq_last_status);
|
|
}
|
|
}
|
|
-
|
|
|
|
/* The main driver is (mostly) up and happy. We need to set this state
|
|
/* The main driver is (mostly) up and happy. We need to set this state
|
|
* before setting up the misc vector or we get a race and the vector
|
|
* before setting up the misc vector or we get a race and the vector
|
|
* ends up disabled forever.
|
|
* ends up disabled forever.
|