@@ -1789,54 +1789,15 @@ static int lan78xx_set_wol(struct net_device *netdev,
1789
1789
static int lan78xx_get_eee (struct net_device * net , struct ethtool_keee * edata )
1790
1790
{
1791
1791
struct lan78xx_net * dev = netdev_priv (net );
1792
- struct phy_device * phydev = net -> phydev ;
1793
- int ret ;
1794
- u32 buf ;
1795
-
1796
- ret = usb_autopm_get_interface (dev -> intf );
1797
- if (ret < 0 )
1798
- return ret ;
1799
-
1800
- ret = phy_ethtool_get_eee (phydev , edata );
1801
- if (ret < 0 )
1802
- goto exit ;
1803
1792
1804
- ret = lan78xx_read_reg (dev , MAC_CR , & buf );
1805
- if (buf & MAC_CR_EEE_EN_ ) {
1806
- /* EEE_TX_LPI_REQ_DLY & tx_lpi_timer are same uSec unit */
1807
- ret = lan78xx_read_reg (dev , EEE_TX_LPI_REQ_DLY , & buf );
1808
- edata -> tx_lpi_timer = buf ;
1809
- } else {
1810
- edata -> tx_lpi_timer = 0 ;
1811
- }
1812
-
1813
- ret = 0 ;
1814
- exit :
1815
- usb_autopm_put_interface (dev -> intf );
1816
-
1817
- return ret ;
1793
+ return phylink_ethtool_get_eee (dev -> phylink , edata );
1818
1794
}
1819
1795
1820
1796
static int lan78xx_set_eee (struct net_device * net , struct ethtool_keee * edata )
1821
1797
{
1822
1798
struct lan78xx_net * dev = netdev_priv (net );
1823
- int ret ;
1824
- u32 buf ;
1825
-
1826
- ret = usb_autopm_get_interface (dev -> intf );
1827
- if (ret < 0 )
1828
- return ret ;
1829
1799
1830
- ret = phy_ethtool_set_eee (net -> phydev , edata );
1831
- if (ret < 0 )
1832
- goto out ;
1833
-
1834
- buf = (u32 )edata -> tx_lpi_timer ;
1835
- ret = lan78xx_write_reg (dev , EEE_TX_LPI_REQ_DLY , buf );
1836
- out :
1837
- usb_autopm_put_interface (dev -> intf );
1838
-
1839
- return ret ;
1800
+ return phylink_ethtool_set_eee (dev -> phylink , edata );
1840
1801
}
1841
1802
1842
1803
static void lan78xx_get_drvinfo (struct net_device * net ,
@@ -2557,10 +2518,62 @@ static void lan78xx_mac_link_up(struct phylink_config *config,
2557
2518
ERR_PTR (ret ));
2558
2519
}
2559
2520
2521
+ /**
2522
+ * lan78xx_mac_eee_enable - Enable or disable MAC-side EEE support
2523
+ * @dev: LAN78xx device
2524
+ * @enable: true to enable EEE, false to disable
2525
+ *
2526
+ * This function sets or clears the MAC_CR_EEE_EN_ bit to control Energy
2527
+ * Efficient Ethernet (EEE) operation. According to current understanding
2528
+ * of the LAN7800 documentation, this bit can be modified while TX and RX
2529
+ * are enabled. No explicit requirement was found to disable data paths
2530
+ * before changing this bit.
2531
+ *
2532
+ * Return: 0 on success or a negative error code
2533
+ */
2534
+ static int lan78xx_mac_eee_enable (struct lan78xx_net * dev , bool enable )
2535
+ {
2536
+ u32 mac_cr = 0 ;
2537
+
2538
+ if (enable )
2539
+ mac_cr |= MAC_CR_EEE_EN_ ;
2540
+
2541
+ return lan78xx_update_reg (dev , MAC_CR , MAC_CR_EEE_EN_ , mac_cr );
2542
+ }
2543
+
2544
+ static void lan78xx_mac_disable_tx_lpi (struct phylink_config * config )
2545
+ {
2546
+ struct net_device * net = to_net_dev (config -> dev );
2547
+ struct lan78xx_net * dev = netdev_priv (net );
2548
+
2549
+ lan78xx_mac_eee_enable (dev , false);
2550
+ }
2551
+
2552
+ static int lan78xx_mac_enable_tx_lpi (struct phylink_config * config , u32 timer ,
2553
+ bool tx_clk_stop )
2554
+ {
2555
+ struct net_device * net = to_net_dev (config -> dev );
2556
+ struct lan78xx_net * dev = netdev_priv (net );
2557
+ int ret ;
2558
+
2559
+ /* Software should only change this field when Energy Efficient
2560
+ * Ethernet Enable (EEEEN) is cleared. We ensure that by clearing
2561
+ * EEEEN during probe, and phylink itself guarantees that
2562
+ * mac_disable_tx_lpi() will have been previously called.
2563
+ */
2564
+ ret = lan78xx_write_reg (dev , EEE_TX_LPI_REQ_DLY , timer );
2565
+ if (ret < 0 )
2566
+ return ret ;
2567
+
2568
+ return lan78xx_mac_eee_enable (dev , true);
2569
+ }
2570
+
2560
2571
static const struct phylink_mac_ops lan78xx_phylink_mac_ops = {
2561
2572
.mac_config = lan78xx_mac_config ,
2562
2573
.mac_link_down = lan78xx_mac_link_down ,
2563
2574
.mac_link_up = lan78xx_mac_link_up ,
2575
+ .mac_disable_tx_lpi = lan78xx_mac_disable_tx_lpi ,
2576
+ .mac_enable_tx_lpi = lan78xx_mac_enable_tx_lpi ,
2564
2577
};
2565
2578
2566
2579
/**
@@ -2756,12 +2769,36 @@ static int lan78xx_phylink_setup(struct lan78xx_net *dev)
2756
2769
pc -> mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE | MAC_10 |
2757
2770
MAC_100 | MAC_1000FD ;
2758
2771
pc -> mac_managed_pm = true;
2772
+ pc -> lpi_capabilities = MAC_100FD | MAC_1000FD ;
2773
+ /*
2774
+ * Default TX LPI (Low Power Idle) request delay count is set to 50us.
2775
+ *
2776
+ * Source: LAN7800 Documentation, DS00001992H, Section 15.1.57, Page 204.
2777
+ *
2778
+ * Reasoning:
2779
+ * According to the application note in the LAN7800 documentation, a
2780
+ * zero delay may negatively impact the TX data path’s ability to
2781
+ * support Gigabit operation. A value of 50us is recommended as a
2782
+ * reasonable default when the part operates at Gigabit speeds,
2783
+ * balancing stability and power efficiency in EEE mode. This delay can
2784
+ * be increased based on performance testing, as EEE is designed for
2785
+ * scenarios with mostly idle links and occasional bursts of full
2786
+ * bandwidth transmission. The goal is to ensure reliable Gigabit
2787
+ * performance without overly aggressive power optimization during
2788
+ * inactive periods.
2789
+ */
2790
+ pc -> lpi_timer_default = 50 ;
2791
+ pc -> eee_enabled_default = true;
2759
2792
2760
2793
if (dev -> chipid == ID_REV_CHIP_ID_7801_ )
2761
2794
phy_interface_set_rgmii (pc -> supported_interfaces );
2762
2795
else
2763
2796
__set_bit (PHY_INTERFACE_MODE_GMII , pc -> supported_interfaces );
2764
2797
2798
+ memcpy (dev -> phylink_config .lpi_interfaces ,
2799
+ dev -> phylink_config .supported_interfaces ,
2800
+ sizeof (dev -> phylink_config .lpi_interfaces ));
2801
+
2765
2802
phylink = phylink_create (pc , dev -> net -> dev .fwnode ,
2766
2803
dev -> interface , & lan78xx_phylink_mac_ops );
2767
2804
if (IS_ERR (phylink ))
@@ -2827,8 +2864,6 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
2827
2864
goto phylink_uninit ;
2828
2865
}
2829
2866
2830
- phy_support_eee (phydev );
2831
-
2832
2867
ret = lan78xx_configure_leds_from_dt (dev , phydev );
2833
2868
if (ret < 0 )
2834
2869
goto phylink_uninit ;
@@ -3333,7 +3368,7 @@ static int lan78xx_reset(struct lan78xx_net *dev)
3333
3368
if (ret < 0 )
3334
3369
return ret ;
3335
3370
3336
- buf &= ~(MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_ );
3371
+ buf &= ~(MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_ | MAC_CR_EEE_EN_ );
3337
3372
3338
3373
/* LAN7801 only has RGMII mode */
3339
3374
if (dev -> chipid == ID_REV_CHIP_ID_7801_ )
0 commit comments