Commit 6f30e8b0 authored by David S. Miller's avatar David S. Miller

Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2016-06-27

This series contains updates to i40e and i40evf only.

Mitch provides several changes, first adds functions to enable and disable
VSI on a VEB, which allows for configuration of limited promiscuous mode
specifically for bridging purposes.  Sets the RSS Hash Enable registers by
default now that VF RSS is configured by the PF driver.  Fixed a issue
where we could overflow the buffer, by checking the address count and bail
out of the loop at the appropriate time.  Removed the need for a reset
when the device enters limited promiscuous mode, since this was causing
heartburn for people who were using VFs and bridging.

Catherine adds a call to set the client interface down when we put the VSI
down.  Fixed an issue where RSS queues was being limited to the number
of CPUs, so if a user wants to use more queues than CPUs, we want to
trust they know what they are doing and let them.

Greg cleans up the driver suspend routine to ensure we are calling
synchronize_irq() before freeing IRQ vectors and explicitly free the other
causes interrupt resources and shut down the MSIX interrupt.

Serey fixes i40e_set_settings() to not fail when a Direct Attach (DA)
cable is used.

Avinash fixes a supported link bug by removing code which was not allowing
100BaseT to show up in the supported link modes for 10GBaseT PHYs.

Shannon adds a bit of information to the error messages to help determine
the source of error by adding VSI info to macaddr messages.

Tushar Dave fixes error received when turning off TSO on some systems,
which was caused by enabling FD_SB without checking availability of
MSIx vectors, so add the check.

