2 #include "lib_printf.h"
6 #include "dev_bcm4413.h"
7 #include "dev_bcm4413_mii.h"
13 #define CTL_RESET (1 << 15) /* reset */
14 #define CTL_SPEED (1 << 13) /* speed selection 0=10, 1=100 */
15 #define CTL_ANENAB (1 << 12) /* autonegotiation enable */
16 #define CTL_RESTART (1 << 9) /* restart autonegotiation */
17 #define CTL_DUPLEX (1 << 8) /* duplex mode 0=half, 1=full */
19 #define ADV_10FULL (1 << 6) /* autonegotiate advertise 10full capability */
20 #define ADV_10HALF (1 << 5) /* autonegotiate advertise 10half capability */
21 #define ADV_100FULL (1 << 8) /* autonegotiate advertise 100full capability */
22 #define ADV_100HALF (1 << 7) /* autonegotiate advertise 100half capability */
25 static uint16_t mii_read( bcmenetregs_t
* regs
, unsigned int reg
)
29 MIITRACE( "mii_read entered\n" );
33 xprintf( "ERROR : invalid register in mii_read (%d)!\n", reg
);
39 W_REG(NULL
, ®s
->emacintstatus
, EI_MII
);
41 mdiodata
= MD_SB_START
| MD_OP_READ
| (1 << MD_PMD_SHIFT
)
42 | (reg
<< MD_RA_SHIFT
) | MD_TA_VALID
;
45 W_REG(NULL
, ®s
->mdiodata
, mdiodata
);
47 MIITRACE( "Waiting for hardware...\n" );
49 /* wait for it to complete */
50 while( !(R_REG(NULL
, ®s
->emacintstatus
) & EI_MII
) ) {
54 mdiodata
= R_REG(NULL
, ®s
->mdiodata
);
56 MIITRACE( "mii_read exited\n" );
58 return mdiodata
& MD_DATA_MASK
;
62 static void mii_write( bcmenetregs_t
* regs
, unsigned int reg
, uint16_t v
)
66 MIITRACE( "mii_write entered\n" );
70 xprintf( "ERROR : invalid register in mii_write (%d)!\n", reg
);
76 W_REG(NULL
, ®s
->emacintstatus
, EI_MII
);
78 mdiodata
= MD_SB_START
| MD_OP_WRITE
| (1 << MD_PMD_SHIFT
)
79 | (reg
<< MD_RA_SHIFT
) | MD_TA_VALID
| v
;
82 W_REG(NULL
, ®s
->mdiodata
, mdiodata
);
84 MIITRACE( "Waiting for hardware...\n" );
86 /* wait for it to complete */
87 while( !(R_REG(NULL
, ®s
->emacintstatus
) & EI_MII
) ) {
91 MIITRACE( "mii_write exited\n" );
95 static void mii_or( bcmenetregs_t
* regs
, unsigned int reg
, uint16_t v
)
99 tmp
= mii_read( regs
, reg
);
101 mii_write( regs
, reg
, tmp
);
105 static void mii_and( bcmenetregs_t
* regs
, unsigned int reg
, uint16_t v
)
109 tmp
= mii_read( regs
, reg
);
111 mii_write( regs
, reg
, tmp
);
115 void mii_init( bcmenetregs_t
* regs
)
117 mii_write( regs
, 0, CTL_RESET
);
119 if (mii_read(regs
, 0) & CTL_RESET
) {
120 xprintf( "mii_reset: reset not complete\n" );
123 /* enable activity led */
124 mii_and( regs
, 26, 0x7fff );
126 /* enable traffic meter led mode */
127 mii_or( regs
, 27, (1 << 6) );
131 void mii_setspeed( bcmenetregs_t
* regs
)
136 * Because of our bcm4413 interface limitations, force 10Mbps.
139 /* reset our advertised capabilitity bits */
140 reg
= mii_read(regs
, 4);
141 reg
&= ~(ADV_100FULL
| ADV_100HALF
| ADV_10FULL
| ADV_10HALF
);
142 reg
|= (ADV_10FULL
| ADV_10HALF
);
143 mii_write(regs
, 4, reg
);
145 /* restart autonegotiation */
146 mii_or(regs
, 0, CTL_RESTART
);