142
142
#define PHY_BCM_FLAGS_MODE_1000BX 0x00000002
143
143
#define PHY_BCM_FLAGS_MODE_COPPER 0x00000001
144
144
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
+
145
174
MODULE_DESCRIPTION ("Broadcom PHY driver" );
146
175
MODULE_AUTHOR ("Maciej W. Rozycki" );
147
176
MODULE_LICENSE ("GPL" );
@@ -436,6 +465,114 @@ static int bcm5481_config_aneg(struct phy_device *phydev)
436
465
return ret ;
437
466
}
438
467
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
+
439
576
static struct phy_driver bcm5411_driver = {
440
577
.phy_id = 0x00206070 ,
441
578
.phy_id_mask = 0xfffffff0 ,
@@ -571,6 +708,21 @@ static struct phy_driver bcm57780_driver = {
571
708
.driver = { .owner = THIS_MODULE },
572
709
};
573
710
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
+
574
726
static int __init broadcom_init (void )
575
727
{
576
728
int ret ;
@@ -602,8 +754,13 @@ static int __init broadcom_init(void)
602
754
ret = phy_driver_register (& bcm57780_driver );
603
755
if (ret )
604
756
goto out_57780 ;
757
+ ret = phy_driver_register (& bcmac131_driver );
758
+ if (ret )
759
+ goto out_ac131 ;
605
760
return ret ;
606
761
762
+ out_ac131 :
763
+ phy_driver_unregister (& bcm57780_driver );
607
764
out_57780 :
608
765
phy_driver_unregister (& bcm50610m_driver );
609
766
out_50610m :
@@ -626,6 +783,7 @@ static int __init broadcom_init(void)
626
783
627
784
static void __exit broadcom_exit (void )
628
785
{
786
+ phy_driver_unregister (& bcmac131_driver );
629
787
phy_driver_unregister (& bcm57780_driver );
630
788
phy_driver_unregister (& bcm50610m_driver );
631
789
phy_driver_unregister (& bcm50610_driver );
0 commit comments