Skip to content

Commit 1585a8a

Browse files
committed
Merge branch 'bcmgenet_eee'
Florian Fainelli says: ==================== net: bcmgenet: EEE support This patch series add EEE support to the Broadcom GENET driver, first patch basically adds register definitions for the hardware, the second patch does the actual implementation and hooks the {get,set}_eee ethtool callbacks, the last patch adds auto-negotiation restart capability. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 8b7f8a9 + 6b0c540 commit 1585a8a

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

drivers/net/ethernet/broadcom/genet/bcmgenet.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,98 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev,
714714
}
715715
}
716716

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+
717809
/* standard ethtool support functions. */
718810
static struct ethtool_ops bcmgenet_ethtool_ops = {
719811
.get_strings = bcmgenet_get_strings,
@@ -727,6 +819,9 @@ static struct ethtool_ops bcmgenet_ethtool_ops = {
727819
.set_msglevel = bcmgenet_set_msglevel,
728820
.get_wol = bcmgenet_get_wol,
729821
.set_wol = bcmgenet_set_wol,
822+
.get_eee = bcmgenet_get_eee,
823+
.set_eee = bcmgenet_set_eee,
824+
.nway_reset = bcmgenet_nway_reset,
730825
};
731826

732827
/* Power down the unimac, based on mode. */
@@ -2585,6 +2680,12 @@ static int bcmgenet_probe(struct platform_device *pdev)
25852680
if (IS_ERR(priv->clk_wol))
25862681
dev_warn(&priv->pdev->dev, "failed to get enet-wol clock\n");
25872682

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+
25882689
err = reset_umac(priv);
25892690
if (err)
25902691
goto err_clk_disable;
@@ -2735,6 +2836,9 @@ static int bcmgenet_resume(struct device *d)
27352836

27362837
phy_resume(priv->phydev);
27372838

2839+
if (priv->eee.eee_enabled)
2840+
bcmgenet_eee_enable_set(dev, true);
2841+
27382842
bcmgenet_netif_start(dev);
27392843

27402844
return 0;

drivers/net/ethernet/broadcom/genet/bcmgenet.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,21 @@ struct bcmgenet_mib_counters {
185185
#define UMAC_MAC1 0x010
186186
#define UMAC_MAX_FRAME_LEN 0x014
187187

188+
#define UMAC_EEE_CTRL 0x064
189+
#define EN_LPI_RX_PAUSE (1 << 0)
190+
#define EN_LPI_TX_PFC (1 << 1)
191+
#define EN_LPI_TX_PAUSE (1 << 2)
192+
#define EEE_EN (1 << 3)
193+
#define RX_FIFO_CHECK (1 << 4)
194+
#define EEE_TX_CLK_DIS (1 << 5)
195+
#define DIS_EEE_10M (1 << 6)
196+
#define LP_IDLE_PREDICTION_MODE (1 << 7)
197+
198+
#define UMAC_EEE_LPI_TIMER 0x068
199+
#define UMAC_EEE_WAKE_TIMER 0x06C
200+
#define UMAC_EEE_REF_COUNT 0x070
201+
#define EEE_REFERENCE_COUNT_MASK 0xffff
202+
188203
#define UMAC_TX_FLUSH 0x334
189204

190205
#define UMAC_MIB_START 0x400
@@ -232,6 +247,10 @@ struct bcmgenet_mib_counters {
232247
#define RBUF_RXCHK_EN (1 << 0)
233248
#define RBUF_SKIP_FCS (1 << 4)
234249

250+
#define RBUF_ENERGY_CTRL 0x9c
251+
#define RBUF_EEE_EN (1 << 0)
252+
#define RBUF_PM_EN (1 << 1)
253+
235254
#define RBUF_TBUF_SIZE_CTRL 0xb4
236255

237256
#define RBUF_HFB_CTRL_V1 0x38
@@ -247,6 +266,9 @@ struct bcmgenet_mib_counters {
247266

248267
#define TBUF_CTRL 0x00
249268
#define TBUF_BP_MC 0x0C
269+
#define TBUF_ENERGY_CTRL 0x14
270+
#define TBUF_EEE_EN (1 << 0)
271+
#define TBUF_PM_EN (1 << 1)
250272

251273
#define TBUF_CTRL_V1 0x80
252274
#define TBUF_BP_MC_V1 0xA0
@@ -551,6 +573,8 @@ struct bcmgenet_priv {
551573
struct device_node *phy_dn;
552574
struct mii_bus *mii_bus;
553575
u16 gphy_rev;
576+
struct clk *clk_eee;
577+
bool clk_eee_enabled;
554578

555579
/* PHY device variables */
556580
int old_link;
@@ -587,6 +611,8 @@ struct bcmgenet_priv {
587611
u32 wolopts;
588612

589613
struct bcmgenet_mib_counters mib;
614+
615+
struct ethtool_eee eee;
590616
};
591617

592618
#define GENET_IO_MACRO(name, offset) \

0 commit comments

Comments
 (0)