Add Ethernet 1000BASE-X support for PPC4xx
PATCH 3/9 Add Ethernet 1000BASE-X support for PPC4xx
This patch adds a new switch: "CONFIG_PHY_DYNAMIC_ANEG". When this symbol is defined, the PHY will advertise it's capabilities for autonegotiation based on the capabilities shown in the PHY's status registers, including 1000BASE-X. When "CONFIG_PHY_DYNAMIC_ANEG" is not defined, the PHY will advertise hard-coded capabilities, as before.
--- cpu/ppc4xx/miiphy.c | 143 +++++++++++++++++++++++++++++++++++--------------- 1 files changed, 100 insertions(+), 43 deletions(-)
cpu/ppc4xx/miiphy.c +100 -43
@@ -27,19 +27,6 @@| | Author: Mark Wisner | -| Change Activity- -| -| Date Description of Change BY -| --------- --------------------- --- -| 05-May-99 Created MKW -| 01-Jul-99 Changed clock setting of sta_reg from 66Mhz to 50Mhz to -| better match OPB speed. Also modified delay times. JWB -| 29-Jul-99 Added Full duplex support MKW -| 24-Aug-99 Removed printf from dp83843_duplex() JWB -| 19-Jul-00 Ported to esd cpci405 sr -| 23-Dec-03 Ported from miiphy.c to 440GX Travis Sawyer TBS -| <[email protected]> -| +-----------------------------------------------------------------------------*/ #include <common.h>
@@ -61,7 +48,6 @@ void miiphy_dump (char *devname, unsigned char addr)unsigned long i;unsigned short data; -for (i =0 ; i <0x1A ; i++) {if (miiphy_read (devname, addr, i, &data)) {printf ("read error for reg %lx\n" , i);
@@ -76,15 +62,87 @@ void miiphy_dump (char *devname, unsigned char addr) }/* end for loop */ }/* end dump */ -/***********************************************************/ /* (Re)start autonegotiation */ /***********************************************************/ int phy_setup_aneg (char *devname,unsigned char addr) { -unsigned short ctl, adv; +u16 bmcr; + +#if defined(CONFIG_PHY_DYNAMIC_ANEG ) +/* +* Set up advertisement based on capablilities reported by the PHY. +* This should work for both copper and fiber. +*/ +u16 bmsr; +#if defined(CONFIG_PHY_GIGE ) +u16 exsr =0x0000 ; +#endif + +miiphy_read (devname, addr,PHY_BMSR , &bmsr); + +#if defined(CONFIG_PHY_GIGE ) +if (bmsr &PHY_BMSR_EXT_STAT ) { +miiphy_read (devname, addr,PHY_EXSR , &exsr); + } + +if (exsr & (PHY_EXSR_1000XF |PHY_EXSR_1000XH )) { +/* 1000BASE-X */ +u16 anar =0x0000 ; + +if (exsr &PHY_EXSR_1000XF ) { + anar |=PHY_X_ANLPAR_FD ; + } +if (exsr &PHY_EXSR_1000XH ) { + anar |=PHY_X_ANLPAR_HD ; + } +miiphy_write (devname, addr,PHY_ANAR , anar); + } else +#endif + { +u16 anar, btcr; + +miiphy_read (devname, addr,PHY_ANAR , &anar); + anar &= ~(0x5000 |PHY_ANLPAR_T4 |PHY_ANLPAR_TXFD | +PHY_ANLPAR_TX |PHY_ANLPAR_10FD |PHY_ANLPAR_10 ); + +miiphy_read (devname, addr,PHY_1000BTCR , &btcr); + btcr &= ~(0x00FF |PHY_1000BTCR_1000FD |PHY_1000BTCR_1000HD ); + +if (bmsr &PHY_BMSR_100T4 ) { + anar |=PHY_ANLPAR_T4 ; + } +if (bmsr &PHY_BMSR_100TXF ) { + anar |=PHY_ANLPAR_TXFD ; + } +if (bmsr &PHY_BMSR_100TXH ) { + anar |=PHY_ANLPAR_TX ; + } +if (bmsr &PHY_BMSR_10TF ) { + anar |=PHY_ANLPAR_10FD ; + } +if (bmsr &PHY_BMSR_10TH ) { + anar |=PHY_ANLPAR_10 ; + } +miiphy_write (devname, addr,PHY_ANAR , anar); + +#if defined(CONFIG_PHY_GIGE ) +if (exsr &PHY_EXSR_1000TF ) { + btcr |=PHY_1000BTCR_1000FD ; + } +if (exsr &PHY_EXSR_1000TH ) { + btcr |=PHY_1000BTCR_1000HD ; + } +miiphy_write (devname, addr,PHY_1000BTCR , btcr); +#endif + } + +#else /* defined(CONFIG_PHY_DYNAMIC_ANEG) */ +/* +* Set up standard advertisement +*/ +u16 adv; -/* Setup standard advertise */ miiphy_read (devname, addr,PHY_ANAR , &adv); adv |= (PHY_ANLPAR_ACK | PHY_ANLPAR_RF | PHY_ANLPAR_T4 | PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD |
@@ -95,15 +153,16 @@ int phy_setup_aneg (char *devname, unsigned char addr) adv |= (0x0300 );miiphy_write (devname, addr,PHY_1000BTCR , adv); +#endif /* defined(CONFIG_PHY_DYNAMIC_ANEG) */ +/* Start/Restart aneg */ -miiphy_read (devname, addr,PHY_BMCR , &ctl); - ctl |= (PHY_BMCR_AUTON |PHY_BMCR_RST_NEG ); -miiphy_write (devname, addr,PHY_BMCR , ctl); +miiphy_read (devname, addr,PHY_BMCR , &bmcr); + bmcr |= (PHY_BMCR_AUTON |PHY_BMCR_RST_NEG ); +miiphy_write (devname, addr,PHY_BMCR , bmcr);return 0 ; } -/***********************************************************/ /* read a phy reg and return the value with a rc */ /***********************************************************/
@@ -156,21 +215,20 @@ unsigned int miiphy_getemac_offset (void)#endif } - -int emac4xx_miiphy_read (char *devname,unsigned char addr, -unsigned char reg,unsigned short *value) +int emac4xx_miiphy_read (char *devname,unsigned char addr,unsigned char reg, +unsigned short *value) {unsigned long sta_reg;/* STA scratch area */ unsigned long i;unsigned long emac_reg; - emac_reg =miiphy_getemac_offset ();/* see if it is ready for 1000 nsec */ i =0 ;/* see if it is ready for sec */ -while ((in_be32 ((void *)EMAC_STACR + emac_reg) &EMAC_STACR_OC ) ==EMAC_STACR_OC_MASK ) { +while ((in_be32 ((void *)EMAC_STACR + emac_reg) &EMAC_STACR_OC ) == +EMAC_STACR_OC_MASK ) {udelay (7 );if (i >5 ) {#ifdef ET_DEBUG
@@ -187,10 +245,10 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr,#if defined(CONFIG_440GX ) || defined(CONFIG_440SPE ) || \ defined(CONFIG_440EPX ) || defined(CONFIG_440GRX ) || \ defined(CONFIG_405EX ) -#if defined(CONFIG_IBM_EMAC4_V4 )/* EMAC4 V4 changed bit setting */ - sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK ) |EMAC_STACR_READ ; +#if defined(CONFIG_IBM_EMAC4_V4 )/* EMAC4 V4 changed bit setting */ + sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK ) |EMAC_STACR_READ ;#else - sta_reg |=EMAC_STACR_READ ; + sta_reg |=EMAC_STACR_READ ;#endif #else sta_reg = (sta_reg |EMAC_STACR_READ ) & ~EMAC_STACR_CLK_100MHZ ;
@@ -211,7 +269,7 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr, sta_reg =in_be32 ((void *)EMAC_STACR + emac_reg);#ifdef ET_DEBUG -printf ("a21: read : EMAC_STACR=0x%0x\n" , sta_reg);/* test-only */ +printf ("a21: read : EMAC_STACR=0x%0x\n" , sta_reg);/* test-only */ #endif i =0 ;while ((sta_reg &EMAC_STACR_OC ) ==EMAC_STACR_OC_MASK ) {
@@ -229,19 +287,17 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr,return -1 ; } - *value = *(short *) (&sta_reg); + *value = *(short *)(&sta_reg);return 0 ; - }/* phy_read */ -/***********************************************************/ /* write a phy reg and return the value with a rc */ /***********************************************************/ -int emac4xx_miiphy_write (char *devname,unsigned char addr, -unsigned char reg,unsigned short value) +int emac4xx_miiphy_write (char *devname,unsigned char addr,unsigned char reg, +unsigned short value) {unsigned long sta_reg;/* STA scratch area */ unsigned long i;
@@ -251,7 +307,8 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,/* see if it is ready for 1000 nsec */ i =0 ; -while ((in_be32 ((void *)EMAC_STACR + emac_reg) &EMAC_STACR_OC ) ==EMAC_STACR_OC_MASK ) { +while ((in_be32 ((void *)EMAC_STACR + emac_reg) &EMAC_STACR_OC ) == +EMAC_STACR_OC_MASK ) {if (i >5 )return -1 ;udelay (7 );
@@ -263,10 +320,10 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,#if defined(CONFIG_440GX ) || defined(CONFIG_440SPE ) || \ defined(CONFIG_440EPX ) || defined(CONFIG_440GRX ) || \ defined(CONFIG_405EX ) -#if defined(CONFIG_IBM_EMAC4_V4 )/* EMAC4 V4 changed bit setting */ - sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK ) |EMAC_STACR_WRITE ; +#if defined(CONFIG_IBM_EMAC4_V4 )/* EMAC4 V4 changed bit setting */ + sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK ) |EMAC_STACR_WRITE ;#else - sta_reg |=EMAC_STACR_WRITE ; + sta_reg |=EMAC_STACR_WRITE ;#endif #else sta_reg = (sta_reg |EMAC_STACR_WRITE ) & ~EMAC_STACR_CLK_100MHZ ;
@@ -278,8 +335,8 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr, !defined (CONFIG_405EX ) sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ; /* Set clock frequency (PLB freq. dependend) */#endif - sta_reg = sta_reg | ((unsigned long ) addr <<5 );/* Phy address */ - sta_reg = sta_reg |EMAC_STACR_OC_MASK ;/* new IBM emac v4 */ + sta_reg = sta_reg | ((unsigned long )addr <<5 );/* Phy address */ + sta_reg = sta_reg |EMAC_STACR_OC_MASK ;/* new IBM emac v4 */ memcpy (&sta_reg, &value,2 );/* put in data */ out_be32 ((void *)EMAC_STACR + emac_reg, sta_reg);
@@ -288,7 +345,7 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr, i =0 ; sta_reg =in_be32 ((void *)EMAC_STACR + emac_reg);#ifdef ET_DEBUG -printf ("a31: read : EMAC_STACR=0x%0x\n" , sta_reg);/* test-only */ +printf ("a31: read : EMAC_STACR=0x%0x\n" , sta_reg);/* test-only */ #endif while ((sta_reg &EMAC_STACR_OC ) ==EMAC_STACR_OC_MASK ) {udelay (7 );
@@ -305,4 +362,4 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,return -1 ;return 0 ; -}/* phy_write */ +}/* phy_write */
Signature · 1 line
1.5.2.5
PATCH 3/9 Add Ethernet 1000BASE-X support for PPC4xx
Quoted 5 lines · Larry Johnson
This patch adds a new switch: "
CONFIG_PHY_DYNAMIC_ANEG". When this symbol is defined, the PHY will advertise it's capabilities for autonegotiation based on the capabilities shown in the PHY's status registers, including 1000BASE-X. When "CONFIG_PHY_DYNAMIC_ANEG" is not defined, the PHY will advertise hard-coded capabilities, as before.
Sorry for the late review, but I have still some remarks. Please see below.
Quoted 59 lines
Signed-off-by Larry Johnson <[email protected]>--- cpu/ppc4xx/miiphy.c | 143+++++++++++++++++++++++++++++++++++--------------- 1 files changed, 100 insertions(+), 43 deletions(-)
cpu/ppc4xx/miiphy.c +1
-14@@ -27,19 +27,6 @@ | Author: Mark Wisner -| Change Activity- -| -| Date Description of Change BY -| --------- --------------------- --- -| 05-May-99 Created MKW -| 01-Jul-99 Changed clock setting of sta_reg from 66Mhz to 50Mhz to -| better match OPB speed. Also modified delay times. JWB -| 29-Jul-99 Added Full duplex support MKW -| 24-Aug-99 Removed printf from dp83843_duplex() JWB -| 19-Jul-00 Ported to esd cpci405 sr -| 23-Dec-03 Ported from miiphy.c to 440GX Travis Sawyer TBS -| <[email protected]> -| +-------------------------------------------------------------------------- ---*/ #include <
common.h>cpu/ppc4xx/miiphy.c +8
-3@@ -61,7 +48,6 @@ void miiphy_dump (char *devname, unsigned char addr)unsigned long i;unsigned short data; -for (i =0 ; i <0x1A ; i++) {if (miiphy_read (devname, addr, i, &data)) {printf ("read error for reg %lx\n" , i);@@ -76,15 +62,87 @@ void miiphy_dump (char *devname, unsigned char addr) }/* end for loop */ }/* end dump */ -/***********************************************************/ /* (Re)start autonegotiation */ /***********************************************************/ int phy_setup_aneg (char *devname,unsigned char addr) { -unsigned short ctl, adv; +u16 bmcr; + +#if defined(CONFIG_PHY_DYNAMIC_ANEG ) +/* +* Set up advertisement based on capablilities reported by the PHY. +* This should work for both copper and fiber. +*/ +u16 bmsr;
cpu/ppc4xx/miiphy.c void miiphy_dump (char *devname, unsigned char addr) · line 87
Quoted 10 lines
cpu/ppc4xx/miiphy.c +10
-0+#if defined(CONFIG_PHY_GIGE ) +u16 exsr =0x0000 ; +#endif + +miiphy_read (devname, addr,PHY_BMSR , &bmsr); + +#if defined(CONFIG_PHY_GIGE ) +if (bmsr &PHY_BMSR_EXT_STAT ) { +miiphy_read (devname, addr,PHY_EXSR , &exsr); + }
No parantheses (braces ?) for one line statements please.
cpu/ppc4xx/miiphy.c void miiphy_dump (char *devname, unsigned char addr) · line 98
Quoted 10 lines
cpu/ppc4xx/miiphy.c +10
-0+if (exsr & (PHY_EXSR_1000XF |PHY_EXSR_1000XH )) { +/* 1000BASE-X */ +u16 anar =0x0000 ; + +if (exsr &PHY_EXSR_1000XF ) { + anar |=PHY_X_ANLPAR_FD ; + } +if (exsr &PHY_EXSR_1000XH ) { + anar |=PHY_X_ANLPAR_HD ; + }
Again, please check the complete source for such on lined statements and remove those braces.
Thanks.
Best regards,
Stefan
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
=====================================================================