aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-08-23 14:39:24 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-23 14:39:24 -0400
commit1ad676a6bc4b284b68e4d24c0eac366438a32af6 (patch)
tree6990b37910085fec8a0b832f807d9e2c22ff73de
parent5aa8dbbd5f9ae6ec6f5ab88596a29a5b5d4caf31 (diff)
parentb8f9a02924bbeb0c46ca4c19561cbe765b80e264 (diff)
Merge branch 'bcm7xxx_apd_eee'
Florian Fainelli says: ==================== net: phy: bcm7xxx: APD and EEE support This patch series enables Auto-power down and EEE for the BCM7xxx integrated Gigabit PHYs. I also put a fix for the fixed PHY that would allow clause 45 over clause 22 reads/writes but would return bogus data by using e.g: ethtool --show-eee ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/phy/bcm7xxx.c58
-rw-r--r--drivers/net/phy/broadcom.c122
-rw-r--r--drivers/net/phy/fixed.c11
-rw-r--r--drivers/net/phy/phy.c12
-rw-r--r--include/linux/brcmphy.h126
-rw-r--r--include/linux/phy.h27
6 files changed, 229 insertions, 127 deletions
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
index fdce1ea28790..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
@@ -146,6 +147,53 @@ static int bcm7xxx_28nm_afe_config_init(struct phy_device *phydev)
146 return 0; 147 return 0;
147} 148}
148 149
150static int bcm7xxx_apd_enable(struct phy_device *phydev)
151{
152 int val;
153
154 /* Enable powering down of the DLL during auto-power down */
155 val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_SCR3);
156 if (val < 0)
157 return val;
158
159 val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
160 bcm54xx_shadow_write(phydev, BCM54XX_SHD_SCR3, val);
161
162 /* Enable auto-power down */
163 val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_APD);
164 if (val < 0)
165 return val;
166
167 val |= BCM54XX_SHD_APD_EN;
168 return bcm54xx_shadow_write(phydev, BCM54XX_SHD_APD, val);
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
149static int bcm7xxx_28nm_config_init(struct phy_device *phydev) 197static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
150{ 198{
151 int ret; 199 int ret;
@@ -154,7 +202,15 @@ static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
154 if (ret) 202 if (ret)
155 return ret; 203 return ret;
156 204
157 return bcm7xxx_28nm_afe_config_init(phydev); 205 ret = bcm7xxx_28nm_afe_config_init(phydev);
206 if (ret)
207 return ret;
208
209 ret = bcm7xxx_eee_enable(phydev);
210 if (ret)
211 return ret;
212
213 return bcm7xxx_apd_enable(phydev);
158} 214}
159 215
160static int bcm7xxx_28nm_resume(struct phy_device *phydev) 216static int bcm7xxx_28nm_resume(struct phy_device *phydev)
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 34088d60da74..854f2c9a7b2b 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -25,132 +25,10 @@
25#define BRCM_PHY_REV(phydev) \ 25#define BRCM_PHY_REV(phydev) \
26 ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask)) 26 ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask))
27 27
28/*
29 * Broadcom LED source encodings. These are used in BCM5461, BCM5481,
30 * BCM5482, and possibly some others.
31 */
32#define BCM_LED_SRC_LINKSPD1 0x0
33#define BCM_LED_SRC_LINKSPD2 0x1
34#define BCM_LED_SRC_XMITLED 0x2
35#define BCM_LED_SRC_ACTIVITYLED 0x3
36#define BCM_LED_SRC_FDXLED 0x4
37#define BCM_LED_SRC_SLAVE 0x5
38#define BCM_LED_SRC_INTR 0x6
39#define BCM_LED_SRC_QUALITY 0x7
40#define BCM_LED_SRC_RCVLED 0x8
41#define BCM_LED_SRC_MULTICOLOR1 0xa
42#define BCM_LED_SRC_OPENSHORT 0xb
43#define BCM_LED_SRC_OFF 0xe /* Tied high */
44#define BCM_LED_SRC_ON 0xf /* Tied low */
45
46
47/*
48 * BCM5482: Shadow registers
49 * Shadow values go into bits [14:10] of register 0x1c to select a shadow
50 * register to access.
51 */
52/* 00101: Spare Control Register 3 */
53#define BCM54XX_SHD_SCR3 0x05
54#define BCM54XX_SHD_SCR3_DEF_CLK125 0x0001
55#define BCM54XX_SHD_SCR3_DLLAPD_DIS 0x0002
56#define BCM54XX_SHD_SCR3_TRDDAPD 0x0004
57
58/* 01010: Auto Power-Down */
59#define BCM54XX_SHD_APD 0x0a
60#define BCM54XX_SHD_APD_EN 0x0020
61
62#define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */
63 /* LED3 / ~LINKSPD[2] selector */
64#define BCM5482_SHD_LEDS1_LED3(src) ((src & 0xf) << 4)
65 /* LED1 / ~LINKSPD[1] selector */
66#define BCM5482_SHD_LEDS1_LED1(src) ((src & 0xf) << 0)
67#define BCM54XX_SHD_RGMII_MODE 0x0b /* 01011: RGMII Mode Selector */
68#define BCM5482_SHD_SSD 0x14 /* 10100: Secondary SerDes control */
69#define BCM5482_SHD_SSD_LEDM 0x0008 /* SSD LED Mode enable */
70#define BCM5482_SHD_SSD_EN 0x0001 /* SSD enable */
71#define BCM5482_SHD_MODE 0x1f /* 11111: Mode Control Register */
72#define BCM5482_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */
73
74
75/*
76 * EXPANSION SHADOW ACCESS REGISTERS. (PHY REG 0x15, 0x16, and 0x17)
77 */
78#define MII_BCM54XX_EXP_AADJ1CH0 0x001f
79#define MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN 0x0200
80#define MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF 0x0100
81#define MII_BCM54XX_EXP_AADJ1CH3 0x601f
82#define MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ 0x0002
83#define MII_BCM54XX_EXP_EXP08 0x0F08
84#define MII_BCM54XX_EXP_EXP08_RJCT_2MHZ 0x0001
85#define MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE 0x0200
86#define MII_BCM54XX_EXP_EXP75 0x0f75
87#define MII_BCM54XX_EXP_EXP75_VDACCTRL 0x003c
88#define MII_BCM54XX_EXP_EXP75_CM_OSC 0x0001
89#define MII_BCM54XX_EXP_EXP96 0x0f96
90#define MII_BCM54XX_EXP_EXP96_MYST 0x0010
91#define MII_BCM54XX_EXP_EXP97 0x0f97
92#define MII_BCM54XX_EXP_EXP97_MYST 0x0c0c
93
94/*
95 * BCM5482: Secondary SerDes registers
96 */
97#define BCM5482_SSD_1000BX_CTL 0x00 /* 1000BASE-X Control */
98#define BCM5482_SSD_1000BX_CTL_PWRDOWN 0x0800 /* Power-down SSD */
99#define BCM5482_SSD_SGMII_SLAVE 0x15 /* SGMII Slave Register */
100#define BCM5482_SSD_SGMII_SLAVE_EN 0x0002 /* Slave mode enable */
101#define BCM5482_SSD_SGMII_SLAVE_AD 0x0001 /* Slave auto-detection */
102
103
104/*****************************************************************************/
105/* Fast Ethernet Transceiver definitions. */
106/*****************************************************************************/
107
108#define MII_BRCM_FET_INTREG 0x1a /* Interrupt register */
109#define MII_BRCM_FET_IR_MASK 0x0100 /* Mask all interrupts */
110#define MII_BRCM_FET_IR_LINK_EN 0x0200 /* Link status change enable */
111#define MII_BRCM_FET_IR_SPEED_EN 0x0400 /* Link speed change enable */
112#define MII_BRCM_FET_IR_DUPLEX_EN 0x0800 /* Duplex mode change enable */
113#define MII_BRCM_FET_IR_ENABLE 0x4000 /* Interrupt enable */
114
115#define MII_BRCM_FET_BRCMTEST 0x1f /* Brcm test register */
116#define MII_BRCM_FET_BT_SRE 0x0080 /* Shadow register enable */
117
118
119/*** Shadow register definitions ***/
120
121#define MII_BRCM_FET_SHDW_MISCCTRL 0x10 /* Shadow misc ctrl */
122#define MII_BRCM_FET_SHDW_MC_FAME 0x4000 /* Force Auto MDIX enable */
123
124#define MII_BRCM_FET_SHDW_AUXMODE4 0x1a /* Auxiliary mode 4 */
125#define MII_BRCM_FET_SHDW_AM4_LED_MASK 0x0003
126#define MII_BRCM_FET_SHDW_AM4_LED_MODE1 0x0001
127
128#define MII_BRCM_FET_SHDW_AUXSTAT2 0x1b /* Auxiliary status 2 */
129#define MII_BRCM_FET_SHDW_AS2_APDE 0x0020 /* Auto power down enable */
130
131
132MODULE_DESCRIPTION("Broadcom PHY driver"); 28MODULE_DESCRIPTION("Broadcom PHY driver");
133MODULE_AUTHOR("Maciej W. Rozycki"); 29MODULE_AUTHOR("Maciej W. Rozycki");
134MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
135 31
136/*
137 * Indirect register access functions for the 1000BASE-T/100BASE-TX/10BASE-T
138 * 0x1c shadow registers.
139 */
140static int bcm54xx_shadow_read(struct phy_device *phydev, u16 shadow)
141{
142 phy_write(phydev, MII_BCM54XX_SHD, MII_BCM54XX_SHD_VAL(shadow));
143 return MII_BCM54XX_SHD_DATA(phy_read(phydev, MII_BCM54XX_SHD));
144}
145
146static int bcm54xx_shadow_write(struct phy_device *phydev, u16 shadow, u16 val)
147{
148 return phy_write(phydev, MII_BCM54XX_SHD,
149 MII_BCM54XX_SHD_WRITE |
150 MII_BCM54XX_SHD_VAL(shadow) |
151 MII_BCM54XX_SHD_DATA(val));
152}
153
154/* Indirect register access functions for the Expansion Registers */ 32/* Indirect register access functions for the Expansion Registers */
155static int bcm54xx_exp_read(struct phy_device *phydev, u16 regnum) 33static int bcm54xx_exp_read(struct phy_device *phydev, u16 regnum)
156{ 34{
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index d60d875cb445..5b19fbbda6d4 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -124,6 +124,17 @@ static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
124 if (reg_num >= MII_REGS_NUM) 124 if (reg_num >= MII_REGS_NUM)
125 return -1; 125 return -1;
126 126
127 /* We do not support emulating Clause 45 over Clause 22 register reads
128 * return an error instead of bogus data.
129 */
130 switch (reg_num) {
131 case MII_MMD_CTRL:
132 case MII_MMD_DATA:
133 return -1;
134 default:
135 break;
136 }
137
127 list_for_each_entry(fp, &fmb->phys, node) { 138 list_for_each_entry(fp, &fmb->phys, node) {
128 if (fp->addr == phy_addr) { 139 if (fp->addr == phy_addr) {
129 /* Issue callback if user registered it. */ 140 /* Issue callback if user registered it. */
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index c94e2a27446a..932190e04d08 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -955,7 +955,7 @@ static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
955 * 3) Write reg 13 // MMD Data Command for MMD DEVAD 955 * 3) Write reg 13 // MMD Data Command for MMD DEVAD
956 * 3) Read reg 14 // Read MMD data 956 * 3) Read reg 14 // Read MMD data
957 */ 957 */
958static int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, 958int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
959 int devad, int addr) 959 int devad, int addr)
960{ 960{
961 struct phy_driver *phydrv = phydev->drv; 961 struct phy_driver *phydrv = phydev->drv;
@@ -971,6 +971,7 @@ static int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
971 } 971 }
972 return value; 972 return value;
973} 973}
974EXPORT_SYMBOL(phy_read_mmd_indirect);
974 975
975/** 976/**
976 * phy_write_mmd_indirect - writes data to the MMD registers 977 * phy_write_mmd_indirect - writes data to the MMD registers
@@ -988,7 +989,7 @@ static int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
988 * 3) Write reg 13 // MMD Data Command for MMD DEVAD 989 * 3) Write reg 13 // MMD Data Command for MMD DEVAD
989 * 3) Write reg 14 // Write MMD data 990 * 3) Write reg 14 // Write MMD data
990 */ 991 */
991static void phy_write_mmd_indirect(struct phy_device *phydev, int prtad, 992void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
992 int devad, int addr, u32 data) 993 int devad, int addr, u32 data)
993{ 994{
994 struct phy_driver *phydrv = phydev->drv; 995 struct phy_driver *phydrv = phydev->drv;
@@ -1002,6 +1003,7 @@ static void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
1002 phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data); 1003 phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data);
1003 } 1004 }
1004} 1005}
1006EXPORT_SYMBOL(phy_write_mmd_indirect);
1005 1007
1006/** 1008/**
1007 * phy_init_eee - init and check the EEE feature 1009 * phy_init_eee - init and check the EEE feature
@@ -1017,12 +1019,14 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
1017{ 1019{
1018 /* According to 802.3az,the EEE is supported only in full duplex-mode. 1020 /* According to 802.3az,the EEE is supported only in full duplex-mode.
1019 * Also EEE feature is active when core is operating with MII, GMII 1021 * Also EEE feature is active when core is operating with MII, GMII
1020 * or RGMII. 1022 * or RGMII. Internal PHYs are also allowed to proceed and should
1023 * return an error if they do not support EEE.
1021 */ 1024 */
1022 if ((phydev->duplex == DUPLEX_FULL) && 1025 if ((phydev->duplex == DUPLEX_FULL) &&
1023 ((phydev->interface == PHY_INTERFACE_MODE_MII) || 1026 ((phydev->interface == PHY_INTERFACE_MODE_MII) ||
1024 (phydev->interface == PHY_INTERFACE_MODE_GMII) || 1027 (phydev->interface == PHY_INTERFACE_MODE_GMII) ||
1025 (phydev->interface == PHY_INTERFACE_MODE_RGMII))) { 1028 (phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
1029 phy_is_internal(phydev))) {
1026 int eee_lp, eee_cap, eee_adv; 1030 int eee_lp, eee_cap, eee_adv;
1027 u32 lp, cap, adv; 1031 u32 lp, cap, adv;
1028 int status; 1032 int status;
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 61219b9b3445..ee1431d976fa 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -92,4 +92,130 @@
92 92
93#define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL 0x0000 93#define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL 0x0000
94 94
95/*
96 * Broadcom LED source encodings. These are used in BCM5461, BCM5481,
97 * BCM5482, and possibly some others.
98 */
99#define BCM_LED_SRC_LINKSPD1 0x0
100#define BCM_LED_SRC_LINKSPD2 0x1
101#define BCM_LED_SRC_XMITLED 0x2
102#define BCM_LED_SRC_ACTIVITYLED 0x3
103#define BCM_LED_SRC_FDXLED 0x4
104#define BCM_LED_SRC_SLAVE 0x5
105#define BCM_LED_SRC_INTR 0x6
106#define BCM_LED_SRC_QUALITY 0x7
107#define BCM_LED_SRC_RCVLED 0x8
108#define BCM_LED_SRC_MULTICOLOR1 0xa
109#define BCM_LED_SRC_OPENSHORT 0xb
110#define BCM_LED_SRC_OFF 0xe /* Tied high */
111#define BCM_LED_SRC_ON 0xf /* Tied low */
112
113
114/*
115 * BCM5482: Shadow registers
116 * Shadow values go into bits [14:10] of register 0x1c to select a shadow
117 * register to access.
118 */
119/* 00101: Spare Control Register 3 */
120#define BCM54XX_SHD_SCR3 0x05
121#define BCM54XX_SHD_SCR3_DEF_CLK125 0x0001
122#define BCM54XX_SHD_SCR3_DLLAPD_DIS 0x0002
123#define BCM54XX_SHD_SCR3_TRDDAPD 0x0004
124
125/* 01010: Auto Power-Down */
126#define BCM54XX_SHD_APD 0x0a
127#define BCM54XX_SHD_APD_EN 0x0020
128
129#define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */
130 /* LED3 / ~LINKSPD[2] selector */
131#define BCM5482_SHD_LEDS1_LED3(src) ((src & 0xf) << 4)
132 /* LED1 / ~LINKSPD[1] selector */
133#define BCM5482_SHD_LEDS1_LED1(src) ((src & 0xf) << 0)
134#define BCM54XX_SHD_RGMII_MODE 0x0b /* 01011: RGMII Mode Selector */
135#define BCM5482_SHD_SSD 0x14 /* 10100: Secondary SerDes control */
136#define BCM5482_SHD_SSD_LEDM 0x0008 /* SSD LED Mode enable */
137#define BCM5482_SHD_SSD_EN 0x0001 /* SSD enable */
138#define BCM5482_SHD_MODE 0x1f /* 11111: Mode Control Register */
139#define BCM5482_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */
140
141
142/*
143 * EXPANSION SHADOW ACCESS REGISTERS. (PHY REG 0x15, 0x16, and 0x17)
144 */
145#define MII_BCM54XX_EXP_AADJ1CH0 0x001f
146#define MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN 0x0200
147#define MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF 0x0100
148#define MII_BCM54XX_EXP_AADJ1CH3 0x601f
149#define MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ 0x0002
150#define MII_BCM54XX_EXP_EXP08 0x0F08
151#define MII_BCM54XX_EXP_EXP08_RJCT_2MHZ 0x0001
152#define MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE 0x0200
153#define MII_BCM54XX_EXP_EXP75 0x0f75
154#define MII_BCM54XX_EXP_EXP75_VDACCTRL 0x003c
155#define MII_BCM54XX_EXP_EXP75_CM_OSC 0x0001
156#define MII_BCM54XX_EXP_EXP96 0x0f96
157#define MII_BCM54XX_EXP_EXP96_MYST 0x0010
158#define MII_BCM54XX_EXP_EXP97 0x0f97
159#define MII_BCM54XX_EXP_EXP97_MYST 0x0c0c
160
161/*
162 * BCM5482: Secondary SerDes registers
163 */
164#define BCM5482_SSD_1000BX_CTL 0x00 /* 1000BASE-X Control */
165#define BCM5482_SSD_1000BX_CTL_PWRDOWN 0x0800 /* Power-down SSD */
166#define BCM5482_SSD_SGMII_SLAVE 0x15 /* SGMII Slave Register */
167#define BCM5482_SSD_SGMII_SLAVE_EN 0x0002 /* Slave mode enable */
168#define BCM5482_SSD_SGMII_SLAVE_AD 0x0001 /* Slave auto-detection */
169
170
171/*****************************************************************************/
172/* Fast Ethernet Transceiver definitions. */
173/*****************************************************************************/
174
175#define MII_BRCM_FET_INTREG 0x1a /* Interrupt register */
176#define MII_BRCM_FET_IR_MASK 0x0100 /* Mask all interrupts */
177#define MII_BRCM_FET_IR_LINK_EN 0x0200 /* Link status change enable */
178#define MII_BRCM_FET_IR_SPEED_EN 0x0400 /* Link speed change enable */
179#define MII_BRCM_FET_IR_DUPLEX_EN 0x0800 /* Duplex mode change enable */
180#define MII_BRCM_FET_IR_ENABLE 0x4000 /* Interrupt enable */
181
182#define MII_BRCM_FET_BRCMTEST 0x1f /* Brcm test register */
183#define MII_BRCM_FET_BT_SRE 0x0080 /* Shadow register enable */
184
185
186/*** Shadow register definitions ***/
187
188#define MII_BRCM_FET_SHDW_MISCCTRL 0x10 /* Shadow misc ctrl */
189#define MII_BRCM_FET_SHDW_MC_FAME 0x4000 /* Force Auto MDIX enable */
190
191#define MII_BRCM_FET_SHDW_AUXMODE4 0x1a /* Auxiliary mode 4 */
192#define MII_BRCM_FET_SHDW_AM4_LED_MASK 0x0003
193#define MII_BRCM_FET_SHDW_AM4_LED_MODE1 0x0001
194
195#define MII_BRCM_FET_SHDW_AUXSTAT2 0x1b /* Auxiliary status 2 */
196#define MII_BRCM_FET_SHDW_AS2_APDE 0x0020 /* Auto power down enable */
197
198/*
199 * Indirect register access functions for the 1000BASE-T/100BASE-TX/10BASE-T
200 * 0x1c shadow registers.
201 */
202static inline int bcm54xx_shadow_read(struct phy_device *phydev, u16 shadow)
203{
204 phy_write(phydev, MII_BCM54XX_SHD, MII_BCM54XX_SHD_VAL(shadow));
205 return MII_BCM54XX_SHD_DATA(phy_read(phydev, MII_BCM54XX_SHD));
206}
207
208static inline int bcm54xx_shadow_write(struct phy_device *phydev, u16 shadow,
209 u16 val)
210{
211 return phy_write(phydev, MII_BCM54XX_SHD,
212 MII_BCM54XX_SHD_WRITE |
213 MII_BCM54XX_SHD_VAL(shadow) |
214 MII_BCM54XX_SHD_DATA(val));
215}
216
217#define BRCM_CL45VEN_EEE_CONTROL 0x803d
218#define LPI_FEATURE_EN 0x8000
219#define LPI_FEATURE_EN_DIG1000X 0x4000
220
95#endif /* _LINUX_BRCMPHY_H */ 221#endif /* _LINUX_BRCMPHY_H */
diff --git a/include/linux/phy.h b/include/linux/phy.h
index ed39956b5613..d090cfcaa167 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -598,6 +598,19 @@ static inline int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
598} 598}
599 599
600/** 600/**
601 * phy_read_mmd_indirect - reads data from the MMD registers
602 * @phydev: The PHY device bus
603 * @prtad: MMD Address
604 * @devad: MMD DEVAD
605 * @addr: PHY address on the MII bus
606 *
607 * Description: it reads data from the MMD registers (clause 22 to access to
608 * clause 45) of the specified phy address.
609 */
610int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
611 int devad, int addr);
612
613/**
601 * phy_read - Convenience function for reading a given PHY register 614 * phy_read - Convenience function for reading a given PHY register
602 * @phydev: the phy_device struct 615 * @phydev: the phy_device struct
603 * @regnum: register number to read 616 * @regnum: register number to read
@@ -668,6 +681,20 @@ static inline int phy_write_mmd(struct phy_device *phydev, int devad,
668 return mdiobus_write(phydev->bus, phydev->addr, regnum, val); 681 return mdiobus_write(phydev->bus, phydev->addr, regnum, val);
669} 682}
670 683
684/**
685 * phy_write_mmd_indirect - writes data to the MMD registers
686 * @phydev: The PHY device
687 * @prtad: MMD Address
688 * @devad: MMD DEVAD
689 * @addr: PHY address on the MII bus
690 * @data: data to write in the MMD register
691 *
692 * Description: Write data from the MMD registers of the specified
693 * phy address.
694 */
695void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
696 int devad, int addr, u32 data);
697
671struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, 698struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
672 bool is_c45, 699 bool is_c45,
673 struct phy_c45_device_ids *c45_ids); 700 struct phy_c45_device_ids *c45_ids);