Neerav fixes a possible panic when LLDP/DCBX change happens and the
driver tried to notify the client(s) for each of the PF VSIs, which would
panic when it reached a VSI that did not have any netdev associated with
it.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cb90d3e1 85a1aab7
...@@ -283,6 +283,7 @@ struct i40e_pf { ...@@ -283,6 +283,7 @@ struct i40e_pf {
#endif /* I40E_FCOE */ #endif /* I40E_FCOE */
u16 num_lan_qps; /* num lan queues this PF has set up */ u16 num_lan_qps; /* num lan queues this PF has set up */
u16 num_lan_msix; /* num queue vectors for the base PF vsi */ u16 num_lan_msix; /* num queue vectors for the base PF vsi */
u16 num_fdsb_msix; /* num queue vectors for sideband Fdir */
u16 num_iwarp_msix; /* num of iwarp vectors for this PF */ u16 num_iwarp_msix; /* num of iwarp vectors for this PF */
int iwarp_base_vector; int iwarp_base_vector;
int queues_left; /* queues left unclaimed */ int queues_left; /* queues left unclaimed */
......
...@@ -1966,6 +1966,62 @@ i40e_status i40e_aq_add_vsi(struct i40e_hw *hw, ...@@ -1966,6 +1966,62 @@ i40e_status i40e_aq_add_vsi(struct i40e_hw *hw,
return status; return status;
} }
/**
* i40e_aq_set_default_vsi
* @hw: pointer to the hw struct
* @seid: vsi number
* @cmd_details: pointer to command details structure or NULL
**/
i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw,
u16 seid,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
(struct i40e_aqc_set_vsi_promiscuous_modes *)
&desc.params.raw;
i40e_status status;
i40e_fill_default_direct_cmd_desc(&desc,
i40e_aqc_opc_set_vsi_promiscuous_modes);
cmd->promiscuous_flags = cpu_to_le16(I40E_AQC_SET_VSI_DEFAULT);
cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_DEFAULT);
cmd->seid = cpu_to_le16(seid);
status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
return status;
}
/**
* i40e_aq_clear_default_vsi
* @hw: pointer to the hw struct
* @seid: vsi number
* @cmd_details: pointer to command details structure or NULL
**/
i40e_status i40e_aq_clear_default_vsi(struct i40e_hw *hw,
u16 seid,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
(struct i40e_aqc_set_vsi_promiscuous_modes *)
&desc.params.raw;
i40e_status status;
i40e_fill_default_direct_cmd_desc(&desc,
i40e_aqc_opc_set_vsi_promiscuous_modes);
cmd->promiscuous_flags = cpu_to_le16(0);
cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_DEFAULT);
cmd->seid = cpu_to_le16(seid);
status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
return status;
}
/** /**
* i40e_aq_set_vsi_unicast_promiscuous * i40e_aq_set_vsi_unicast_promiscuous
* @hw: pointer to the hw struct * @hw: pointer to the hw struct
......
...@@ -313,8 +313,7 @@ static void i40e_phy_type_to_ethtool(struct i40e_pf *pf, u32 *supported, ...@@ -313,8 +313,7 @@ static void i40e_phy_type_to_ethtool(struct i40e_pf *pf, u32 *supported,
*advertising |= ADVERTISED_Autoneg | *advertising |= ADVERTISED_Autoneg |
ADVERTISED_40000baseCR4_Full; ADVERTISED_40000baseCR4_Full;
} }
if ((phy_types & I40E_CAP_PHY_TYPE_100BASE_TX) && if (phy_types & I40E_CAP_PHY_TYPE_100BASE_TX) {
!(phy_types & I40E_CAP_PHY_TYPE_1000BASE_T)) {
*supported |= SUPPORTED_Autoneg | *supported |= SUPPORTED_Autoneg |
SUPPORTED_100baseT_Full; SUPPORTED_100baseT_Full;
*advertising |= ADVERTISED_Autoneg | *advertising |= ADVERTISED_Autoneg |
...@@ -663,6 +662,7 @@ static int i40e_set_settings(struct net_device *netdev, ...@@ -663,6 +662,7 @@ static int i40e_set_settings(struct net_device *netdev,
if (hw->phy.media_type != I40E_MEDIA_TYPE_BASET && if (hw->phy.media_type != I40E_MEDIA_TYPE_BASET &&
hw->phy.media_type != I40E_MEDIA_TYPE_FIBER && hw->phy.media_type != I40E_MEDIA_TYPE_FIBER &&
hw->phy.media_type != I40E_MEDIA_TYPE_BACKPLANE && hw->phy.media_type != I40E_MEDIA_TYPE_BACKPLANE &&
hw->phy.media_type != I40E_MEDIA_TYPE_DA &&
hw->phy.link_info.link_info & I40E_AQ_LINK_UP) hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
return -EOPNOTSUPP; return -EOPNOTSUPP;
......
...@@ -40,8 +40,8 @@ static const char i40e_driver_string[] = ...@@ -40,8 +40,8 @@ static const char i40e_driver_string[] =
#define DRV_KERN "-k" #define DRV_KERN "-k"
#define DRV_VERSION_MAJOR 1 #define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 5 #define DRV_VERSION_MINOR 6
#define DRV_VERSION_BUILD 16 #define DRV_VERSION_BUILD 4
#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
...@@ -1579,14 +1579,8 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi, ...@@ -1579,14 +1579,8 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
vsi->tc_config.numtc = numtc; vsi->tc_config.numtc = numtc;
vsi->tc_config.enabled_tc = enabled_tc ? enabled_tc : 1; vsi->tc_config.enabled_tc = enabled_tc ? enabled_tc : 1;
/* Number of queues per enabled TC */ /* Number of queues per enabled TC */
/* In MFP case we can have a much lower count of MSIx qcount = vsi->alloc_queue_pairs;
* vectors available and so we need to lower the used
* q count.
*/
if (pf->flags & I40E_FLAG_MSIX_ENABLED)
qcount = min_t(int, vsi->alloc_queue_pairs, pf->num_lan_msix);
else
qcount = vsi->alloc_queue_pairs;
num_tc_qps = qcount / numtc; num_tc_qps = qcount / numtc;
num_tc_qps = min_t(int, num_tc_qps, i40e_pf_get_max_q_per_tc(pf)); num_tc_qps = min_t(int, num_tc_qps, i40e_pf_get_max_q_per_tc(pf));
...@@ -1840,8 +1834,10 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -1840,8 +1834,10 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
{ {
struct list_head tmp_del_list, tmp_add_list; struct list_head tmp_del_list, tmp_add_list;
struct i40e_mac_filter *f, *ftmp, *fclone; struct i40e_mac_filter *f, *ftmp, *fclone;
struct i40e_hw *hw = &vsi->back->hw;
bool promisc_forced_on = false; bool promisc_forced_on = false;
bool add_happened = false; bool add_happened = false;
char vsi_name[16] = "PF";
int filter_list_len = 0; int filter_list_len = 0;
u32 changed_flags = 0; u32 changed_flags = 0;
i40e_status aq_ret = 0; i40e_status aq_ret = 0;
...@@ -1869,6 +1865,11 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -1869,6 +1865,11 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
INIT_LIST_HEAD(&tmp_del_list); INIT_LIST_HEAD(&tmp_del_list);
INIT_LIST_HEAD(&tmp_add_list); INIT_LIST_HEAD(&tmp_add_list);
if (vsi->type == I40E_VSI_SRIOV)
snprintf(vsi_name, sizeof(vsi_name) - 1, "VF %d", vsi->vf_id);
else if (vsi->type != I40E_VSI_MAIN)
snprintf(vsi_name, sizeof(vsi_name) - 1, "vsi %d", vsi->seid);
if (vsi->flags & I40E_VSI_FLAG_FILTER_CHANGED) { if (vsi->flags & I40E_VSI_FLAG_FILTER_CHANGED) {
vsi->flags &= ~I40E_VSI_FLAG_FILTER_CHANGED; vsi->flags &= ~I40E_VSI_FLAG_FILTER_CHANGED;
...@@ -1920,7 +1921,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -1920,7 +1921,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
if (!list_empty(&tmp_del_list)) { if (!list_empty(&tmp_del_list)) {
int del_list_size; int del_list_size;
filter_list_len = pf->hw.aq.asq_buf_size / filter_list_len = hw->aq.asq_buf_size /
sizeof(struct i40e_aqc_remove_macvlan_element_data); sizeof(struct i40e_aqc_remove_macvlan_element_data);
del_list_size = filter_list_len * del_list_size = filter_list_len *
sizeof(struct i40e_aqc_remove_macvlan_element_data); sizeof(struct i40e_aqc_remove_macvlan_element_data);
...@@ -1952,21 +1953,21 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -1952,21 +1953,21 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
/* flush a full buffer */ /* flush a full buffer */
if (num_del == filter_list_len) { if (num_del == filter_list_len) {
aq_ret = i40e_aq_remove_macvlan(&pf->hw, aq_ret =
vsi->seid, i40e_aq_remove_macvlan(hw, vsi->seid,
del_list, del_list,
num_del, num_del, NULL);
NULL); aq_err = hw->aq.asq_last_status;
aq_err = pf->hw.aq.asq_last_status;
num_del = 0; num_del = 0;
memset(del_list, 0, del_list_size); memset(del_list, 0, del_list_size);
if (aq_ret && aq_err != I40E_AQ_RC_ENOENT) { if (aq_ret && aq_err != I40E_AQ_RC_ENOENT) {
retval = -EIO; retval = -EIO;
dev_err(&pf->pdev->dev, dev_err(&pf->pdev->dev,
"ignoring delete macvlan error, err %s, aq_err %s while flushing a full buffer\n", "ignoring delete macvlan error on %s, err %s, aq_err %s while flushing a full buffer\n",
i40e_stat_str(&pf->hw, aq_ret), vsi_name,
i40e_aq_str(&pf->hw, aq_err)); i40e_stat_str(hw, aq_ret),
i40e_aq_str(hw, aq_err));
} }
} }
/* Release memory for MAC filter entries which were /* Release memory for MAC filter entries which were
...@@ -1977,17 +1978,17 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -1977,17 +1978,17 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
} }
if (num_del) { if (num_del) {
aq_ret = i40e_aq_remove_macvlan(&pf->hw, vsi->seid, aq_ret = i40e_aq_remove_macvlan(hw, vsi->seid, del_list,
del_list, num_del, num_del, NULL);
NULL); aq_err = hw->aq.asq_last_status;
aq_err = pf->hw.aq.asq_last_status;
num_del = 0; num_del = 0;
if (aq_ret && aq_err != I40E_AQ_RC_ENOENT) if (aq_ret && aq_err != I40E_AQ_RC_ENOENT)
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"ignoring delete macvlan error, err %s aq_err %s\n", "ignoring delete macvlan error on %s, err %s aq_err %s\n",
i40e_stat_str(&pf->hw, aq_ret), vsi_name,
i40e_aq_str(&pf->hw, aq_err)); i40e_stat_str(hw, aq_ret),
i40e_aq_str(hw, aq_err));
} }
kfree(del_list); kfree(del_list);
...@@ -1998,7 +1999,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -1998,7 +1999,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
int add_list_size; int add_list_size;
/* do all the adds now */ /* do all the adds now */
filter_list_len = pf->hw.aq.asq_buf_size / filter_list_len = hw->aq.asq_buf_size /
sizeof(struct i40e_aqc_add_macvlan_element_data), sizeof(struct i40e_aqc_add_macvlan_element_data),
add_list_size = filter_list_len * add_list_size = filter_list_len *
sizeof(struct i40e_aqc_add_macvlan_element_data); sizeof(struct i40e_aqc_add_macvlan_element_data);
...@@ -2033,10 +2034,10 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -2033,10 +2034,10 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
/* flush a full buffer */ /* flush a full buffer */
if (num_add == filter_list_len) { if (num_add == filter_list_len) {
aq_ret = i40e_aq_add_macvlan(&pf->hw, vsi->seid, aq_ret = i40e_aq_add_macvlan(hw, vsi->seid,
add_list, num_add, add_list, num_add,
NULL); NULL);
aq_err = pf->hw.aq.asq_last_status; aq_err = hw->aq.asq_last_status;
num_add = 0; num_add = 0;
if (aq_ret) if (aq_ret)
...@@ -2051,9 +2052,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -2051,9 +2052,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
} }
if (num_add) { if (num_add) {
aq_ret = i40e_aq_add_macvlan(&pf->hw, vsi->seid, aq_ret = i40e_aq_add_macvlan(hw, vsi->seid,
add_list, num_add, NULL); add_list, num_add, NULL);
aq_err = pf->hw.aq.asq_last_status; aq_err = hw->aq.asq_last_status;
num_add = 0; num_add = 0;
} }
kfree(add_list); kfree(add_list);
...@@ -2062,16 +2063,18 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -2062,16 +2063,18 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
if (add_happened && aq_ret && aq_err != I40E_AQ_RC_EINVAL) { if (add_happened && aq_ret && aq_err != I40E_AQ_RC_EINVAL) {
retval = i40e_aq_rc_to_posix(aq_ret, aq_err); retval = i40e_aq_rc_to_posix(aq_ret, aq_err);
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"add filter failed, err %s aq_err %s\n", "add filter failed on %s, err %s aq_err %s\n",
i40e_stat_str(&pf->hw, aq_ret), vsi_name,
i40e_aq_str(&pf->hw, aq_err)); i40e_stat_str(hw, aq_ret),
if ((pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOSPC) && i40e_aq_str(hw, aq_err));
if ((hw->aq.asq_last_status == I40E_AQ_RC_ENOSPC) &&
!test_bit(__I40E_FILTER_OVERFLOW_PROMISC, !test_bit(__I40E_FILTER_OVERFLOW_PROMISC,
&vsi->state)) { &vsi->state)) {
promisc_forced_on = true; promisc_forced_on = true;
set_bit(__I40E_FILTER_OVERFLOW_PROMISC, set_bit(__I40E_FILTER_OVERFLOW_PROMISC,
&vsi->state); &vsi->state);
dev_info(&pf->pdev->dev, "promiscuous mode forced on\n"); dev_info(&pf->pdev->dev, "promiscuous mode forced on %s\n",
vsi_name);
} }
} }
} }
...@@ -2093,12 +2096,12 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -2093,12 +2096,12 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
NULL); NULL);
if (aq_ret) { if (aq_ret) {
retval = i40e_aq_rc_to_posix(aq_ret, retval = i40e_aq_rc_to_posix(aq_ret,
pf->hw.aq.asq_last_status); hw->aq.asq_last_status);
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"set multi promisc failed, err %s aq_err %s\n", "set multi promisc failed on %s, err %s aq_err %s\n",
i40e_stat_str(&pf->hw, aq_ret), vsi_name,
i40e_aq_str(&pf->hw, i40e_stat_str(hw, aq_ret),
pf->hw.aq.asq_last_status)); i40e_aq_str(hw, hw->aq.asq_last_status));
} }
} }
if ((changed_flags & IFF_PROMISC) || promisc_forced_on) { if ((changed_flags & IFF_PROMISC) || promisc_forced_on) {
...@@ -2117,33 +2120,58 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -2117,33 +2120,58 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
*/ */
if (pf->cur_promisc != cur_promisc) { if (pf->cur_promisc != cur_promisc) {
pf->cur_promisc = cur_promisc; pf->cur_promisc = cur_promisc;
set_bit(__I40E_PF_RESET_REQUESTED, &pf->state); if (cur_promisc)
aq_ret =
i40e_aq_set_default_vsi(hw,
vsi->seid,
NULL);
else
aq_ret =
i40e_aq_clear_default_vsi(hw,
vsi->seid,
NULL);
if (aq_ret) {
retval = i40e_aq_rc_to_posix(aq_ret,
hw->aq.asq_last_status);
dev_info(&pf->pdev->dev,
"Set default VSI failed on %s, err %s, aq_err %s\n",
vsi_name,
i40e_stat_str(hw, aq_ret),
i40e_aq_str(hw,
hw->aq.asq_last_status));
}
} }
} else { } else {
aq_ret = i40e_aq_set_vsi_unicast_promiscuous( aq_ret = i40e_aq_set_vsi_unicast_promiscuous(
&vsi->back->hw, hw,
vsi->seid, vsi->seid,
cur_promisc, NULL, cur_promisc, NULL,
true); true);
if (aq_ret) { if (aq_ret) {
retval = retval =
i40e_aq_rc_to_posix(aq_ret, i40e_aq_rc_to_posix(aq_ret,
pf->hw.aq.asq_last_status); hw->aq.asq_last_status);
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"set unicast promisc failed, err %d, aq_err %d\n", "set unicast promisc failed on %s, err %s, aq_err %s\n",
aq_ret, pf->hw.aq.asq_last_status); vsi_name,
i40e_stat_str(hw, aq_ret),
i40e_aq_str(hw,
hw->aq.asq_last_status));
} }
aq_ret = i40e_aq_set_vsi_multicast_promiscuous( aq_ret = i40e_aq_set_vsi_multicast_promiscuous(
&vsi->back->hw, hw,
vsi->seid, vsi->seid,
cur_promisc, NULL); cur_promisc, NULL);
if (aq_ret) { if (aq_ret) {
retval = retval =
i40e_aq_rc_to_posix(aq_ret, i40e_aq_rc_to_posix(aq_ret,
pf->hw.aq.asq_last_status); hw->aq.asq_last_status);
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"set multicast promisc failed, err %d, aq_err %d\n", "set multicast promisc failed on %s, err %s, aq_err %s\n",
aq_ret, pf->hw.aq.asq_last_status); vsi_name,
i40e_stat_str(hw, aq_ret),
i40e_aq_str(hw,
hw->aq.asq_last_status));
} }
} }
aq_ret = i40e_aq_set_vsi_broadcast(&vsi->back->hw, aq_ret = i40e_aq_set_vsi_broadcast(&vsi->back->hw,
...@@ -2154,9 +2182,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) ...@@ -2154,9 +2182,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
pf->hw.aq.asq_last_status); pf->hw.aq.asq_last_status);
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"set brdcast promisc failed, err %s, aq_err %s\n", "set brdcast promisc failed, err %s, aq_err %s\n",
i40e_stat_str(&pf->hw, aq_ret), i40e_stat_str(hw, aq_ret),
i40e_aq_str(&pf->hw, i40e_aq_str(hw,
pf->hw.aq.asq_last_status)); hw->aq.asq_last_status));
} }
} }
out: out:
...@@ -3947,6 +3975,7 @@ static void i40e_vsi_free_irq(struct i40e_vsi *vsi) ...@@ -3947,6 +3975,7 @@ static void i40e_vsi_free_irq(struct i40e_vsi *vsi)
/* clear the affinity_mask in the IRQ descriptor */ /* clear the affinity_mask in the IRQ descriptor */
irq_set_affinity_hint(pf->msix_entries[vector].vector, irq_set_affinity_hint(pf->msix_entries[vector].vector,
NULL); NULL);
synchronize_irq(pf->msix_entries[vector].vector);
free_irq(pf->msix_entries[vector].vector, free_irq(pf->msix_entries[vector].vector,
vsi->q_vectors[i]); vsi->q_vectors[i]);
...@@ -4953,7 +4982,6 @@ static void i40e_dcb_reconfigure(struct i40e_pf *pf) ...@@ -4953,7 +4982,6 @@ static void i40e_dcb_reconfigure(struct i40e_pf *pf)
if (pf->vsi[v]->netdev) if (pf->vsi[v]->netdev)
i40e_dcbnl_set_all(pf->vsi[v]); i40e_dcbnl_set_all(pf->vsi[v]);
} }
i40e_notify_client_of_l2_param_changes(pf->vsi[v]);
} }
} }
...@@ -5178,12 +5206,6 @@ static void i40e_vsi_reinit_locked(struct i40e_vsi *vsi) ...@@ -5178,12 +5206,6 @@ static void i40e_vsi_reinit_locked(struct i40e_vsi *vsi)
usleep_range(1000, 2000); usleep_range(1000, 2000);
i40e_down(vsi); i40e_down(vsi);
/* Give a VF some time to respond to the reset. The
* two second wait is based upon the watchdog cycle in
* the VF driver.
*/
if (vsi->type == I40E_VSI_SRIOV)
msleep(2000);
i40e_up(vsi); i40e_up(vsi);
clear_bit(__I40E_CONFIG_BUSY, &pf->state); clear_bit(__I40E_CONFIG_BUSY, &pf->state);
} }
...@@ -5226,6 +5248,9 @@ void i40e_down(struct i40e_vsi *vsi) ...@@ -5226,6 +5248,9 @@ void i40e_down(struct i40e_vsi *vsi)
i40e_clean_tx_ring(vsi->tx_rings[i]); i40e_clean_tx_ring(vsi->tx_rings[i]);
i40e_clean_rx_ring(vsi->rx_rings[i]); i40e_clean_rx_ring(vsi->rx_rings[i]);
} }
i40e_notify_client_of_netdev_close(vsi, false);
} }
/** /**
...@@ -5704,6 +5729,8 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf, ...@@ -5704,6 +5729,8 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf,
i40e_service_event_schedule(pf); i40e_service_event_schedule(pf);
} else { } else {
i40e_pf_unquiesce_all_vsi(pf); i40e_pf_unquiesce_all_vsi(pf);
/* Notify the client for the DCB changes */
i40e_notify_client_of_l2_param_changes(pf->vsi[pf->lan_vsi]);
} }
exit: exit:
...@@ -5928,7 +5955,6 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf) ...@@ -5928,7 +5955,6 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
if (I40E_DEBUG_FD & pf->hw.debug_mask) if (I40E_DEBUG_FD & pf->hw.debug_mask)
dev_info(&pf->pdev->dev, "FD Filter table flushed and FD-SB replayed.\n"); dev_info(&pf->pdev->dev, "FD Filter table flushed and FD-SB replayed.\n");
} }
} }
/** /**
...@@ -7160,7 +7186,7 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi) ...@@ -7160,7 +7186,7 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)
vsi->alloc_queue_pairs = 1; vsi->alloc_queue_pairs = 1;
vsi->num_desc = ALIGN(I40E_FDIR_RING_COUNT, vsi->num_desc = ALIGN(I40E_FDIR_RING_COUNT,
I40E_REQ_DESCRIPTOR_MULTIPLE); I40E_REQ_DESCRIPTOR_MULTIPLE);
vsi->num_q_vectors = 1; vsi->num_q_vectors = pf->num_fdsb_msix;
break; break;
case I40E_VSI_VMDQ2: case I40E_VSI_VMDQ2:
...@@ -7544,9 +7570,11 @@ static int i40e_init_msix(struct i40e_pf *pf) ...@@ -7544,9 +7570,11 @@ static int i40e_init_msix(struct i40e_pf *pf)
/* reserve one vector for sideband flow director */ /* reserve one vector for sideband flow director */
if (pf->flags & I40E_FLAG_FD_SB_ENABLED) { if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
if (vectors_left) { if (vectors_left) {
pf->num_fdsb_msix = 1;
v_budget++; v_budget++;
vectors_left--; vectors_left--;
} else { } else {
pf->num_fdsb_msix = 0;
pf->flags &= ~I40E_FLAG_FD_SB_ENABLED; pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
} }
} }
...@@ -8565,7 +8593,9 @@ bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features) ...@@ -8565,7 +8593,9 @@ bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features)
/* Enable filters and mark for reset */ /* Enable filters and mark for reset */
if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED)) if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED))
need_reset = true; need_reset = true;
pf->flags |= I40E_FLAG_FD_SB_ENABLED; /* enable FD_SB only if there is MSI-X vector */
if (pf->num_fdsb_msix > 0)
pf->flags |= I40E_FLAG_FD_SB_ENABLED;
} else { } else {
/* turn off filters, mark for reset and clear SW filter list */ /* turn off filters, mark for reset and clear SW filter list */
if (pf->flags & I40E_FLAG_FD_SB_ENABLED) { if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
...@@ -10053,14 +10083,14 @@ void i40e_veb_release(struct i40e_veb *veb) ...@@ -10053,14 +10083,14 @@ void i40e_veb_release(struct i40e_veb *veb)
static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi) static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi)
{ {
struct i40e_pf *pf = veb->pf; struct i40e_pf *pf = veb->pf;
bool is_default = veb->pf->cur_promisc;
bool enable_stats = !!(pf->flags & I40E_FLAG_VEB_STATS_ENABLED); bool enable_stats = !!(pf->flags & I40E_FLAG_VEB_STATS_ENABLED);
int ret; int ret;
/* get a VEB from the hardware */
ret = i40e_aq_add_veb(&pf->hw, veb->uplink_seid, vsi->seid, ret = i40e_aq_add_veb(&pf->hw, veb->uplink_seid, vsi->seid,
veb->enabled_tc, is_default, veb->enabled_tc, false,
&veb->seid, enable_stats, NULL); &veb->seid, enable_stats, NULL);
/* get a VEB from the hardware */
if (ret) { if (ret) {
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"couldn't add VEB, err %s aq_err %s\n", "couldn't add VEB, err %s aq_err %s\n",
...@@ -11441,6 +11471,7 @@ static int i40e_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -11441,6 +11471,7 @@ static int i40e_suspend(struct pci_dev *pdev, pm_message_t state)
{ {
struct i40e_pf *pf = pci_get_drvdata(pdev); struct i40e_pf *pf = pci_get_drvdata(pdev);
struct i40e_hw *hw = &pf->hw; struct i40e_hw *hw = &pf->hw;
int retval = 0;
set_bit(__I40E_SUSPENDED, &pf->state); set_bit(__I40E_SUSPENDED, &pf->state);
set_bit(__I40E_DOWN, &pf->state); set_bit(__I40E_DOWN, &pf->state);
...@@ -11452,10 +11483,16 @@ static int i40e_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -11452,10 +11483,16 @@ static int i40e_suspend(struct pci_dev *pdev, pm_message_t state)
wr32(hw, I40E_PFPM_APM, (pf->wol_en ? I40E_PFPM_APM_APME_MASK : 0)); wr32(hw, I40E_PFPM_APM, (pf->wol_en ? I40E_PFPM_APM_APME_MASK : 0));
wr32(hw, I40E_PFPM_WUFC, (pf->wol_en ? I40E_PFPM_WUFC_MAG_MASK : 0)); wr32(hw, I40E_PFPM_WUFC, (pf->wol_en ? I40E_PFPM_WUFC_MAG_MASK : 0));
i40e_stop_misc_vector(pf);
retval = pci_save_state(pdev);
if (retval)
return retval;
pci_wake_from_d3(pdev, pf->wol_en); pci_wake_from_d3(pdev, pf->wol_en);
pci_set_power_state(pdev, PCI_D3hot); pci_set_power_state(pdev, PCI_D3hot);
return 0; return retval;
} }
/** /**
......
...@@ -98,6 +98,8 @@ i40e_status i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags, ...@@ -98,6 +98,8 @@ i40e_status i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
struct i40e_asq_cmd_details *cmd_details); struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw, u16 vsi_id, i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw, u16 vsi_id,
struct i40e_asq_cmd_details *cmd_details); struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_clear_default_vsi(struct i40e_hw *hw, u16 vsi_id,
struct i40e_asq_cmd_details *cmd_details);
enum i40e_status_code i40e_aq_get_phy_capabilities(struct i40e_hw *hw, enum i40e_status_code i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
bool qualified_modules, bool report_init, bool qualified_modules, bool report_init,
struct i40e_aq_get_phy_abilities_resp *abilities, struct i40e_aq_get_phy_abilities_resp *abilities,
......
...@@ -665,6 +665,8 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type) ...@@ -665,6 +665,8 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
goto error_alloc_vsi_res; goto error_alloc_vsi_res;
} }
if (type == I40E_VSI_SRIOV) { if (type == I40E_VSI_SRIOV) {
u64 hena = i40e_pf_get_default_rss_hena(pf);
vf->lan_vsi_idx = vsi->idx; vf->lan_vsi_idx = vsi->idx;
vf->lan_vsi_id = vsi->id; vf->lan_vsi_id = vsi->id;
/* If the port VLAN has been configured and then the /* If the port VLAN has been configured and then the
...@@ -687,6 +689,10 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type) ...@@ -687,6 +689,10 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
vf->default_lan_addr.addr, vf->vf_id); vf->default_lan_addr.addr, vf->vf_id);
} }
spin_unlock_bh(&vsi->mac_filter_list_lock); spin_unlock_bh(&vsi->mac_filter_list_lock);
i40e_write_rx_ctl(&pf->hw, I40E_VFQF_HENA1(0, vf->vf_id),
(u32)hena);
i40e_write_rx_ctl(&pf->hw, I40E_VFQF_HENA1(1, vf->vf_id),
(u32)(hena >> 32));
} }
/* program mac filter */ /* program mac filter */
......
...@@ -37,8 +37,8 @@ static const char i40evf_driver_string[] = ...@@ -37,8 +37,8 @@ static const char i40evf_driver_string[] =
#define DRV_KERN "-k" #define DRV_KERN "-k"
#define DRV_VERSION_MAJOR 1 #define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 5 #define DRV_VERSION_MINOR 6
#define DRV_VERSION_BUILD 10 #define DRV_VERSION_BUILD 4
#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) \ __stringify(DRV_VERSION_BUILD) \
...@@ -825,7 +825,7 @@ i40evf_mac_filter *i40evf_add_filter(struct i40evf_adapter *adapter, ...@@ -825,7 +825,7 @@ i40evf_mac_filter *i40evf_add_filter(struct i40evf_adapter *adapter,
ether_addr_copy(f->macaddr, macaddr); ether_addr_copy(f->macaddr, macaddr);
list_add(&f->list, &adapter->mac_filter_list); list_add_tail(&f->list, &adapter->mac_filter_list);
f->add = true; f->add = true;
adapter->aq_required |= I40EVF_FLAG_AQ_ADD_MAC_FILTER; adapter->aq_required |= I40EVF_FLAG_AQ_ADD_MAC_FILTER;
} }
......
...@@ -434,6 +434,8 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter) ...@@ -434,6 +434,8 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter)
ether_addr_copy(veal->list[i].addr, f->macaddr); ether_addr_copy(veal->list[i].addr, f->macaddr);
i++; i++;
f->add = false; f->add = false;
if (i == count)
break;
} }
} }
if (!more) if (!more)
...@@ -497,6 +499,8 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter) ...@@ -497,6 +499,8 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter)
i++; i++;
list_del(&f->list); list_del(&f->list);
kfree(f); kfree(f);
if (i == count)
break;
} }
} }
if (!more) if (!more)
...@@ -560,6 +564,8 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter) ...@@ -560,6 +564,8 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter)
vvfl->vlan_id[i] = f->vlan; vvfl->vlan_id[i] = f->vlan;
i++; i++;
f->add = false; f->add = false;
if (i == count)
break;
} }
} }
if (!more) if (!more)
...@@ -623,6 +629,8 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter) ...@@ -623,6 +629,8 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter)
i++; i++;
list_del(&f->list); list_del(&f->list);
kfree(f); kfree(f);
if (i == count)
break;
} }
} }
if (!more) if (!more)
......
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