diff options
| -rw-r--r-- | common/cmd_mii.c | 8 | ||||
| -rw-r--r-- | common/miiphyutil.c | 151 | ||||
| -rw-r--r-- | include/miiphy.h | 22 | 
3 files changed, 121 insertions, 60 deletions
| diff --git a/common/cmd_mii.c b/common/cmd_mii.c index 72e11d544..3b4dc8ae0 100644 --- a/common/cmd_mii.c +++ b/common/cmd_mii.c @@ -112,9 +112,11 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  					"OUI = 0x%04X, "  					"Model = 0x%02X, "  					"Rev = 0x%02X, " -					"%3dbaseT, %s\n", +					"%3dbase%s, %s\n",  					j, oui, model, rev,  					miiphy_speed (devname, j), +					miiphy_is_1000base_x (devname, j) +						? "X" : "T",  					(miiphy_duplex (devname, j) == FULL)  						? "FDX" : "HDX");  			} @@ -496,9 +498,11 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  					"OUI = 0x%04X, "  					"Model = 0x%02X, "  					"Rev = 0x%02X, " -					"%3dbaseT, %s\n", +					"%3dbase%s, %s\n",  					j, oui, model, rev,  					miiphy_speed (devname, j), +					miiphy_is_1000base_x (devname, j) +						? "X" : "T",  					(miiphy_duplex (devname, j) == FULL)  						? "FDX" : "HDX");  			} diff --git a/common/miiphyutil.c b/common/miiphyutil.c index 58ebc5ec2..281f0b29e 100644 --- a/common/miiphyutil.c +++ b/common/miiphyutil.c @@ -344,101 +344,136 @@ 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, anlpar;  #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; + +	/* +	 * Check for 1000BASE-X.  If it is supported, then assume that the speed +	 * is 1000. +	 */ +	if (miiphy_is_1000base_x (devname, addr)) { +		return _1000BASET; +	} +	/* +	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set. +	 */ +	/* 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); +		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, anlpar;  #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; + +	/* Check for 1000BASE-X. */ +	if (miiphy_is_1000base_x (devname, addr)) { +		/* 1000BASE-X */ +		if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) { +			printf ("1000BASE-X PHY AN duplex"); +			goto miiphy_read_failed; +		} +	} +	/* +	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set. +	 */ +	/* 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); -		} - -		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; +} +/***************************************************************************** + * + * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/ + * 1000BASE-T, or on error. + */ +int miiphy_is_1000base_x (char *devname, unsigned char addr) +{ +#if defined(CONFIG_PHY_GIGE) +	u16 exsr; + +	if (miiphy_read (devname, addr, PHY_EXSR, &exsr)) { +		printf ("PHY extended status read failed, assuming no " +			"1000BASE-X\n"); +		return 0; +	} +	return 0 != (exsr & (PHY_EXSR_1000XF | PHY_EXSR_1000XH)); +#else +	return 0; +#endif  }  #ifdef CFG_FAULT_ECHO_LINK_DOWN diff --git a/include/miiphy.h b/include/miiphy.h index 42f2ad0c9..5518a0a89 100644 --- a/include/miiphy.h +++ b/include/miiphy.h @@ -41,6 +41,7 @@ int miiphy_info (char *devname, unsigned char addr, unsigned int *oui,  int miiphy_reset (char *devname, unsigned char addr);  int miiphy_speed (char *devname, unsigned char addr);  int miiphy_duplex (char *devname, unsigned char addr); +int miiphy_is_1000base_x (char *devname, unsigned char addr);  #ifdef CFG_FAULT_ECHO_LINK_DOWN  int miiphy_link (char *devname, unsigned char addr);  #endif @@ -85,6 +86,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 +120,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 +133,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 +165,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 |