Skip to content

Commit

Permalink
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/tnguy/next-queue

Tony Nguyen says:

====================
100GbE Intel Wired LAN Driver Updates 2022-07-28

This series contains updates to ice driver only.

Michal allows for VF true promiscuous mode to be set for multiple VFs
and adds clearing of promiscuous filters when VF trust is removed.

Maciej refactors ice_set_features() to track/check changed features
instead of constantly checking against netdev features and adds support for
NETIF_F_LOOPBACK.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  ice: allow toggling loopback mode via ndo_set_features callback
  ice: compress branches in ice_set_features()
  ice: Fix promiscuous mode not turning off
  ice: Introduce enabling promiscuous mode on multiple VF's
====================

Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
kuba-moo committed Jul 30, 2022
2 parents ed3849e + 44ece4e commit 84a8d93
Show file tree
Hide file tree
Showing 12 changed files with 269 additions and 202 deletions.
2 changes: 0 additions & 2 deletions drivers/net/ethernet/intel/ice/ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,6 @@ struct ice_sw {
struct ice_pf *pf;
u16 sw_id; /* switch ID for this switch */
u16 bridge_mode; /* VEB/VEPA/Port Virtualizer */
struct ice_vsi *dflt_vsi; /* default VSI for this switch */
u8 dflt_vsi_ena:1; /* true if above dflt_vsi is enabled */
};

