summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/ice/ice_ethtool.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2021-04-08 14:18:25 -0700
committerDavid S. Miller <davem@davemloft.net>2021-04-08 14:18:25 -0700
commit4914a4f6a7a5ee5f8faeb91bb6ee4ee19c2a72b7 (patch)
tree709f40e7210bbb2897fe448f7d86bbce45090fe8 /drivers/net/ethernet/intel/ice/ice_ethtool.c
parent4667bf7135147aaf71947bb9195b35eded1df55c (diff)
parent2e20521b80c76ba517a060a5db752a9ca21c597c (diff)
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue
Tony Nguyen says: ==================== 100GbE Intel Wired LAN Driver Updates 2021-04-08 This series contains updates to ice driver only. Chinh adds retrying of sending some AQ commands when receiving EBUSY error. Victor modifies how nodes are added to reduce stack usage. Ani renames some variables to either follow spec naming or to be inline with naming in the rest of the driver. Ignores EMODE error as there are cases where this error is expected. Performs some cleanup such as removing unnecessary checks, doing variable assignments over copies, and removing unneeded variables. Revises some error codes returned in link settings to be more appropriate. He also implements support for new firmware option to get default link configuration which accounts for any needed NVM based overrides for PHY configuration. He also removes the rx_gro_dropped stat as the value no longer changes. Jeb removes setting specific link modes on firmwares that no longer require it. Brett removes unnecessary checks when adding and removing VLANs. Tony fixes a checkpatch warning for unnecessary blank line. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_ethtool.c')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_ethtool.c165
1 files changed, 77 insertions, 88 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
index 15152e63f204..51d3a929ecfd 100644
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
@@ -60,7 +60,6 @@ static const struct ice_stats ice_gstrings_vsi_stats[] = {
ICE_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol),
ICE_VSI_STAT("rx_alloc_fail", rx_buf_failed),
ICE_VSI_STAT("rx_pg_alloc_fail", rx_page_failed),
- ICE_VSI_STAT("rx_gro_dropped", rx_gro_dropped),
ICE_VSI_STAT("tx_errors", eth_stats.tx_errors),
ICE_VSI_STAT("tx_linearize", tx_linearize),
ICE_VSI_STAT("tx_busy", tx_busy),
@@ -1060,7 +1059,7 @@ ice_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
if (!caps)
return -ENOMEM;
- status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP,
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA,
caps, NULL);
if (status) {
err = -EAGAIN;
@@ -1095,24 +1094,15 @@ static int ice_nway_reset(struct net_device *netdev)
{
struct ice_netdev_priv *np = netdev_priv(netdev);
struct ice_vsi *vsi = np->vsi;
- struct ice_port_info *pi;
- enum ice_status status;
+ int err;
- pi = vsi->port_info;
/* If VSI state is up, then restart autoneg with link up */
if (!test_bit(__ICE_DOWN, vsi->back->state))
- status = ice_aq_set_link_restart_an(pi, true, NULL);
+ err = ice_set_link(vsi, true);
else
- status = ice_aq_set_link_restart_an(pi, false, NULL);
-
- if (status) {
- netdev_info(netdev, "link restart failed, err %s aq_err %s\n",
- ice_stat_str(status),
- ice_aq_str(pi->hw->adminq.sq_last_status));
- return -EIO;
- }
+ err = ice_set_link(vsi, false);
- return 0;
+ return err;
}
/**
@@ -1454,8 +1444,8 @@ void ice_mask_min_supported_speeds(u64 phy_types_high, u64 *phy_types_low)
do { \
if (req_speeds & (aq_link_speed) || \
(!req_speeds && \
- (adv_phy_type_lo & phy_type_mask_lo || \
- adv_phy_type_hi & phy_type_mask_hi))) \
+ (advert_phy_type_lo & phy_type_mask_lo || \
+ advert_phy_type_hi & phy_type_mask_hi))) \
ethtool_link_ksettings_add_link_mode(ks, advertising,\
ethtool_link_mode); \
} while (0)
@@ -1472,10 +1462,10 @@ ice_phy_type_to_ethtool(struct net_device *netdev,
struct ice_netdev_priv *np = netdev_priv(netdev);
struct ice_vsi *vsi = np->vsi;
struct ice_pf *pf = vsi->back;
+ u64 advert_phy_type_lo = 0;
+ u64 advert_phy_type_hi = 0;
u64 phy_type_mask_lo = 0;
u64 phy_type_mask_hi = 0;
- u64 adv_phy_type_lo = 0;
- u64 adv_phy_type_hi = 0;
u64 phy_types_high = 0;
u64 phy_types_low = 0;
u16 req_speeds;
@@ -1493,28 +1483,35 @@ ice_phy_type_to_ethtool(struct net_device *netdev,
* requested by user.
*/
if (test_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags)) {
- struct ice_link_default_override_tlv *ldo;
-
- ldo = &pf->link_dflt_override;
phy_types_low = le64_to_cpu(pf->nvm_phy_type_lo);
phy_types_high = le64_to_cpu(pf->nvm_phy_type_hi);
ice_mask_min_supported_speeds(phy_types_high, &phy_types_low);
-
- /* If override enabled and PHY mask set, then
- * Advertising link mode is the intersection of the PHY
- * types without media and the override PHY mask.
+ /* determine advertised modes based on link override only
+ * if it's supported and if the FW doesn't abstract the
+ * driver from having to account for link overrides
*/
- if (ldo->options & ICE_LINK_OVERRIDE_EN &&
- (ldo->phy_type_low || ldo->phy_type_high)) {
- adv_phy_type_lo =
- le64_to_cpu(pf->nvm_phy_type_lo) &
- ldo->phy_type_low;
- adv_phy_type_hi =
- le64_to_cpu(pf->nvm_phy_type_hi) &
- ldo->phy_type_high;
+ if (ice_fw_supports_link_override(&pf->hw) &&
+ !ice_fw_supports_report_dflt_cfg(&pf->hw)) {
+ struct ice_link_default_override_tlv *ldo;
+
+ ldo = &pf->link_dflt_override;
+ /* If override enabled and PHY mask set, then
+ * Advertising link mode is the intersection of the PHY
+ * types without media and the override PHY mask.
+ */
+ if (ldo->options & ICE_LINK_OVERRIDE_EN &&
+ (ldo->phy_type_low || ldo->phy_type_high)) {
+ advert_phy_type_lo =
+ le64_to_cpu(pf->nvm_phy_type_lo) &
+ ldo->phy_type_low;
+ advert_phy_type_hi =
+ le64_to_cpu(pf->nvm_phy_type_hi) &
+ ldo->phy_type_high;
+ }
}
} else {
+ /* strict mode */
phy_types_low = vsi->port_info->phy.phy_type_low;
phy_types_high = vsi->port_info->phy.phy_type_high;
}
@@ -1522,9 +1519,9 @@ ice_phy_type_to_ethtool(struct net_device *netdev,
/* If Advertising link mode PHY type is not using override PHY type,
* then use PHY type with media.
*/
- if (!adv_phy_type_lo && !adv_phy_type_hi) {
- adv_phy_type_lo = vsi->port_info->phy.phy_type_low;
- adv_phy_type_hi = vsi->port_info->phy.phy_type_high;
+ if (!advert_phy_type_lo && !advert_phy_type_hi) {
+ advert_phy_type_lo = vsi->port_info->phy.phy_type_low;
+ advert_phy_type_hi = vsi->port_info->phy.phy_type_high;
}
ethtool_link_ksettings_zero_link_mode(ks, supported);
@@ -2000,7 +1997,7 @@ ice_get_link_ksettings(struct net_device *netdev,
return -ENOMEM;
status = ice_aq_get_phy_caps(vsi->port_info, false,
- ICE_AQC_REPORT_SW_CFG, caps, NULL);
+ ICE_AQC_REPORT_ACTIVE_CFG, caps, NULL);
if (status) {
err = -EIO;
goto done;
@@ -2037,7 +2034,7 @@ ice_get_link_ksettings(struct net_device *netdev,
ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
status = ice_aq_get_phy_caps(vsi->port_info, false,
- ICE_AQC_REPORT_TOPO_CAP, caps, NULL);
+ ICE_AQC_REPORT_TOPO_CAP_MEDIA, caps, NULL);
if (status) {
err = -EIO;
goto done;
@@ -2204,13 +2201,14 @@ ice_set_link_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *ks)
{
struct ice_netdev_priv *np = netdev_priv(netdev);
- struct ethtool_link_ksettings safe_ks, copy_ks;
- struct ice_aqc_get_phy_caps_data *abilities;
u8 autoneg, timeout = TEST_SET_BITS_TIMEOUT;
- u16 adv_link_speed, curr_link_speed, idx;
+ struct ethtool_link_ksettings copy_ks = *ks;
+ struct ethtool_link_ksettings safe_ks = {};
+ struct ice_aqc_get_phy_caps_data *phy_caps;
struct ice_aqc_set_phy_cfg_data config;
+ u16 adv_link_speed, curr_link_speed;
struct ice_pf *pf = np->vsi->back;
- struct ice_port_info *p;
+ struct ice_port_info *pi;
u8 autoneg_changed = 0;
enum ice_status status;
u64 phy_type_high = 0;
@@ -2218,46 +2216,37 @@ ice_set_link_ksettings(struct net_device *netdev,
int err = 0;
bool linkup;
- p = np->vsi->port_info;
-
- if (!p)
- return -EOPNOTSUPP;
+ pi = np->vsi->port_info;
- /* Check if this is LAN VSI */
- ice_for_each_vsi(pf, idx)
- if (pf->vsi[idx]->type == ICE_VSI_PF) {
- if (np->vsi != pf->vsi[idx])
- return -EOPNOTSUPP;
- break;
- }
+ if (!pi)
+ return -EIO;
- if (p->phy.media_type != ICE_MEDIA_BASET &&
- p->phy.media_type != ICE_MEDIA_FIBER &&
- p->phy.media_type != ICE_MEDIA_BACKPLANE &&
- p->phy.media_type != ICE_MEDIA_DA &&
- p->phy.link_info.link_info & ICE_AQ_LINK_UP)
+ if (pi->phy.media_type != ICE_MEDIA_BASET &&
+ pi->phy.media_type != ICE_MEDIA_FIBER &&
+ pi->phy.media_type != ICE_MEDIA_BACKPLANE &&
+ pi->phy.media_type != ICE_MEDIA_DA &&
+ pi->phy.link_info.link_info & ICE_AQ_LINK_UP)
return -EOPNOTSUPP;
- abilities = kzalloc(sizeof(*abilities), GFP_KERNEL);
- if (!abilities)
+ phy_caps = kzalloc(sizeof(*phy_caps), GFP_KERNEL);
+ if (!phy_caps)
return -ENOMEM;
/* Get the PHY capabilities based on media */
- status = ice_aq_get_phy_caps(p, false, ICE_AQC_REPORT_TOPO_CAP,
- abilities, NULL);
+ if (ice_fw_supports_report_dflt_cfg(pi->hw))
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_DFLT_CFG,
+ phy_caps, NULL);
+ else
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA,
+ phy_caps, NULL);
if (status) {
- err = -EAGAIN;
+ err = -EIO;
goto done;
}
- /* copy the ksettings to copy_ks to avoid modifying the original */
- memcpy(&copy_ks, ks, sizeof(copy_ks));
-
/* save autoneg out of ksettings */
autoneg = copy_ks.base.autoneg;
- memset(&safe_ks, 0, sizeof(safe_ks));
-
/* Get link modes supported by hardware.*/
ice_phy_type_to_ethtool(netdev, &safe_ks);
@@ -2269,7 +2258,7 @@ ice_set_link_ksettings(struct net_device *netdev,
__ETHTOOL_LINK_MODE_MASK_NBITS)) {
if (!test_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags))
netdev_info(netdev, "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
- err = -EINVAL;
+ err = -EOPNOTSUPP;
goto done;
}
@@ -2306,26 +2295,26 @@ ice_set_link_ksettings(struct net_device *netdev,
* configuration is initialized during probe from PHY capabilities
* software mode, and updated on set PHY configuration.
*/
- memcpy(&config, &p->phy.curr_user_phy_cfg, sizeof(config));
+ config = pi->phy.curr_user_phy_cfg;
config.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
/* Check autoneg */
- err = ice_setup_autoneg(p, &safe_ks, &config, autoneg, &autoneg_changed,
+ err = ice_setup_autoneg(pi, &safe_ks, &config, autoneg, &autoneg_changed,
netdev);
if (err)
goto done;
/* Call to get the current link speed */
- p->phy.get_link_info = true;
- status = ice_get_link_status(p, &linkup);
+ pi->phy.get_link_info = true;
+ status = ice_get_link_status(pi, &linkup);
if (status) {
- err = -EAGAIN;
+ err = -EIO;
goto done;
}
- curr_link_speed = p->phy.link_info.link_speed;
+ curr_link_speed = pi->phy.link_info.link_speed;
adv_link_speed = ice_ksettings_find_adv_link_speed(ks);
/* If speed didn't get set, set it to what it currently is.
@@ -2344,7 +2333,7 @@ ice_set_link_ksettings(struct net_device *netdev,
}
/* save the requested speeds */
- p->phy.link_info.req_speeds = adv_link_speed;
+ pi->phy.link_info.req_speeds = adv_link_speed;
/* set link and auto negotiation so changes take effect */
config.caps |= ICE_AQ_PHY_ENA_LINK;
@@ -2352,7 +2341,7 @@ ice_set_link_ksettings(struct net_device *netdev,
/* check if there is a PHY type for the requested advertised speed */
if (!(phy_type_low || phy_type_high)) {
netdev_info(netdev, "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
- err = -EAGAIN;
+ err = -EOPNOTSUPP;
goto done;
}
@@ -2360,9 +2349,9 @@ ice_set_link_ksettings(struct net_device *netdev,
* for set PHY configuration
*/
config.phy_type_high = cpu_to_le64(phy_type_high) &
- abilities->phy_type_high;
+ phy_caps->phy_type_high;
config.phy_type_low = cpu_to_le64(phy_type_low) &
- abilities->phy_type_low;
+ phy_caps->phy_type_low;
if (!(config.phy_type_high || config.phy_type_low)) {
/* If there is no intersection and lenient mode is enabled, then
@@ -2376,13 +2365,13 @@ ice_set_link_ksettings(struct net_device *netdev,
pf->nvm_phy_type_lo;
} else {
netdev_info(netdev, "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
- err = -EAGAIN;
+ err = -EOPNOTSUPP;
goto done;
}
}
/* If link is up put link down */
- if (p->phy.link_info.link_info & ICE_AQ_LINK_UP) {
+ if (pi->phy.link_info.link_info & ICE_AQ_LINK_UP) {
/* Tell the OS link is going down, the link will go
* back up when fw says it is ready asynchronously
*/
@@ -2392,17 +2381,17 @@ ice_set_link_ksettings(struct net_device *netdev,
}
/* make the aq call */
- status = ice_aq_set_phy_cfg(&pf->hw, p, &config, NULL);
+ status = ice_aq_set_phy_cfg(&pf->hw, pi, &config, NULL);
if (status) {
netdev_info(netdev, "Set phy config failed,\n");
- err = -EAGAIN;
+ err = -EIO;
goto done;
}
/* Save speed request */
- p->phy.curr_user_speed_req = adv_link_speed;
+ pi->phy.curr_user_speed_req = adv_link_speed;
done:
- kfree(abilities);
+ kfree(phy_caps);
clear_bit(__ICE_CFG_BUSY, pf->state);
return err;
@@ -2972,7 +2961,7 @@ ice_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
return;
/* Get current PHY config */
- status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG, pcaps,
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_ACTIVE_CFG, pcaps,
NULL);
if (status)
goto out;
@@ -3039,7 +3028,7 @@ ice_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
return -ENOMEM;
/* Get current PHY config */
- status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG, pcaps,
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_ACTIVE_CFG, pcaps,
NULL);
if (status) {
kfree(pcaps);