PPC4xx: Add Ethernet 1000BASE-X support for PPC4xx
PATCH 2/2 PPC4xx: 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.
Signed-off-by Larry Johnson <[email protected]>
---
common/miiphyutil.c | 157 +++++++++++++++++++++++++++++++++------------------ cpu/ppc4xx/miiphy.c | 85 ++++++++++++++++++++++++++-- include/miiphy.h | 21 +++++++ 3 files changed, 203 insertions(+), 60 deletions(-)
common/miiphyutil.c +102 -55
@@ -344,101 +344,148 @@ int miiphy_reset (char *devname, unsigned char addr)/***************************************************************************** * -* Determine the ethernet speed (10/100). +* Determine the ethernet speed (10/100/1000). Return 10 on error. */ int miiphy_speed (char *devname,unsigned char addr) { -unsigned short reg; +u16 bmcr;#if defined(CONFIG_PHY_GIGE ) -if (miiphy_read (devname, addr,PHY_1000BTSR , ®)) { -printf ("PHY 1000BT Status read failed\n" ); - }else { -if (reg !=0xFFFF ) { -if ((reg & (PHY_1000BTSR_1000FD |PHY_1000BTSR_1000HD )) - !=0 ) { -return (_1000BASET); - } +u16 btsr; + +#if defined(CONFIG_PHY_DYNAMIC_ANEG ) +u16 bmsr; + +/* Check for 1000BASE-X. */ +if (miiphy_read (devname, addr,PHY_BMSR , &bmsr)) { +printf ("PHY status" ); + goto miiphy_read_failed; + } +if (bmsr &PHY_BMSR_EXT_STAT ) { +u16 exsr; + +if (miiphy_read (devname, addr,PHY_EXSR , &exsr)) { +printf ("PHY extended status" ); + goto miiphy_read_failed; + } +if (exsr & (PHY_EXSR_1000XF |PHY_EXSR_1000XH )) { +/* 1000BASE-X */ +return _1000BASET; } } +#endif /* defined(CONFIG_PHY_DYNAMIC_ANEG) */ + +/* Check for 1000BASE-T. */ +if (miiphy_read (devname, addr,PHY_1000BTSR , &btsr)) { +printf ("PHY 1000BT status" ); + goto miiphy_read_failed; + } +if (btsr !=0xFFFF && + (btsr & (PHY_1000BTSR_1000FD |PHY_1000BTSR_1000HD ))) { +return _1000BASET; + }#endif /* CONFIG_PHY_GIGE */ /* Check Basic Management Control Register first. */ -if (miiphy_read (devname, addr,PHY_BMCR , ®)) { -puts ("PHY speed read failed, assuming 10bT\n" ); -return (_10BASET); +if (miiphy_read (devname, addr,PHY_BMCR , &bmcr)) { +printf ("PHY speed" ); + goto miiphy_read_failed; }/* Check if auto-negotiation is on. */ -if ((reg &PHY_BMCR_AUTON ) !=0 ) { +if (bmcr &PHY_BMCR_AUTON ) {/* Get auto-negotiation results. */ -if (miiphy_read (devname, addr,PHY_ANLPAR , ®)) { -puts ("PHY AN speed read failed, assuming 10bT\n" ); -return (_10BASET); - } -if ((reg &PHY_ANLPAR_100 ) !=0 ) { -return (_100BASET); - }else { -return (_10BASET); +u16 anlpar; + +if (miiphy_read (devname, addr,PHY_ANLPAR , &anlpar)) { +printf ("PHY AN speed" ); + goto miiphy_read_failed; } +return (anlpar &PHY_ANLPAR_100 ) ? _100BASET : _10BASET; }/* Get speed from basic control settings. */ -else if (reg &PHY_BMCR_100MB ) { -return (_100BASET); - }else { -return (_10BASET); - } +return (bmcr &PHY_BMCR_100MB ) ? _100BASET : _10BASET; + miiphy_read_failed: +printf (" read failed, assuming 10BASE-T\n" ); +return _10BASET; }/***************************************************************************** * -* Determine full/half duplex. +* Determine full/half duplex. Return half on error. */ int miiphy_duplex (char *devname,unsigned char addr) { -unsigned short reg; +u16 bmcr;#if defined(CONFIG_PHY_GIGE ) -if (miiphy_read (devname, addr,PHY_1000BTSR , ®)) { -printf ("PHY 1000BT Status read failed\n" ); - }else { -if ((reg !=0xFFFF ) && - (reg & (PHY_1000BTSR_1000FD |PHY_1000BTSR_1000HD ))) { -if ((reg &PHY_1000BTSR_1000FD ) !=0 ) { -return (FULL ); - }else { -return (HALF ); +u16 btsr; + +#if defined(CONFIG_PHY_DYNAMIC_ANEG ) +u16 bmsr; + +/* Check for 1000BASE-X. */ +if (miiphy_read (devname, addr,PHY_BMSR , &bmsr)) { +printf ("PHY status" ); + goto miiphy_read_failed; + } +if (bmsr &PHY_BMSR_EXT_STAT ) { +u16 exsr; + +if (miiphy_read (devname, addr,PHY_EXSR , &exsr)) { +printf ("PHY extended status" ); + goto miiphy_read_failed; + } +if (exsr & (PHY_EXSR_1000XF |PHY_EXSR_1000XH )) { +/* 1000BASE-X */ +u16 anlpar; + +if (miiphy_read (devname, addr,PHY_ANLPAR , &anlpar)) { +printf ("1000BASE-X PHY AN duplex" ); + goto miiphy_read_failed; } +return (anlpar &PHY_X_ANLPAR_FD ) ?FULL :HALF ; + } + } +#endif /* defined(CONFIG_PHY_DYNAMIC_ANEG) */ + +/* Check for 1000BASE-T. */ +if (miiphy_read (devname, addr,PHY_1000BTSR , &btsr)) { +printf ("PHY 1000BT status" ); + goto miiphy_read_failed; + } +if (btsr !=0xFFFF ) { +if (btsr &PHY_1000BTSR_1000FD ) { +return FULL ; + }else if (btsr &PHY_1000BTSR_1000HD ) { +return HALF ; } }#endif /* CONFIG_PHY_GIGE */ /* Check Basic Management Control Register first. */ -if (miiphy_read (devname, addr,PHY_BMCR , ®)) { -puts ("PHY duplex read failed, assuming half duplex\n" ); -return (HALF ); +if (miiphy_read (devname, addr,PHY_BMCR , &bmcr)) { +puts ("PHY duplex" ); + goto miiphy_read_failed; }/* Check if auto-negotiation is on. */ -if ((reg &PHY_BMCR_AUTON ) !=0 ) { +if (bmcr &PHY_BMCR_AUTON ) {/* Get auto-negotiation results. */ -if (miiphy_read (devname, addr,PHY_ANLPAR , ®)) { -puts ("PHY AN duplex read failed, assuming half duplex\n" ); -return (HALF ); - } +u16 anlpar; -if ((reg & (PHY_ANLPAR_10FD |PHY_ANLPAR_TXFD )) !=0 ) { -return (FULL ); - }else { -return (HALF ); +if (miiphy_read (devname, addr,PHY_ANLPAR , &anlpar)) { +puts ("PHY AN duplex" ); + goto miiphy_read_failed; } +return (anlpar & (PHY_ANLPAR_10FD |PHY_ANLPAR_TXFD )) ? +FULL :HALF ; }/* Get speed from basic control settings. */ -else if (reg &PHY_BMCR_DPLX ) { -return (FULL ); - }else { -return (HALF ); - } +return (bmcr &PHY_BMCR_DPLX ) ?FULL :HALF ; + miiphy_read_failed: +printf (" read failed, assuming half duplex\n" ); +return HALF ; }#ifdef CFG_FAULT_ECHO_LINK_DOWN
cpu/ppc4xx/miiphy.c +80 -5
99 lines not on this page · raw message
include/miiphy.h +21 -0
@@ -85,6 +85,7 @@ int bb_miiphy_write (char *devname, unsigned char addr,#define PHY_ANLPNP 0x08#define PHY_1000BTCR 0x09#define PHY_1000BTSR 0x0A +#define PHY_EXSR 0x0F#define PHY_PHYSTS 0x10#define PHY_MIPSCR 0x11#define PHY_MIPGSR 0x12
@@ -118,6 +119,7 @@ int bb_miiphy_write (char *devname, unsigned char addr,#define PHY_BMSR_100TXH 0x2000#define PHY_BMSR_10TF 0x1000#define PHY_BMSR_10TH 0x0800 +#define PHY_BMSR_EXT_STAT 0x0100#define PHY_BMSR_PRE_SUP 0x0040#define PHY_BMSR_AUTN_COMP 0x0020#define PHY_BMSR_RF 0x0010
@@ -130,17 +132,30 @@ int bb_miiphy_write (char *devname, unsigned char addr,#define PHY_ANLPAR_NP 0x8000#define PHY_ANLPAR_ACK 0x4000#define PHY_ANLPAR_RF 0x2000 +#define PHY_ANLPAR_ASYMP 0x0800 +#define PHY_ANLPAR_PAUSE 0x0400#define PHY_ANLPAR_T4 0x0200#define PHY_ANLPAR_TXFD 0x0100#define PHY_ANLPAR_TX 0x0080#define PHY_ANLPAR_10FD 0x0040#define PHY_ANLPAR_10 0x0020#define PHY_ANLPAR_100 0x0380/* we can run at 100 */ +/* phy ANLPAR 1000BASE-X */ +#define PHY_X_ANLPAR_NP 0x8000 +#define PHY_X_ANLPAR_ACK 0x4000 +#define PHY_X_ANLPAR_RF_MASK 0x3000 +#define PHY_X_ANLPAR_PAUSE_MASK 0x0180 +#define PHY_X_ANLPAR_HD 0x0040 +#define PHY_X_ANLPAR_FD 0x0020#define PHY_ANLPAR_PSB_MASK 0x001f#define PHY_ANLPAR_PSB_802_3 0x0001#define PHY_ANLPAR_PSB_802_9 0x0002 +/* phy 1000BTCR */ +#define PHY_1000BTCR_1000FD 0x0200 +#define PHY_1000BTCR_1000HD 0x0100 +/* phy 1000BTSR */ #define PHY_1000BTSR_MSCF 0x8000#define PHY_1000BTSR_MSCR 0x4000
@@ -149,4 +164,10 @@ int bb_miiphy_write (char *devname, unsigned char addr,#define PHY_1000BTSR_1000FD 0x0800#define PHY_1000BTSR_1000HD 0x0400 +/* phy EXSR */ +#define PHY_EXSR_1000XF 0x8000 +#define PHY_EXSR_1000XH 0x4000 +#define PHY_EXSR_1000TF 0x2000 +#define PHY_EXSR_1000TH 0x1000 +#endif