RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / arch / mips / board / bcm97115 / src / dev_bcm4413_mii.c
blob80371e1349c98a8799649c16526d39e1b5e8b564
1 #include "lib_types.h"
2 #include "lib_printf.h"
4 #include "cfe_timer.h"
6 #include "dev_bcm4413.h"
7 #include "dev_bcm4413_mii.h"
10 #define MIITRACE( x )
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 )
27 uint32_t mdiodata;
29 MIITRACE( "mii_read entered\n" );
31 #ifdef DEBUG
32 if( reg >= 32 ) {
33 xprintf( "ERROR : invalid register in mii_read (%d)!\n", reg );
34 return -1;
36 #endif
38 /* clear mii_int */
39 W_REG(NULL, &regs->emacintstatus, EI_MII );
41 mdiodata = MD_SB_START | MD_OP_READ | (1 << MD_PMD_SHIFT)
42 | (reg << MD_RA_SHIFT) | MD_TA_VALID;
44 /* issue the read */
45 W_REG(NULL, &regs->mdiodata, mdiodata );
47 MIITRACE( "Waiting for hardware...\n" );
49 /* wait for it to complete */
50 while( !(R_REG(NULL, &regs->emacintstatus) & EI_MII) ) {
51 cfe_usleep( 10 );
54 mdiodata = R_REG(NULL, &regs->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 )
64 uint32_t mdiodata;
66 MIITRACE( "mii_write entered\n" );
68 #ifdef DEBUG
69 if( reg >= 32 ) {
70 xprintf( "ERROR : invalid register in mii_write (%d)!\n", reg );
71 return;
73 #endif
75 /* clear mii_int */
76 W_REG(NULL, &regs->emacintstatus, EI_MII );
78 mdiodata = MD_SB_START | MD_OP_WRITE | (1 << MD_PMD_SHIFT)
79 | (reg << MD_RA_SHIFT) | MD_TA_VALID | v;
81 /* issue the write */
82 W_REG(NULL, &regs->mdiodata, mdiodata );
84 MIITRACE( "Waiting for hardware...\n" );
86 /* wait for it to complete */
87 while( !(R_REG(NULL, &regs->emacintstatus) & EI_MII) ) {
88 cfe_usleep( 10 );
91 MIITRACE( "mii_write exited\n" );
95 static void mii_or( bcmenetregs_t * regs, unsigned int reg, uint16_t v )
97 uint16_t tmp;
99 tmp = mii_read( regs, reg );
100 tmp |= v;
101 mii_write( regs, reg, tmp );
105 static void mii_and( bcmenetregs_t * regs, unsigned int reg, uint16_t v )
107 uint16_t tmp;
109 tmp = mii_read( regs, reg );
110 tmp &= v;
111 mii_write( regs, reg, tmp );
115 void mii_init( bcmenetregs_t * regs )
117 mii_write( regs, 0, CTL_RESET );
118 cfe_usleep( 10 );
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 )
133 uint16_t reg;
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);