diff options
author | David S. Miller <davem@davemloft.net> | 2014-08-23 14:39:24 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-08-23 14:39:24 -0400 |
commit | 1ad676a6bc4b284b68e4d24c0eac366438a32af6 (patch) | |
tree | 6990b37910085fec8a0b832f807d9e2c22ff73de | |
parent | 5aa8dbbd5f9ae6ec6f5ab88596a29a5b5d4caf31 (diff) | |
parent | b8f9a02924bbeb0c46ca4c19561cbe765b80e264 (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.c | 58 | ||||
-rw-r--r-- | drivers/net/phy/broadcom.c | 122 | ||||
-rw-r--r-- | drivers/net/phy/fixed.c | 11 | ||||
-rw-r--r-- | drivers/net/phy/phy.c | 12 | ||||
-rw-r--r-- | include/linux/brcmphy.h | 126 | ||||
-rw-r--r-- | include/linux/phy.h | 27 |
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 | ||
150 | static 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 | |||
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 | |||
149 | static int bcm7xxx_28nm_config_init(struct phy_device *phydev) | 197 | static 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 | ||
160 | static int bcm7xxx_28nm_resume(struct phy_device *phydev) | 216 | static 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 | |||
132 | MODULE_DESCRIPTION("Broadcom PHY driver"); | 28 | MODULE_DESCRIPTION("Broadcom PHY driver"); |
133 | MODULE_AUTHOR("Maciej W. Rozycki"); | 29 | MODULE_AUTHOR("Maciej W. Rozycki"); |
134 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
135 | 31 | ||
136 | /* | ||
137 | * Indirect register access functions for the 1000BASE-T/100BASE-TX/10BASE-T | ||
138 | * 0x1c shadow registers. | ||
139 | */ | ||
140 | static 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 | |||
146 | static 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 */ |
155 | static int bcm54xx_exp_read(struct phy_device *phydev, u16 regnum) | 33 | static 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 | */ |
958 | static int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, | 958 | int 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 | } |
974 | EXPORT_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 | */ |
991 | static void phy_write_mmd_indirect(struct phy_device *phydev, int prtad, | 992 | void 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 | } |
1006 | EXPORT_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 | */ | ||
202 | static 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 | |||
208 | static 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 | */ | ||
610 | int 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 | */ | ||
695 | void phy_write_mmd_indirect(struct phy_device *phydev, int prtad, | ||
696 | int devad, int addr, u32 data); | ||
697 | |||
671 | struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, | 698 | struct 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); |