diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2014-08-22 21:55:45 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-08-23 14:39:09 -0400 |
commit | b8f9a02924bbeb0c46ca4c19561cbe765b80e264 (patch) | |
tree | 6990b37910085fec8a0b832f807d9e2c22ff73de /drivers/net/phy | |
parent | a9f6309585cbefa4a7f08c9017ca482c3222323a (diff) |
net: phy: bcm7xxx: enable EEE at the PHY level
The 28nm Gigabit PHY on BCM7xxx chips comes out of reset with absolutely
no EEE capabilities, such that we would actually return that we do not
support EEE when accessing 3.20 (MDIO_PCS_EEE_ABLE) registers.
Poke through the vendor-specific C45 register to enable EEE globally at
the PHY level, and advertise supported EEE modes.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/bcm7xxx.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c index 29e256a4ed57..e98c510b75c5 100644 --- a/drivers/net/phy/bcm7xxx.c +++ b/drivers/net/phy/bcm7xxx.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/bitops.h> | 15 | #include <linux/bitops.h> |
16 | #include <linux/brcmphy.h> | 16 | #include <linux/brcmphy.h> |
17 | #include <linux/mdio.h> | ||
17 | 18 | ||
18 | /* Broadcom BCM7xxx internal PHY registers */ | 19 | /* Broadcom BCM7xxx internal PHY registers */ |
19 | #define MII_BCM7XXX_CHANNEL_WIDTH 0x2000 | 20 | #define MII_BCM7XXX_CHANNEL_WIDTH 0x2000 |
@@ -167,6 +168,32 @@ static int bcm7xxx_apd_enable(struct phy_device *phydev) | |||
167 | return bcm54xx_shadow_write(phydev, BCM54XX_SHD_APD, val); | 168 | return bcm54xx_shadow_write(phydev, BCM54XX_SHD_APD, val); |
168 | } | 169 | } |
169 | 170 | ||
171 | static int bcm7xxx_eee_enable(struct phy_device *phydev) | ||
172 | { | ||
173 | int val; | ||
174 | |||
175 | val = phy_read_mmd_indirect(phydev, BRCM_CL45VEN_EEE_CONTROL, | ||
176 | MDIO_MMD_AN, phydev->addr); | ||
177 | if (val < 0) | ||
178 | return val; | ||
179 | |||
180 | /* Enable general EEE feature at the PHY level */ | ||
181 | val |= LPI_FEATURE_EN | LPI_FEATURE_EN_DIG1000X; | ||
182 | |||
183 | phy_write_mmd_indirect(phydev, BRCM_CL45VEN_EEE_CONTROL, | ||
184 | MDIO_MMD_AN, phydev->addr, val); | ||
185 | |||
186 | /* Advertise supported modes */ | ||
187 | val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV, | ||
188 | MDIO_MMD_AN, phydev->addr); | ||
189 | |||
190 | val |= (MDIO_AN_EEE_ADV_100TX | MDIO_AN_EEE_ADV_1000T); | ||
191 | phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV, | ||
192 | MDIO_MMD_AN, phydev->addr, val); | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
170 | static int bcm7xxx_28nm_config_init(struct phy_device *phydev) | 197 | static int bcm7xxx_28nm_config_init(struct phy_device *phydev) |
171 | { | 198 | { |
172 | int ret; | 199 | int ret; |
@@ -179,6 +206,10 @@ static int bcm7xxx_28nm_config_init(struct phy_device *phydev) | |||
179 | if (ret) | 206 | if (ret) |
180 | return ret; | 207 | return ret; |
181 | 208 | ||
209 | ret = bcm7xxx_eee_enable(phydev); | ||
210 | if (ret) | ||
211 | return ret; | ||
212 | |||
182 | return bcm7xxx_apd_enable(phydev); | 213 | return bcm7xxx_apd_enable(phydev); |
183 | } | 214 | } |
184 | 215 | ||