bnxt_en: Add get_eee() and set_eee() ethtool support.

Allow users to get|set EEE parameters.

v2: Added comment for preserving the tx_lpi_timer value in get_eee.

Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Michael Chan 2016-04-05 14:08:59 -04:00 committed by David S. Miller
parent 939f7f0ca4
commit 72b34f04e0

View File

@ -1379,6 +1379,80 @@ static int bnxt_set_eeprom(struct net_device *dev,
eeprom->len);
}
static int bnxt_set_eee(struct net_device *dev, struct ethtool_eee *edata)
{
struct bnxt *bp = netdev_priv(dev);
struct ethtool_eee *eee = &bp->eee;
struct bnxt_link_info *link_info = &bp->link_info;
u32 advertising =
_bnxt_fw_to_ethtool_adv_spds(link_info->advertising, 0);
int rc = 0;
if (BNXT_VF(bp))
return 0;
if (!(bp->flags & BNXT_FLAG_EEE_CAP))
return -EOPNOTSUPP;
if (!edata->eee_enabled)
goto eee_ok;
if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) {
netdev_warn(dev, "EEE requires autoneg\n");
return -EINVAL;
}
if (edata->tx_lpi_enabled) {
if (bp->lpi_tmr_hi && (edata->tx_lpi_timer > bp->lpi_tmr_hi ||
edata->tx_lpi_timer < bp->lpi_tmr_lo)) {
netdev_warn(dev, "Valid LPI timer range is %d and %d microsecs\n",
bp->lpi_tmr_lo, bp->lpi_tmr_hi);
return -EINVAL;
} else if (!bp->lpi_tmr_hi) {
edata->tx_lpi_timer = eee->tx_lpi_timer;
}
}
if (!edata->advertised) {
edata->advertised = advertising & eee->supported;
} else if (edata->advertised & ~advertising) {
netdev_warn(dev, "EEE advertised %x must be a subset of autoneg advertised speeds %x\n",
edata->advertised, advertising);
return -EINVAL;
}
eee->advertised = edata->advertised;
eee->tx_lpi_enabled = edata->tx_lpi_enabled;
eee->tx_lpi_timer = edata->tx_lpi_timer;
eee_ok:
eee->eee_enabled = edata->eee_enabled;
if (netif_running(dev))
rc = bnxt_hwrm_set_link_setting(bp, false, true);
return rc;
}
static int bnxt_get_eee(struct net_device *dev, struct ethtool_eee *edata)
{
struct bnxt *bp = netdev_priv(dev);
if (!(bp->flags & BNXT_FLAG_EEE_CAP))
return -EOPNOTSUPP;
*edata = bp->eee;
if (!bp->eee.eee_enabled) {
/* Preserve tx_lpi_timer so that the last value will be used
* by default when it is re-enabled.
*/
edata->advertised = 0;
edata->tx_lpi_enabled = 0;
}
if (!bp->eee.eee_active)
edata->lp_advertised = 0;
return 0;
}
const struct ethtool_ops bnxt_ethtool_ops = {
.get_settings = bnxt_get_settings,
.set_settings = bnxt_set_settings,
@ -1407,4 +1481,6 @@ const struct ethtool_ops bnxt_ethtool_ops = {
.get_eeprom = bnxt_get_eeprom,
.set_eeprom = bnxt_set_eeprom,
.get_link = bnxt_get_link,
.get_eee = bnxt_get_eee,
.set_eee = bnxt_set_eee,
};