Skip to content

Commit d7a2ed9

Browse files
Matt Carlsondavem330
authored andcommitted
broadcom: Add AC131 phy support
This patch adds support for the AC131 fast ethernet transceiver. Signed-off-by: Matt Carlson <[email protected]> Reviewed-by: Michael Chan <[email protected]> Reviewed-by: Benjamin Li <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4f4598f commit d7a2ed9

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed

drivers/net/phy/broadcom.c

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,35 @@
142142
#define PHY_BCM_FLAGS_MODE_1000BX 0x00000002
143143
#define PHY_BCM_FLAGS_MODE_COPPER 0x00000001
144144

145+
146+
/*****************************************************************************/
147+
/* Fast Ethernet Transceiver definitions. */
148+
/*****************************************************************************/
149+
150+
#define MII_BRCM_FET_INTREG 0x1a /* Interrupt register */
151+
#define MII_BRCM_FET_IR_MASK 0x0100 /* Mask all interrupts */
152+
#define MII_BRCM_FET_IR_LINK_EN 0x0200 /* Link status change enable */
153+
#define MII_BRCM_FET_IR_SPEED_EN 0x0400 /* Link speed change enable */
154+
#define MII_BRCM_FET_IR_DUPLEX_EN 0x0800 /* Duplex mode change enable */
155+
#define MII_BRCM_FET_IR_ENABLE 0x4000 /* Interrupt enable */
156+
157+
#define MII_BRCM_FET_BRCMTEST 0x1f /* Brcm test register */
158+
#define MII_BRCM_FET_BT_SRE 0x0080 /* Shadow register enable */
159+
160+
161+
/*** Shadow register definitions ***/
162+
163+
#define MII_BRCM_FET_SHDW_MISCCTRL 0x10 /* Shadow misc ctrl */
164+
#define MII_BRCM_FET_SHDW_MC_FAME 0x4000 /* Force Auto MDIX enable */
165+
166+
#define MII_BRCM_FET_SHDW_AUXMODE4 0x1a /* Auxiliary mode 4 */
167+
#define MII_BRCM_FET_SHDW_AM4_LED_MASK 0x0003
168+
#define MII_BRCM_FET_SHDW_AM4_LED_MODE1 0x0001
169+
170+
#define MII_BRCM_FET_SHDW_AUXSTAT2 0x1b /* Auxiliary status 2 */
171+
#define MII_BRCM_FET_SHDW_AS2_APDE 0x0020 /* Auto power down enable */
172+
173+
145174
MODULE_DESCRIPTION("Broadcom PHY driver");
146175
MODULE_AUTHOR("Maciej W. Rozycki");
147176
MODULE_LICENSE("GPL");
@@ -436,6 +465,114 @@ static int bcm5481_config_aneg(struct phy_device *phydev)
436465
return ret;
437466
}
438467

