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

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

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2020-02-19

This series contains fixes to the ice driver.

Brett fixes an issue where if a user sets an odd [tx|rx]-usecs value
through ethtool, the request is denied because the hardware is set to
have an ITR with 2us granularity.  Also fix an issue where the VF has
not been completely removed/reset after being unbound from the host
driver, so resolve this by waiting for the VF remove/reset process to
happen before checking if the VF is disabled.

Michal fixes an issue, where when the user changes flow control via
ethtool, the OS is told the link is going down when that may not be the
case.  Before the fix, the only way to get out of this state was to take
the interface down and up again.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 303d0403 c54d209c
...@@ -2936,13 +2936,6 @@ ice_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) ...@@ -2936,13 +2936,6 @@ ice_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
else else
return -EINVAL; return -EINVAL;
/* Tell the OS link is going down, the link will go back up when fw
* says it is ready asynchronously
*/
ice_print_link_msg(vsi, false);
netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev);
/* Set the FC mode and only restart AN if link is up */ /* Set the FC mode and only restart AN if link is up */
status = ice_set_fc(pi, &aq_failures, link_up); status = ice_set_fc(pi, &aq_failures, link_up);
...@@ -3489,21 +3482,13 @@ ice_set_rc_coalesce(enum ice_container_type c_type, struct ethtool_coalesce *ec, ...@@ -3489,21 +3482,13 @@ ice_set_rc_coalesce(enum ice_container_type c_type, struct ethtool_coalesce *ec,
return -EINVAL; return -EINVAL;
} }
/* hardware only supports an ITR granularity of 2us */
if (coalesce_usecs % 2 != 0) {
netdev_info(vsi->netdev, "Invalid value, %s-usecs must be even\n",
c_type_str);
return -EINVAL;
}
if (use_adaptive_coalesce) { if (use_adaptive_coalesce) {
rc->itr_setting |= ICE_ITR_DYNAMIC; rc->itr_setting |= ICE_ITR_DYNAMIC;
} else { } else {
/* store user facing value how it was set */ /* save the user set usecs */
rc->itr_setting = coalesce_usecs; rc->itr_setting = coalesce_usecs;
/* set to static and convert to value HW understands */ /* device ITR granularity is in 2 usec increments */
rc->target_itr = rc->target_itr = ITR_REG_ALIGN(rc->itr_setting);
ITR_TO_REG(ITR_REG_ALIGN(rc->itr_setting));
} }
return 0; return 0;
...@@ -3596,6 +3581,30 @@ ice_is_coalesce_param_invalid(struct net_device *netdev, ...@@ -3596,6 +3581,30 @@ ice_is_coalesce_param_invalid(struct net_device *netdev,
return 0; return 0;
} }
/**
* ice_print_if_odd_usecs - print message if user tries to set odd [tx|rx]-usecs
* @netdev: netdev used for print
* @itr_setting: previous user setting
* @use_adaptive_coalesce: if adaptive coalesce is enabled or being enabled
* @coalesce_usecs: requested value of [tx|rx]-usecs
* @c_type_str: either "rx" or "tx" to match user set field of [tx|rx]-usecs
*/
static void
ice_print_if_odd_usecs(struct net_device *netdev, u16 itr_setting,
u32 use_adaptive_coalesce, u32 coalesce_usecs,
const char *c_type_str)
{
if (use_adaptive_coalesce)
return;
itr_setting = ITR_TO_REG(itr_setting);
if (itr_setting != coalesce_usecs && (coalesce_usecs % 2))
netdev_info(netdev, "User set %s-usecs to %d, device only supports even values. Rounding down and attempting to set %s-usecs to %d\n",
c_type_str, coalesce_usecs, c_type_str,
ITR_REG_ALIGN(coalesce_usecs));
}
/** /**
* __ice_set_coalesce - set ITR/INTRL values for the device * __ice_set_coalesce - set ITR/INTRL values for the device
* @netdev: pointer to the netdev associated with this query * @netdev: pointer to the netdev associated with this query
...@@ -3616,8 +3625,19 @@ __ice_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec, ...@@ -3616,8 +3625,19 @@ __ice_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec,
return -EINVAL; return -EINVAL;
if (q_num < 0) { if (q_num < 0) {
struct ice_q_vector *q_vector = vsi->q_vectors[0];
int v_idx; int v_idx;
if (q_vector) {
ice_print_if_odd_usecs(netdev, q_vector->rx.itr_setting,
ec->use_adaptive_rx_coalesce,
ec->rx_coalesce_usecs, "rx");
ice_print_if_odd_usecs(netdev, q_vector->tx.itr_setting,
ec->use_adaptive_tx_coalesce,
ec->tx_coalesce_usecs, "tx");
}
ice_for_each_q_vector(vsi, v_idx) { ice_for_each_q_vector(vsi, v_idx) {
/* In some cases if DCB is configured the num_[rx|tx]q /* In some cases if DCB is configured the num_[rx|tx]q
* can be less than vsi->num_q_vectors. This check * can be less than vsi->num_q_vectors. This check
......
...@@ -222,7 +222,7 @@ enum ice_rx_dtype { ...@@ -222,7 +222,7 @@ enum ice_rx_dtype {
#define ICE_ITR_GRAN_S 1 /* ITR granularity is always 2us */ #define ICE_ITR_GRAN_S 1 /* ITR granularity is always 2us */
#define ICE_ITR_GRAN_US BIT(ICE_ITR_GRAN_S) #define ICE_ITR_GRAN_US BIT(ICE_ITR_GRAN_S)
#define ICE_ITR_MASK 0x1FFE /* ITR register value alignment mask */ #define ICE_ITR_MASK 0x1FFE /* ITR register value alignment mask */
#define ITR_REG_ALIGN(setting) __ALIGN_MASK(setting, ~ICE_ITR_MASK) #define ITR_REG_ALIGN(setting) ((setting) & ICE_ITR_MASK)
#define ICE_ITR_ADAPTIVE_MIN_INC 0x0002 #define ICE_ITR_ADAPTIVE_MIN_INC 0x0002
#define ICE_ITR_ADAPTIVE_MIN_USECS 0x0002 #define ICE_ITR_ADAPTIVE_MIN_USECS 0x0002
......
...@@ -1873,6 +1873,48 @@ static int ice_vc_config_rss_lut(struct ice_vf *vf, u8 *msg) ...@@ -1873,6 +1873,48 @@ static int ice_vc_config_rss_lut(struct ice_vf *vf, u8 *msg)
NULL, 0); NULL, 0);
} }
/**
* ice_wait_on_vf_reset - poll to make sure a given VF is ready after reset
* @vf: The VF being resseting
*
* The max poll time is about ~800ms, which is about the maximum time it takes
* for a VF to be reset and/or a VF driver to be removed.
*/
static void ice_wait_on_vf_reset(struct ice_vf *vf)
{
int i;
for (i = 0; i < ICE_MAX_VF_RESET_TRIES; i++) {
if (test_bit(ICE_VF_STATE_INIT, vf->vf_states))
break;
msleep(ICE_MAX_VF_RESET_SLEEP_MS);
}
}
/**
* ice_check_vf_ready_for_cfg - check if VF is ready to be configured/queried
* @vf: VF to check if it's ready to be configured/queried
*
* The purpose of this function is to make sure the VF is not in reset, not
* disabled, and initialized so it can be configured and/or queried by a host
* administrator.
*/
static int ice_check_vf_ready_for_cfg(struct ice_vf *vf)
{
struct ice_pf *pf;
ice_wait_on_vf_reset(vf);
if (ice_is_vf_disabled(vf))
return -EINVAL;
pf = vf->pf;
if (ice_check_vf_init(pf, vf))
return -EBUSY;
return 0;
}
/** /**
* ice_set_vf_spoofchk * ice_set_vf_spoofchk
* @netdev: network interface device structure * @netdev: network interface device structure
...@@ -1890,16 +1932,16 @@ int ice_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool ena) ...@@ -1890,16 +1932,16 @@ int ice_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool ena)
enum ice_status status; enum ice_status status;
struct device *dev; struct device *dev;
struct ice_vf *vf; struct ice_vf *vf;
int ret = 0; int ret;
dev = ice_pf_to_dev(pf); dev = ice_pf_to_dev(pf);
if (ice_validate_vf_id(pf, vf_id)) if (ice_validate_vf_id(pf, vf_id))
return -EINVAL; return -EINVAL;
vf = &pf->vf[vf_id]; vf = &pf->vf[vf_id];
ret = ice_check_vf_ready_for_cfg(vf);
if (ice_check_vf_init(pf, vf)) if (ret)
return -EBUSY; return ret;
vf_vsi = pf->vsi[vf->lan_vsi_idx]; vf_vsi = pf->vsi[vf->lan_vsi_idx];
if (!vf_vsi) { if (!vf_vsi) {
...@@ -2696,7 +2738,7 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos, ...@@ -2696,7 +2738,7 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
struct ice_vsi *vsi; struct ice_vsi *vsi;
struct device *dev; struct device *dev;
struct ice_vf *vf; struct ice_vf *vf;
int ret = 0; int ret;
dev = ice_pf_to_dev(pf); dev = ice_pf_to_dev(pf);
if (ice_validate_vf_id(pf, vf_id)) if (ice_validate_vf_id(pf, vf_id))
...@@ -2714,13 +2756,15 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos, ...@@ -2714,13 +2756,15 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
vf = &pf->vf[vf_id]; vf = &pf->vf[vf_id];
vsi = pf->vsi[vf->lan_vsi_idx]; vsi = pf->vsi[vf->lan_vsi_idx];
if (ice_check_vf_init(pf, vf))
return -EBUSY; ret = ice_check_vf_ready_for_cfg(vf);
if (ret)
return ret;
if (le16_to_cpu(vsi->info.pvid) == vlanprio) { if (le16_to_cpu(vsi->info.pvid) == vlanprio) {
/* duplicate request, so just return success */ /* duplicate request, so just return success */
dev_dbg(dev, "Duplicate pvid %d request\n", vlanprio); dev_dbg(dev, "Duplicate pvid %d request\n", vlanprio);
return ret; return 0;
} }
/* If PVID, then remove all filters on the old VLAN */ /* If PVID, then remove all filters on the old VLAN */
...@@ -2731,7 +2775,7 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos, ...@@ -2731,7 +2775,7 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
if (vlan_id || qos) { if (vlan_id || qos) {
ret = ice_vsi_manage_pvid(vsi, vlanprio, true); ret = ice_vsi_manage_pvid(vsi, vlanprio, true);
if (ret) if (ret)
goto error_set_pvid; return ret;
} else { } else {
ice_vsi_manage_pvid(vsi, 0, false); ice_vsi_manage_pvid(vsi, 0, false);
vsi->info.pvid = 0; vsi->info.pvid = 0;
...@@ -2744,7 +2788,7 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos, ...@@ -2744,7 +2788,7 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
/* add new VLAN filter for each MAC */ /* add new VLAN filter for each MAC */
ret = ice_vsi_add_vlan(vsi, vlan_id); ret = ice_vsi_add_vlan(vsi, vlan_id);
if (ret) if (ret)
goto error_set_pvid; return ret;
} }
/* The Port VLAN needs to be saved across resets the same as the /* The Port VLAN needs to be saved across resets the same as the
...@@ -2752,8 +2796,7 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos, ...@@ -2752,8 +2796,7 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
*/ */
vf->port_vlan_id = le16_to_cpu(vsi->info.pvid); vf->port_vlan_id = le16_to_cpu(vsi->info.pvid);
error_set_pvid: return 0;
return ret;
} }
/** /**
...@@ -3236,23 +3279,6 @@ ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi) ...@@ -3236,23 +3279,6 @@ ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi)
return 0; return 0;
} }
/**
* ice_wait_on_vf_reset
* @vf: The VF being resseting
*
* Poll to make sure a given VF is ready after reset
*/
static void ice_wait_on_vf_reset(struct ice_vf *vf)
{
int i;
for (i = 0; i < ICE_MAX_VF_RESET_WAIT; i++) {
if (test_bit(ICE_VF_STATE_INIT, vf->vf_states))
break;
msleep(20);
}
}
/** /**
* ice_set_vf_mac * ice_set_vf_mac
* @netdev: network interface device structure * @netdev: network interface device structure
...@@ -3265,29 +3291,21 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) ...@@ -3265,29 +3291,21 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
{ {
struct ice_pf *pf = ice_netdev_to_pf(netdev); struct ice_pf *pf = ice_netdev_to_pf(netdev);
struct ice_vf *vf; struct ice_vf *vf;
int ret = 0; int ret;
if (ice_validate_vf_id(pf, vf_id)) if (ice_validate_vf_id(pf, vf_id))
return -EINVAL; return -EINVAL;
vf = &pf->vf[vf_id];
/* Don't set MAC on disabled VF */
if (ice_is_vf_disabled(vf))
return -EINVAL;
/* In case VF is in reset mode, wait until it is completed. Depending
* on factors like queue disabling routine, this could take ~250ms
*/
ice_wait_on_vf_reset(vf);
if (ice_check_vf_init(pf, vf))
return -EBUSY;
if (is_zero_ether_addr(mac) || is_multicast_ether_addr(mac)) { if (is_zero_ether_addr(mac) || is_multicast_ether_addr(mac)) {
netdev_err(netdev, "%pM not a valid unicast address\n", mac); netdev_err(netdev, "%pM not a valid unicast address\n", mac);
return -EINVAL; return -EINVAL;
} }
vf = &pf->vf[vf_id];
ret = ice_check_vf_ready_for_cfg(vf);
if (ret)
return ret;
/* copy MAC into dflt_lan_addr and trigger a VF reset. The reset /* copy MAC into dflt_lan_addr and trigger a VF reset. The reset
* flow will use the updated dflt_lan_addr and add a MAC filter * flow will use the updated dflt_lan_addr and add a MAC filter
* using ice_add_mac. Also set pf_set_mac to indicate that the PF has * using ice_add_mac. Also set pf_set_mac to indicate that the PF has
...@@ -3299,7 +3317,7 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) ...@@ -3299,7 +3317,7 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
vf_id, mac); vf_id, mac);
ice_vc_reset_vf(vf); ice_vc_reset_vf(vf);
return ret; return 0;
} }
/** /**
...@@ -3314,22 +3332,15 @@ int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted) ...@@ -3314,22 +3332,15 @@ int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted)
{ {
struct ice_pf *pf = ice_netdev_to_pf(netdev); struct ice_pf *pf = ice_netdev_to_pf(netdev);
struct ice_vf *vf; struct ice_vf *vf;
int ret;
if (ice_validate_vf_id(pf, vf_id)) if (ice_validate_vf_id(pf, vf_id))
return -EINVAL; return -EINVAL;
vf = &pf->vf[vf_id]; vf = &pf->vf[vf_id];
/* Don't set Trusted Mode on disabled VF */ ret = ice_check_vf_ready_for_cfg(vf);
if (ice_is_vf_disabled(vf)) if (ret)
return -EINVAL; return ret;
/* In case VF is in reset mode, wait until it is completed. Depending
* on factors like queue disabling routine, this could take ~250ms
*/
ice_wait_on_vf_reset(vf);
if (ice_check_vf_init(pf, vf))
return -EBUSY;
/* Check if already trusted */ /* Check if already trusted */
if (trusted == vf->trusted) if (trusted == vf->trusted)
...@@ -3355,13 +3366,15 @@ int ice_set_vf_link_state(struct net_device *netdev, int vf_id, int link_state) ...@@ -3355,13 +3366,15 @@ int ice_set_vf_link_state(struct net_device *netdev, int vf_id, int link_state)
{ {
struct ice_pf *pf = ice_netdev_to_pf(netdev); struct ice_pf *pf = ice_netdev_to_pf(netdev);
struct ice_vf *vf; struct ice_vf *vf;
int ret;
if (ice_validate_vf_id(pf, vf_id)) if (ice_validate_vf_id(pf, vf_id))
return -EINVAL; return -EINVAL;
vf = &pf->vf[vf_id]; vf = &pf->vf[vf_id];
if (ice_check_vf_init(pf, vf)) ret = ice_check_vf_ready_for_cfg(vf);
return -EBUSY; if (ret)
return ret;
switch (link_state) { switch (link_state) {
case IFLA_VF_LINK_STATE_AUTO: case IFLA_VF_LINK_STATE_AUTO:
...@@ -3397,14 +3410,15 @@ int ice_get_vf_stats(struct net_device *netdev, int vf_id, ...@@ -3397,14 +3410,15 @@ int ice_get_vf_stats(struct net_device *netdev, int vf_id,
struct ice_eth_stats *stats; struct ice_eth_stats *stats;
struct ice_vsi *vsi; struct ice_vsi *vsi;
struct ice_vf *vf; struct ice_vf *vf;
int ret;
if (ice_validate_vf_id(pf, vf_id)) if (ice_validate_vf_id(pf, vf_id))
return -EINVAL; return -EINVAL;
vf = &pf->vf[vf_id]; vf = &pf->vf[vf_id];
ret = ice_check_vf_ready_for_cfg(vf);
if (ice_check_vf_init(pf, vf)) if (ret)
return -EBUSY; return ret;
vsi = pf->vsi[vf->lan_vsi_idx]; vsi = pf->vsi[vf->lan_vsi_idx];
if (!vsi) if (!vsi)
......
...@@ -38,7 +38,8 @@ ...@@ -38,7 +38,8 @@
#define ICE_MAX_POLICY_INTR_PER_VF 33 #define ICE_MAX_POLICY_INTR_PER_VF 33
#define ICE_MIN_INTR_PER_VF (ICE_MIN_QS_PER_VF + 1) #define ICE_MIN_INTR_PER_VF (ICE_MIN_QS_PER_VF + 1)
#define ICE_DFLT_INTR_PER_VF (ICE_DFLT_QS_PER_VF + 1) #define ICE_DFLT_INTR_PER_VF (ICE_DFLT_QS_PER_VF + 1)
#define ICE_MAX_VF_RESET_WAIT 15 #define ICE_MAX_VF_RESET_TRIES 40
#define ICE_MAX_VF_RESET_SLEEP_MS 20
#define ice_for_each_vf(pf, i) \ #define ice_for_each_vf(pf, i) \
for ((i) = 0; (i) < (pf)->num_alloc_vfs; (i)++) for ((i) = 0; (i) < (pf)->num_alloc_vfs; (i)++)
......
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