Commit 6fb5dfee authored by Heiner Kallweit's avatar Heiner Kallweit Committed by Jakub Kicinski

bnxt: convert EEE handling to use linkmode bitmaps

Convert EEE handling to use linkmode bitmaps. This prepares for removing
the legacy bitmaps from struct ethtool_keee. No functional change
intended. When replacing _bnxt_fw_to_ethtool_adv_spds() with
_bnxt_fw_to_linkmode(), remove the fw_pause argument because it's
always passed as 0.

Note:
There's a discussion on whether the underlying implementation is correct,
but it's independent of this mechanical conversion w/o functional change.
Signed-off-by: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: default avatarMichael Chan <michael.chan@broadcom.com>
Link: https://lore.kernel.org/r/9123bf18-a0d0-404e-a7c4-d6c466b4c5e8@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 5c80e62a
...@@ -10624,7 +10624,7 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp) ...@@ -10624,7 +10624,7 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp)
struct ethtool_keee *eee = &bp->eee; struct ethtool_keee *eee = &bp->eee;
u16 fw_speeds = le16_to_cpu(resp->supported_speeds_eee_mode); u16 fw_speeds = le16_to_cpu(resp->supported_speeds_eee_mode);
eee->supported_u32 = _bnxt_fw_to_ethtool_adv_spds(fw_speeds, 0); _bnxt_fw_to_linkmode(eee->supported, fw_speeds);
bp->lpi_tmr_lo = le32_to_cpu(resp->tx_lpi_timer_low) & bp->lpi_tmr_lo = le32_to_cpu(resp->tx_lpi_timer_low) &
PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_LOW_MASK; PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_LOW_MASK;
bp->lpi_tmr_hi = le32_to_cpu(resp->valid_tx_lpi_timer_high) & bp->lpi_tmr_hi = le32_to_cpu(resp->valid_tx_lpi_timer_high) &
...@@ -10775,8 +10775,7 @@ int bnxt_update_link(struct bnxt *bp, bool chng_link_state) ...@@ -10775,8 +10775,7 @@ int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
eee->eee_active = 1; eee->eee_active = 1;
fw_speeds = le16_to_cpu( fw_speeds = le16_to_cpu(
resp->link_partner_adv_eee_link_speed_mask); resp->link_partner_adv_eee_link_speed_mask);
eee->lp_advertised_u32 = _bnxt_fw_to_linkmode(eee->lp_advertised, fw_speeds);
_bnxt_fw_to_ethtool_adv_spds(fw_speeds, 0);
} }
/* Pull initial EEE config */ /* Pull initial EEE config */
...@@ -10786,8 +10785,7 @@ int bnxt_update_link(struct bnxt *bp, bool chng_link_state) ...@@ -10786,8 +10785,7 @@ int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
eee->eee_enabled = 1; eee->eee_enabled = 1;
fw_speeds = le16_to_cpu(resp->adv_eee_link_speed_mask); fw_speeds = le16_to_cpu(resp->adv_eee_link_speed_mask);
eee->advertised_u32 = _bnxt_fw_to_linkmode(eee->advertised, fw_speeds);
_bnxt_fw_to_ethtool_adv_spds(fw_speeds, 0);
if (resp->eee_config_phy_addr & if (resp->eee_config_phy_addr &
PORT_PHY_QCFG_RESP_EEE_CONFIG_EEE_TX_LPI) { PORT_PHY_QCFG_RESP_EEE_CONFIG_EEE_TX_LPI) {
...@@ -10969,7 +10967,7 @@ static void bnxt_hwrm_set_eee(struct bnxt *bp, ...@@ -10969,7 +10967,7 @@ static void bnxt_hwrm_set_eee(struct bnxt *bp,
flags |= PORT_PHY_CFG_REQ_FLAGS_EEE_TX_LPI_DISABLE; flags |= PORT_PHY_CFG_REQ_FLAGS_EEE_TX_LPI_DISABLE;
req->flags |= cpu_to_le32(flags); req->flags |= cpu_to_le32(flags);
eee_speeds = bnxt_get_fw_auto_link_speeds(eee->advertised_u32); eee_speeds = bnxt_get_fw_auto_link_speeds(eee->advertised);
req->eee_link_speed_mask = cpu_to_le16(eee_speeds); req->eee_link_speed_mask = cpu_to_le16(eee_speeds);
req->tx_lpi_timer = cpu_to_le32(eee->tx_lpi_timer); req->tx_lpi_timer = cpu_to_le32(eee->tx_lpi_timer);
} else { } else {
...@@ -11329,15 +11327,18 @@ static bool bnxt_eee_config_ok(struct bnxt *bp) ...@@ -11329,15 +11327,18 @@ static bool bnxt_eee_config_ok(struct bnxt *bp)
return true; return true;
if (eee->eee_enabled) { if (eee->eee_enabled) {
u32 advertising = __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
_bnxt_fw_to_ethtool_adv_spds(link_info->advertising, 0); __ETHTOOL_DECLARE_LINK_MODE_MASK(tmp);
_bnxt_fw_to_linkmode(advertising, link_info->advertising);
if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) { if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) {
eee->eee_enabled = 0; eee->eee_enabled = 0;
return false; return false;
} }
if (eee->advertised_u32 & ~advertising) { if (linkmode_andnot(tmp, eee->advertised, advertising)) {
eee->advertised_u32 = advertising & eee->supported_u32; linkmode_and(eee->advertised, advertising,
eee->supported);
return false; return false;
} }
} }
......
...@@ -1751,31 +1751,21 @@ static int bnxt_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ...@@ -1751,31 +1751,21 @@ static int bnxt_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return 0; return 0;
} }
u32 _bnxt_fw_to_ethtool_adv_spds(u16 fw_speeds, u8 fw_pause) /* TODO: support 25GB, 40GB, 50GB with different cable type */
void _bnxt_fw_to_linkmode(unsigned long *mode, u16 fw_speeds)
{ {
u32 speed_mask = 0; linkmode_zero(mode);
/* TODO: support 25GB, 40GB, 50GB with different cable type */
/* set the advertised speeds */
if (fw_speeds & BNXT_LINK_SPEED_MSK_100MB) if (fw_speeds & BNXT_LINK_SPEED_MSK_100MB)
speed_mask |= ADVERTISED_100baseT_Full; linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mode);
if (fw_speeds & BNXT_LINK_SPEED_MSK_1GB) if (fw_speeds & BNXT_LINK_SPEED_MSK_1GB)
speed_mask |= ADVERTISED_1000baseT_Full; linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, mode);
if (fw_speeds & BNXT_LINK_SPEED_MSK_2_5GB) if (fw_speeds & BNXT_LINK_SPEED_MSK_2_5GB)
speed_mask |= ADVERTISED_2500baseX_Full; linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, mode);
if (fw_speeds & BNXT_LINK_SPEED_MSK_10GB) if (fw_speeds & BNXT_LINK_SPEED_MSK_10GB)
speed_mask |= ADVERTISED_10000baseT_Full; linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, mode);
if (fw_speeds & BNXT_LINK_SPEED_MSK_40GB) if (fw_speeds & BNXT_LINK_SPEED_MSK_40GB)
speed_mask |= ADVERTISED_40000baseCR4_Full; linkmode_set_bit(ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, mode);
if ((fw_pause & BNXT_LINK_PAUSE_BOTH) == BNXT_LINK_PAUSE_BOTH)
speed_mask |= ADVERTISED_Pause;
else if (fw_pause & BNXT_LINK_PAUSE_TX)
speed_mask |= ADVERTISED_Asym_Pause;
else if (fw_pause & BNXT_LINK_PAUSE_RX)
speed_mask |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
return speed_mask;
} }
enum bnxt_media_type { enum bnxt_media_type {
...@@ -2643,23 +2633,22 @@ bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed, u32 lanes) ...@@ -2643,23 +2633,22 @@ bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed, u32 lanes)
return 0; return 0;
} }
u16 bnxt_get_fw_auto_link_speeds(u32 advertising) u16 bnxt_get_fw_auto_link_speeds(const unsigned long *mode)
{ {
u16 fw_speed_mask = 0; u16 fw_speed_mask = 0;
/* only support autoneg at speed 100, 1000, and 10000 */ if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mode) ||
if (advertising & (ADVERTISED_100baseT_Full | linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mode))
ADVERTISED_100baseT_Half)) {
fw_speed_mask |= BNXT_LINK_SPEED_MSK_100MB; fw_speed_mask |= BNXT_LINK_SPEED_MSK_100MB;
}
if (advertising & (ADVERTISED_1000baseT_Full | if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, mode) ||
ADVERTISED_1000baseT_Half)) { linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, mode))
fw_speed_mask |= BNXT_LINK_SPEED_MSK_1GB; fw_speed_mask |= BNXT_LINK_SPEED_MSK_1GB;
}
if (advertising & ADVERTISED_10000baseT_Full) if (linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, mode))
fw_speed_mask |= BNXT_LINK_SPEED_MSK_10GB; fw_speed_mask |= BNXT_LINK_SPEED_MSK_10GB;
if (advertising & ADVERTISED_40000baseCR4_Full) if (linkmode_test_bit(ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, mode))
fw_speed_mask |= BNXT_LINK_SPEED_MSK_40GB; fw_speed_mask |= BNXT_LINK_SPEED_MSK_40GB;
return fw_speed_mask; return fw_speed_mask;
...@@ -3886,10 +3875,11 @@ static int bnxt_set_eeprom(struct net_device *dev, ...@@ -3886,10 +3875,11 @@ static int bnxt_set_eeprom(struct net_device *dev,
static int bnxt_set_eee(struct net_device *dev, struct ethtool_keee *edata) static int bnxt_set_eee(struct net_device *dev, struct ethtool_keee *edata)
{ {
__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
__ETHTOOL_DECLARE_LINK_MODE_MASK(tmp);
struct bnxt *bp = netdev_priv(dev); struct bnxt *bp = netdev_priv(dev);
struct ethtool_keee *eee = &bp->eee; struct ethtool_keee *eee = &bp->eee;
struct bnxt_link_info *link_info = &bp->link_info; struct bnxt_link_info *link_info = &bp->link_info;
u32 advertising;
int rc = 0; int rc = 0;
if (!BNXT_PHY_CFG_ABLE(bp)) if (!BNXT_PHY_CFG_ABLE(bp))
...@@ -3899,7 +3889,7 @@ static int bnxt_set_eee(struct net_device *dev, struct ethtool_keee *edata) ...@@ -3899,7 +3889,7 @@ static int bnxt_set_eee(struct net_device *dev, struct ethtool_keee *edata)
return -EOPNOTSUPP; return -EOPNOTSUPP;
mutex_lock(&bp->link_lock); mutex_lock(&bp->link_lock);
advertising = _bnxt_fw_to_ethtool_adv_spds(link_info->advertising, 0); _bnxt_fw_to_linkmode(advertising, link_info->advertising);
if (!edata->eee_enabled) if (!edata->eee_enabled)
goto eee_ok; goto eee_ok;
...@@ -3919,16 +3909,15 @@ static int bnxt_set_eee(struct net_device *dev, struct ethtool_keee *edata) ...@@ -3919,16 +3909,15 @@ static int bnxt_set_eee(struct net_device *dev, struct ethtool_keee *edata)
edata->tx_lpi_timer = eee->tx_lpi_timer; edata->tx_lpi_timer = eee->tx_lpi_timer;
} }
} }
if (!edata->advertised_u32) { if (linkmode_empty(edata->advertised)) {
edata->advertised_u32 = advertising & eee->supported_u32; linkmode_and(edata->advertised, advertising, eee->supported);
} else if (edata->advertised_u32 & ~advertising) { } else if (linkmode_andnot(tmp, edata->advertised, advertising)) {
netdev_warn(dev, "EEE advertised %x must be a subset of autoneg advertised speeds %x\n", netdev_warn(dev, "EEE advertised must be a subset of autoneg advertised speeds\n");
edata->advertised_u32, advertising);
rc = -EINVAL; rc = -EINVAL;
goto eee_exit; goto eee_exit;
} }
eee->advertised_u32 = edata->advertised_u32; linkmode_copy(eee->advertised, edata->advertised);
eee->tx_lpi_enabled = edata->tx_lpi_enabled; eee->tx_lpi_enabled = edata->tx_lpi_enabled;
eee->tx_lpi_timer = edata->tx_lpi_timer; eee->tx_lpi_timer = edata->tx_lpi_timer;
eee_ok: eee_ok:
...@@ -3954,12 +3943,12 @@ static int bnxt_get_eee(struct net_device *dev, struct ethtool_keee *edata) ...@@ -3954,12 +3943,12 @@ static int bnxt_get_eee(struct net_device *dev, struct ethtool_keee *edata)
/* Preserve tx_lpi_timer so that the last value will be used /* Preserve tx_lpi_timer so that the last value will be used
* by default when it is re-enabled. * by default when it is re-enabled.
*/ */
edata->advertised_u32 = 0; linkmode_zero(edata->advertised);
edata->tx_lpi_enabled = 0; edata->tx_lpi_enabled = 0;
} }
if (!bp->eee.eee_active) if (!bp->eee.eee_active)
edata->lp_advertised_u32 = 0; linkmode_zero(edata->lp_advertised);
return 0; return 0;
} }
......
...@@ -46,9 +46,9 @@ struct bnxt_led_cfg { ...@@ -46,9 +46,9 @@ struct bnxt_led_cfg {
extern const struct ethtool_ops bnxt_ethtool_ops; extern const struct ethtool_ops bnxt_ethtool_ops;
u32 bnxt_get_rxfh_indir_size(struct net_device *dev); u32 bnxt_get_rxfh_indir_size(struct net_device *dev);
u32 _bnxt_fw_to_ethtool_adv_spds(u16, u8); void _bnxt_fw_to_linkmode(unsigned long *mode, u16 fw_speeds);
u32 bnxt_fw_to_ethtool_speed(u16); u32 bnxt_fw_to_ethtool_speed(u16);
u16 bnxt_get_fw_auto_link_speeds(u32); u16 bnxt_get_fw_auto_link_speeds(const unsigned long *mode);
int bnxt_hwrm_nvm_get_dev_info(struct bnxt *bp, int bnxt_hwrm_nvm_get_dev_info(struct bnxt *bp,
struct hwrm_nvm_get_dev_info_output *nvm_dev_info); struct hwrm_nvm_get_dev_info_output *nvm_dev_info);
int bnxt_hwrm_firmware_reset(struct net_device *dev, u8 proc_type, int bnxt_hwrm_firmware_reset(struct net_device *dev, u8 proc_type,
......
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