Skip to content

Commit 95f352d

Browse files
aloktionanguy11
authored andcommitted
i40e: Add EEE status getting & setting implementation
Implement Energy Efficient Ethernet (EEE) status getting & setting. The i40e_get_eee() requesting PHY EEE capabilities from firmware. The i40e_set_eee() function requests PHY EEE capabilities from firmware and sets PHY EEE advertising to full abilities or 0 depending whether EEE is to be enabled or disabled. Signed-off-by: Aleksandr Loktionov <[email protected]> Tested-by: Tony Brelinski <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 5effa78 commit 95f352d

File tree

2 files changed

+123
-2
lines changed

2 files changed

+123
-2
lines changed

drivers/net/ethernet/intel/i40e/i40e_ethtool.c

Lines changed: 121 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5242,12 +5242,131 @@ static int i40e_get_module_eeprom(struct net_device *netdev,
52425242

52435243
static int i40e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
52445244
{
5245-
return -EOPNOTSUPP;
5245+
struct i40e_netdev_priv *np = netdev_priv(netdev);
5246+
struct i40e_aq_get_phy_abilities_resp phy_cfg;
5247+
enum i40e_status_code status = 0;
5248+
struct i40e_vsi *vsi = np->vsi;
5249+
struct i40e_pf *pf = vsi->back;
5250+
struct i40e_hw *hw = &pf->hw;
5251+
5252+
/* Get initial PHY capabilities */
5253+
status = i40e_aq_get_phy_capabilities(hw, false, true, &phy_cfg, NULL);
5254+
if (status)
5255+
return -EAGAIN;
5256+
5257+
/* Check whether NIC configuration is compatible with Energy Efficient
5258+
* Ethernet (EEE) mode.
5259+
*/
5260+
if (phy_cfg.eee_capability == 0)
5261+
return -EOPNOTSUPP;
5262+
5263+
edata->supported = SUPPORTED_Autoneg;
5264+
edata->lp_advertised = edata->supported;
5265+
5266+
/* Get current configuration */
5267+
status = i40e_aq_get_phy_capabilities(hw, false, false, &phy_cfg, NULL);
5268+
if (status)
5269+
return -EAGAIN;
5270+
5271+
edata->advertised = phy_cfg.eee_capability ? SUPPORTED_Autoneg : 0U;
5272+
edata->eee_enabled = !!edata->advertised;
5273+
edata->tx_lpi_enabled = pf->stats.tx_lpi_status;
5274+
5275+
edata->eee_active = pf->stats.tx_lpi_status && pf->stats.rx_lpi_status;
5276+
5277+
return 0;
5278+
}
5279+
5280+
static int i40e_is_eee_param_supported(struct net_device *netdev,
5281+
struct ethtool_eee *edata)
5282+
{
5283+
struct i40e_netdev_priv *np = netdev_priv(netdev);
5284+
struct i40e_vsi *vsi = np->vsi;
5285+
struct i40e_pf *pf = vsi->back;
5286+
struct i40e_ethtool_not_used {
5287+
u32 value;
5288+
const char *name;
5289+
} param[] = {
5290+
{edata->advertised & ~SUPPORTED_Autoneg, "advertise"},
5291+
{edata->tx_lpi_timer, "tx-timer"},
5292+
{edata->tx_lpi_enabled != pf->stats.tx_lpi_status, "tx-lpi"}
5293+
};
5294+
int i;
5295+
5296+
for (i = 0; i < ARRAY_SIZE(param); i++) {
5297+
if (param[i].value) {
5298+
netdev_info(netdev,
5299+
"EEE setting %s not supported\n",
5300+
param[i].name);
5301+
return -EOPNOTSUPP;
5302+
}
5303+
}
5304+
5305+
return 0;
52465306
}
52475307

52485308
static int i40e_set_eee(struct net_device *netdev, struct ethtool_eee *edata)
52495309
{
5250-
return -EOPNOTSUPP;
5310+
struct i40e_netdev_priv *np = netdev_priv(netdev);
5311+
struct i40e_aq_get_phy_abilities_resp abilities;
5312+
enum i40e_status_code status = I40E_SUCCESS;
5313+
struct i40e_aq_set_phy_config config;
5314+
struct i40e_vsi *vsi = np->vsi;
5315+
struct i40e_pf *pf = vsi->back;
5316+
struct i40e_hw *hw = &pf->hw;
5317+
__le16 eee_capability;
5318+
5319+
/* Deny parameters we don't support */
5320+
if (i40e_is_eee_param_supported(netdev, edata))
5321+
return -EOPNOTSUPP;
5322+
5323+
/* Get initial PHY capabilities */
5324+
status = i40e_aq_get_phy_capabilities(hw, false, true, &abilities,
5325+
NULL);
5326+
if (status)
5327+
return -EAGAIN;
5328+
5329+
/* Check whether NIC configuration is compatible with Energy Efficient
5330+
* Ethernet (EEE) mode.
5331+
*/
5332+
if (abilities.eee_capability == 0)
5333+
return -EOPNOTSUPP;
5334+
5335+
/* Cache initial EEE capability */
5336+
eee_capability = abilities.eee_capability;
5337+
5338+
/* Get current PHY configuration */
5339+
status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
5340+
NULL);
5341+
if (status)
5342+
return -EAGAIN;
5343+
5344+
/* Cache current PHY configuration */
5345+
config.phy_type = abilities.phy_type;
5346+
config.phy_type_ext = abilities.phy_type_ext;
5347+
config.link_speed = abilities.link_speed;
5348+
config.abilities = abilities.abilities |
5349+
I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
5350+
config.eeer = abilities.eeer_val;
5351+
config.low_power_ctrl = abilities.d3_lpan;
5352+
config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
5353+
I40E_AQ_PHY_FEC_CONFIG_MASK;
5354+
5355+
/* Set desired EEE state */
5356+
if (edata->eee_enabled) {
5357+
config.eee_capability = eee_capability;
5358+
config.eeer |= cpu_to_le32(I40E_PRTPM_EEER_TX_LPI_EN_MASK);
5359+
} else {
5360+
config.eee_capability = 0;
5361+
config.eeer &= cpu_to_le32(~I40E_PRTPM_EEER_TX_LPI_EN_MASK);
5362+
}
5363+
5364+
/* Apply modified PHY configuration */
5365+
status = i40e_aq_set_phy_config(hw, &config, NULL);
5366+
if (status)
5367+
return -EAGAIN;
5368+
5369+
return 0;
52515370
}
52525371

52535372
static const struct ethtool_ops i40e_ethtool_recovery_mode_ops = {

drivers/net/ethernet/intel/i40e/i40e_register.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,8 @@
544544
#define I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK I40E_MASK(0x1, I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT)
545545
#define I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT 31
546546
#define I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK I40E_MASK(0x1, I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT)
547+
#define I40E_PRTPM_EEER_TX_LPI_EN_SHIFT 16
548+
#define I40E_PRTPM_EEER_TX_LPI_EN_MASK I40E_MASK(0x1, I40E_PRTPM_EEER_TX_LPI_EN_SHIFT)
547549
#define I40E_PRTPM_RLPIC 0x001E43A0 /* Reset: GLOBR */
548550
#define I40E_PRTPM_TLPIC 0x001E43C0 /* Reset: GLOBR */
549551
#define I40E_PRTRPB_DHW(_i) (0x000AC100 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */

0 commit comments

Comments
 (0)