NET: Add Ethernet 1000BASE-X support for PPC4xx
This patch adds support for 1000BASE-X to functions "miiphy_speed ()" and "miiphy_duplex()". It also adds function "miiphy_is_1000base_x ()", which returns non-zero iff the PHY registers are configured for 1000BASE-X. The "mii info" command is modified to distinguish between 1000BASE-T and -X. Signed-off-by: Larry Johnson <lrj@acm.org> Signed-off-by: Ben Warren <bwarren@qstreams.com>
This commit is contained in:
parent
298035df49
commit
71bc6e6474
|
@ -112,9 +112,11 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||||
"OUI = 0x%04X, "
|
"OUI = 0x%04X, "
|
||||||
"Model = 0x%02X, "
|
"Model = 0x%02X, "
|
||||||
"Rev = 0x%02X, "
|
"Rev = 0x%02X, "
|
||||||
"%3dbaseT, %s\n",
|
"%3dbase%s, %s\n",
|
||||||
j, oui, model, rev,
|
j, oui, model, rev,
|
||||||
miiphy_speed (devname, j),
|
miiphy_speed (devname, j),
|
||||||
|
miiphy_is_1000base_x (devname, j)
|
||||||
|
? "X" : "T",
|
||||||
(miiphy_duplex (devname, j) == FULL)
|
(miiphy_duplex (devname, j) == FULL)
|
||||||
? "FDX" : "HDX");
|
? "FDX" : "HDX");
|
||||||
}
|
}
|
||||||
|
@ -496,9 +498,11 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||||
"OUI = 0x%04X, "
|
"OUI = 0x%04X, "
|
||||||
"Model = 0x%02X, "
|
"Model = 0x%02X, "
|
||||||
"Rev = 0x%02X, "
|
"Rev = 0x%02X, "
|
||||||
"%3dbaseT, %s\n",
|
"%3dbase%s, %s\n",
|
||||||
j, oui, model, rev,
|
j, oui, model, rev,
|
||||||
miiphy_speed (devname, j),
|
miiphy_speed (devname, j),
|
||||||
|
miiphy_is_1000base_x (devname, j)
|
||||||
|
? "X" : "T",
|
||||||
(miiphy_duplex (devname, j) == FULL)
|
(miiphy_duplex (devname, j) == FULL)
|
||||||
? "FDX" : "HDX");
|
? "FDX" : "HDX");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
int miiphy_speed (char *devname, unsigned char addr)
|
||||||
{
|
{
|
||||||
unsigned short reg;
|
u16 bmcr, anlpar;
|
||||||
|
|
||||||
#if defined(CONFIG_PHY_GIGE)
|
#if defined(CONFIG_PHY_GIGE)
|
||||||
if (miiphy_read (devname, addr, PHY_1000BTSR, ®)) {
|
u16 btsr;
|
||||||
printf ("PHY 1000BT Status read failed\n");
|
|
||||||
} else {
|
/*
|
||||||
if (reg != 0xFFFF) {
|
* Check for 1000BASE-X. If it is supported, then assume that the speed
|
||||||
if ((reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))
|
* is 1000.
|
||||||
!= 0) {
|
*/
|
||||||
return (_1000BASET);
|
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 */
|
#endif /* CONFIG_PHY_GIGE */
|
||||||
|
|
||||||
/* Check Basic Management Control Register first. */
|
/* Check Basic Management Control Register first. */
|
||||||
if (miiphy_read (devname, addr, PHY_BMCR, ®)) {
|
if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) {
|
||||||
puts ("PHY speed read failed, assuming 10bT\n");
|
printf ("PHY speed");
|
||||||
return (_10BASET);
|
goto miiphy_read_failed;
|
||||||
}
|
}
|
||||||
/* Check if auto-negotiation is on. */
|
/* Check if auto-negotiation is on. */
|
||||||
if ((reg & PHY_BMCR_AUTON) != 0) {
|
if (bmcr & PHY_BMCR_AUTON) {
|
||||||
/* Get auto-negotiation results. */
|
/* Get auto-negotiation results. */
|
||||||
if (miiphy_read (devname, addr, PHY_ANLPAR, ®)) {
|
if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
|
||||||
puts ("PHY AN speed read failed, assuming 10bT\n");
|
printf ("PHY AN speed");
|
||||||
return (_10BASET);
|
goto miiphy_read_failed;
|
||||||
}
|
|
||||||
if ((reg & PHY_ANLPAR_100) != 0) {
|
|
||||||
return (_100BASET);
|
|
||||||
} else {
|
|
||||||
return (_10BASET);
|
|
||||||
}
|
}
|
||||||
|
return (anlpar & PHY_ANLPAR_100) ? _100BASET : _10BASET;
|
||||||
}
|
}
|
||||||
/* Get speed from basic control settings. */
|
/* Get speed from basic control settings. */
|
||||||
else if (reg & PHY_BMCR_100MB) {
|
return (bmcr & PHY_BMCR_100MB) ? _100BASET : _10BASET;
|
||||||
return (_100BASET);
|
|
||||||
} else {
|
|
||||||
return (_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)
|
int miiphy_duplex (char *devname, unsigned char addr)
|
||||||
{
|
{
|
||||||
unsigned short reg;
|
u16 bmcr, anlpar;
|
||||||
|
|
||||||
#if defined(CONFIG_PHY_GIGE)
|
#if defined(CONFIG_PHY_GIGE)
|
||||||
if (miiphy_read (devname, addr, PHY_1000BTSR, ®)) {
|
u16 btsr;
|
||||||
printf ("PHY 1000BT Status read failed\n");
|
|
||||||
} else {
|
/* Check for 1000BASE-X. */
|
||||||
if ((reg != 0xFFFF) &&
|
if (miiphy_is_1000base_x (devname, addr)) {
|
||||||
(reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))) {
|
/* 1000BASE-X */
|
||||||
if ((reg & PHY_1000BTSR_1000FD) != 0) {
|
if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
|
||||||
return (FULL);
|
printf ("1000BASE-X PHY AN duplex");
|
||||||
} else {
|
goto miiphy_read_failed;
|
||||||
return (HALF);
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* 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 */
|
#endif /* CONFIG_PHY_GIGE */
|
||||||
|
|
||||||
/* Check Basic Management Control Register first. */
|
/* Check Basic Management Control Register first. */
|
||||||
if (miiphy_read (devname, addr, PHY_BMCR, ®)) {
|
if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) {
|
||||||
puts ("PHY duplex read failed, assuming half duplex\n");
|
puts ("PHY duplex");
|
||||||
return (HALF);
|
goto miiphy_read_failed;
|
||||||
}
|
}
|
||||||
/* Check if auto-negotiation is on. */
|
/* Check if auto-negotiation is on. */
|
||||||
if ((reg & PHY_BMCR_AUTON) != 0) {
|
if (bmcr & PHY_BMCR_AUTON) {
|
||||||
/* Get auto-negotiation results. */
|
/* Get auto-negotiation results. */
|
||||||
if (miiphy_read (devname, addr, PHY_ANLPAR, ®)) {
|
if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
|
||||||
puts ("PHY AN duplex read failed, assuming half duplex\n");
|
puts ("PHY AN duplex");
|
||||||
return (HALF);
|
goto miiphy_read_failed;
|
||||||
}
|
|
||||||
|
|
||||||
if ((reg & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) != 0) {
|
|
||||||
return (FULL);
|
|
||||||
} else {
|
|
||||||
return (HALF);
|
|
||||||
}
|
}
|
||||||
|
return (anlpar & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) ?
|
||||||
|
FULL : HALF;
|
||||||
}
|
}
|
||||||
/* Get speed from basic control settings. */
|
/* Get speed from basic control settings. */
|
||||||
else if (reg & PHY_BMCR_DPLX) {
|
return (bmcr & PHY_BMCR_DPLX) ? FULL : HALF;
|
||||||
return (FULL);
|
|
||||||
} else {
|
|
||||||
return (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
|
#ifdef CFG_FAULT_ECHO_LINK_DOWN
|
||||||
|
|
|
@ -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_reset (char *devname, unsigned char addr);
|
||||||
int miiphy_speed (char *devname, unsigned char addr);
|
int miiphy_speed (char *devname, unsigned char addr);
|
||||||
int miiphy_duplex (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
|
#ifdef CFG_FAULT_ECHO_LINK_DOWN
|
||||||
int miiphy_link (char *devname, unsigned char addr);
|
int miiphy_link (char *devname, unsigned char addr);
|
||||||
#endif
|
#endif
|
||||||
|
@ -85,6 +86,7 @@ int bb_miiphy_write (char *devname, unsigned char addr,
|
||||||
#define PHY_ANLPNP 0x08
|
#define PHY_ANLPNP 0x08
|
||||||
#define PHY_1000BTCR 0x09
|
#define PHY_1000BTCR 0x09
|
||||||
#define PHY_1000BTSR 0x0A
|
#define PHY_1000BTSR 0x0A
|
||||||
|
#define PHY_EXSR 0x0F
|
||||||
#define PHY_PHYSTS 0x10
|
#define PHY_PHYSTS 0x10
|
||||||
#define PHY_MIPSCR 0x11
|
#define PHY_MIPSCR 0x11
|
||||||
#define PHY_MIPGSR 0x12
|
#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_100TXH 0x2000
|
||||||
#define PHY_BMSR_10TF 0x1000
|
#define PHY_BMSR_10TF 0x1000
|
||||||
#define PHY_BMSR_10TH 0x0800
|
#define PHY_BMSR_10TH 0x0800
|
||||||
|
#define PHY_BMSR_EXT_STAT 0x0100
|
||||||
#define PHY_BMSR_PRE_SUP 0x0040
|
#define PHY_BMSR_PRE_SUP 0x0040
|
||||||
#define PHY_BMSR_AUTN_COMP 0x0020
|
#define PHY_BMSR_AUTN_COMP 0x0020
|
||||||
#define PHY_BMSR_RF 0x0010
|
#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_NP 0x8000
|
||||||
#define PHY_ANLPAR_ACK 0x4000
|
#define PHY_ANLPAR_ACK 0x4000
|
||||||
#define PHY_ANLPAR_RF 0x2000
|
#define PHY_ANLPAR_RF 0x2000
|
||||||
|
#define PHY_ANLPAR_ASYMP 0x0800
|
||||||
|
#define PHY_ANLPAR_PAUSE 0x0400
|
||||||
#define PHY_ANLPAR_T4 0x0200
|
#define PHY_ANLPAR_T4 0x0200
|
||||||
#define PHY_ANLPAR_TXFD 0x0100
|
#define PHY_ANLPAR_TXFD 0x0100
|
||||||
#define PHY_ANLPAR_TX 0x0080
|
#define PHY_ANLPAR_TX 0x0080
|
||||||
#define PHY_ANLPAR_10FD 0x0040
|
#define PHY_ANLPAR_10FD 0x0040
|
||||||
#define PHY_ANLPAR_10 0x0020
|
#define PHY_ANLPAR_10 0x0020
|
||||||
#define PHY_ANLPAR_100 0x0380 /* we can run at 100 */
|
#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_MASK 0x001f
|
||||||
#define PHY_ANLPAR_PSB_802_3 0x0001
|
#define PHY_ANLPAR_PSB_802_3 0x0001
|
||||||
#define PHY_ANLPAR_PSB_802_9 0x0002
|
#define PHY_ANLPAR_PSB_802_9 0x0002
|
||||||
|
|
||||||
|
/* phy 1000BTCR */
|
||||||
|
#define PHY_1000BTCR_1000FD 0x0200
|
||||||
|
#define PHY_1000BTCR_1000HD 0x0100
|
||||||
|
|
||||||
/* phy 1000BTSR */
|
/* phy 1000BTSR */
|
||||||
#define PHY_1000BTSR_MSCF 0x8000
|
#define PHY_1000BTSR_MSCF 0x8000
|
||||||
#define PHY_1000BTSR_MSCR 0x4000
|
#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_1000FD 0x0800
|
||||||
#define PHY_1000BTSR_1000HD 0x0400
|
#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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue