summaryrefslogtreecommitdiff
path: root/drivers/net/phy/bcm7xxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy/bcm7xxx.c')
-rw-r--r--drivers/net/phy/bcm7xxx.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
index 29e256a..e98c510 100644
--- a/drivers/net/phy/bcm7xxx.c
+++ b/drivers/net/phy/bcm7xxx.c
@@ -14,6 +14,7 @@
#include <linux/delay.h>
#include <linux/bitops.h>
#include <linux/brcmphy.h>
+#include <linux/mdio.h>
/* Broadcom BCM7xxx internal PHY registers */
#define MII_BCM7XXX_CHANNEL_WIDTH 0x2000
@@ -167,6 +168,32 @@ static int bcm7xxx_apd_enable(struct phy_device *phydev)
return bcm54xx_shadow_write(phydev, BCM54XX_SHD_APD, val);
}
+static int bcm7xxx_eee_enable(struct phy_device *phydev)
+{
+ int val;
+
+ val = phy_read_mmd_indirect(phydev, BRCM_CL45VEN_EEE_CONTROL,
+ MDIO_MMD_AN, phydev->addr);
+ if (val < 0)
+ return val;
+
+ /* Enable general EEE feature at the PHY level */
+ val |= LPI_FEATURE_EN | LPI_FEATURE_EN_DIG1000X;
+
+ phy_write_mmd_indirect(phydev, BRCM_CL45VEN_EEE_CONTROL,
+ MDIO_MMD_AN, phydev->addr, val);
+
+ /* Advertise supported modes */
+ val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
+ MDIO_MMD_AN, phydev->addr);
+
+ val |= (MDIO_AN_EEE_ADV_100TX | MDIO_AN_EEE_ADV_1000T);
+ phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
+ MDIO_MMD_AN, phydev->addr, val);
+
+ return 0;
+}
+
static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
{
int ret;
@@ -179,6 +206,10 @@ static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
if (ret)
return ret;
+ ret = bcm7xxx_eee_enable(phydev);
+ if (ret)
+ return ret;
+
return bcm7xxx_apd_enable(phydev);
}