@@ -714,6 +714,98 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev,
714
714
}
715
715
}
716
716
717
+ static void bcmgenet_eee_enable_set (struct net_device * dev , bool enable )
718
+ {
719
+ struct bcmgenet_priv * priv = netdev_priv (dev );
720
+ u32 off = priv -> hw_params -> tbuf_offset + TBUF_ENERGY_CTRL ;
721
+ u32 reg ;
722
+
723
+ if (enable && !priv -> clk_eee_enabled ) {
724
+ clk_prepare_enable (priv -> clk_eee );
725
+ priv -> clk_eee_enabled = true;
726
+ }
727
+
728
+ reg = bcmgenet_umac_readl (priv , UMAC_EEE_CTRL );
729
+ if (enable )
730
+ reg |= EEE_EN ;
731
+ else
732
+ reg &= ~EEE_EN ;
733
+ bcmgenet_umac_writel (priv , reg , UMAC_EEE_CTRL );
734
+
735
+ /* Enable EEE and switch to a 27Mhz clock automatically */
736
+ reg = __raw_readl (priv -> base + off );
737
+ if (enable )
738
+ reg |= TBUF_EEE_EN | TBUF_PM_EN ;
739
+ else
740
+ reg &= ~(TBUF_EEE_EN | TBUF_PM_EN );
741
+ __raw_writel (reg , priv -> base + off );
742
+
743
+ /* Do the same for thing for RBUF */
744
+ reg = bcmgenet_rbuf_readl (priv , RBUF_ENERGY_CTRL );
745
+ if (enable )
746
+ reg |= RBUF_EEE_EN | RBUF_PM_EN ;
747
+ else
748
+ reg &= ~(RBUF_EEE_EN | RBUF_PM_EN );
749
+ bcmgenet_rbuf_writel (priv , reg , RBUF_ENERGY_CTRL );
750
+
751
+ if (!enable && priv -> clk_eee_enabled ) {
752
+ clk_disable_unprepare (priv -> clk_eee );
753
+ priv -> clk_eee_enabled = false;
754
+ }
755
+
756
+ priv -> eee .eee_enabled = enable ;
757
+ priv -> eee .eee_active = enable ;
758
+ }
759
+
760
+ static int bcmgenet_get_eee (struct net_device * dev , struct ethtool_eee * e )
761
+ {
762
+ struct bcmgenet_priv * priv = netdev_priv (dev );
763
+ struct ethtool_eee * p = & priv -> eee ;
764
+
765
+ if (GENET_IS_V1 (priv ))
766
+ return - EOPNOTSUPP ;
767
+
768
+ e -> eee_enabled = p -> eee_enabled ;
769
+ e -> eee_active = p -> eee_active ;
770
+ e -> tx_lpi_timer = bcmgenet_umac_readl (priv , UMAC_EEE_LPI_TIMER );
771
+
772
+ return phy_ethtool_get_eee (priv -> phydev , e );
773
+ }
774
+
775
+ static int bcmgenet_set_eee (struct net_device * dev , struct ethtool_eee * e )
776
+ {
777
+ struct bcmgenet_priv * priv = netdev_priv (dev );
778
+ struct ethtool_eee * p = & priv -> eee ;
779
+ int ret = 0 ;
780
+
781
+ if (GENET_IS_V1 (priv ))
782
+ return - EOPNOTSUPP ;
783
+
784
+ p -> eee_enabled = e -> eee_enabled ;
785
+
786
+ if (!p -> eee_enabled ) {
787
+ bcmgenet_eee_enable_set (dev , false);
788
+ } else {
789
+ ret = phy_init_eee (priv -> phydev , 0 );
790
+ if (ret ) {
791
+ netif_err (priv , hw , dev , "EEE initialization failed\n" );
792
+ return ret ;
793
+ }
794
+
795
+ bcmgenet_umac_writel (priv , e -> tx_lpi_timer , UMAC_EEE_LPI_TIMER );
796
+ bcmgenet_eee_enable_set (dev , true);
797
+ }
798
+
799
+ return phy_ethtool_set_eee (priv -> phydev , e );
800
+ }
801
+
802
+ static int bcmgenet_nway_reset (struct net_device * dev )
803
+ {
804
+ struct bcmgenet_priv * priv = netdev_priv (dev );
805
+
806
+ return genphy_restart_aneg (priv -> phydev );
807
+ }
808
+
717
809
/* standard ethtool support functions. */
718
810
static struct ethtool_ops bcmgenet_ethtool_ops = {
719
811
.get_strings = bcmgenet_get_strings ,
@@ -727,6 +819,9 @@ static struct ethtool_ops bcmgenet_ethtool_ops = {
727
819
.set_msglevel = bcmgenet_set_msglevel ,
728
820
.get_wol = bcmgenet_get_wol ,
729
821
.set_wol = bcmgenet_set_wol ,
822
+ .get_eee = bcmgenet_get_eee ,
823
+ .set_eee = bcmgenet_set_eee ,
824
+ .nway_reset = bcmgenet_nway_reset ,
730
825
};
731
826
732
827
/* Power down the unimac, based on mode. */
@@ -2585,6 +2680,12 @@ static int bcmgenet_probe(struct platform_device *pdev)
2585
2680
if (IS_ERR (priv -> clk_wol ))
2586
2681
dev_warn (& priv -> pdev -> dev , "failed to get enet-wol clock\n" );
2587
2682
2683
+ priv -> clk_eee = devm_clk_get (& priv -> pdev -> dev , "enet-eee" );
2684
+ if (IS_ERR (priv -> clk_eee )) {
2685
+ dev_warn (& priv -> pdev -> dev , "failed to get enet-eee clock\n" );
2686
+ priv -> clk_eee = NULL ;
2687
+ }
2688
+
2588
2689
err = reset_umac (priv );
2589
2690
if (err )
2590
2691
goto err_clk_disable ;
@@ -2735,6 +2836,9 @@ static int bcmgenet_resume(struct device *d)
2735
2836
2736
2837
phy_resume (priv -> phydev );
2737
2838
2839
+ if (priv -> eee .eee_enabled )
2840
+ bcmgenet_eee_enable_set (dev , true);
2841
+
2738
2842
bcmgenet_netif_start (dev );
2739
2843
2740
2844
return 0 ;
0 commit comments