@@ -5242,12 +5242,131 @@ static int i40e_get_module_eeprom(struct net_device *netdev,
52425242
52435243static 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
52485308static 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
52535372static const struct ethtool_ops i40e_ethtool_recovery_mode_ops = {
0 commit comments