Complete replacement of PHY logic for Am79c874
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1573 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
e8a4d3516b
commit
64b9459a4c
@ -123,13 +123,29 @@
|
|||||||
# error "Unsupported CONFIG_EZ80_PKTBUFSIZE value"
|
# error "Unsupported CONFIG_EZ80_PKTBUFSIZE value"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Am79c874 PHY configuration */
|
||||||
|
|
||||||
|
#define EZ80_EMAC_AUTONEG 0
|
||||||
|
#define EZ80_EMAC_100BFD 1
|
||||||
|
#define EZ80_EMAC_100BHD 2
|
||||||
|
#define EZ80_EMAC_10BFD 3
|
||||||
|
#define EZ80_EMAC_10BHD 4
|
||||||
|
|
||||||
|
#ifndef CONFIG_EZ80_PHYCONFIG
|
||||||
|
# define CONFIG_EZ80_PHYCONFIG EZ80_EMAC_10BFD
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Select the fastest MDC clock that does not exceed 25MHz. The MDC
|
/* Select the fastest MDC clock that does not exceed 25MHz. The MDC
|
||||||
* clock derives from the SCLK divided by 4, 6, 8, 10, 14, 20, or 28.
|
* clock derives from the SCLK divided by 4, 6, 8, 10, 14, 20, or 28.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONFIG_EZ80_MDCDIV
|
#ifndef CONFIG_EZ80_MDCDIV
|
||||||
|
# ifdef CONFIG_EZ80_PHYAM79C874
|
||||||
|
# define CONFIG_EZ80_MDCDIV EMAC_MDC_DIV20
|
||||||
|
# else
|
||||||
# define CONFIG_EZ80_MDCDIV EMAC_MDC_DIV4
|
# define CONFIG_EZ80_MDCDIV EMAC_MDC_DIV4
|
||||||
# endif
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Select the Tx poll timer. If not specified, a 10MS timer is set */
|
/* Select the Tx poll timer. If not specified, a 10MS timer is set */
|
||||||
|
|
||||||
@ -319,7 +335,7 @@ static void ez80emac_miiwrite(FAR struct ez80emac_driver_s *priv, ubyte offse
|
|||||||
static uint16 ez80emac_miiread(FAR struct ez80emac_driver_s *priv, uint32 offset);
|
static uint16 ez80emac_miiread(FAR struct ez80emac_driver_s *priv, uint32 offset);
|
||||||
static boolean ez80emac_miipoll(FAR struct ez80emac_driver_s *priv, uint32 offset,
|
static boolean ez80emac_miipoll(FAR struct ez80emac_driver_s *priv, uint32 offset,
|
||||||
uint16 bits, boolean bclear);
|
uint16 bits, boolean bclear);
|
||||||
static void ez80emac_miiautonegotiate(FAR struct ez80emac_driver_s *priv);
|
static int ez80emac_miiautonegotiate(FAR struct ez80emac_driver_s *priv);
|
||||||
|
|
||||||
/* Multi-cast filtering */
|
/* Multi-cast filtering */
|
||||||
|
|
||||||
@ -523,7 +539,156 @@ static boolean ez80emac_miipoll(FAR struct ez80emac_driver_s *priv, uint32 offse
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void ez80emac_miiautonegotiate(FAR struct ez80emac_driver_s *priv)
|
#ifdef CONFIG_EZ80_PHYAM79C874
|
||||||
|
static int ez80emac_miiautonegotiate(FAR struct ez80emac_driver_s *priv)
|
||||||
|
{
|
||||||
|
uint16 phyval;
|
||||||
|
boolean bauto;
|
||||||
|
int ret = OK;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Verify that the detect PHY is an AMD Am87c874 as expected */
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG /* Parameter checking only done when DEBUG is enabled */
|
||||||
|
phyval = ez80emac_miiread(priv, MII_PHYID1);
|
||||||
|
if (phyval != MII_PHYID1_AM79C874)
|
||||||
|
{
|
||||||
|
ndbg("Not an Am79c874 PHY: PHY1=%04x vs %04x\n", phyval, MII_PHYID1_AM79C874);
|
||||||
|
ret = -ENODEV;
|
||||||
|
goto dumpregs;
|
||||||
|
}
|
||||||
|
|
||||||
|
phyval = ez80emac_miiread(priv, MII_PHYID2);
|
||||||
|
if (phyval != MII_PHYID2_AM79C874)
|
||||||
|
{
|
||||||
|
ndbg("Not an Am79c874 PHY: PHY2=%04x vs %04x\n", phyval, MII_PHYID2_AM79C874);
|
||||||
|
ret = -ENODEV;
|
||||||
|
goto dumpregs;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check if the PHY can do auto-negotiation */
|
||||||
|
|
||||||
|
phyval = ez80emac_miiread(priv, MII_MSR);
|
||||||
|
if (phyval & MII_MSR_ANEGABLE)
|
||||||
|
{
|
||||||
|
phyval = MII_MCR_ANRESTART | MII_MCR_ANENABLE;
|
||||||
|
bauto = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
phyval = 0;
|
||||||
|
bauto = FALSE;
|
||||||
|
|
||||||
|
/* PADEN - EMAC pads all short frames by adding zeroes to the end of
|
||||||
|
* the data field. This bit is used in conjunction with ADPADN
|
||||||
|
* and VLPAD.
|
||||||
|
* CRCEN - Append CRC to every frame regardless of padding options.
|
||||||
|
*/
|
||||||
|
|
||||||
|
outp(EZ80_EMAC_CFG1, EMAC_CFG1_PADEN|EMAC_CFG1_CRCEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the configured link capabilities */
|
||||||
|
|
||||||
|
#if CONFIG_EZ80_PHYCONFIG == EZ80_EMAC_AUTONEG
|
||||||
|
|
||||||
|
ndbg("Configure autonegotiation\n");
|
||||||
|
if (bauto)
|
||||||
|
{
|
||||||
|
ez80emac_miiwrite(priv, MII_ADVERTISE,
|
||||||
|
MII_ADVERTISE_100BASETXFULL|MII_ADVERTISE_100BASETXHALF|
|
||||||
|
MII_ADVERTISE_10BASETXFULL|MII_ADVERTISE_10BASETXHALF|
|
||||||
|
MII_ADVERTISE_CSMA);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ndbg("Am79c784 is not capable of autonegotiation\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif CONFIG_EZ80_PHYCONFIG == EZ80_EMAC_100BFD
|
||||||
|
|
||||||
|
ndbg("100BASETX full duplex\n");
|
||||||
|
phyval |= MII_MCR_SPEED100 | MII_MCR_FULLDPLX;
|
||||||
|
ez80emac_miiwrite(priv, MII_ADVERTISE,
|
||||||
|
MII_ADVERTISE_100BASETXFULL|MII_ADVERTISE_100BASETXHALF|
|
||||||
|
MII_ADVERTISE_10BASETXFULL|MII_ADVERTISE_10BASETXHALF|
|
||||||
|
MII_ADVERTISE_CSMA);
|
||||||
|
|
||||||
|
#elif CONFIG_EZ80_PHYCONFIG == EZ80_EMAC_100BHD
|
||||||
|
|
||||||
|
ndbg("100BASETX half duplex\n");
|
||||||
|
phyval |= MII_MCR_SPEED100;
|
||||||
|
ez80emac_miiwrite(priv, MII_ADVERTISE,
|
||||||
|
MII_ADVERTISE_100BASETXHALF|MII_ADVERTISE_10BASETXFULL|
|
||||||
|
MII_ADVERTISE_10BASETXHALF|MII_ADVERTISE_CSMA);
|
||||||
|
|
||||||
|
#elif CONFIG_EZ80_PHYCONFIG == EZ80_EMAC_10BFD
|
||||||
|
|
||||||
|
ndbg("10BASETX full duplex\n");
|
||||||
|
phyval |= MII_MCR_FULLDPLX;
|
||||||
|
ez80emac_miiwrite(priv, MII_ADVERTISE,
|
||||||
|
MII_ADVERTISE_10BASETXFULL|MII_ADVERTISE_10BASETXHALF|MII_ADVERTISE_CSMA);
|
||||||
|
|
||||||
|
#elif CONFIG_EZ80_PHYCONFIG == EZ80_EMAC_10BHD
|
||||||
|
|
||||||
|
ndbg("10BASETX half duplex\n");
|
||||||
|
ez80emac_miiwrite(priv, MII_ADVERTISE,
|
||||||
|
MII_ADVERTISE_10BASETXHALF|MII_ADVERTISE_CSMA);
|
||||||
|
|
||||||
|
#else
|
||||||
|
# error "No recognized value of CONFIG_EZ80_PHYCONFIG"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ez80emac_miiwrite(priv, MII_MCR, phyval);
|
||||||
|
|
||||||
|
/* Wait for a link to be established */
|
||||||
|
|
||||||
|
for (i = 0; i < 50; i++)
|
||||||
|
{
|
||||||
|
phyval = ez80emac_miiread(priv, MII_MSR);
|
||||||
|
if ((phyval & (MII_MSR_ANEGCOMPLETE | MII_MSR_LINKSTATUS)) != 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
up_mdelay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((phyval & MII_MSR_LINKSTATUS) == 0)
|
||||||
|
{
|
||||||
|
ndbg("Failed to establish link\n");
|
||||||
|
ret = -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Read the Am79c874 diagnostics register for link settings */
|
||||||
|
|
||||||
|
phyval = ez80emac_miiread(priv, MII_AM79C874_DIAGNOSTIC);
|
||||||
|
if (phyval & AM79C874_DIAG_FULLDPLX)
|
||||||
|
{
|
||||||
|
outp(EZ80_EMAC_CFG1, EMAC_CFG1_PADEN|EMAC_CFG1_CRCEN|EMAC_CFG1_FULLHD);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outp(EZ80_EMAC_CFG1, EMAC_CFG1_PADEN|EMAC_CFG1_CRCEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dumpregs:
|
||||||
|
nvdbg("Am79c874 MII registers (FIAD=%lx)\n", CONFIG_EZ80_FIAD);
|
||||||
|
nvdbg(" MII_MCR: %04x\n", ez80emac_miiread(priv, MII_MCR));
|
||||||
|
nvdbg(" MII_MSR: %04x\n", ez80emac_miiread(priv, MII_MSR));
|
||||||
|
nvdbg(" MII_PHYID1: %04x\n", ez80emac_miiread(priv, MII_PHYID1));
|
||||||
|
nvdbg(" MII_PHYID2: %04x\n", ez80emac_miiread(priv, MII_PHYID2));
|
||||||
|
nvdbg(" MII_ADVERTISE: %04x\n", ez80emac_miiread(priv, MII_ADVERTISE));
|
||||||
|
nvdbg(" MII_LPA: %04x\n", ez80emac_miiread(priv, MII_LPA));
|
||||||
|
nvdbg(" MII_EXPANSION: %04x\n", ez80emac_miiread(priv, MII_EXPANSION));
|
||||||
|
nvdbg(" MII_DIAGNOSTICS: %04x\n", ez80emac_miiread(priv, MII_AM79C874_DIAGNOSTIC));
|
||||||
|
nvdbg("EMAC CFG1: %02x\n", inp(EZ80_EMAC_CFG1));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int ez80emac_miiautonegotiate(FAR struct ez80emac_driver_s *priv)
|
||||||
{
|
{
|
||||||
uint16 advertise;
|
uint16 advertise;
|
||||||
uint16 lpa;
|
uint16 lpa;
|
||||||
@ -656,7 +821,10 @@ static void ez80emac_miiautonegotiate(FAR struct ez80emac_driver_s *priv)
|
|||||||
nvdbg(" MII_ADVERTISE: %04x\n", ez80emac_miiread(priv, MII_ADVERTISE));
|
nvdbg(" MII_ADVERTISE: %04x\n", ez80emac_miiread(priv, MII_ADVERTISE));
|
||||||
nvdbg(" MII_LPA: %04x\n", ez80emac_miiread(priv, MII_LPA));
|
nvdbg(" MII_LPA: %04x\n", ez80emac_miiread(priv, MII_LPA));
|
||||||
nvdbg(" MII_EXPANSION: %04x\n", ez80emac_miiread(priv, MII_EXPANSION));
|
nvdbg(" MII_EXPANSION: %04x\n", ez80emac_miiread(priv, MII_EXPANSION));
|
||||||
|
nvdbg("EMAC CFG1: %02x\n", inp(EZ80_EMAC_CFG11));
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ez80emac_machash
|
* Function: ez80emac_machash
|
||||||
@ -1308,9 +1476,13 @@ static int ez80emac_ifup(FAR struct uip_driver_s *dev)
|
|||||||
ubyte regval;
|
ubyte regval;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ndbg("Bringing up: %d.%d.%d.%d\n",
|
ndbg("Bringing up: MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||||
dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
|
dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1],
|
||||||
(dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24)
|
dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3],
|
||||||
|
dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]);
|
||||||
|
ndbg(" IP %d.%d.%d.%d\n",
|
||||||
|
dev->d_ipaddr >> 24, (dev->d_ipaddr >> 16) & 0xff,
|
||||||
|
(dev->d_ipaddr >> 8) & 0xff, dev->d_ipaddr & 0xff);
|
||||||
|
|
||||||
/* Bring up the interface -- Must be down right now */
|
/* Bring up the interface -- Must be down right now */
|
||||||
|
|
||||||
@ -1678,7 +1850,7 @@ static int ez80_emacinitialize(void)
|
|||||||
|
|
||||||
/* Set auto-negotion */
|
/* Set auto-negotion */
|
||||||
|
|
||||||
ez80emac_miiautonegotiate(priv);
|
ret = ez80emac_miiautonegotiate(priv);
|
||||||
|
|
||||||
/* Initialize DMA / FIFO */
|
/* Initialize DMA / FIFO */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user