468+
static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set)
469+
{
470+
int val;
471+
472+
val = phy_read(phydev, reg);
473+
if (val < 0)
474+
return val;
475+
476+
return phy_write(phydev, reg, val | set);
477+
}
478+
479+
static int brcm_fet_config_init(struct phy_device *phydev)
480+
{
481+
int reg, err, err2, brcmtest;
482+
483+
/* Reset the PHY to bring it to a known state. */
484+
err = phy_write(phydev, MII_BMCR, BMCR_RESET);
485+
if (err < 0)
486+
return err;
487+
488+
reg = phy_read(phydev, MII_BRCM_FET_INTREG);
489+
if (reg < 0)
490+
return reg;
491+
492+
/* Unmask events we are interested in and mask interrupts globally. */
493+
reg = MII_BRCM_FET_IR_DUPLEX_EN |
494+
MII_BRCM_FET_IR_SPEED_EN |
495+
MII_BRCM_FET_IR_LINK_EN |
496+
MII_BRCM_FET_IR_ENABLE |
497+
MII_BRCM_FET_IR_MASK;
498+
499+
err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
500+
if (err < 0)
501+
return err;
502+
503+
/* Enable shadow register access */
504+
brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
505+
if (brcmtest < 0)
506+
return brcmtest;
507+
508+
reg = brcmtest | MII_BRCM_FET_BT_SRE;
509+
510+
err = phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
511+
if (err < 0)
512+
return err;
513+
514+
/* Set the LED mode */
515+
reg = phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
516+
if (reg < 0) {
517+
err = reg;
518+
goto done;
519+
}
520+
521+
reg &= ~MII_BRCM_FET_SHDW_AM4_LED_MASK;
522+
reg |= MII_BRCM_FET_SHDW_AM4_LED_MODE1;
523+
524+
err = phy_write(phydev, MII_BRCM_FET_SHDW_AUXMODE4, reg);
525+
if (err < 0)
526+
goto done;
527+
528+
/* Enable auto MDIX */
529+
err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_MISCCTRL,
530+
MII_BRCM_FET_SHDW_MC_FAME);
531+
if (err < 0)
532+
goto done;
533+
534+
/* Enable auto power down */
535+
err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
536+
MII_BRCM_FET_SHDW_AS2_APDE);
537+
538+
done:
539+
/* Disable shadow register access */
540+
err2 = phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
541+
if (!err)
542+
err = err2;
543+
544+
return err;
545+
}
546+
547+
static int brcm_fet_ack_interrupt(struct phy_device *phydev)
548+
{
549+
int reg;
550+
551+
/* Clear pending interrupts. */
552+
reg = phy_read(phydev, MII_BRCM_FET_INTREG);
553+
if (reg < 0)
554+
return reg;
555+
556+
return 0;
557+
}
558+
559+
static int brcm_fet_config_intr(struct phy_device *phydev)
560+
{
561+
int reg, err;
562+
563+
reg = phy_read(phydev, MII_BRCM_FET_INTREG);
564+
if (reg < 0)
565+
return reg;
566+
567+
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
568+
reg &= ~MII_BRCM_FET_IR_MASK;
569+
else
570+
reg |= MII_BRCM_FET_IR_MASK;
571+
572+
err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
573+
return err;
574+
}
575+
439576
static struct phy_driver bcm5411_driver = {
440577
.phy_id = 0x00206070,
441578
.phy_id_mask = 0xfffffff0,
@@ -571,6 +708,21 @@ static struct phy_driver bcm57780_driver = {
571708
.driver = { .owner = THIS_MODULE },
572709
};
573710

711+
static struct phy_driver bcmac131_driver = {
712+
.phy_id = 0x0143bc70,
713+
.phy_id_mask = 0xfffffff0,
714+
.name = "Broadcom BCMAC131",
715+
.features = PHY_BASIC_FEATURES |
716+
SUPPORTED_Pause | SUPPORTED_Asym_Pause,
717+
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
718+
.config_init = brcm_fet_config_init,
719+
.config_aneg = genphy_config_aneg,
720+
.read_status = genphy_read_status,
721+
.ack_interrupt = brcm_fet_ack_interrupt,
722+
.config_intr = brcm_fet_config_intr,
723+
.driver = { .owner = THIS_MODULE },
724+
};
725+
574726
static int __init broadcom_init(void)
575727
{
576728
int ret;
@@ -602,8 +754,13 @@ static int __init broadcom_init(void)
602754
ret = phy_driver_register(&bcm57780_driver);
603755
if (ret)
604756
goto out_57780;
757+
ret = phy_driver_register(&bcmac131_driver);
758+
if (ret)
759+
goto out_ac131;
605760
return ret;
606761

762+
out_ac131:
763+
phy_driver_unregister(&bcm57780_driver);
607764
out_57780:
608765
phy_driver_unregister(&bcm50610m_driver);
609766
out_50610m:
@@ -626,6 +783,7 @@ static int __init broadcom_init(void)
626783

627784
static void __exit broadcom_exit(void)
628785
{
786+
phy_driver_unregister(&bcmac131_driver);
629787
phy_driver_unregister(&bcm57780_driver);
630788
phy_driver_unregister(&bcm50610m_driver);
631789
phy_driver_unregister(&bcm50610_driver);

0 commit comments

Comments
 (0)