diff options
-rw-r--r-- | drivers/net/phy/broadcom.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 5b80358af658..f5310ed3760d 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c | |||
@@ -99,6 +99,41 @@ static int bcm54xx_config_intr(struct phy_device *phydev) | |||
99 | return err; | 99 | return err; |
100 | } | 100 | } |
101 | 101 | ||
102 | static int bcm5481_config_aneg(struct phy_device *phydev) | ||
103 | { | ||
104 | int ret; | ||
105 | |||
106 | /* Aneg firsly. */ | ||
107 | ret = genphy_config_aneg(phydev); | ||
108 | |||
109 | /* Then we can set up the delay. */ | ||
110 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { | ||
111 | u16 reg; | ||
112 | |||
113 | /* | ||
114 | * There is no BCM5481 specification available, so down | ||
115 | * here is everything we know about "register 0x18". This | ||
116 | * at least helps BCM5481 to successfuly receive packets | ||
117 | * on MPC8360E-RDK board. Peter Barada <peterb@logicpd.com> | ||
118 | * says: "This sets delay between the RXD and RXC signals | ||
119 | * instead of using trace lengths to achieve timing". | ||
120 | */ | ||
121 | |||
122 | /* Set RDX clk delay. */ | ||
123 | reg = 0x7 | (0x7 << 12); | ||
124 | phy_write(phydev, 0x18, reg); | ||
125 | |||
126 | reg = phy_read(phydev, 0x18); | ||
127 | /* Set RDX-RXC skew. */ | ||
128 | reg |= (1 << 8); | ||
129 | /* Write bits 14:0. */ | ||
130 | reg |= (1 << 15); | ||
131 | phy_write(phydev, 0x18, reg); | ||
132 | } | ||
133 | |||
134 | return ret; | ||
135 | } | ||
136 | |||
102 | static struct phy_driver bcm5411_driver = { | 137 | static struct phy_driver bcm5411_driver = { |
103 | .phy_id = 0x00206070, | 138 | .phy_id = 0x00206070, |
104 | .phy_id_mask = 0xfffffff0, | 139 | .phy_id_mask = 0xfffffff0, |
@@ -141,8 +176,22 @@ static struct phy_driver bcm5461_driver = { | |||
141 | .driver = { .owner = THIS_MODULE }, | 176 | .driver = { .owner = THIS_MODULE }, |
142 | }; | 177 | }; |
143 | 178 | ||
179 | static struct phy_driver bcm5481_driver = { | ||
180 | .phy_id = 0x0143bca0, | ||
181 | .phy_id_mask = 0xfffffff0, | ||
182 | .name = "Broadcom BCM5481", | ||
183 | .features = PHY_GBIT_FEATURES, | ||
184 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | ||
185 | .config_init = bcm54xx_config_init, | ||
186 | .config_aneg = bcm5481_config_aneg, | ||
187 | .read_status = genphy_read_status, | ||
188 | .ack_interrupt = bcm54xx_ack_interrupt, | ||
189 | .config_intr = bcm54xx_config_intr, | ||
190 | .driver = { .owner = THIS_MODULE }, | ||
191 | }; | ||
192 | |||
144 | static struct phy_driver bcm5482_driver = { | 193 | static struct phy_driver bcm5482_driver = { |
145 | .phy_id = 0x0143bcb0, | 194 | .phy_id = 0x0143bcb0, |
146 | .phy_id_mask = 0xfffffff0, | 195 | .phy_id_mask = 0xfffffff0, |
147 | .name = "Broadcom BCM5482", | 196 | .name = "Broadcom BCM5482", |
148 | .features = PHY_GBIT_FEATURES, | 197 | .features = PHY_GBIT_FEATURES, |
@@ -168,12 +217,17 @@ static int __init broadcom_init(void) | |||
168 | ret = phy_driver_register(&bcm5461_driver); | 217 | ret = phy_driver_register(&bcm5461_driver); |
169 | if (ret) | 218 | if (ret) |
170 | goto out_5461; | 219 | goto out_5461; |
220 | ret = phy_driver_register(&bcm5481_driver); | ||
221 | if (ret) | ||
222 | goto out_5481; | ||
171 | ret = phy_driver_register(&bcm5482_driver); | 223 | ret = phy_driver_register(&bcm5482_driver); |
172 | if (ret) | 224 | if (ret) |
173 | goto out_5482; | 225 | goto out_5482; |
174 | return ret; | 226 | return ret; |
175 | 227 | ||
176 | out_5482: | 228 | out_5482: |
229 | phy_driver_unregister(&bcm5481_driver); | ||
230 | out_5481: | ||
177 | phy_driver_unregister(&bcm5461_driver); | 231 | phy_driver_unregister(&bcm5461_driver); |
178 | out_5461: | 232 | out_5461: |
179 | phy_driver_unregister(&bcm5421_driver); | 233 | phy_driver_unregister(&bcm5421_driver); |
@@ -186,6 +240,7 @@ out_5411: | |||
186 | static void __exit broadcom_exit(void) | 240 | static void __exit broadcom_exit(void) |
187 | { | 241 | { |
188 | phy_driver_unregister(&bcm5482_driver); | 242 | phy_driver_unregister(&bcm5482_driver); |
243 | phy_driver_unregister(&bcm5481_driver); | ||
189 | phy_driver_unregister(&bcm5461_driver); | 244 | phy_driver_unregister(&bcm5461_driver); |
190 | phy_driver_unregister(&bcm5421_driver); | 245 | phy_driver_unregister(&bcm5421_driver); |
191 | phy_driver_unregister(&bcm5411_driver); | 246 | phy_driver_unregister(&bcm5411_driver); |