aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/broadcom.c
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2008-11-03 19:56:51 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-03 19:56:51 -0500
commit772638b6c87da7043c50914dbb033c08155508dd (patch)
tree186389bdcc22be1eb0a89944d553d8c246dedf51 /drivers/net/phy/broadcom.c
parent042a75b99fbda6bf7c7bf4496e205e3e7acc953a (diff)
broadcom: Add support for BCM50610
This patch adds the BCM50610 to the list of phys supported by the broadcom driver. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/broadcom.c')
-rw-r--r--drivers/net/phy/broadcom.c119
1 files changed, 118 insertions, 1 deletions
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 7e935924793d..fd4fc66b6d6e 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -17,6 +17,8 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/phy.h> 18#include <linux/phy.h>
19 19
20#define PHY_ID_BCM50610 0x0143bd60
21
20#define MII_BCM54XX_ECR 0x10 /* BCM54xx extended control register */ 22#define MII_BCM54XX_ECR 0x10 /* BCM54xx extended control register */
21#define MII_BCM54XX_ECR_IM 0x1000 /* Interrupt mask */ 23#define MII_BCM54XX_ECR_IM 0x1000 /* Interrupt mask */
22#define MII_BCM54XX_ECR_IF 0x0800 /* Interrupt force */ 24#define MII_BCM54XX_ECR_IF 0x0800 /* Interrupt force */
@@ -54,6 +56,21 @@
54#define MII_BCM54XX_SHD_DATA(x) ((x & 0x3ff) << 0) 56#define MII_BCM54XX_SHD_DATA(x) ((x & 0x3ff) << 0)
55 57
56/* 58/*
59 * AUXILIARY CONTROL SHADOW ACCESS REGISTERS. (PHY REG 0x18)
60 */
61#define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL 0x0000
62#define MII_BCM54XX_AUXCTL_ACTL_TX_6DB 0x0400
63#define MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA 0x0800
64
65#define MII_BCM54XX_AUXCTL_MISC_WREN 0x8000
66#define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX 0x0200
67#define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000
68#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC 0x0007
69
70#define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL 0x0000
71
72
73/*
57 * Broadcom LED source encodings. These are used in BCM5461, BCM5481, 74 * Broadcom LED source encodings. These are used in BCM5461, BCM5481,
58 * BCM5482, and possibly some others. 75 * BCM5482, and possibly some others.
59 */ 76 */
@@ -88,6 +105,24 @@
88#define BCM5482_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */ 105#define BCM5482_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */
89 106
90/* 107/*
108 * EXPANSION SHADOW ACCESS REGISTERS. (PHY REG 0x15, 0x16, and 0x17)
109 */
110#define MII_BCM54XX_EXP_AADJ1CH0 0x001f
111#define MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN 0x0200
112#define MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF 0x0100
113#define MII_BCM54XX_EXP_AADJ1CH3 0x601f
114#define MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ 0x0002
115#define MII_BCM54XX_EXP_EXP08 0x0F08
116#define MII_BCM54XX_EXP_EXP08_RJCT_2MHZ 0x0001
117#define MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE 0x0200
118#define MII_BCM54XX_EXP_EXP75 0x0f75
119#define MII_BCM54XX_EXP_EXP75_VDACCTRL 0x003c
120#define MII_BCM54XX_EXP_EXP96 0x0f96
121#define MII_BCM54XX_EXP_EXP96_MYST 0x0010
122#define MII_BCM54XX_EXP_EXP97 0x0f97
123#define MII_BCM54XX_EXP_EXP97_MYST 0x0c0c
124
125/*
91 * BCM5482: Secondary SerDes registers 126 * BCM5482: Secondary SerDes registers
92 */ 127 */
93#define BCM5482_SSD_1000BX_CTL 0x00 /* 1000BASE-X Control */ 128#define BCM5482_SSD_1000BX_CTL 0x00 /* 1000BASE-X Control */
@@ -145,7 +180,7 @@ static int bcm54xx_exp_read(struct phy_device *phydev, u8 regnum)
145 return val; 180 return val;
146} 181}
147 182
148static int bcm54xx_exp_write(struct phy_device *phydev, u8 regnum, u16 val) 183static int bcm54xx_exp_write(struct phy_device *phydev, u16 regnum, u16 val)
149{ 184{
150 int ret; 185 int ret;
151 186
@@ -161,6 +196,60 @@ static int bcm54xx_exp_write(struct phy_device *phydev, u8 regnum, u16 val)
161 return ret; 196 return ret;
162} 197}
163 198
199static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
200{
201 return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
202}
203
204static int bcm50610_a0_workaround(struct phy_device *phydev)
205{
206 int err;
207
208 err = bcm54xx_auxctl_write(phydev,
209 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
210 MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
211 MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
212 if (err < 0)
213 return err;
214
215 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP08,
216 MII_BCM54XX_EXP_EXP08_RJCT_2MHZ |
217 MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE);
218 if (err < 0)
219 goto error;
220
221 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH0,
222 MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN |
223 MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF);
224 if (err < 0)
225 goto error;
226
227 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH3,
228 MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ);
229 if (err < 0)
230 goto error;
231
232 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75,
233 MII_BCM54XX_EXP_EXP75_VDACCTRL);
234 if (err < 0)
235 goto error;
236
237 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP96,
238 MII_BCM54XX_EXP_EXP96_MYST);
239 if (err < 0)
240 goto error;
241
242 err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP97,
243 MII_BCM54XX_EXP_EXP97_MYST);
244
245error:
246 bcm54xx_auxctl_write(phydev,
247 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
248 MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
249
250 return err;
251}
252
164static int bcm54xx_config_init(struct phy_device *phydev) 253static int bcm54xx_config_init(struct phy_device *phydev)
165{ 254{
166 int reg, err; 255 int reg, err;
@@ -182,6 +271,13 @@ static int bcm54xx_config_init(struct phy_device *phydev)
182 err = phy_write(phydev, MII_BCM54XX_IMR, reg); 271 err = phy_write(phydev, MII_BCM54XX_IMR, reg);
183 if (err < 0) 272 if (err < 0)
184 return err; 273 return err;
274
275 if (phydev->drv->phy_id == PHY_ID_BCM50610) {
276 err = bcm50610_a0_workaround(phydev);
277 if (err < 0)
278 return err;
279 }
280
185 return 0; 281 return 0;
186} 282}
187 283
@@ -429,6 +525,21 @@ static struct phy_driver bcm5482_driver = {
429 .driver = { .owner = THIS_MODULE }, 525 .driver = { .owner = THIS_MODULE },
430}; 526};
431 527
528static struct phy_driver bcm50610_driver = {
529 .phy_id = PHY_ID_BCM50610,
530 .phy_id_mask = 0xfffffff0,
531 .name = "Broadcom BCM50610",
532 .features = PHY_GBIT_FEATURES |
533 SUPPORTED_Pause | SUPPORTED_Asym_Pause,
534 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
535 .config_init = bcm54xx_config_init,
536 .config_aneg = genphy_config_aneg,
537 .read_status = genphy_read_status,
538 .ack_interrupt = bcm54xx_ack_interrupt,
539 .config_intr = bcm54xx_config_intr,
540 .driver = { .owner = THIS_MODULE },
541};
542
432static int __init broadcom_init(void) 543static int __init broadcom_init(void)
433{ 544{
434 int ret; 545 int ret;
@@ -451,8 +562,13 @@ static int __init broadcom_init(void)
451 ret = phy_driver_register(&bcm5482_driver); 562 ret = phy_driver_register(&bcm5482_driver);
452 if (ret) 563 if (ret)
453 goto out_5482; 564 goto out_5482;
565 ret = phy_driver_register(&bcm50610_driver);
566 if (ret)
567 goto out_50610;
454 return ret; 568 return ret;
455 569
570out_50610:
571 phy_driver_unregister(&bcm5482_driver);
456out_5482: 572out_5482:
457 phy_driver_unregister(&bcm5481_driver); 573 phy_driver_unregister(&bcm5481_driver);
458out_5481: 574out_5481:
@@ -469,6 +585,7 @@ out_5411:
469 585
470static void __exit broadcom_exit(void) 586static void __exit broadcom_exit(void)
471{ 587{
588 phy_driver_unregister(&bcm50610_driver);
472 phy_driver_unregister(&bcm5482_driver); 589 phy_driver_unregister(&bcm5482_driver);
473 phy_driver_unregister(&bcm5481_driver); 590 phy_driver_unregister(&bcm5481_driver);
474 phy_driver_unregister(&bcm5464_driver); 591 phy_driver_unregister(&bcm5464_driver);