enum ice_pf_state {
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/ethernet/intel/ice/ice_eswitch.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ static int ice_eswitch_setup_env(struct ice_pf *pf)
if (ice_vsi_add_vlan_zero(uplink_vsi))
goto err_def_rx;

if (!ice_is_dflt_vsi_in_use(uplink_vsi->vsw)) {
if (ice_set_dflt_vsi(uplink_vsi->vsw, uplink_vsi))
if (!ice_is_dflt_vsi_in_use(uplink_vsi->port_info)) {
if (ice_set_dflt_vsi(uplink_vsi))
goto err_def_rx;
rule_added = true;
}
Expand All @@ -151,7 +151,7 @@ static int ice_eswitch_setup_env(struct ice_pf *pf)
ice_vsi_update_security(uplink_vsi, ice_vsi_ctx_clear_allow_override);
err_override_uplink:
if (rule_added)
ice_clear_dflt_vsi(uplink_vsi->vsw);
ice_clear_dflt_vsi(uplink_vsi);
err_def_rx:
ice_fltr_add_mac_and_broadcast(uplink_vsi,
uplink_vsi->port_info->mac.perm_addr,
Expand Down Expand Up @@ -411,7 +411,7 @@ static void ice_eswitch_release_env(struct ice_pf *pf)

ice_vsi_update_security(ctrl_vsi, ice_vsi_ctx_clear_allow_override);
ice_vsi_update_security(uplink_vsi, ice_vsi_ctx_clear_allow_override);
ice_clear_dflt_vsi(uplink_vsi->vsw);
ice_clear_dflt_vsi(uplink_vsi);
ice_fltr_add_mac_and_broadcast(uplink_vsi,
uplink_vsi->port_info->mac.perm_addr,
ICE_FWD_TO_VSI);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/ice/ice_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,7 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags)
* promiscuous mode because it's not supported
*/
if (test_bit(ICE_FLAG_VF_TRUE_PROMISC_ENA, change_flags) &&
ice_is_any_vf_in_promisc(pf)) {
ice_is_any_vf_in_unicast_promisc(pf)) {
dev_err(dev, "Changing vf-true-promisc-support flag while VF(s) are in promiscuous mode not supported\n");
/* toggle bit back to previous state */
change_bit(ICE_FLAG_VF_TRUE_PROMISC_ENA, pf->flags);
Expand Down
67 changes: 24 additions & 43 deletions drivers/net/ethernet/intel/ice/ice_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -3006,8 +3006,8 @@ int ice_vsi_release(struct ice_vsi *vsi)
}
}

if (ice_is_vsi_dflt_vsi(pf->first_sw, vsi))
ice_clear_dflt_vsi(pf->first_sw);
if (ice_is_vsi_dflt_vsi(vsi))
ice_clear_dflt_vsi(vsi);
ice_fltr_remove_all(vsi);
ice_rm_vsi_lan_cfg(vsi->port_info, vsi->idx);
err = ice_rm_vsi_rdma_cfg(vsi->port_info, vsi->idx);
Expand Down Expand Up @@ -3690,116 +3690,97 @@ void ice_update_rx_ring_stats(struct ice_rx_ring *rx_ring, u64 pkts, u64 bytes)

/**
* ice_is_dflt_vsi_in_use - check if the default forwarding VSI is being used
* @sw: switch to check if its default forwarding VSI is free
* @pi: port info of the switch with default VSI
*
* Return true if the default forwarding VSI is already being used, else returns
* false signalling that it's available to use.
* Return true if the there is a single VSI in default forwarding VSI list
*/
bool ice_is_dflt_vsi_in_use(struct ice_sw *sw)
bool ice_is_dflt_vsi_in_use(struct ice_port_info *pi)
{
return (sw->dflt_vsi && sw->dflt_vsi_ena);
bool exists = false;

ice_check_if_dflt_vsi(pi, 0, &exists);
return exists;
}

/**
* ice_is_vsi_dflt_vsi - check if the VSI passed in is the default VSI
* @sw: switch for the default forwarding VSI to compare against
* @vsi: VSI to compare against default forwarding VSI
*
* If this VSI passed in is the default forwarding VSI then return true, else
* return false
*/
bool ice_is_vsi_dflt_vsi(struct ice_sw *sw, struct ice_vsi *vsi)
bool ice_is_vsi_dflt_vsi(struct ice_vsi *vsi)
{
return (sw->dflt_vsi == vsi && sw->dflt_vsi_ena);
return ice_check_if_dflt_vsi(vsi->port_info, vsi->idx, NULL);
}

/**
* ice_set_dflt_vsi - set the default forwarding VSI
* @sw: switch used to assign the default forwarding VSI
* @vsi: VSI getting set as the default forwarding VSI on the switch
*
* If the VSI passed in is already the default VSI and it's enabled just return
* success.
*
* If there is already a default VSI on the switch and it's enabled then return
* -EEXIST since there can only be one default VSI per switch.
*
* Otherwise try to set the VSI passed in as the switch's default VSI and
* return the result.
* Otherwise try to set the VSI passed in as the switch's default VSI and
* return the result.
*/
int ice_set_dflt_vsi(struct ice_sw *sw, struct ice_vsi *vsi)
int ice_set_dflt_vsi(struct ice_vsi *vsi)
{
struct device *dev;
int status;

if (!sw || !vsi)
if (!vsi)
return -EINVAL;

dev = ice_pf_to_dev(vsi->back);

/* the VSI passed in is already the default VSI */
if (ice_is_vsi_dflt_vsi(sw, vsi)) {
if (ice_is_vsi_dflt_vsi(vsi)) {
dev_dbg(dev, "VSI %d passed in is already the default forwarding VSI, nothing to do\n",
vsi->vsi_num);
return 0;
}

/* another VSI is already the default VSI for this switch */
if (ice_is_dflt_vsi_in_use(sw)) {
dev_err(dev, "Default forwarding VSI %d already in use, disable it and try again\n",
sw->dflt_vsi->vsi_num);
return -EEXIST;
}

status = ice_cfg_dflt_vsi(&vsi->back->hw, vsi->idx, true, ICE_FLTR_RX);
status = ice_cfg_dflt_vsi(vsi->port_info, vsi->idx, true, ICE_FLTR_RX);
if (status) {
dev_err(dev, "Failed to set VSI %d as the default forwarding VSI, error %d\n",
vsi->vsi_num, status);
return status;
}

sw->dflt_vsi = vsi;
sw->dflt_vsi_ena = true;

return 0;
}

/**
* ice_clear_dflt_vsi - clear the default forwarding VSI
* @sw: switch used to clear the default VSI
* @vsi: VSI to remove from filter list
*
* If the switch has no default VSI or it's not enabled then return error.
*
* Otherwise try to clear the default VSI and return the result.
*/
int ice_clear_dflt_vsi(struct ice_sw *sw)
int ice_clear_dflt_vsi(struct ice_vsi *vsi)
{
struct ice_vsi *dflt_vsi;
struct device *dev;
int status;

if (!sw)
if (!vsi)
return -EINVAL;

dev = ice_pf_to_dev(sw->pf);

dflt_vsi = sw->dflt_vsi;
dev = ice_pf_to_dev(vsi->back);

/* there is no default VSI configured */
if (!ice_is_dflt_vsi_in_use(sw))
if (!ice_is_dflt_vsi_in_use(vsi->port_info))
return -ENODEV;

status = ice_cfg_dflt_vsi(&dflt_vsi->back->hw, dflt_vsi->idx, false,
status = ice_cfg_dflt_vsi(vsi->port_info, vsi->idx, false,
ICE_FLTR_RX);
if (status) {
dev_err(dev, "Failed to clear the default forwarding VSI %d, error %d\n",
dflt_vsi->vsi_num, status);
vsi->vsi_num, status);
return -EIO;
}

sw->dflt_vsi = NULL;
sw->dflt_vsi_ena = false;

return 0;
}

Expand Down
11 changes: 4 additions & 7 deletions drivers/net/ethernet/intel/ice/ice_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,10 @@ int ice_vsi_cfg_mac_fltr(struct ice_vsi *vsi, const u8 *macaddr, bool set);

bool ice_is_safe_mode(struct ice_pf *pf);
bool ice_is_rdma_ena(struct ice_pf *pf);
bool ice_is_dflt_vsi_in_use(struct ice_sw *sw);

bool ice_is_vsi_dflt_vsi(struct ice_sw *sw, struct ice_vsi *vsi);

int ice_set_dflt_vsi(struct ice_sw *sw, struct ice_vsi *vsi);

int ice_clear_dflt_vsi(struct ice_sw *sw);
bool ice_is_dflt_vsi_in_use(struct ice_port_info *pi);
bool ice_is_vsi_dflt_vsi(struct ice_vsi *vsi);
int ice_set_dflt_vsi(struct ice_vsi *vsi);
int ice_clear_dflt_vsi(struct ice_vsi *vsi);
int ice_set_min_bw_limit(struct ice_vsi *vsi, u64 min_tx_rate);
int ice_set_max_bw_limit(struct ice_vsi *vsi, u64 max_tx_rate);
int ice_get_link_speed_kbps(struct ice_vsi *vsi);
Expand Down
86 changes: 54 additions & 32 deletions drivers/net/ethernet/intel/ice/ice_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,8 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
clear_bit(ICE_VSI_PROMISC_CHANGED, vsi->state);
if (vsi->current_netdev_flags & IFF_PROMISC) {
/* Apply Rx filter rule to get traffic from wire */
if (!ice_is_dflt_vsi_in_use(pf->first_sw)) {
err = ice_set_dflt_vsi(pf->first_sw, vsi);
if (!ice_is_dflt_vsi_in_use(vsi->port_info)) {
err = ice_set_dflt_vsi(vsi);
if (err && err != -EEXIST) {
netdev_err(netdev, "Error %d setting default VSI %i Rx rule\n",
err, vsi->vsi_num);
Expand All @@ -424,8 +424,8 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
}
} else {
/* Clear Rx filter to remove traffic from wire */
if (ice_is_vsi_dflt_vsi(pf->first_sw, vsi)) {
err = ice_clear_dflt_vsi(pf->first_sw);
if (ice_is_vsi_dflt_vsi(vsi)) {
err = ice_clear_dflt_vsi(vsi);
if (err) {
netdev_err(netdev, "Error %d clearing default VSI %i Rx rule\n",
err, vsi->vsi_num);
Expand Down Expand Up @@ -3358,6 +3358,7 @@ static void ice_set_netdev_features(struct net_device *netdev)
netdev->features |= netdev->hw_features;

netdev->hw_features |= NETIF_F_HW_TC;
netdev->hw_features |= NETIF_F_LOOPBACK;

/* encap and VLAN devices inherit default, csumo and tso features */
netdev->hw_enc_features |= dflt_features | csumo_features |
Expand Down Expand Up @@ -5912,6 +5913,32 @@ ice_set_vlan_features(struct net_device *netdev, netdev_features_t features)
return 0;
}

/**
* ice_set_loopback - turn on/off loopback mode on underlying PF
* @vsi: ptr to VSI
* @ena: flag to indicate the on/off setting
*/
static int ice_set_loopback(struct ice_vsi *vsi, bool ena)
{
bool if_running = netif_running(vsi->netdev);
int ret;

if (if_running && !test_and_set_bit(ICE_VSI_DOWN, vsi->state)) {
ret = ice_down(vsi);
if (ret) {
netdev_err(vsi->netdev, "Preparing device to toggle loopback failed\n");
return ret;
}
}
ret = ice_aq_set_mac_loopback(&vsi->back->hw, ena, NULL);
if (ret)
netdev_err(vsi->netdev, "Failed to toggle loopback state\n");
if (if_running)
ret = ice_up(vsi);

return ret;
}

/**
* ice_set_features - set the netdev feature flags
* @netdev: ptr to the netdev being adjusted
Expand All @@ -5920,44 +5947,41 @@ ice_set_vlan_features(struct net_device *netdev, netdev_features_t features)
static int
ice_set_features(struct net_device *netdev, netdev_features_t features)
{
netdev_features_t changed = netdev->features ^ features;
struct ice_netdev_priv *np = netdev_priv(netdev);
struct ice_vsi *vsi = np->vsi;
struct ice_pf *pf = vsi->back;
int ret = 0;

/* Don't set any netdev advanced features with device in Safe Mode */
if (ice_is_safe_mode(vsi->back)) {
dev_err(ice_pf_to_dev(vsi->back), "Device is in Safe Mode - not enabling advanced netdev features\n");
if (ice_is_safe_mode(pf)) {
dev_err(ice_pf_to_dev(pf),
"Device is in Safe Mode - not enabling advanced netdev features\n");
return ret;
}

/* Do not change setting during reset */
if (ice_is_reset_in_progress(pf->state)) {
dev_err(ice_pf_to_dev(vsi->back), "Device is resetting, changing advanced netdev features temporarily unavailable.\n");
dev_err(ice_pf_to_dev(pf),
"Device is resetting, changing advanced netdev features temporarily unavailable.\n");
return -EBUSY;
}

/* Multiple features can be changed in one call so keep features in
* separate if/else statements to guarantee each feature is checked
*/
if (features & NETIF_F_RXHASH && !(netdev->features & NETIF_F_RXHASH))
ice_vsi_manage_rss_lut(vsi, true);
else if (!(features & NETIF_F_RXHASH) &&
netdev->features & NETIF_F_RXHASH)
ice_vsi_manage_rss_lut(vsi, false);
if (changed & NETIF_F_RXHASH)
ice_vsi_manage_rss_lut(vsi, !!(features & NETIF_F_RXHASH));

ret = ice_set_vlan_features(netdev, features);
if (ret)
return ret;

if ((features & NETIF_F_NTUPLE) &&
!(netdev->features & NETIF_F_NTUPLE)) {
ice_vsi_manage_fdir(vsi, true);
ice_init_arfs(vsi);
} else if (!(features & NETIF_F_NTUPLE) &&
(netdev->features & NETIF_F_NTUPLE)) {
ice_vsi_manage_fdir(vsi, false);
ice_clear_arfs(vsi);
if (changed & NETIF_F_NTUPLE) {
bool ena = !!(features & NETIF_F_NTUPLE);

ice_vsi_manage_fdir(vsi, ena);
ena ? ice_init_arfs(vsi) : ice_clear_arfs(vsi);
}

/* don't turn off hw_tc_offload when ADQ is already enabled */
Expand All @@ -5966,13 +5990,17 @@ ice_set_features(struct net_device *netdev, netdev_features_t features)
return -EACCES;
}

if ((features & NETIF_F_HW_TC) &&
!(netdev->features & NETIF_F_HW_TC))
set_bit(ICE_FLAG_CLS_FLOWER, pf->flags);
else
clear_bit(ICE_FLAG_CLS_FLOWER, pf->flags);
if (changed & NETIF_F_HW_TC) {
bool ena = !!(features & NETIF_F_HW_TC);

return 0;
ena ? set_bit(ICE_FLAG_CLS_FLOWER, pf->flags) :
clear_bit(ICE_FLAG_CLS_FLOWER, pf->flags);
}

if (changed & NETIF_F_LOOPBACK)
ret = ice_set_loopback(vsi, !!(features & NETIF_F_LOOPBACK));

return ret;
}

/**
Expand Down Expand Up @@ -6994,12 +7022,6 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
goto err_init_ctrlq;
}

if (pf->first_sw->dflt_vsi_ena)
dev_info(dev, "Clearing default VSI, re-enable after reset completes\n");
/* clear the default VSI configuration if it exists */
pf->first_sw->dflt_vsi = NULL;
pf->first_sw->dflt_vsi_ena = false;

ice_clear_pxe_mode(hw);

err = ice_init_nvm(hw);
Expand Down
Loading

0 comments on commit 84a8d93

Please sign in to comment.