aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2014-08-22 21:55:45 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-23 14:39:09 -0400
commitb8f9a02924bbeb0c46ca4c19561cbe765b80e264 (patch)
tree6990b37910085fec8a0b832f807d9e2c22ff73de /drivers/net/phy
parenta9f6309585cbefa4a7f08c9017ca482c3222323a (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.c31
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
171static 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
170static int bcm7xxx_28nm_config_init(struct phy_device *phydev) 197static 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