From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ben Warren Date: Wed, 31 Oct 2007 13:45:37 -0400 Subject: [U-Boot-Users] [PATCH 2/2 (resubmit)] NET: Add Ethernet 1000BASE-X support for PPC4xx In-Reply-To: <4728ABA6.3090101@arlinx.com> References: <4728ABA6.3090101@arlinx.com> Message-ID: <4728BF41.8040208@qstreams.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Larry, I think this can be simplified a bit. More later on... Larry Johnson wrote: > 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 > --- > > common/miiphyutil.c | 155 +++++++++++++++++++++++++++++++++------------------ > include/miiphy.h | 21 +++++++ > 2 files changed, 121 insertions(+), 55 deletions(-) > > diff --git a/common/miiphyutil.c b/common/miiphyutil.c > index 58ebc5e..b2f62d0 100644 > --- a/common/miiphyutil.c > +++ b/common/miiphyutil.c > @@ -344,101 +344,146 @@ 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) > I don't think you need this CONFIG. It doesn't really do anything. > + u16 bmsr, exsr; > + > + /* 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) { > + > + 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; > Per IEEE 802.3-2005, All PHYs with capabilities > 100Mbps must have PHY_MBSR_EXT_STAT set, and EXSR contains capability info for 1000BX and 1000BT, so you can check for all four here. Please correct me if I'm wrong. > } > } > +#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; > + } > And then you don't need to check 1000BTSR > #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; > Please move the anlpar declaration to the top of the function > + > + 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) > Same as above. Don't need it, I don't think. > + u16 bmsr, exsr; > + > + /* 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) { > + > + 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; > } > Same as above. All GigE capabilities are listed in EXSR > } > #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; > See comment above > - 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 > diff --git a/include/miiphy.h b/include/miiphy.h > index 42f2ad0..83234b9 100644 > --- a/include/miiphy.h > +++ b/include/miiphy.h > @@ -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 > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Splunk Inc. > Still grepping through log files to find problems? Stop. > Now Search log events and configuration files using AJAX and a browser. > Download your FREE copy of Splunk now >> http://get.splunk.com/ > _______________________________________________ > U-Boot-Users mailing list > U-Boot-Users at lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/u-boot-users > > Nice work. regards, Ben