mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-24 10:39:52 +00:00
ice: Add ethtool private flag to make forcing link down optional
Add new infrastructure for implementing ethtool private flags using the existing pf->flags bitmap to store them, and add the link-down-on-close ethtool private flag to optionally bring down the PHY link when the interface is administratively downed. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
b6f934f027
commit
ab4ab73fc1
3 changed files with 95 additions and 6 deletions
|
@ -270,6 +270,7 @@ enum ice_pf_flags {
|
||||||
ICE_FLAG_RSS_ENA,
|
ICE_FLAG_RSS_ENA,
|
||||||
ICE_FLAG_SRIOV_ENA,
|
ICE_FLAG_SRIOV_ENA,
|
||||||
ICE_FLAG_SRIOV_CAPABLE,
|
ICE_FLAG_SRIOV_CAPABLE,
|
||||||
|
ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA,
|
||||||
ICE_PF_FLAGS_NBITS /* must be last */
|
ICE_PF_FLAGS_NBITS /* must be last */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,22 @@ static const u32 ice_regs_dump_list[] = {
|
||||||
QRX_ITR(0),
|
QRX_ITR(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ice_priv_flag {
|
||||||
|
char name[ETH_GSTRING_LEN];
|
||||||
|
u32 bitno; /* bit position in pf->flags */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ICE_PRIV_FLAG(_name, _bitno) { \
|
||||||
|
.name = _name, \
|
||||||
|
.bitno = _bitno, \
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct ice_priv_flag ice_gstrings_priv_flags[] = {
|
||||||
|
ICE_PRIV_FLAG("link-down-on-close", ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA),
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ICE_PRIV_FLAG_ARRAY_SIZE ARRAY_SIZE(ice_gstrings_priv_flags)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_nvm_version_str - format the NVM version strings
|
* ice_nvm_version_str - format the NVM version strings
|
||||||
* @hw: ptr to the hardware info
|
* @hw: ptr to the hardware info
|
||||||
|
@ -152,6 +168,7 @@ ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
|
||||||
sizeof(drvinfo->fw_version));
|
sizeof(drvinfo->fw_version));
|
||||||
strlcpy(drvinfo->bus_info, pci_name(pf->pdev),
|
strlcpy(drvinfo->bus_info, pci_name(pf->pdev),
|
||||||
sizeof(drvinfo->bus_info));
|
sizeof(drvinfo->bus_info));
|
||||||
|
drvinfo->n_priv_flags = ICE_PRIV_FLAG_ARRAY_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ice_get_regs_len(struct net_device __always_unused *netdev)
|
static int ice_get_regs_len(struct net_device __always_unused *netdev)
|
||||||
|
@ -292,6 +309,13 @@ static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
|
||||||
p += ETH_GSTRING_LEN;
|
p += ETH_GSTRING_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ETH_SS_PRIV_FLAGS:
|
||||||
|
for (i = 0; i < ICE_PRIV_FLAG_ARRAY_SIZE; i++) {
|
||||||
|
snprintf(p, ETH_GSTRING_LEN, "%s",
|
||||||
|
ice_gstrings_priv_flags[i].name);
|
||||||
|
p += ETH_GSTRING_LEN;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -321,6 +345,64 @@ ice_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_get_priv_flags - report device private flags
|
||||||
|
* @netdev: network interface device structure
|
||||||
|
*
|
||||||
|
* The get string set count and the string set should be matched for each
|
||||||
|
* flag returned. Add new strings for each flag to the ice_gstrings_priv_flags
|
||||||
|
* array.
|
||||||
|
*
|
||||||
|
* Returns a u32 bitmap of flags.
|
||||||
|
*/
|
||||||
|
static u32 ice_get_priv_flags(struct net_device *netdev)
|
||||||
|
{
|
||||||
|
struct ice_netdev_priv *np = netdev_priv(netdev);
|
||||||
|
struct ice_vsi *vsi = np->vsi;
|
||||||
|
struct ice_pf *pf = vsi->back;
|
||||||
|
u32 i, ret_flags = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ICE_PRIV_FLAG_ARRAY_SIZE; i++) {
|
||||||
|
const struct ice_priv_flag *priv_flag;
|
||||||
|
|
||||||
|
priv_flag = &ice_gstrings_priv_flags[i];
|
||||||
|
|
||||||
|
if (test_bit(priv_flag->bitno, pf->flags))
|
||||||
|
ret_flags |= BIT(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_set_priv_flags - set private flags
|
||||||
|
* @netdev: network interface device structure
|
||||||
|
* @flags: bit flags to be set
|
||||||
|
*/
|
||||||
|
static int ice_set_priv_flags(struct net_device *netdev, u32 flags)
|
||||||
|
{
|
||||||
|
struct ice_netdev_priv *np = netdev_priv(netdev);
|
||||||
|
struct ice_vsi *vsi = np->vsi;
|
||||||
|
struct ice_pf *pf = vsi->back;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
if (flags > BIT(ICE_PRIV_FLAG_ARRAY_SIZE))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (i = 0; i < ICE_PRIV_FLAG_ARRAY_SIZE; i++) {
|
||||||
|
const struct ice_priv_flag *priv_flag;
|
||||||
|
|
||||||
|
priv_flag = &ice_gstrings_priv_flags[i];
|
||||||
|
|
||||||
|
if (flags & BIT(i))
|
||||||
|
set_bit(priv_flag->bitno, pf->flags);
|
||||||
|
else
|
||||||
|
clear_bit(priv_flag->bitno, pf->flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ice_get_sset_count(struct net_device *netdev, int sset)
|
static int ice_get_sset_count(struct net_device *netdev, int sset)
|
||||||
{
|
{
|
||||||
switch (sset) {
|
switch (sset) {
|
||||||
|
@ -344,6 +426,8 @@ static int ice_get_sset_count(struct net_device *netdev, int sset)
|
||||||
* not safe.
|
* not safe.
|
||||||
*/
|
*/
|
||||||
return ICE_ALL_STATS_LEN(netdev);
|
return ICE_ALL_STATS_LEN(netdev);
|
||||||
|
case ETH_SS_PRIV_FLAGS:
|
||||||
|
return ICE_PRIV_FLAG_ARRAY_SIZE;
|
||||||
default:
|
default:
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
@ -1753,6 +1837,8 @@ static const struct ethtool_ops ice_ethtool_ops = {
|
||||||
.get_strings = ice_get_strings,
|
.get_strings = ice_get_strings,
|
||||||
.set_phys_id = ice_set_phys_id,
|
.set_phys_id = ice_set_phys_id,
|
||||||
.get_ethtool_stats = ice_get_ethtool_stats,
|
.get_ethtool_stats = ice_get_ethtool_stats,
|
||||||
|
.get_priv_flags = ice_get_priv_flags,
|
||||||
|
.set_priv_flags = ice_set_priv_flags,
|
||||||
.get_sset_count = ice_get_sset_count,
|
.get_sset_count = ice_get_sset_count,
|
||||||
.get_rxnfc = ice_get_rxnfc,
|
.get_rxnfc = ice_get_rxnfc,
|
||||||
.get_ringparam = ice_get_ringparam,
|
.get_ringparam = ice_get_ringparam,
|
||||||
|
|
|
@ -3029,7 +3029,7 @@ out:
|
||||||
*/
|
*/
|
||||||
int ice_down(struct ice_vsi *vsi)
|
int ice_down(struct ice_vsi *vsi)
|
||||||
{
|
{
|
||||||
int i, tx_err, rx_err, link_err;
|
int i, tx_err, rx_err, link_err = 0;
|
||||||
|
|
||||||
/* Caller of this function is expected to set the
|
/* Caller of this function is expected to set the
|
||||||
* vsi->state __ICE_DOWN bit
|
* vsi->state __ICE_DOWN bit
|
||||||
|
@ -3054,11 +3054,13 @@ int ice_down(struct ice_vsi *vsi)
|
||||||
|
|
||||||
ice_napi_disable_all(vsi);
|
ice_napi_disable_all(vsi);
|
||||||
|
|
||||||
|
if (test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, vsi->back->flags)) {
|
||||||
link_err = ice_force_phys_link_state(vsi, false);
|
link_err = ice_force_phys_link_state(vsi, false);
|
||||||
if (link_err)
|
if (link_err)
|
||||||
netdev_err(vsi->netdev,
|
netdev_err(vsi->netdev,
|
||||||
"Failed to set physical link down, VSI %d error %d\n",
|
"Failed to set physical link down, VSI %d error %d\n",
|
||||||
vsi->vsi_num, link_err);
|
vsi->vsi_num, link_err);
|
||||||
|
}
|
||||||
|
|
||||||
ice_for_each_txq(vsi, i)
|
ice_for_each_txq(vsi, i)
|
||||||
ice_clean_tx_ring(vsi->tx_rings[i]);
|
ice_clean_tx_ring(vsi->tx_rings[i]);
|
||||||
|
|
Loading…
Add table
Reference in a new issue